页面加载中,请稍候
来源:玩点嵌入式发布时间:2022-10-202777浏览
询问 AI
typedefstruct
{
uint8_t*dst_buf;//指向接收缓存
uint8_tsfd;//帧首标志,为0xFF或者0xEE
uint8_tsfd_flag;//找到帧首,一般是3~5个FF或EE
uint8_tsfd_count;//帧首的个数,一般3~5个
uint8_treceived_len;//已经接收的字节数
uint8_tfind_fram_flag;//找到完整帧后,置1
uint8_tframe_len;//本帧数据总长度,这个区域是可选的
}find_frame_struct;3.2 初始化数据结构,一般放在串口初始化中/**
*@brief初始化寻找帧的数据结构
*@paramp_fine_frame:指向打包帧数据结构体变量
*@paramdst_buf:指向帧缓冲区
*@paramsfd:帧首标志,一般为0xFF或者0xEE
*/
voidinit_find_frame_struct(find_frame_struct*p_find_frame,uint8_t*dst_buf,uint8_tsfd)
{
p_find_frame->dst_buf=dst_buf;
p_find_frame->sfd=sfd;
p_find_frame->find_fram_flag=0;
p_find_frame->frame_len=10;
p_find_frame->received_len=0;
p_find_frame->sfd_count=0;
p_find_frame->sfd_flag=0;
}3.3 数据打包程序/**
*@brief寻找一帧数据返回处理的数据个数
*@paramp_find_frame:指向打包帧数据结构体变量
*@paramsrc_buf:指向串口接收的原始数据
*@paramdata_len:src_buf本次串口接收到的原始数据个数
*@paramsum_len:帧缓存的最大长度
*@return本次处理的数据个数
*/
uint32_tfind_one_frame(find_frame_struct*p_find_frame,constuint8_t*src_buf,uint32_tdata_len,uint32_tsum_len)
{
uint32_tsrc_len=0;
while(data_len--)
{
if(p_find_frame->sfd_flag==0)
{//没有找到起始帧首
if(src_buf[src_len++]==p_find_frame->sfd)
{
p_find_frame->dst_buf[p_find_frame->received_len++]=p_find_frame->sfd;
if(++p_find_frame->sfd_count==5)
{
p_find_frame->sfd_flag=1;
p_find_frame->sfd_count=0;
p_find_frame->frame_len=10;
}
}
else
{
p_find_frame->sfd_count=0;
p_find_frame->received_len=0;
}
}
else
{//是否是"长度"字节?Y->获取这帧的数据长度
if(7==p_find_frame->received_len)
{
p_find_frame->frame_len=src_buf[src_len]+5+1+1+1+2;//帧首+地址号+命令号+数据长度+校验
if(p_find_frame->frame_len>=sum_len)
{//这里处理方法根据具体应用不一定相同
MY_DEBUGF(SLAVE_DEBUG,("数据长度超出缓存!\n"));
p_find_frame->frame_len=sum_len;
}
}
p_find_frame->dst_buf[p_find_frame->received_len++]=src_buf[src_len++];
if(p_find_frame->received_len==p_find_frame->frame_len)
{
p_find_frame->received_len=0;//一帧完成
p_find_frame->sfd_flag=0;
p_find_frame->find_fram_flag=1;
returnsrc_len;
}
}
}
p_find_frame->find_fram_flag=0;
returnsrc_len;
}find_frame_structslave_find_frame_srt;定义接收数据缓冲区:#defineSLAVE_REC_DATA_LEN128
uint8_tslave_rec_buf[SLAVE_REC_DATA_LEN];在串口初始化中调用结构体变量初始化函数:init_find_frame_struct(slave_find_frame_srt,slave_rec_buf,0xEE);在串口接收中断中调用数据打包函数:find_one_frame(slave_find_frame_srt,tmp_rec_buf,data_len,SLAVE_REC_DATA_LEN);/*串口帧发送结构体*/
typedefstruct
{
uint16_tsend_sum_len;//要发送的帧数据长度
uint8_tsend_cur_len;//当前已经发送的数据长度
uint8_tsend_flag;//是否发送标志
uint8_t*send_data;//指向要发送的数据缓冲区
}uart_send_struct;
4.2 定时处理函数/**
*@brief定时发送函数,在定时器中断中调用,不使用发送中断的情况下减少发送等待
*@paramUARTx:指向硬件串口寄存器基地址
*@paramp:指向串口帧发送结构体变量
*/
#defineFARME_SEND_FALG0x5A
#defineSEND_DATA_NUM12
staticvoiduart_send_com(LPC_UART_TypeDef*UARTx,uart_send_struct*p)
{
uint32_ti;
uint32_ttmp32;
if(UARTx->LSR(0x01<<6))//发送为空
{
if(p->send_flag==FARME_SEND_FALG)
{
RS485ClrDE;//置485为发送状态
tmp32=p->send_sum_len-p->send_cur_len;
if(tmp32>SEND_DATA_NUM)//向发送FIFO填充字节数据
{
for(i=0;i<SEND_DATA_NUM;i++)
{
UARTx->THR=p->send_data[p->send_cur_len++];
}
}
else
{
for(i=0;i<tmp32;i++)
{
UARTx->THR=p->send_data[p->send_cur_len++];
}
p->send_flag=0;
}
}
else
{
RS485SetDE;
}
}
}
uart_send_structuart0_send_str;
uint8_tuart0_send_buf[UART0_SEND_LEN];
voiduart0_send_data(void)
{
uart_send_com(LPC_UART0,uart0_send_str);
}
uart0_send_str.send_sum_len=data_len;//data_len为要发送的数据长度
uart0_send_str.send_cur_len=0;//固定为0
uart0_send_str.send_data=uart0_send_buf;//绑定发送缓冲区
uart0_send_str.send_flag=FARME_SEND_FALG;//设置发送标志

扫码添加客服微信,备注“入群”拉您进凡亿教育官方专属技术微信群,与众位电子技术大神一起交流技术问题及心得~
新闻来源:玩点嵌入式,文中所述为作者独立观点,不代表icspec立场。更多精彩资讯请下载icspec App。如对本稿件有异议,请联系微信客服specltkj。
暂无评论哦,快来评论一下吧!
2026-07-09

4 小时前
2026-06-11