This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
大家好。 我在 MSP430G2955上有一个应用、用于测量连续6个元件的电容。 遗憾的是、在 WDT 栅极计时器期间、只有六个焊盘中的一个(焊盘0-5、只有焊盘1工作一致)会使 TA0R 计数。 当使用调试器在从 LPM3唤醒后检查 TA0R 的值时、对于焊盘1、TA0R 仅为非零、有时为 Pad2 (每5个读数)。 我的引脚映射已经过验证、此外、在使用示波器探测焊盘时、我可以在每个焊盘上看到正确的信号(每500ms 脉冲一次、其中每个脉冲的顶部由 RO 频率调制计数信号组成)。 振荡器似乎正常运行、但定时器没有计数。
以下是我的 CapSense 代码:
void TI_CTS_RO_PINOSC_TA0_WDTp_HAL (const 结构传感器*组、uint16_t *计数) { uint8_t i = 0; //**上下文保存 //状态寄存器: // WDTp:IE1、WDTCTL // TIMERA0:TA0CTL、TA0CCTL1 //端口:PxSEL、PxSEL2 uint8_t contextSaveSR; uint8_t contextSaveIE1; uint16_t contextSaveWDTCTL; uint16_t contextSaveTA0CTL、contextSaveTA0CCTL1、contextSaveTA0CCR1; uint8_t contextSaveSel、contextSaveSel2; contextSaveSR =__get_SR_register (); contextSaveIE1 = IE1; contextSaveWDTCTL = WDTCTL; contextSaveWDTCTL &= 0x00FF; contextSaveWDTCTL |= WDTPW; contextSaveTA0CTL = TA0CTL; contextSaveTA0CCTL1 = TA0CCTL1; contextSaveTA0CCR1 = TA0CCR1; //**设置测量计时器********* //选项为 TA0、TA1、TB0、TB1、TD0、TD1这些选项被向上推入 //电容式触控层。 //配置和启动计时器 TA0CTL = tassel_3 + MC_2; // INCLK、CONT 模式//从 tassel_3中更改 TA0CCTL1 = CM_3 + CCIS_2 + CAP; //位置 Neg、GND、电容 IE1|= WDTIE; //启用 WDT 中断
//循环所有6个焊盘 对于(i = 0;i <(group->numElements, i++) { //上下文保存 contextSaveSel =*((group->arrayPtr[i])->inputPxselRegister); contextSaveSel2 =*((group->arrayPtr[i])->inputPxsel2Register); //为张弛振荡器配置端口(英文... 启用电容式感应) *((group->arrayPtr[i])->inputPxselRegister )和=~((group->arrayPtr[i])->inputBits ); *((group->arrayPtr[i])->inputPxsel2Register)|=((group->arrayPtr[i])->inputBits ); //**设置门定时器******** //设置传感器测量的持续时间 WDTCTL =(WDTPW + WDTTMSEL +(group->measGateSource)+(group->accumulationCycles));// WDT 来自 aclk (栅极源)、aclk/512 ->使用 aclk 作为 CapSense TA0CTL |= TACLR; //清除 Timer_A TAR if (group->measGateSource == GATE _WDT_ACLK) { _bis_SR_register (LPM3_bits + GIE); //等待 WDT 中断 } 其他 { _bis_SR_register (LPM0_bits + GIE); //等待 WDT 中断 } //基准信号在 GND 和 VCC 之间交替(这会导致上升和下降触发事件) //这会导致一个转换、开始计算电容 TA0CCTL1 ^= CCIS0;//创建 CCR1的软件捕捉(设置比较源与 VCC) Counts[i]= TA0CCR1; //保存结果-此处的断点用于检查 TA0R 和 TA0CCR1 WDTCTL = WDTPW + WDTHOLD; //停止看门狗计时器 //上下文恢复 *((group->arrayPtr[i])->inputPxselRegister)= contextSaveSel; *((group->arrayPtr[i])->inputPxsel2Register)= contextSaveSel2; } //结束序列 //上下文恢复 _bis_SR_register (contextSaveSR); if (!(contextSaveSR & GIE)) { _BIC_SR_register (GIE); // } IE1 = contextSaveIE1; WDTCTL = contextSaveWDTCTL; TA0CTL = contextSaveTA0CTL; TA0CCTL1 = contextSaveTA0CCTL1; TA0CCR1 = contextSaveTA0CCR1; }
我们非常感谢您的任何帮助或想法。 您可以随时提出问题;我很乐意提供更多信息。
Ryan、
感谢你的帮助。 我已经阅读过您提到的示例、似乎我正在以与该示例相同的方式实施多个元素。 该示例中提供的 CTS_HAL.c 与我正在使用的 CTS_HAL.c 稍有不同(并在我的初始帖子中引用)、但进行这些微小的更改对我的系统没有任何影响。 (这些更改包括在进入看门狗 LPM 之前立即启用 TimerA0、以及不使用捕捉控制硬件寄存器 TA0CCTL1和 CCIS0软件捕捉)。
正如我在最初的帖子中所说的、主要问题是连接到引脚振荡器的计数器仅对焊盘1 (和 pad2、但每20个焊盘采样一次)的脉冲进行计数。 也许这一附加代码将有助于发现问题的根源。
这是我的主代码和按钮结构;此应用程序的主循环位于 sysExec 函数中。
int main (void) { WDTCTL = WDTPW | WDTHOLD; //停止看门狗计时器 //将初始化引脚设置为0 P1DIR = 0xFF; P2DIR = 0xF9;// 2.1和2.2上的 CapSense 引脚 P3DIR = 0xFE;// CapSense 3.0 P4DIR = 0x8F;// CapSense 引脚4.5、4.6、4.7 P1OUT = 0; P2OUT = 0; P3OUT = 0; P4OUT = 0; //执行硬件初始化 clock_init(); PIN_INIT(); UART_INIT (); #ifdef direct_debug_UART DBG_UART_INIT (); #endif //调用 sys exec,从不返回。 sysExec_exec(); //系统永远不应达到执行的这一点。 //但只是以防… disableGlobalInterrupt(); //强制看门狗复位 WDTCTL = 0xDEAD; while (1); } void clock_init (void) { DCOCTL = 0; //选择最低 DCOx 和 MODx 设置 BCSCTL1 = CALBC1_1MHz; //设置 DCO DCOCTL = CALDCO_1MHz; BCSCTL1 |= DIV_0; // ACLK/1 [ACLK/(0:1、1:2、2:4、3:8)] BCSCTL2 = 0; // SMCLK [SMCLK/(0:1、1:2:4、3:8)] BCSCTL3 |= LFXT1S_0 | XCAP_2; // LFXT1上的 LFXT1S0 32768Hz 晶振 } void PIN_INIT (void) { P1SEL |= GSM_INT + GSM_STATUS;//GSM_DCDC + GSM_INT + GSM_STATUS;Still TBD P1DIR |= VBAT_GND +_1V8_EN + GSM_DCDC; P1DIR &=~ GSM_INT_INT + GSM_INT_INT + GPT/ INT_INT 输入;P1DIR + GPT_0 + GPT_INT_INT_INT_INT + GPT/ INT_INT_INT_INT + INT_INT + // VBAT_GND 控制 VBAT 感应、默认关闭(低电平有效) // GSM_DCDC 控制(U4)默认关闭(高电平有效) //_1V8_EN 控制(U5)默认关闭(高电平有效) P2SEL |= BIT6 + BIT7;//为 P2.6 P2DIR 配置晶振 XIN |= I2C_DRV + GSM_EN + BIT7;//为 BIT7; // I2C_DRV 是输出 GPIO (默认为 hi-z)控制引脚2.0上的 I2C // BIT0 = ACLK OUT //当 GPS 打开时,GSM_PWR 是输出 GPIO (默认为 OFF)打开 //当调制解调器打开时,LS_VCC 为输出 GPIO (默认为关闭) // BIT7用于 P2.7 P3SEL 上的晶振 XOUT |= I2C_SDA + I2C_SCL + TXD; P3SEL2 |= RXD; P3DIR |= VBAT_GND +_1V8_EN; P4DIR |= GPS_ON_OFF; } void UART_init (void) { // UART 的 ACLK 源 UCA0CTL1 |= UCSSEL_1; // ACLK UCA0BR0 = 0x03; // 32 kHz 9600 UCA0BR1 = 0x00; // 32 kHz 9600 UCA0MCTL = UCBRS0 + UCBRS1; //调制 UCBRSx = 3. UCA0CTL1 &=~UCSWRST; //**初始化 USCI 状态机** UC0IE |= UCA0RXIE; //启用 USCI_A0 RX 中断 } void dbg_UART_init (void) { uint8_t 垃圾; memset (isrCommBuf、0、ISR_BUF_SIZE); isrCommBufHead = 0; isrCommBufTail = ISR_BUF_SIZE - 1; memset (isrCommRecv、0xff、3); //清除接收缓冲区 disable_UART_Rx (); 垃圾= UCA0RXBUF; enable_UART_Rx(); } void sysExec_exec(void) { uint32_t LOOP_COUNT; uint16_t NO_Water; uint8_t sample_period; //每秒启动计时器中断2x timerA1_init(); //初始化2015年1月1日的日期 // h、m、s、AM/pm settime (0x00、0x00、0x00、0x00); // y、m、d setdate (2015、1、1); WatersSense 初始化();//此函数不获取数据,它仅插入数据结构 //启用全局中断 enableGlobalInterrupt(); LOOP_COUNT = 0; NO_Water 时间= 0; SAMPLE_PERIOD = 0; //主循环 while (1) { //现在是取样的时候了 WaterSense_TakeReading();//此函数最终调用 PIN 振荡器函数 debug_sampProgress ();//向 UART 输入@ LOOP_COUNT++; //每个 tICKS_PER_second (2)秒更新并报告统计信息 如果(!(LOOP_COUNT % tICKS_PER_TREND) { uint8_t 级别; //水感应和存储 Level = WaterSenseAnalyzeData ((loop_count * seconds_per_Trend)/ticks per_Trend); 如果(!level) { 如果(no_water _time < 0xFFFE) NO_Water Time += seconds_per_Trend; } 其他 NO_Water 时间= 0; 如果(NO_Water 时间> NO_Water HF 到 LF Time in 秒) SAMPLE_PERIOD = 20秒_PER_TREND; 其他 SAMPLE_PERIOD = 0; #IF (PERIOD_TEMP_MEAS=1) //每分钟进行一次温度测量 if (!(loop_count %(ticks per_Trend *(60/seconds_per_Trend)))) WatersSenseReadInternalTemp ((loop_count * seconds_per_Trend)/ticks per_Trend); #endif } //现在是取样的时候了 IF (SAMPLE_PERIOD) { #ifdef direct_debug_UART //即将入睡20秒 while (!dbg_UART_txqempty ());//发送其余的调试数据 while (dbg_UART_txpend ()); //等待最后一个字符被使用 _delay_cycles (2000); //之后等待一个字符,以便终端不会被混淆 #endif timera1_20sec_sleep();//将深度睡眠时间设置为20秒 //此时禁用 UART TX ISR } //睡眠、Timer1A 中断时唤醒 _bis_SR_register (LPM3_bits); IF (SAMPLE_PERIOD) { timerA1_inter_sample_sleep ();//将计时器设置回采样频率 //此时启用 UART TX ISR SAMPLE_PERIOD = 0; LOOP_COUNT +=((20*TICKS_PER_TREND)/Seconds_PER_TREND);//我们睡眠了20秒(循环计数是样本滴答而不是秒) 如果(no_water _time < 0xFFFE) NO_WASE_TIME += 20;//我们在20秒内也没有水(可能) } //如果接收到 OTA 复位器件消息、则重新启动活动 //将为 true,等待延迟时间到期执行 // MSP430重新启动 。} } void waterscens_takeReading (void) { uint8_t pad_number; uint16_t padCounts[total_pad]; //执行电容测量 TI_CAPT_Raw (&PAD_SENSORS、&padCount[0]);//向 TI_CTS_RO_PINOSC_TA0_WDTp_HAL () //每个焊盘的环路。 对于(PAD_NUMBER = 0;PAD_NUMBER < NUM_PADS;PAD_NUMBER_++) { WaterDetect_add_sample, pad_number , padCounts[pad_number]; } } void timerA1_init (void) { //#if ticks per_Trend = 3 && seconds_per_Trend = 2 // TA1CCR0 = 21845-1;// 32786Hz/21845=1/1.5HZ //#elif (ticks per_Trend = 4 & seconds_per_Trend = 2+ ticks = 1)= 1CCR384 (ticks = 1)|= 1 (ticks = 1)|= 1–1–1 (ticks = 1) // 32786Hz/16384=2Hz 这是当前使用的设置 //#Elif TICKS_PER_Trend == 3 && Seconds_per_Trend == 1 // TA1CCR0=10922-1;// 32786Hz/1/10922 =32786HZ/10922 = 3Hz // TA1Elif=1/tIC1Hz;/1= 32786202Hz /1&tICK=1/tures=1/tures=1/tic4Hz;// tures=32786_1&ticf=1/tures=1/tic4Hz;// tures=1/tic1&tages=1/tic1&tic TA1CTL = tassel_1 + MC_1 + TACLR; TA1CCTL0 &=~CCIFG; TA1CCTL0 |= CCIE; TICKS_PER_second = 0; } //==== 下面的 structure.c 中的焊盘=== //================================================================================ //第一个元素(P4.7) const 结构元素 pad0 ={ .inputPxselRegister =(unsigned char *)&P4SEL、 .inputPxsel2Register =(unsigned char *)&P4SEL2、 .inputBits = BIT7、 .threshold = 500 }; //第二个元素(P2.1) const 结构元素 pad1 ={ .inputPxselRegister =(unsigned char *)&P2SEL、 .inputPxsel2Register =(unsigned char *)&P2SEL2、 .inputBits = BIT1、 .threshold = 100 }; //第三个元素(P4.6) const 结构元素 pad2 ={ .inputPxselRegister =(unsigned char *)&P4SEL、 .inputPxsel2Register =(unsigned char *)&P4SEL2、 .inputBits = BIT6、 .threshold = 100 }; //第四个元素(P2.2) const 结构元素 pad3 ={ .inputPxselRegister =(unsigned char *)&P2SEL、 .inputPxsel2Register =(unsigned char *)&P2SEL2、 .inputBits = BIT2、 .threshold = 100 }; //第五个元素(P4.5) const 结构元素 pad4 ={ .inputPxselRegister =(unsigned char *)&P4SEL、 .inputPxsel2Register =(unsigned char *)&P4SEL2、 .inputBits = BIT5、 .threshold = 100 }; //第六个元素(P3.0) const 结构元素 pad5 ={ .inputPxselRegister =(unsigned char *)&P3SEL、 .inputPxsel2Register =(unsigned char *)&P3SEL2、 .inputBits = BIT0、 .threshold = 100 };