HI
现在我要使用MSP430F5172的比较器B,对4个外部信号电平跟内部的参考电压进行比较判断,单独使用一个通道对外部电平信号进行比较都没有问题,
现在是问题是MCU只有一个比较器B,而我需要对4个外部电平进行判断,所以我想使用时间片来动态切换输入通道,验证了就是不行,输入通道配置为第一个后就不能配置为其他输入通道了,造成根本没办法检测到后面3个通道的输入变化。
我找了好多资料和例子,都是只使用一个输入通道的,如果说硬件上不支持多个通道进行切换,那为什么有CB0 到CB15 多达15个通道???
1.比较器B框图
2.原理图
3.部分代码
// MOTOR1_TOUCH ---- CB15
// MOTOR2_TOUCH ---- CB14
// MOTOR3_TOUCH ---- CB13
// MOTOR4_TOUCH ---- CB10
volatile uint8_t touched; //Is the fader currently being touched?
volatile uint8_t index_port;
uint16_t time_count_1ms;
uint16_t time1_bak;
uint16_t time2_bak;
uint16_t time3_bak;
uint16_t time4_bak;
// Setup ComparatorB
void initCompare(void)
{
CBCTL0 &=~(CBIPSEL_10+CBIPSEL_13+CBIPSEL_14+CBIPSEL_15);
CBCTL3 &=~(BITA+BITD+BITE+BITF);
CBCTL0 |= CBIPEN;// + CBIPSEL_15;// + CBIPSEL_13 + CBIPSEL_14 + CBIPSEL_15;
// Enable V+, input channel CB0
CBCTL1 |= CBPWRMD_1; // normal power mode
CBCTL2 |= CBRSEL; // VREF is applied to -terminal
//Vcb_refv = IN*(n+1)/32
CBCTL2 |= CBRS_1+CBREF0_15; // VREF0设为16/32*Vcc == 1.15v 3.3
//CBCTL3 |= BITF; // + BITD + BITE + BITF;
// Input Buffer Disable @P3.7/CB10 @P3.3/CB13 @P3.2/CB14 @PJ.6/CB15
__delay_cycles(7500); // 延迟以待参考电压稳定
CBINT &= ~(CBIFG + CBIIFG); // Clear any errant interrupts
//CBINT |= CBIE; // Enable CompB Interrupt on rising edge of CBIFG (CBIES=0) 0 ---> 1.15
CBINT |= CBIE + CBIES; // Enable CompB Interrupt on falling edge of CBIFG (CBIES=1) 3.3 ---> 1.15
CBCTL1 |= CBON; // Turn On ComparatorB
//
index_port = 0;
}
// Comp_B ISR
#pragma vector=COMP_B_VECTOR
__interrupt void Comp_B_ISR (void)
{
CBINT &=~CBIFG; // Clear Interrupt flag
if(index_port == 0)
return;
if(index_port == 1){ // MOTOR1_TOUCH
touched |= 0x01; // Detect do touch
time1_bak = time_count_1ms; // Record curent time
}
if(index_port == 2){ // MOTOR2_TOUCH
touched |= 0x02; // Detect do touch
time2_bak = time_count_1ms; // Record curent time
}
if(index_port == 3){ // MOTOR3_TOUCH
touched |= 0x04; // Detect do touch
time3_bak = time_count_1ms; // Record curent time
}
if(index_port == 4){ // MOTOR4_TOUCH
touched |= 0x08; // Detect do touch
time4_bak = time_count_1ms; // Record curent time
}
}
//Check to see if the fader is being touched
void checkTouch(void)
{
if(time_count_1ms%1000 == 0){
time_count_1ms++;
index_port++;
if(index_port>4)
index_port = 1;
CBCTL0 &=~(CBIPSEL_10+CBIPSEL_13+CBIPSEL_14+CBIPSEL_15);
CBCTL3 &=~(BITA+BITD+BITE+BITF);
if(index_port == 1){
CBCTL0 |= CBIPSEL_15;
CBCTL3 |= BITF;
}else if(index_port == 2){
CBCTL0 |= CBIPSEL_14;
CBCTL3 |= BITE;
}else if(index_port == 3){
CBCTL0 |= CBIPSEL_13;
CBCTL3 |= BITD;
}else if(index_port == 4){
CBCTL0 |= CBIPSEL_10;
CBCTL3 |= BITA;
}
}
//juge Touch
if(time_count_1ms > time1_bak + 20){ //timeout
touched &=~0x01;
}
if(time_count_1ms > time2_bak + 20){
touched &=~0x02;
}
if(time_count_1ms > time3_bak + 20){
touched &=~0x04;
}
if(time_count_1ms > time4_bak + 20){
touched &=~0x08;
}
printf("--touch--0x%d index_port:%d\r\n",touched,index_port);
}
void main(void)
{
WDTCTL = WDTPW | WDTHOLD; // stop watchdog timer
pmm_setVcoreUp(0x01); // Vcore setting of at max 3 for 24MHz MCLK
pmm_setVcoreUp(0x02);
pmm_setVcoreUp(0x03);
initPorts(); // Config all the GPIOS for low-power (output low)
initClocks(); // Config clocks. MCLK=SMCLK=DCO=2*XT1=24MHz; ACLK=REFO=32kHz
//....
initCompare();
//....
initTimerA0();
__enable_interrupt();
while(1){
checkTouch();
}
}

