串口接收处理数据
串口初始化
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;
}
串口接收处理数据
串口初始化
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;
}
举报