51单片机串口通讯例程源码

一、完整工程参考:示例工程源码(点击下载@akoc)

二、源码展示:

#define USART_RX_LEN 20  //接收缓存长度(请勿超过芯片rom剩余空间大小)  
#define USART_TX_LEN 20  //发送缓存长度                                                                
typedef struct      //串口相关结构体定义(主要用于接收):
{
    u8 RX_BUFF[USART_RX_LEN]; //接收缓存
    u8 TX_BUFF[USART_TX_LEN]; //发送缓存
    u16 RX_COUNT;
}USART;
USART Usart;

void USART_Configure(u16 BaudRate) //初使化函数  输入参数:波特率
{
    u8 TH1_Dat;
    
  switch(BaudRate) //采用switch提高可读性
    {
      case 1200:  TH1_Dat=0xE8; break;
        case 2400:  TH1_Dat=0xF4; break;
        case 4800:  TH1_Dat=0xFA; break;
        case 9600:  TH1_Dat=0xFD; break;
        case 14400: TH1_Dat=0xFE; break;
    }
    TMOD &= 0x0F;//先清除再配置
    TMOD |= 0x20;
    SCON &= 0x0F;
    SCON |= 0x50;
    TH1 = TH1_Dat;
    TL1 = TH1;
    PCON = 0x00;
    EA = 1;
    ES = 1;
    TR1 = 1;  
}

void USART_SendByte(u8 dat) //单字符发送
{
    SBUF=dat;
    while(!TI);  //等待发送数据完成
    TI=0;                //清除发送完成标志位
}
void USART_Send(u8* arr,u16 len)//多字符发送
{
  u16 i;
    for(i=0;i<len;i++)
    {
        SBUF=arr[i];
      while(!TI);  //等待发送数据完成
      TI=0;                //清除发送完成标志位  
    }
}
void USART_SendStr(u8* str)//字符串发送
{
  while(1)
    {
      if(*str=='\0') break;
        SBUF=*str++;
        while(!TI);  //等待发送数据完成
      TI=0;                //清除发送完成标志位
    }
}

void USART_IRQHandler(void) interrupt 4  //串口中断函数
{          
  if(RI==1)    //判断是否为接收中断(串口中断分为发送中断和接收中断,均用同一个中断服务函数入口)
    {
        RI = 0;    //清除RI硬件接收中断标志 
        Usart.RX_BUFF[Usart.RX_COUNT++]=SBUF;
        if(Usart.RX_COUNT==USART_RX_LEN) Usart.RX_COUNT=0;
    }    
}

//示例:

/*Uart串口发送函数示例:
1.USART_SendByte(u8 dat) //发送单字节数据
  例:USART_SendByte(0x04);

2.USART_Send(u8* arr,u16 len) //发送多字节数据
  例:
  Usart.TX_BUFF[0]=0xA1;
  Usart.TX_BUFF[1]=0x08;
  Usart.TX_BUFF[2]=0x04;
  Usart.TX_BUFF[3]=0xF9;
  USART_Send(Usart.TX_BUFF,4);
  或
  u8 Arr[16]={0xA1,0x08,0x04,0xF9};
  USART_Send(Arr,4);

3.USART_SendStr(u8* str) //发送字符串数据
  USART_SendStr("大吉在利,晚上吃鸡!\r\n");


Uart串口接收函数示例:
 

//1.单字符指令接收:

#include "reg51.h"
void main(void)
{
   USART_Configure(9600);//配置9600波特率(默认无奇偶校验,1位停止位,8位数据位)
   while(1)
     {
       if(Usart.RX_COUNT>0) //判断串口是否有接收
         {
           Usart.RX_COUNT=0;
             if(Usart.RX_BUFF[0]=='A') //如果控制对象比较多请换成switch()
             {
               P1=0x0F;
             }
             if(Usart.RX_BUFF[0]=='B')
             {
               P1=0xF0;
             }
         }
     }
}

//2.多字符指令接收:(为了方便,我们用C标准库自带的string.h)
#include "reg51.h"
#include <string.h>
void main(void)
{
   char xbuff[20];
   USART_Configure(9600);//配置9600波特率(默认无奇偶校验,1位停止位,8位数据位)
   while(1)
     {
       if(Usart.RX_COUNT>4) //判断串口是否接收到指令(设指令格式为:开灯/  关灯/  用/来表示指令结束符)
         {
           if(Usart.RX_BUFF[4]=='/') //断判结束符
             {
                 Usart.RX_COUNT=0;
                 strncpy(xbuff, Usart.RX_BUFF+0 , 4);//+0表示从接收缓存的第0个字符开始截取4个字符到xbuff判断指令
                 if(strncmp(xbuff,"开灯",4) == 0) 
                 {
                   P1=0x01;
                 }
                 if(strncmp(xbuff,"关灯",4) == 0) 
                 {
                   P1=~0x01;
                 }
             }
             else
             {
               Usart.RX_COUNT=0;
             }
     }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章