PC控制单片机LED
电脑通过串口控制单片机LED亮灭
设计所需:Keil MDK5 软件 STM32单片机一块
前言
主要内容:
本章主要介绍如何利用PC机控制单片机的板载小灯的亮灭,电脑与单片机的串口通讯方式主要有查询法和中断法,程序编程方法主要采用标准库函数进行编程,本章中两种方法都有介绍,其次控制代码以及完整的代码会附录在文章后面。
以下是本篇文章正文内容,下面案例可供参考学习
一、功能要求
在单片机输出速度不高的的情况下,数据接收方式主要采用查询法或中断法,查询法主要是通过间隔一定的周期不停的查询接收标志方法,如果串口接收标志为真,表明接收到了数据,下位机就可以读数据函数读取该数据,否则继续进行查询是否有数据过来。中断法主要是当串口接收到数据即进入中断函数,接收数据。接收数据和发送数据的数据帧长度可变,但总主句字节数不能超过255。
二、通讯方法
1.查询法
查询法主要代码包括串口初始化、一字节数据发送函数、一字节数据接收函数、接收一帧数据函数、发送一帧数据函数以及清空数据发送缓冲区函数。
串口初始化函数不过多介绍,这里主要介绍发送一字节数据函数,该函数主要是自定义的枚举类来写的,函数返回值为枚举类定义的值,下位机就是通过接收数据中的值与枚举类中的值进行对比,ON为小灯灯熄,OFF为小灭点亮。
代码如下:
//枚举类型定义
typedef enum{NO=0,YES=1}TX_RX;
枚举类定义的函数
代码如下:
TX_RX Send_Byte(USART_TypeDef * USARTx,u8 dat){
vu32 cnt=0;
USART_SendData(USARTx,dat);
while(USART_GetFlagStatus(USARTx,USART_FLAG_TXE)==RESET){
cnt++;
if(cnt>100000){
return NO;
}
}
return YES;
}
查询法的数据接收函数
代码如下:
//查询法接收数据一字节函数
u8 Receive_Byte(USART_TypeDef * USARTx){
while(USART_GetFlagStatus(USARTx,USART_FLAG_RXNE)==RESET){}
return (USART_ReceiveData(USARTx));
}
//接收一帧数据函数
u8 ReceiveOK(USART_TypeDef * USARTx){
vu32 cnt=0;
while(1){
RxBuffer[RxCount++]=Receive_Byte(USARTx);
if(strstr((char *)RxBuffer,"ON")!=NULL){
RxCount=0;
return 1;
}
else{
if(strstr((char *)RxBuffer,"OFF")!=NULL){
RxCount=0;
return 2;
}
else{
if(RxCount>3){
RxCount=0;
}
}
}
cnt++;
if(cnt>100000)
return 0;
}
}
查询法数据发送一帧函数
代码如下:
void Send_String(USART_TypeDef * USARTx,u8 *Message){
while(*Message!='\0'){
Send_Byte(USARTx,*Message++);
}
}
数据发送完成后需要清空数据发送缓冲区,清空函数主要对发送缓冲区中的值逐一赋值0。
代码如下:
void Send_Clear(u8 len){
u8 i;
for(i=0;i<len;i++){
RxBuffer[i]=0;
}
}
2.中断法
中断法中主要修改的代码包括配置中断初始化、使能串口中断、编写串口中断函数。
这里主要介绍串口中断函数,中断法中加入了数据帧头以及数据帧尾,如0xEA作为数据帧头,0x55作为数据帧尾。
代码如下:
//串口中断函数
void USART1_IRQHandler(void){
if(USART_GetFlagStatus(USART1,USART_IT_RXNE)!=RESET){ //接收中断
USART_ClearITPendingBit(USART1,USART_IT_RXNE); //清除接收中断标志
RxBuffer[RxCount]=USART_ReceiveData(USART1);
RxCount++;
RxCount&=0xFF;
}
if(RxBuffer[RxCount-1]==0xEA){ //数据帧头
RxHeader=RxCount-1; //记录数据帧头位置
}
if((RxBuffer[RxHeader]==0xEA)&&(RxBuffer[RxCount-1]==0x55)){
RxLen=RxCount-1-RxHeader; //数据帧长度
RxOK=1; //接收到数据的标志
}
if(USART_GetFlagStatus(USART1,USART_FLAG_ORE)==SET){ //数据溢出处理
USART_ClearFlag(USART1,USART_FLAG_ORE); //读到SR
USART_ReceiveData(USART1); //读DR
}
}