Part Number: MSP432P401R
Hi, the idea of the project is to detect the Back Electromagnetic Force (BEMF) of a BLDC and for this I have made this simple program where I wanted to use the ADC of the MSP432P401R in differential mode, since I have used six consecutive channels and the idea was to take the difference between two channels (the phase and the reference voltage) and study the change of sign, which would allow me to detect a zero crossing.
The problem is that I don't know if the idea of defining the channels I am interested in, enable the ADC, start conversion and assign the difference between the channels is correct in each case of the switch-case. The thing is that, despite of having caught six consecutive channels, I would only be interested in dealing with the difference between two channels depending on the state in which I find myself, but I do not know if it is the most indicated way as I have planned it.
-
#include "msp.h"
-
#include <stdint.h>
-
#include <stdio.h>
-
-
uint8_t estado = 0;
-
-
void inicializaciones(void){
-
// GPIO pin (P5.1) to be set to HIGH when zero-crossing to detect the BEMF
-
P5SEL0 &= ~BIT1;
-
P5SEL1 &= ~BIT1;
-
P5DIR |= BIT1; // output
-
}
-
-
void configuracion_ADC(void){
-
ADC14->CTL0 |= ADC14_CTL0_ON;
-
ADC14->CTL0 |= ADC14_CTL0_MSC | ADC14_CTL0_CONSEQ_2 | ADC14_CTL0_SSEL_4 | ADC14_CTL0_SHT0_7 | ADC14_CTL0_SHP;
-
ADC14->CTL1 = ADC14_CTL1_RES_3 | ADC14_CTL1_DF; /* 14-bit resolution; ADC14DF: -V(REF) = 8000h, +V(REF) = 7FFCh */
-
P8SEL1 |= (BIT2 | BIT3 | BIT4 | BIT5 | BIT6 | BIT7); // Enable A/D input channels
-
P8SEL0 |= (BIT2 | BIT3 | BIT4 | BIT5 | BIT6 | BIT7);
-
ADC14->CTL0 |= ADC14_CTL0_ENC; // ADC14ENC: Enable conversion after ADC configuration
-
}
-
-
void init_interrupciones(void){
-
NVIC_EnableIRQ(ADC14_IRQn);
-
__enable_irq(); // Enable global interrupt
-
}
-
-
void main(void)
-
{
-
WDT_A->CTL = WDT_A_CTL_PW | WDT_A_CTL_HOLD; // stop watchdog timer
-
inicializaciones();
-
configuracion_ADC();
-
init_interrupciones();
-
-
while(1){
-
static int16_t last_delta = -1; // By using "static" on variables that are inside a function, it allows their value to persist between calls.
-
static int16_t delta = 0;
-
-
switch(estado){
-
case 0: {
-
P5OUT &= ~BIT1; // We set the GPIO of the zero-crossing to LOW
-
ADC14->MCTL[0] |= ADC14_MCTLN_INCH_20 | ADC14_MCTLN_DIF; // ADC14DIF: ADC Differential Mode ADC; ADC14INCH_20 (when DIFF Mode is active): Ain+ = Channel A20, Ain- = Channel A21; Input in differential mode selection; Vref=AVCC
-
ADC14->CTL0 |= ADC14_CTL0_ENC | ADC14_CTL0_SC; /* ADC14ENC | ADC14SC: Enable conversions and start conversions */
-
while(!ADC14->IFGR0 & ADC14_IFGR0_IFG21) // wait till conversion is complete
-
delta = ADC14->MEM[20] - ADC14->MEM[21];
-
break;
-
}
-
case 1: {
-
P5OUT &= ~BIT1;
-
ADC14->MCTL[0] |= ADC14_MCTLN_INCH_18 | ADC14_MCTLN_DIF; // ADC14DIF: ADC Differential Mode ADC; ADC14INCH_18 (when DIFF Mode is active): Ain+ = Channel A18, Ain- = Channel A19; Input in differential mode selection; Vref=AVCC
-
ADC14->CTL0 |= ADC14_CTL0_ENC | ADC14_CTL0_SC;
-
while(!ADC14->IFGR0 & ADC14_IFGR0_IFG19)
-
delta = ADC14->MEM[18] - ADC14->MEM[19];
-
break;
-
}
-
case 2: {
-
P5OUT &= ~BIT1;
-
ADC14->MCTL[0] |= ADC14_MCTLN_INCH_22 | ADC14_MCTLN_DIF; // ADC14DIF: ADC Differential Mode ADC; ADC14INCH_22 (when DIFF Mode is active): Ain+ = Channel A22, Ain- = Channel A23; Input in differential mode selection; Vref=AVCC
-
ADC14->CTL0 |= ADC14_CTL0_ENC | ADC14_CTL0_SC;
-
while(!ADC14->IFGR0 & ADC14_IFGR0_IFG23)
-
delta = ADC14->MEM[22] - ADC14->MEM[23];
-
break;
-
}
-
case 3: {
-
P5OUT &= ~BIT1;
-
ADC14->MCTL[0] |= ADC14_MCTLN_INCH_20 | ADC14_MCTLN_DIF;
-
ADC14->CTL0 |= ADC14_CTL0_ENC | ADC14_CTL0_SC;
-
while(!ADC14->IFGR0 & ADC14_IFGR0_IFG21)
-
delta = ADC14->MEM[20] - ADC14->MEM[21];
-
break;
-
}
-
case 4: {
-
P5OUT &= ~BIT1;
-
ADC14->MCTL[0] |= ADC14_MCTLN_INCH_18 | ADC14_MCTLN_DIF;
-
ADC14->CTL0 |= ADC14_CTL0_ENC | ADC14_CTL0_SC;
-
while(!ADC14->IFGR0 & ADC14_IFGR0_IFG19)
-
delta = ADC14->MEM[18] - ADC14->MEM[19];
-
break;
-
}
-
case 5: {
-
P5OUT &= ~BIT1;
-
ADC14->MCTL[0] |= ADC14_MCTLN_INCH_22 | ADC14_MCTLN_DIF;
-
ADC14->CTL0 |= ADC14_CTL0_ENC | ADC14_CTL0_SC;
-
while(!ADC14->IFGR0 & ADC14_IFGR0_IFG23)
-
delta = ADC14->MEM[22] - ADC14->MEM[23];
-
break;
-
}
-
}
-
-
if(last_delta < 0){
-
if(delta > 0){
-
ADC14CTL0 &= ~ADC14ENC; // We stop the ADC, since it is NOT possible to change channel if the ADC is enabled.
-
P5OUT |= BIT1; // Set GPIO to HIGH when zero-crossing is detected
-
last_delta = delta;
-
estado = estado + 1;
-
if(estado > 5){
-
estado = 1;
-
}
-
}
-
}
-
-
if(last_delta > 0){
-
if(delta < 0){
-
ADC14CTL0 &= ~ADC14ENC;
-
P5OUT |= BIT1;
-
last_delta = delta;
-
estado = estado + 1;
-
if(estado > 5){
-
estado = 1;
-
}
-
}
-
}
-
}
-
}