鸿哥的串口发送程序
#include "REG52.H"void UsartSendByteData(unsigned char u8SendData); //发送一个字节的底层驱动函数
//发送任意起始位置任意长度的函数
void UsartSendBuffer(const unsigned char *pCu8SendBuffer,unsigned long u32SendSize);
//发送带协议的函数
void UsartSendMessage(const unsigned char *pCu8SendMessage,unsigned long u32SendMaxSize);
void usart(void); //串口接收的中断函数
void SystemInitial(void);
void Delay(unsigned long u32DelayTime);
void PeripheralInitial(void);
unsigned char Gu8ReceData;
unsigned char Gu8SendByteFinish=0; //发送一个字节完成的标志
//任意数组
unsigned char Gu8SendBuffer={0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A};
//“固定协议”十六进制的数据格式:EB 01 00 00 00 0B 03 E8 00 01 0B 。其中:
// EB 是数据头。
// 01 是代表数据类型。
// 00 00 00 0B 代表数据长度是 11 个(十进制)。
// 03 E8 00 01 0B 代表其它数据
//“带固定协议”的数组
unsigned char Gu8SendMessage={0xEB,0x01,0x00,0x00,0x00,0x0B,0x03,0xE8,0x00,0x01,0x0B};
void main()
{
SystemInitial();
Delay(10000);
PeripheralInitial(); //在此函数内部调用了发送的三串数据
while(1)
{
}
}
void usart(void) interrupt 4 //串口的中断函数
{
if(1==RI)
{
RI = 0;
Gu8ReceData=SBUF;
}
else //发送数据引起的中断
{
TI = 0; //及时清除发送中断的标志,避免一直无缘无故的进入中断。
Gu8SendByteFinish=1; //从 0 变成 1 通知主函数已经发送完一个字节的数据了。
}
}
void UsartSendByteData(unsigned char u8SendData) //发送一个字节的底层驱动函数
{
static unsigned int Su16TimeOutDelay; //超时处理的延时计时器
Gu8SendByteFinish=0; //在发送以字节之前,必须先把此全局变量的标志清零。
SBUF =u8SendData; //依靠寄存器 SBUF 作为载体发送一个字节的数据
Su16TimeOutDelay=0xffff; //超时处理的延时计时器装载一个相对合理的计时初始值
while(Su16TimeOutDelay>0) //超时处理
{
if(1==Gu8SendByteFinish)
{
break; //如果 Gu8SendByteFinish 为 1,则发送一个字节完成,退出当前循环等待。
}
Su16TimeOutDelay--; //超时计时器不断递减
}
//Delay();//在实际应用中,当连续发送一堆数据时如果发现丢失数据,可以尝试在此增加延时
}
//发送任意起始位置任意长度的函数
void UsartSendBuffer(const unsigned char *pCu8SendBuffer,unsigned long u32SendSize)
{
static unsigned long i;
for(i=0;i<u32SendSize;i++) //u32SendSize 为发送的数据长度
{
UsartSendByteData(pCu8SendBuffer); //基于“发送单字节的最小接口函数”来实现的
}
}
//发送带协议的函数
void UsartSendMessage(const unsigned char *pCu8SendMessage,unsigned long u32SendMaxSize)
{
static unsigned long i;
static unsigned long *pSu32;
static unsigned long u32SendSize;
pSu32=(const unsigned long *)&pCu8SendMessage;
u32SendSize=*pSu32; //从带协议的数组中提取整包数组的有效发送长度
if(u32SendSize>u32SendMaxSize) //如果“有效发送长度”大于“最大限制的长度”,数据异常
{
return; //数据异常,直接退出当前函数,预防数组越界
}
for(i=0;i<u32SendSize;i++) //u32SendSize 为发送的数据长度
{
UsartSendByteData(pCu8SendMessage); //基于“发送单字节的最小接口函数”来实现的
}
}
void SystemInitial(void)
{
unsigned char u8_TMOD_Temp=0;
//以下是定时器 0 的中断的配置
TMOD=0x01;
TH0=0xfc;
TL0=0x66;
EA=1;
ET0=1;
TR0=1;
//以下是串口接收中断的配置
//串口的波特率与内置的定时器 1 直接相关,因此配置此定时器 1 就等效于配置波特率。
u8_TMOD_Temp=0x20; //即将把定时器 1 设置为:工作方式 2,初值自动重装的 8 位定时器。
TMOD=TMOD&0x0f; //此寄存器低 4 位是跟定时器 0 相关,高 4 位是跟定时器 1 相关。先清零定时器 1。
TMOD=TMOD|u8_TMOD_Temp; //把高 4 位的定时器 1 填入 0x2,低 4 位的定时器 0 保持不变。
TH1=256-(11059200L/12/32/9600); //波特率为 9600。11059200 代表晶振 11.0592MHz,
TL1=256-(11059200L/12/32/9600); //L 代表 long 的长类型数据。根据芯片手册提供的计算公式。
TR1=1; //开启定时器 1
SM0=0;
SM1=1; //SM0 与 SM1 的设置:选择 10 位异步通信,波特率根据定时器 1 可变
REN=1; //允许串口接收数据
//为了保证串口中断接收的数据不丢失,必须设置 IP = 0x10,相当于把串口中断设置为最高优先级,
//这个时候,串口中断可以打断任何其他的中断服务函数实现嵌套,
IP =0x10; //把串口中断设置为最高优先级,必须的。
ES=1; //允许串口中断
EA=1; //允许总中断
}
void Delay(unsigned long u32DelayTime)
{
for(;u32DelayTime>0;u32DelayTime--);
}
void PeripheralInitial(void)
{
//发送任意数组
UsartSendBuffer((const unsigned char *)&Gu8SendBuffer,5);//从第 0 位置发送 5 个数据
UsartSendBuffer((const unsigned char *)&Gu8SendBuffer,5);//从第 6 位置发送 5 个数据
//发送带协议的数组
UsartSendMessage((const unsigned char *)&Gu8SendMessage,100); //必须从第 0 位置发送
}
鸿哥的串口发送程序展示了一个典型的串口通信实现,涵盖了字节发送、缓冲区发送以及带协议消息发送的功能。以下是对代码的简要分析:<br><br>1. UsartSendByteData:该函数负责发送单个字节数据,是串口通信的底层驱动。通过直接操作串口寄存器,确保数据以正确的波特率发送出去。<br><br>2. UsartSendBuffer:该函数实现了从任意起始位置发送任意长度数据的功能。通过指针和长度参数,程序可以灵活地处理不同大小的数据块,适用于大数据传输场景。<br><br>3. UsartSendMessage:该函数在发送数据的基础上增加了协议处理,通常用于封装数据包,包含起始标志、数据长度、校验和等信息,确保数据传输的完整性和可靠性。<br><br>该程序结构清晰,功能模块化,便于扩展和维护。建议在实际应用中,进一步考虑异常处理、超时重发等机制,以提高系统的鲁棒性。<br><br>[本文内容由国芯人工智能辅助生成,仅供参考]
页:
[1]