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.
工具/软件:Code Composer Studio
您好! 我有一段代码、总共大约6秒、它成功地使 LED 进入和退出。 我想知道是否有办法让 WDT_ISR 改变 LED 亮度? (可能处于间隔模式)?
#include void _delay_ms (volatile unsigned int length){ volatile unsigned int delay = 0; for (delay = 0;delay < length;delay++){ _delay_cycles (1000); } } int main (void){ WDTCTL = WDTPW + WDTHOLD;//停止 WDT //**注意:此设置需要在电路板上的 LED1和 P1.2之间放置一根跳线** P1DIR |= BIT2; //为输出设置 Timer A 0.1 (P1.2) P1SEL |= BIT2; //P1.2特殊功能 SFRIE1 |= WDTIE;//启用 WDT 中断 TA0CCR0 = 350; TA0CCTL1 = OUTMOD_7; TA0CCR1 = 0; TA0CTL = tassel_1 + MC_1; volatile signed int i = 0; while (1){ 对于(I = 1;I < 309;I += 5){ TA0CCR1 = I; _delay_ms (50); } 对于(I = 309-1;I > 0;I -= 5){ TA0CCR1 = I; _delay_ms (50); } }
我更改了代码一位、我认为 WDT_ISR 工作正常。 它可以正常地使 LED 变暗、而不会出现问题。 我现在遇到了另外2个尝试实现的中断的问题。 我想让开关1暂停衰减、开关2恢复衰减。 我以为我所要做的就是停止和重新启动 WDT 来实现这一点、但似乎我错了。 如果我能获得一些帮助、我将不胜感激。
#include void _delay_ms (volatile unsigned int length){ volatile unsigned int delay = 0; for (delay = 0;delay < length;delay++){ _delay_cycles (1000); } } int main (void) { WDTCTL = WDT_MDLY_32;//设置 WDT 间隔 _EINT(); //启用中断 //**注:此设置需要在板上的 LED1和 P1.2之间放置一根跳线** P1DIR |= BIT2; //为输出设置计时器 A 0.1 (P1.2) P1SEL |= BIT2; // P1.2特殊功能 SFRIE1 |= WDTIE;//启用 WDT 中断 P1DIR &=~BIT1; //将 P1.1设置为输入(SW2) P1REN |= BIT1; //启用上拉电阻器 P1OUT |= BIT1; //正确的 IO 所需 P1IE |= BIT1; //在 P1.1上启用中断 P1IES |= BIT1; //为中断启用 hi->lo 边缘 P1IFG &=~BIT1; //清除任何错误的中断标志 P2DIR &=~BIT1; //将 P2.1设置为输入(SW1) P2REN |= BIT1; //启用上拉电阻器 P2OUT |= BIT1; //正确的 IO 所需 P2IE |= BIT1; //在 P2.1上启用中断 P2IES |= BIT1; //为中断启用 hi->lo 边缘 P2IFG &=~BIT1; //清除任何错误的中断标志 TA0CCR0 = 350; TA0CCTL1 = OUTMOD_7; TA0CCR1 = 0; TA0CTL = tassel_1 + MC_1; while (1){}//在这里等待 } #pragma vector = WDT_vector __interrupt void watchdog_timer (void) { volatile signed int i = 0; 对于(I = 1;I < 309;I += 5){ TA0CCR1 = I; _delay_ms (50); } 对于(I = 309-1;I > 0;I -= 5){ TA0CCR1 = I; _delay_ms (50); } } //此 ISR 处理 SW1键按 #pragma vector = port2_vector __interrupt void port2_ISR (void) { //让我们清除标志 P2IFG &=~BIT1; //去抖部分 _DELAY_CYCLES (25000); //如果 SW1未按下,则返回 if ((P2IN&BIT1)!=0x00) 返回; WDTCTL = WDTPW + WDTHOLD;//停止 WDT } //此 ISR 处理 SW2键按 #pragma vector = Port1_vector __interrupt void Port1_ISR (void) { //让我们清除标志 P1IFG &=~BIT1; //去抖部分 _DELAY_CYCLES (25000); //如果未按下 SW2,则返回 if (((P1IN&BIT1)!=0x00) 返回; WDTCTL = WDT_MDLY_32;//设置 WDT 间隔 }
1) 1)中断在进入 ISR 时被禁用。 因此,当 watchdog_timer()正在运行时,按钮不会中断它。 这是 ISR 非常短的原因之一。
2) 2)看门狗间隔为32ms、但 ISR 需要6秒。 在完成时、WDT 将触发另一个中断。 WDTIFG 的优先级高于任一端口 IFG [参考数据表(SLAS590N)表6-1]、因此它将(始终)优先、并且端口 ISR 将永远不会运行。
我建议您将褪色代码(返回)移到 main()中,并让按钮设置一个开/关字节,以控制褪色循环的工作方式。
哦、我明白了。 首先是不可能尝试这种方法。 我将其改回 main 中的循环、并尝试创建一个简单的 int 变量作为0/1标志。 出于某种原因、我的按钮仍然不会暂停/重新启动淡入淡出。 相反、SW1会导致 LED 在完全淡入周期后暂停、而 SW2无法重新启动。 以下是我的更新代码:
#include volatile signed int i = 0; volatile unsigned int j = 1; void _delay_ms (volatile unsigned int length) { volatile unsigned int delay = 0; for (delay = 0;delay < length;delay++) { _delay_cycles (1000); } } int main (void) { WDTCTL = WDTPW + WDTHOLD;//停止看门狗计时器 _EINT(); //启用中断 //**注:此设置需要在板上的 LED1和 P1.2之间放置跳线** P1DIR |= BIT2; //为输出设置计时器 A 0.1 (P1.2) P1SEL |= BIT2; // P1.2特殊功能 P1DIR &=~BIT1; //将 P1.1设置为输入(SW2) P1REN |= BIT1; //启用上拉电阻器 P1OUT |= BIT1; //正确的 IO 所需 P1IE |= BIT1; //在 P1.1上启用中断 P1IES |= BIT1; //为中断启用 hi->lo 边缘 P1IFG &=~BIT1; //清除任何错误的中断标志 P2DIR &=~BIT1; //将 P2.1设置为输入(SW1) P2REN |= BIT1; //启用上拉电阻器 P2OUT |= BIT1; //正确的 IO 所需 P2IE |= BIT1; //在 P2.1上启用中断 P2IES |= BIT1; //为中断启用 hi->lo 边缘 P2IFG &=~BIT1; //清除任何错误的中断标志 TA0CCR0 = 350; TA0CCTL1 = OUTMOD_7;//定时器 A 处于增/减模式 TA0CCR1 = 0; TA0CTL = tassel_1 + MC_1; while (j = 1)//在这里等待中断 { 对于(I = 1;I < 309;I += 5){ TA0CCR1 = I; _delay_ms (50); } 对于(I = 309-1;I > 0;I -= 5){ TA0CCR1 = I; _delay_ms (50); } } }// 此 ISR 处理 SW1键按 #pragma vector = port2_vector __interrupt void port2_ISR (void) { //让我们清除标志 P2IFG &=~BIT1; //去抖部分 _DELAY_CYCLES (25000); //如果 SW1未按下,则返回 if ((P2IN&BIT1)!=0x00) { 返回; } //暂停褪色 if (j ==1) { J = 0; } } //此 ISR 处理 SW2键按 #pragma vector = Port1_vector __interrupt void Port1_ISR (void) { //让我们清除标志 P1IFG &=~BIT1; //去抖部分 _DELAY_CYCLES (25000); //如果未按下 SW2,则返回 if (((P1IN&BIT1)!=0x00) { 返回; } //继续褪色 if (j ==0) { J = 1; } }
好的、我将它非常接近正常运行。 我更改了环路位以解决编码错误。 现在、其行为是 SW1始终暂停衰减、但 SW2在恢复时随机决定衰减的方向。 有时、当我按下它时、它将恢复其所处方向的衰减、有时它将反转衰减的方向。
#include volatile signed int i = 0; volatile unsigned int j = 1; void _delay_ms (volatile unsigned int length) { volatile unsigned int delay = 0; for (delay = 0;delay < length;delay++) { _delay_cycles (1000); } } int main (void) { WDTCTL = WDTPW + WDTHOLD;//停止看门狗计时器 _EINT(); //启用中断 //**注:此设置需要在板上的 LED1和 P1.2之间放置跳线** P1DIR |= BIT2; //为输出设置计时器 A 0.1 (P1.2) P1SEL |= BIT2; // P1.2特殊功能 P1DIR &=~BIT1; //将 P1.1设置为输入(SW2) P1REN |= BIT1; //启用上拉电阻器 P1OUT |= BIT1; //正确的 IO 所需 P1IE |= BIT1; //在 P1.1上启用中断 P1IES |= BIT1; //为中断启用 hi->lo 边缘 P1IFG &=~BIT1; //清除任何错误的中断标志 P2DIR &=~BIT1; //将 P2.1设置为输入(SW1) P2REN |= BIT1; //启用上拉电阻器 P2OUT |= BIT1; //正确的 IO 所需 P2IE |= BIT1; //在 P2.1上启用中断 P2IES |= BIT1; //为中断启用 hi->lo 边缘 P2IFG &=~BIT1; //清除任何错误的中断标志 TA0CCR0 = 350; TA0CCTL1 = OUTMOD_7;//定时器 A 处于增/减模式 TA0CCR1 = 0; TA0CTL = tassel_1 + MC_1; while (1)//在这里等待中断 { 对于(I;j = 1 && I < 309;I += 5) { TA0CCR1 = I; _delay_ms (50); } for (i;j = 1 && I > 0;i = 5){ TA0CCR1 = I; _delay_ms (50); } } }// 此 ISR 处理 SW1键按 #pragma vector = port2_vector __interrupt void port2_ISR (void) { //让我们清除标志 P2IFG &=~BIT1; //去抖部分 _DELAY_CYCLES (25000); //如果 SW1未按下,则返回 if ((P2IN&BIT1)!=0x00) { 返回; } //暂停褪色 if (j ==1) { J = 0; } } //此 ISR 处理 SW2键按 #pragma vector = Port1_vector __interrupt void Port1_ISR (void) { //让我们清除标志 P1IFG &=~BIT1; //去抖部分 _DELAY_CYCLES (25000); //如果未按下 SW2,则返回 if (((P1IN&BIT1)!=0x00) { 返回; } //继续褪色 if (j ==0) { J = 1; } }