本帖最后由 corvettey 于 2019-4-3 04:23 编辑 我写了一个按顺序开灯的程序。三个灯都会按照顺序被打开,并再也不会亮起,即使再次按开关。 问题是每当开关被按下,第一个灯需要等到0~5秒的时间才能打开。有时候马上就会亮起,有时候需要等待2秒,等等。 我个人感觉应该是程序速度优化问题,可是我并不能找出问题。 我使用了C和IAR写程序。 麻烦大佬帮忙看看,感谢。 代码如下: #include "IOSTM8S103F3.h" void LightPC5(); void lightPC6(); void LightPC7(); void delay(int CountForDelay); void SequentialLighting(); void PinConfiguration(); int PseudoSwitch = 0; //这个全局变量控制第二三个LED的输入,使开关只用按一次而不用长按才能开灯 void main() { PinConfiguration(); SequentialLighting(); } void PinConfiguration() { //设置PC5为推挽输出控制LED PC_ODR = 0; PC_DDR_DDR5 = 1; PC_CR1_C15 = 1; PC_CR2_C25 = 1; //设置PC6为推挽输出控制LED PC_ODR = 0; PC_DDR_DDR6 = 1; PC_CR1_C16 = 1; PC_CR2_C26 = 1; //设置PC7为推挽输出控制LED PC_ODR = 0; PC_DDR_DDR7 = 1; PC_CR1_C17 = 1; PC_CR2_C27 = 1; //设置PD5为上拉模式的开关 PC_ODR = 0; PD_DDR_DDR5 = 0; PD_CR1_C15 = 1; PD_CR2_C25 = 0; } void SequentialLighting(void) { int CounterForOrder = 0; /*这个计数器变量确保三个灯严格按照顺序点亮(我不知道有没有更好的办法所以用了这个笨办法)*/ while (1) { if(CounterForOrder==0) //点亮第一个灯,PC7控制 { LightPC7(); CounterForOrder++; delay(700); } if(CounterForOrder==1) //点亮第二个灯,PC5控制 { LightPC5(); CounterForOrder++; delay(700); } if(CounterForOrder==2) //点亮第三个灯,PC6控制 { LightPC6(); CounterForOrder=0; delay(700); } } } void LightPC7(void) { PC_ODR_bit.ODR7 = !PD_IDR_bit.IDR5; //PC7读取开关状态 if(PC_ODR_bit.ODR7==1){ //如果PC7点亮LED delay(30); //保持很短的时间 //关闭PC7控制的LED,即使开关再被按下,这个LED也不会亮起 PC_ODR = 0; PC_DDR_DDR7 = 0; PC_CR1_C17 = 0; PC_CR2_C27 = 0; PseudoSwitch = 1; /*保证开关只用开一次的变量被激活,意味着开关会被一直认为是开启,即使现实中开关已松开*/ } } void LightPC5(void) { PC_ODR_bit.ODR5 = PseudoSwitch; //PC5直接读取开关变量的值,用开关变量打开PC5控制的LED if(PC_ODR_bit.ODR5==1){ //如果PC5控制的LED被点亮 delay(30); //保持一小会儿 //关闭PC5控制的LED,即使开关再被按下,这个LED也不会亮起 PC_ODR = 0; PC_DDR_DDR5 = 0; PC_CR1_C15 = 0; PC_CR2_C25 = 0; } } void LightPC6(void) { PC_ODR_bit.ODR6 = PseudoSwitch; if(PC_ODR_bit.ODR6==1){ delay(30); PC_ODR = 0; PC_DDR_DDR6 = 0; PC_CR1_C16 = 0; PC_CR2_C26 = 0; } } //延时程序 void delay(int CountForDelay) { volatile int i,j; for (i=0; i<CountForDelay; i++) for(j=0;j<200;j++); } |
STM8S003F3U6 请求各位大佬支援,但是遇到如下问题。。。这样就一定是这颗芯片的问题吗?
STVD如何生成库文件
STM8 flash 库函数 startaddress = startaddress + ((uint32_t)BlockNum * FLASH_BLOCK_S
stm 8 flash 在RAM运行代码的问题,是不是库函数有问题 Library call (?sll32_l0_l0_a) from within a
STM 有能替代MCHC912B32CFUE8 / NXP的型号吗?
STM8S的CAN总线使用
STM8L151在使用DAC功能后严重发热
STM8 IIC SLAVE 400K
STM8S 定时器1互补输出pwm
STM8S003F3 NRST电压低,无法开机
{
while(PD_IDR_bit.IDR5);
PC_ODR_bit.ODR7 = 1;
delay(30); //保持很短的时间
//关闭PC7控制的LED,即使开关再被按下,这个LED也不会亮起
PC_ODR = 0;
PC_DDR_DDR7 = 0;
PC_CR1_C17 = 0;
PC_CR2_C27 = 0;
PseudoSwitch = 1; /*保证开关只用开一次的变量被激活,意味着开关会被一直认为是开启,即使现实中开关已松开*/
}
评分
查看全部评分
评分
查看全部评分
PC_ODR_bit.ODR7 = !PD_IDR_bit.IDR5; //PC7读取开关状态
是在这里读取PD5的输入状态吧?
如果是的话,那么你按下按钮的时,需要程序恰好走到这里,PC7才能根据按钮状态进行响应。而主程序里有延时函数,wihile(1)里的部分循环一周可能需要的时间较长。
按钮可以用中断方式。
或者,把三个Delay(700)去掉,这样while循环里可以快一点,可以在判断灯确实被点亮过以后再进行延时。
评分
查看全部评分
评分
查看全部评分
程序思路非常混乱,把按键扫描和点灯事件分开处理。并且点完灯,也不需要把IO方向切到输入。
目的就是让按一次按键后,三个灯依次各自先点亮后熄灭;并且是一次性事件,再次有按键也不会执行相同操作。
评分
查看全部评分
有的,只不过在SequentialLighting()函数里。
整复杂了。
你的PseudoSwitch在LightPC7(void)第一次执行点亮后,始终等于1,没有清除状态。因此只有PC7灯会根据按键变化。PC5灯和PC6灯都会在每一次进入函数的时候执行持续delay(30)的点亮状态,然后关闭。delay(30)的时间是多久?是否短到无法点亮LED灯。
至于点亮第一个灯需要等到0~5秒,是因为从按键到点亮,你有0-3个delay(700)的范围的延时。
评分
查看全部评分