接收数据为:BB 97 11 30 00 11 22 33 44 55 66 77 88 99 00 11 22 FD 6F 03 1A 0D 0A
发送端一直不定时发此类数据
但是我用STM32F103RCT6单片机接收丢包挺多,丢包的频率很规律 应该是我程序代码没写严谨,求大神指点
void Init_NVIC(void)
{
NVIC_InitTypeDef NVIC_InitStructure; //定义一个NVIC向量表结构体变量
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置中断组 为2
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; //配置串口1为中断源
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3; //设置占先优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //设置副优先级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能串口1中断
NVIC_Init(&NVIC_InitStructure); //根据参数初始化中断寄存器
NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn; //配置串口1为中断源
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //设置占先优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //设置副优先级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能串口1中断
NVIC_Init(&NVIC_InitStructure); //根据参数初始化中断寄存器
NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn; //配置串口1为中断源
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; //设置占先优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; //设置副优先级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能串口1中断
NVIC_Init(&NVIC_InitStructure); //根据参数初始化中断寄存器
NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn; //配置串口1为中断源
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //设置占先优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; //设置副优先级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能串口1中断
NVIC_Init(&NVIC_InitStructure); //根据参数初始化中断寄存器
}
void Init_Usart2(void)
{
GPIO_InitTypeDef GPIO_InitStructure; //定义一个GPIO结构体变量
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO ,ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2 ,ENABLE);
//使能各个端口时钟,重要!!!
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //配置串口发送端口挂接到9端口
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用功能输出开漏
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //配置端口速度为50M
GPIO_Init(GPIOA, &GPIO_InitStructure); //根据参数初始化GPIOA寄存器
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; //接收
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入(复位状态);
GPIO_Init(GPIOA, &GPIO_InitStructure); //根据参数初始化GPIOA寄存器
}
/*:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
** 函数名称: Usart_Configuration
** 功能描述: 串口配置函数
** 参数描述: BaudRate设置波特率
** 作 者: Dream
** 日 期: 2011年6月20日
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/
void Usart2_Configuration(uint32_t BaudRate)
{
USART_InitTypeDef USART_InitStructure; //定义一个串口结构体
USART_InitStructure.USART_BaudRate = BaudRate ; //波特率115200
USART_InitStructure.USART_WordLength = USART_WordLength_8b; //传输过程中使用8位数据
USART_InitStructure.USART_StopBits = USART_StopBits_1; //在帧结尾传输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); //根据参数初始化串口寄存器
USART_ITConfig(USART2,USART_IT_RXNE,ENABLE); //使能串口中断接收
USART_Cmd(USART2, ENABLE); //使能串口外设
}
/*:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
** 函数名称: USART1_IRQHandler
** 功能描述: 串口中断函数
** 参数描述: 无
** 作 者: Dream
** 日 期: 2011年6月20日
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/
void USART2_IRQHandler()
{
int i=0;
u8 a=0;
extern u8 UART2_Save_data_box[UART2_Save_data_box_number]; //放置UART2接收到的字节 需要溢出归0
extern u16 UART2_Save_data_box_pointer; //放置UART2接收到的字节盒子下一个数据放置的位置指向标志 需要溢出归0
extern u32 EPC_box[EPC_number];
extern u16 EPC_box_pointer;
extern u8 back_correct;
extern u32 error1;
extern u32 error2;
extern u32 error3;
extern u32 EPC_count_l;
extern u32 EPC_count_h;
extern u32 timer1;
extern u8 zisuo3;
if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET) //读取接收中断标志位USART_IT_RXNE
//USART_FLAG_RXNE:接收数据寄存器非空标志位
//1:忙状态 0:空闲(没收到数据,等待。。。)
{
if(UART2_Save_data_box[0]==0xBB) //判断数据包头
{
UART2_Save_data_box[UART2_Save_data_box_pointer]=USART_ReceiveData(USART2); //继续存储数据
UART2_Save_data_box_pointer++;
/*
if(UART2_Save_data_box[1]==0x98&&UART2_Save_data_box[5]==0x0D && UART2_Save_data_box[6]==0x0A) //判断数据包尾
{
for(i=1;i<4;i++) //计算校验值
{
a+=(u8)UART2_Save_data_box;
}
if(a==UART2_Save_data_box[4]) //校验成功
{
if(UART2_Save_data_box[3]==0x01)
{
back_correct=1;
OUT2_LED=0;
}
else
{
back_correct=2;
}
}
for(i=0;i<UART2_Save_data_box_number;i++)
{
UART2_Save_data_box=0; //一旦判断到数据包的尾部则数组初始化
}
UART2_Save_data_box_pointer=1; //一旦判断到数据包的尾部则置1
}
else */if(UART2_Save_data_box[1]==0x97&&UART2_Save_data_box[21]==0x0D && UART2_Save_data_box[22]==0x0A) //判断数据包尾
{
for(i=1;i<20;i++) //计算校验值
{
a+=(u8)UART2_Save_data_box;
}
if(a==UART2_Save_data_box[20]) //校验成功
{
for(i=0;i<3;i++)
{
EPC_box[EPC_box_pointer]=(UART2_Save_data_box[i*4+5]<<24)+(UART2_Save_data_box[i*4+1+5]<<16)+(UART2_Save_data_box[i*4+2+5]<<8)+(UART2_Save_data_box[i*4+3+5]<<0); //存储EPC
EPC_box_pointer++;
}
zisuo3=0;
OUT1_jingbao=1; //输出报警
timer1=0; //计时清0
EPC_count_l++; //标签总数+1
if(EPC_count_l>=1000000000)
{
EPC_count_l=0;
EPC_count_h++;
}
}
else
{
error1++; //偶然错误 错误标志加1
}
for(i=0;i<UART2_Save_data_box_number;i++)
{
UART2_Save_data_box=0; //一旦判断到数据包的尾部则数组初始化
}
UART2_Save_data_box_pointer=1; //一旦判断到数据包的尾部则置1
}
else if(UART2_Save_data_box_pointer>=23) //偶尔性的数据错误 开始清0
{
for(i=0;i<UART2_Save_data_box_number;i++)
{
UART2_Save_data_box=0;
}
UART2_Save_data_box_pointer=1;
error2++; //偶然错误 错误标志加1
}
if(EPC_box_pointer>=EPC_number)
{
EPC_box_pointer=0;
}
}
else if(UART2_Save_data_box[0]==0x00) //如果上个数据不是数据包头
{
UART2_Save_data_box[0]=USART_ReceiveData(USART2); //储存数据到UART2
}
else
{
error3++;
UART2_Save_data_box[0]=USART_ReceiveData(USART2); //储存数据到UART2
}
USART_ClearITPendingBit(USART2,USART_IT_RXNE); //清除中断标志位
}
}
|
数据包接收完UART2_Save_data_box_pointer应置0
评分
查看全部评分
因为,当数据接收不够 23 组时,你的程序没有做处理。
导致 UART2_Save_data_box_pointer 一直累加到大于等于23组时,你的程序才做处理。
评分
查看全部评分
评分
查看全部评分
评分
查看全部评分
评分
查看全部评分
就是这么垃圾的中断代码居然也是抄别人的:
** 作 者: Dream
** 日 期: 2011年6月20日
评分
查看全部评分
评分
查看全部评分