一、完整工程參考:示例工程源碼(點擊下載@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;
}
}
}