本项目代码:
链接: https://pan.baidu.com/s/1h-vkvBnWJuqgnlYj7pVryA?pwd=jyjy 提取码: jyjy
1.项目需求
1.通过串口下发流水灯显示顺序指令。
2.当按下按键的时候,按照三种顺序显示流水灯。
3.程序启动时,先从E2PROM中读取查看是否有流水灯顺序,有就按照E2PROM中的第一组显示指令,如果E2PROM没有流水灯的顺序,等待串口下发指令,按照收到指令中的第一条流水灯显示,将指令写入到E2PROM;流水灯正常显示的时候,如果有新的指令下发,就按照新的指令显示流水灯,并更新E2PROM中的值。
2.项目实现例子
串口发送指令:3,1#2,3#1,2
经过解析后指令存入二维数组,可看成下图2-1所示:
图2-1
通过按键按下可控制index的值,选择是哪一组指令的流水灯,假如index=0,那么流水灯会按照key3,key1的顺序亮灭。
3.项目实现思路
本项目简单来说就是通过串口发送流水灯的顺序的指令,E2PROM读取之后处理指令,实现按键选择指令控制LED灯显示。
4.项目实现过程
4.1读取并处理指令
先从E2PROM中读取指令,如果没有读取到指令,串口下发指令,下发后将指令写入E2PROM,再解析指令(解析指令的思路就是用sscanf函数直接解析),详细代码如下所示:
//2.先从E2PROM读取指令
Inf_W24C02_ReadBytes(E2PROM_START_ADDR,buff,CMD_LEN);
printf("读取到指令\r\n");
//3.如果没有读取到指令,等待串口下发指令
if(strstr((char*)buff,(char*)'#') == NULL)
{
//3.1等待串口下发指令
while(!isToSend);
isToSend = 0;
//3.2把指令字符串写到E2PROM
Inf_W24C02_WriteBytes(E2PROM_START_ADDR,buff,CMD_LEN);
printf("指令下发完成\r\n");
}
//4.解析指令(指令可能来自E2PROM也可能来自串口),把解析出来的数字存储到二维数组中
handleCMD();
void handleCMD(void)
{
//3,2#2,3#3,1
sscanf((char*)buff, "%hhu,%hhu#%hhu,%hhu#%hhu,%hhu", &cmd[0][0], &cmd[0][1], &cmd[1][0], &cmd[1][1], &cmd[2][0], &cmd[2][1]);
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 2; j++)
{
printf("%d ", cmd[i][j]);
}
printf("\n");
}
}
4.2流水灯显示
流水灯显示开始之前先将所有灯熄灭,通过二维数组的值来控制LED灯的亮灭(思路是二维数组的行index代表的是对应的指令数,按键按下可选择index的值以此控制执行指令几),详细代码如下所示:
void doledflow(void)
{
for(uint8_t i = 0; i < 2; i++)
{
Driver_Led_Off(LED_1|LED_2|LED_3);
Delay_ms(500);
if(cmd[index][i] == 1)
{
Driver_Led_On(LED_1);
}
else if(cmd[index][i] == 2)
{
Driver_Led_On(LED_2);
}
else if(cmd[index][i] == 3)
{
Driver_Led_On(LED_3);
}
Delay_ms(500);
}
}
4.3检测按键
通过按键按下改变index的值,选择显示第几条指令,详细代码如下所示:
void checkKey(void)
{
if(isKeypressed)
{
isKeypressed = 0;
index++; //判断使用第几组流水灯
index = index % 3;
printf("按下按键:%d\r\n",index);
}
}
4.4检测串口
串口下发命令,详细代码如下所示:
void checkUsart(void)
{
if(isToSend)
{
isToSend = 0;
handleCMD();
Inf_W24C02_WriteBytes(E2PROM_START_ADDR,buff,CMD_LEN);
printf("下发新的命令:%s\r\n",buff);
}
}