当变量更改时如何打破 if
How can I break an if when a variable changes
我需要帮助我有这个基本的基本程序可以根据我按下的开关按顺序播放 LED,我想知道的是:如何中断(或停止)和 运行 另一个序列当我切换其他开关和 运行 新序列而不是之前的序列时,我想知道其他需要中止操作的程序是如何做到的,因为它将在 "loop" 有延迟和其他东西,我想在每个 led 打开和关闭的线之间放置一个 if 就可以了,但我不认为那是 correct/efficient 方式..谢谢!
#include <16f876.h>
#use delay(clock=4M)
#fuses XT,NOWDT
#use standard_io(A)
#use standard_io(B)
int16 t0=2000;
int16 t1=1000;
int16 t2=1000;
int16 t3=500;
void main(){
output_b(0b00000000);
while(TRUE){
if(input(PIN_A0)==0){
output_b(0b00000000);
output_b(0b00011000);
delay_ms(t0);
output_b(0b00100100);
delay_ms(t0);
output_b(0b01000010);
delay_ms(t0);
output_b(0b10000001);
delay_ms(t0);
}
if(input(PIN_A1)==0){
output_b(0b00000000);
output_b(0b00000001);
delay_ms(t1);
output_b(0b00000011);
delay_ms(t1);
output_b(0b00000111);
delay_ms(t1);
output_b(0b00001111);
delay_ms(t1);
output_b(0b00011111);
delay_ms(t1);
output_b(0b00111111);
delay_ms(t1);
output_b(0b01111111);
delay_ms(t1);
output_b(0b11111111);
delay_ms(t1);
}
if(input(PIN_A2)==0){
output_b(0b10000000);
delay_ms(t2);
output_b(0b11000000);
delay_ms(t2);
output_b(0b11100000);
delay_ms(t2);
output_b(0b11110000);
delay_ms(t2);
output_b(0b11111000);
delay_ms(t2);
output_b(0b11111100);
delay_ms(t2);
output_b(0b11111110);
delay_ms(t2);
output_b(0b11111111);
delay_ms(t2);
}
if(input(PIN_A3)==0){
output_b(0b00000000);
output_b(0b00000001);
delay_ms(t3);
output_b(0b00000000);
delay_ms(t3);
output_b(0b00000011);
delay_ms(t3);
output_b(0b00000000);
delay_ms(t3);
output_b(0b00000111);
delay_ms(t3);
output_b(0b00000000);
delay_ms(t3);
output_b(0b00001111);
delay_ms(t3);
output_b(0b00000000);
delay_ms(t3);
output_b(0b00011111);
delay_ms(t3);
output_b(0b00000000);
delay_ms(t3);
output_b(0b00111111);
delay_ms(t3);
output_b(0b00000000);
delay_ms(t3);
output_b(0b01111111);
delay_ms(t3);
output_b(0b00000000);
delay_ms(t3);
output_b(0b11111111);
delay_ms(t3);
}
}
}
您可以像这样编写自己的 delay_ms 函数:
bool my_delay_ms(int mstime) {
int current = 0;
while (current < mstime) {
delay_ms(10);
current += 10;
if (something?) {
return true;
}
}
return false;
}
然后将每个 delay_ms 替换为 if (my_delay_ms(t0)) continue;
。
您可以将 10 更改为您想要轮询中断信号的频率。该条件检测到中断信号,并且 continue
允许您的 while 循环跳转到下一个循环以在适当的情况下更改顺序。
您可以设置一个每毫秒触发一次的计时器,然后将代码重写为状态机。这样您就不会在延迟例程中浪费 cpu 个周期,并且您能够立即响应按钮按下,至少在一毫秒内,这对用户来说是即时的。
状态机跟踪一个变量。数字代表它所处的状态。每次执行状态时,状态可能会发生变化。更改后的状态将在下次计时器触发时执行。每个触发器还检查 buttons/debouncing 等
确保您的代码在计时器周期内运行,因此不要使用任何延迟,而是使用状态机来执行延迟,或者如果您需要不同的 resolution/timing,则使用另一个计时器。
我会留给你设置定时器和中断寄存器。
/* global variables */
int state = 0;
unsigned char delaycnt = 0;
char millisecond_flag = 0;
void DoStateMachine()
{
switch( state )
{
case 100:
output_b(0b00000000);
output_b(0b00011000);
state++;
delaycnt = 10;
break;
case 101:
delaycnt--;
if(delaycnt == 0) state = 102;
break;
case 200:
output_b(0b00000000);
output_b(0b00000001);
state++;
delaycnt = 10;
break;
case 201:
delaycnt--;
if(delaycnt == 0) state = 202;
break;
default:
state = 0; // do nothing
break;
}
}
void CheckButtons()
{
// Do button debounce here
if( BUTTON1 == 1)
state = 100;
if( BUTTON2 == 1)
state = 200;
}
void main()
{
//Setup timer here
while(1)
{
if( millisecond_flag == 1)
{
CheckButtons();
DoStateMachine();
millisecond_flag = 0;
}
//sleep device?
}
}
// Handle interrupt
void interrupt ISR()
{
if( TMR1IF == 1)
{
millisecond_flag = 1;
TMR1IF = 0;
}
}
我需要帮助我有这个基本的基本程序可以根据我按下的开关按顺序播放 LED,我想知道的是:如何中断(或停止)和 运行 另一个序列当我切换其他开关和 运行 新序列而不是之前的序列时,我想知道其他需要中止操作的程序是如何做到的,因为它将在 "loop" 有延迟和其他东西,我想在每个 led 打开和关闭的线之间放置一个 if 就可以了,但我不认为那是 correct/efficient 方式..谢谢!
#include <16f876.h>
#use delay(clock=4M)
#fuses XT,NOWDT
#use standard_io(A)
#use standard_io(B)
int16 t0=2000;
int16 t1=1000;
int16 t2=1000;
int16 t3=500;
void main(){
output_b(0b00000000);
while(TRUE){
if(input(PIN_A0)==0){
output_b(0b00000000);
output_b(0b00011000);
delay_ms(t0);
output_b(0b00100100);
delay_ms(t0);
output_b(0b01000010);
delay_ms(t0);
output_b(0b10000001);
delay_ms(t0);
}
if(input(PIN_A1)==0){
output_b(0b00000000);
output_b(0b00000001);
delay_ms(t1);
output_b(0b00000011);
delay_ms(t1);
output_b(0b00000111);
delay_ms(t1);
output_b(0b00001111);
delay_ms(t1);
output_b(0b00011111);
delay_ms(t1);
output_b(0b00111111);
delay_ms(t1);
output_b(0b01111111);
delay_ms(t1);
output_b(0b11111111);
delay_ms(t1);
}
if(input(PIN_A2)==0){
output_b(0b10000000);
delay_ms(t2);
output_b(0b11000000);
delay_ms(t2);
output_b(0b11100000);
delay_ms(t2);
output_b(0b11110000);
delay_ms(t2);
output_b(0b11111000);
delay_ms(t2);
output_b(0b11111100);
delay_ms(t2);
output_b(0b11111110);
delay_ms(t2);
output_b(0b11111111);
delay_ms(t2);
}
if(input(PIN_A3)==0){
output_b(0b00000000);
output_b(0b00000001);
delay_ms(t3);
output_b(0b00000000);
delay_ms(t3);
output_b(0b00000011);
delay_ms(t3);
output_b(0b00000000);
delay_ms(t3);
output_b(0b00000111);
delay_ms(t3);
output_b(0b00000000);
delay_ms(t3);
output_b(0b00001111);
delay_ms(t3);
output_b(0b00000000);
delay_ms(t3);
output_b(0b00011111);
delay_ms(t3);
output_b(0b00000000);
delay_ms(t3);
output_b(0b00111111);
delay_ms(t3);
output_b(0b00000000);
delay_ms(t3);
output_b(0b01111111);
delay_ms(t3);
output_b(0b00000000);
delay_ms(t3);
output_b(0b11111111);
delay_ms(t3);
}
}
}
您可以像这样编写自己的 delay_ms 函数:
bool my_delay_ms(int mstime) {
int current = 0;
while (current < mstime) {
delay_ms(10);
current += 10;
if (something?) {
return true;
}
}
return false;
}
然后将每个 delay_ms 替换为 if (my_delay_ms(t0)) continue;
。
您可以将 10 更改为您想要轮询中断信号的频率。该条件检测到中断信号,并且 continue
允许您的 while 循环跳转到下一个循环以在适当的情况下更改顺序。
您可以设置一个每毫秒触发一次的计时器,然后将代码重写为状态机。这样您就不会在延迟例程中浪费 cpu 个周期,并且您能够立即响应按钮按下,至少在一毫秒内,这对用户来说是即时的。
状态机跟踪一个变量。数字代表它所处的状态。每次执行状态时,状态可能会发生变化。更改后的状态将在下次计时器触发时执行。每个触发器还检查 buttons/debouncing 等
确保您的代码在计时器周期内运行,因此不要使用任何延迟,而是使用状态机来执行延迟,或者如果您需要不同的 resolution/timing,则使用另一个计时器。
我会留给你设置定时器和中断寄存器。
/* global variables */
int state = 0;
unsigned char delaycnt = 0;
char millisecond_flag = 0;
void DoStateMachine()
{
switch( state )
{
case 100:
output_b(0b00000000);
output_b(0b00011000);
state++;
delaycnt = 10;
break;
case 101:
delaycnt--;
if(delaycnt == 0) state = 102;
break;
case 200:
output_b(0b00000000);
output_b(0b00000001);
state++;
delaycnt = 10;
break;
case 201:
delaycnt--;
if(delaycnt == 0) state = 202;
break;
default:
state = 0; // do nothing
break;
}
}
void CheckButtons()
{
// Do button debounce here
if( BUTTON1 == 1)
state = 100;
if( BUTTON2 == 1)
state = 200;
}
void main()
{
//Setup timer here
while(1)
{
if( millisecond_flag == 1)
{
CheckButtons();
DoStateMachine();
millisecond_flag = 0;
}
//sleep device?
}
}
// Handle interrupt
void interrupt ISR()
{
if( TMR1IF == 1)
{
millisecond_flag = 1;
TMR1IF = 0;
}
}