找回密码
 立即注册
查看: 57|回复: 1

鸿哥的串口发送程序

[复制链接]
  • 打卡等级:常住居民II
  • 打卡总天数:87
  • 最近打卡:2025-04-30 09:11:54
已绑定手机

12

主题

56

回帖

367

积分

中级会员

积分
367
发表于 2025-3-18 09:23:55 | 显示全部楼层 |阅读模式
#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[11]={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[11]={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[i]); //基于“发送单字节的最小接口函数”来实现的
}
}

//发送带协议的函数
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[2];
u32SendSize=*pSu32; //从带协议的数组中提取整包数组的有效发送长度

if(u32SendSize>u32SendMaxSize) //如果“有效发送长度”大于“最大限制的长度”,数据异常
{
return; //数据异常,直接退出当前函数,预防数组越界
}

for(i=0;i<u32SendSize;i++) //u32SendSize 为发送的数据长度
{
UsartSendByteData(pCu8SendMessage[i]); //基于“发送单字节的最小接口函数”来实现的
}
}

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[0],5);//从第 0 位置发送 5 个数据
UsartSendBuffer((const unsigned char *)&Gu8SendBuffer[6],5);//从第 6 位置发送 5 个数据

//发送带协议的数组
UsartSendMessage((const unsigned char *)&Gu8SendMessage[0],100); //必须从第 0 位置发送
}

回复

使用道具 举报 送花

3

主题

1160

回帖

1031

积分

等待验证会员

积分
1031
发表于 2025-3-18 09:33:00 | 显示全部楼层
鸿哥的串口发送程序展示了一个典型的串口通信实现,涵盖了字节发送、缓冲区发送以及带协议消息发送的功能。以下是对代码的简要分析:<br><br>1. UsartSendByteData:该函数负责发送单个字节数据,是串口通信的底层驱动。通过直接操作串口寄存器,确保数据以正确的波特率发送出去。<br><br>2. UsartSendBuffer:该函数实现了从任意起始位置发送任意长度数据的功能。通过指针和长度参数,程序可以灵活地处理不同大小的数据块,适用于大数据传输场景。<br><br>3. UsartSendMessage:该函数在发送数据的基础上增加了协议处理,通常用于封装数据包,包含起始标志、数据长度、校验和等信息,确保数据传输的完整性和可靠性。<br><br>该程序结构清晰,功能模块化,便于扩展和维护。建议在实际应用中,进一步考虑异常处理、超时重发等机制,以提高系统的鲁棒性。<br><br>[本文内容由国芯人工智能辅助生成,仅供参考]
回复 支持 反对

使用道具 举报 送花

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|小黑屋|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-5-3 07:19 , Processed in 0.209321 second(s), 51 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表