使用正点原子STMF4板子完成下列操作:
基础题1,实现从串口输入以下16进制指令操控LED灯的开关状态(40分)
非以下1-7指令,串口返回提示:
AA AA AA AA AA AA AA
指令1:使能LED0的闪烁(开机时默认为关闭状态)
AA AB 01 00 00 0D 0A
指令2:关闭LED0的闪烁
AA AB 02 00 00 0D 0A
指令3:使能LED1的闪烁(开机时默认为关闭状态)
AA AB 03 00 00 0D 0A
指令4:关闭LED1的闪烁
AA AB 04 00 00 0D 0A
基础题2,实现从串口输入以下16进制指令操控LED灯的闪烁间隔(40分)
指令5:配置LED0与LED1共用的闪烁延迟(默认延迟是500ms,注意数据的拼接,XXXX的格式为高8位在前,低8位在后,是一个16位数,表示LED闪烁延迟,单位:ms)
AA AB 05 XX XX 0D 0A
提高题,实现从串口输入以下16进制指令操控LED灯的闪烁机制(20分)
指令6:配置为两个LED交替闪烁模式,但不控制LED开关(默认开机使用的是共同闪烁)
AA AB 06 00 00 0D 0A
指令7:配置为两个LED共同闪烁模式,但不控制LED开关(默认开机使用的是共同闪烁)
AA AB 07 00 00 0D 0A
流程图:
main.c文件代码:
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "beep.h"
#include "key.h"
int chartoint(char hex) //十六进制字符转十进制整型
{
if('0'<=hex&&hex<='9')
return hex-'0';
if('a'<=hex&&hex<='f')
return hex-'a'+10;
if('A'<=hex&&hex<='F')
return hex-'F'+10;
return -1;
}
int main(void)
{
u8 t; //定义循环用的变量
u8 len; //定义接收数据长度变量
u8 Flag=0; //指示输入指令是否正确标志
u8 LED0_flag=0; //指示LED0是否闪烁
u8 LED1_flag=0; //指示LED1是否闪烁
u8 code=0; //指令代号
u16 dalaytime=500; //定义延时时间
u8 shinemode=0; //定义闪烁模式并初始化为共同闪烁0,1为交替闪烁模式
uint8_t str1[]={'A','A',' ','A', 'B',' ', '0',' ','0','0',' ','0','0',' ','0','D',' ','0','A'}; //定义数组用于对比输入指令是否为要求的指令
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
delay_init(168); //延时初始化
uart_init(115200); //串口初始化波特率为115200
LED_Init(); //初始化与LED连接的硬件接口
while(1)
{
if(USART_RX_STA&0x8000) //判断数据是否接收
{
len=USART_RX_STA&0x3fff;//得到此次接收到的数据长度
if(len==20) //判断数据长度是否是20,进一步判断输入代码是否是指令代码
{
Flag=1; //输入标志置1
for(t=0;t<7;t++)
{
if(USART_RX_BUF[t]!=str1[t]) //输入前7个字符是否与要求指令相同,不同输入标志置0并退出
{
Flag=0;
break;
}
}
code=USART_RX_BUF[7]-'0'; //得到指令序号
if(code==5) //判断是否为指令5
{
for(t=14;t<20;t++) //判断后6个字符是否一致,不同输入标志置0并退出
{
if(USART_RX_BUF[t]!=str1[t-1])
{
Flag=0;
break;
}
}
for(t=9;t<14;t++) //判断第10-14个字符是否一致,不同则输入标志置0并退出
{
if(t==11) //判断第12个字符是否一致,不同则输入标志置0
{
if(USART_RX_BUF[11]!=' ')
{
Flag=0;
}
continue ;
}
if (chartoint(USART_RX_BUF[t])==-1) //判断第10,11,13,14字符是否符合,不符合则输入标志置0退出
{
Flag=0;
break;
}
}
}
else //如果指令序号不是5
{
for(t=8;t<20;t++) //判断第9-20字符是否符合,不符合则输入标志置0退出
{
if(USART_RX_BUF[t]!=str1[t-1])
{
Flag=0;
break;
}
}
}
}
if(Flag==1) //判断输入的是否是内部指令
{
switch(code) //根据不同的指令序号,执行相应的操作
{
case 1:
LED0_flag=1; //LED0闪烁
break;
case 2:
LED0_flag=0; //LED0熄灭
break;
case 3:
LED1_flag=1; //LED1闪烁
break;
case 4:
LED1_flag=0; //LED1熄灭
break;
case 5: // 闪烁时间间隔设置
dalaytime=chartoint(USART_RX_BUF[9])*16*16*16+chartoint(USART_RX_BUF[10])*16*16+chartoint(USART_RX_BUF[12])*16+chartoint(USART_RX_BUF[13]);
break;
case 6:
shinemode=1; //交替闪烁
break;
case 7:
shinemode=0; //共同闪烁
break;
default:
printf("AA AA AA AA AA AA AA\r\n"); //不是以上指令 输出错误提示
}
}
else
{
printf("AA AA AA AA AA AA AA\r\n"); //输入错误,输出错误提示
}
USART_RX_STA=0; //接收状态置0
}
if(shinemode==0&&LED0_flag==1&&LED1_flag==1) //共同闪烁
{
GPIO_WriteBit(GPIOF,GPIO_Pin_9|GPIO_Pin_10,Bit_RESET); //点亮LED0,LED1
delay_ms(dalaytime); //延时dalaytime
GPIO_WriteBit(GPIOF,GPIO_Pin_9|GPIO_Pin_10,Bit_SET); //熄灭LED0,LED1
delay_ms(dalaytime);
}
else //交替闪烁
{
if(LED0_flag==1) //LED0闪烁
{
GPIO_WriteBit(GPIOF,GPIO_Pin_9,Bit_RESET);
delay_ms(dalaytime);
GPIO_WriteBit(GPIOF,GPIO_Pin_9,Bit_SET);
delay_ms(dalaytime);
}
if(LED1_flag==1) //LED1闪烁
{
GPIO_WriteBit(GPIOF,GPIO_Pin_10,Bit_RESET);
delay_ms(dalaytime);
GPIO_WriteBit(GPIOF,GPIO_Pin_10,Bit_SET);
delay_ms(dalaytime);
}
}
}
}
欢迎指正和交流!
2020年9月1日