完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
|
相关推荐
1个回答
|
|
串口接收处理数据
串口初始化 stm32的串口初始化 void USART_Config(void) { GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; // 打开串口GPIO的时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); // 打开串口外设的时钟 RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); // 将USART Tx的GPIO配置为推挽复用模式 GPIO_InitStructure.GPIO_Pin = USART_TX_GPIO_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); // 将USART Rx的GPIO配置为浮空输入模式 GPIO_InitStructure.GPIO_Pin = USART_RX_GPIO_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOA, &GPIO_InitStructure); // 配置串口的工作参数 // 配置波特率 USART_InitStructure.USART_BaudRate = 115200; // 配置 针数据字长 USART_InitStructure.USART_WordLength = USART_WordLength_8b; // 配置停止位 USART_InitStructure.USART_StopBits = USART_StopBits_1; // 配置校验位 USART_InitStructure.USART_Parity = USART_Parity_No ; // 配置硬件流控制 USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; // 配置工作模式,收发一起 USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; // 完成串口的初始化配置 USART_Init(USART2, &USART_InitStructure); NVIC_InitTypeDef NVIC_InitStructure; /* 嵌套向量中断控制器组选择 */ NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); /* 配置USART为中断源 */ NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn; /* 抢断优先级*/ NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; /* 子优先级 */ NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; /* 使能中断 */ NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; /* 初始化配置NVIC */ NVIC_Init(&NVIC_InitStructure); // 使能串口接收中断 USART_ITConfig(USART2, USART_IT_RXNE, ENABLE); USART_ClearITPendingBit(USART2, USART_IT_RXNE); //清楚中断标志 // 使能串口 USART_Cmd(USART2, ENABLE); for(int i=0;i _rw_para._r_buf_status = empty;//清空缓存器 } } 数据接收结构体 #define USART_TX_GPIO_PIN GPIO_Pin_2 #define USART_RX_GPIO_PIN GPIO_Pin_3 //枚举类型 typedef enum data_ht { yes, no } data_ht; //数据接收包头状态 typedef enum BufStatus { empty, full } BufStatus; //数据缓存器状态 空还是满 //发送接收数据宏定义 #define r_BufNum 5 //数据接收缓存器个数 #define w_BufNum 5 //数据发送缓存器个数 #define r_BtyeNum 16 //数据接收缓存器长度 #define w_BtyeNum 16 //数据发送缓存器长度 //数据发送以及接受结构体 typedef struct _RW_Data { uint8_t _r_buf[r_BufNum][r_BtyeNum]; //数据接收缓存器 uint8_t _w_buf[w_BufNum][r_BtyeNum]; //数据发送缓存器 uint8_t _r_pos; //数据接收缓存器偏移地址 指在哪个缓存器 uint8_t _w_pos; //数据发送缓存器偏移地址 指在哪个缓存器 uint8_t _r_pos_byte; //数据接收缓存器字节偏移地址 uint8_t _w_pos_byte; //数据发送缓存器字节偏移地址 data_ht _r_header; //数据包头状态 yes=已经收到包头 no=未收到包头 data_ht _r_first; //数据包头第一个字节状态 yes=已经收到第一个字节 no=未收到第一个字节 BufStatus _r_buf_status[r_BufNum]; //数据接送缓存器状态 empty=空 full=满 BufStatus _w_buf_status[w_BufNum]; //数据发送缓存器状态 empty=空 full=满 uint8_t Cur_DealPackage_Pos; //当前数据包处理的位置 } _RW_Data; 中断接收函数 //中断接收 void USART2_IRQHandler(void) //串口2中断服务程序 { if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET) //接收中断 { uint8_t Receivedata; //USART_ClearITPendingBit(USART2, USART_IT_RXNE); //清楚中断标志 USART_ClearFlag(USART2, USART_FLAG_RXNE); Receivedata = USART_ReceiveData(USART2); uint8_t i; crc=0; if(_rw_para._r_header == no)//包头数据还未找到 { if(_rw_para._r_first == yes)//第一个字节已经收到 { if(Receivedata == 0x55)//如果数据是55 则说明包头数据接收成功 { _rw_para._r_buf[_rw_para._r_pos][1] = 0x55;//存储数据 _rw_para._r_pos_byte=2; //数据储存位置为2 _rw_para._r_header = yes;//包头数据已经找到 } else//如果数据不对 则清除数据 { _rw_para._r_pos_byte=0; //数据储存位置清零 _rw_para._r_first=no;//清空 _rw_para._r_header = no;//包头数据清空 } } else//还未收到第一个字节 { if((uint8_t)Receivedata == 0xAA)//接收到包头数据 { if(_rw_para._r_pos>=r_BufNum)//判断是否越界 _rw_para._r_pos = 0; //判断缓存器是否是空的 if(_rw_para._r_buf_status[_rw_para._r_pos] == empty) { _rw_para._r_buf[_rw_para._r_pos][0] = 0xAA;//存储数据 _rw_para._r_pos_byte=1; //数据储存位置为1 _rw_para._r_first=yes;//第一个字节数据已经收到 } else { //这里要做报警处理 } } else//数据不对 则直接抛掉 { _rw_para._r_pos_byte=0; //数据储存位置清零 _rw_para._r_first=no;//清空 _rw_para._r_header = no;//包头数据清空 } } } else//包头数据已经找到 开始接收数据 { if(_rw_para._r_pos_byte>=r_BtyeNum)//如果越界的话 { _rw_para._r_pos_byte = 0; //这里要添加报警 } else//数据储存 { _rw_para._r_buf[_rw_para._r_pos][_rw_para._r_pos_byte] = Receivedata;//存储数据 //如果数据个数到达了 那么可以进行数据处理了 if((_rw_para._r_buf[_rw_para._r_pos][2]+4) == _rw_para._r_pos_byte) { //判断包尾的数据是否正确 如果正确 则进行解析 if(_rw_para._r_buf[_rw_para._r_pos][_rw_para._r_pos_byte] == 0xFF && _rw_para._r_buf[_rw_para._r_pos][_rw_para._r_pos_byte-1] == 0x55) { //这里要做CRC校验 for(i=3;i<13;i++) { crc += _rw_para._r_buf[_rw_para._r_pos];//CRC } if(crc == _rw_para._r_buf[_rw_para._r_pos][13])//CRC校验成功 { _rw_para._r_buf_status[_rw_para._r_pos] = full;//数据为满状态 _rw_para._r_pos++;//缓存地址增加 if(_rw_para._r_pos>=r_BufNum)//判断是否越界 _rw_para._r_pos = 0; //这里开始进行数据处理 或者在中断外部处理 这里到时候看情况 Deal_Package();//数据处理完后 状态要变成空 } else;//这里发送CRC校验错误报警 } else//如果数据包尾不正确 则需要进行报警 { //这里添加报警 } _rw_para._r_pos_byte=0; //数据储存位置清零 _rw_para._r_first=no;//清空 _rw_para._r_header = no;//包头数据清空 } else//数据个数没有到达 则继续接收 { _rw_para._r_pos_byte++;//地址进行偏移 } } } } } 数据处理函数 //数据处理 void Deal_Package(void){ if(_rw_para._r_buf_status[_rw_para.Cur_DealPackage_Pos] == full) { ................................................ } _rw_para._r_buf_status[_rw_para.Cur_DealPackage_Pos] = empty;//数据为空状态 _rw_para.Cur_DealPackage_Pos++;//偏移量增加 if(_rw_para.Cur_DealPackage_Pos>=r_BufNum)//地址越界判断 _rw_para.Cur_DealPackage_Pos = 0; } |
|
|
|
只有小组成员才能发言,加入小组>>
3323 浏览 9 评论
3000 浏览 16 评论
3498 浏览 1 评论
9073 浏览 16 评论
4093 浏览 18 评论
1194浏览 3评论
614浏览 2评论
const uint16_t Tab[10]={0}; const uint16_t *p; p = Tab;//报错是怎么回事?
603浏览 2评论
用NUC131单片机UART3作为打印口,但printf没有输出东西是什么原因?
2343浏览 2评论
NUC980DK61YC启动随机性出现Err-DDR是为什么?
1902浏览 2评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-30 19:49 , Processed in 1.228202 second(s), Total 81, Slave 60 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号