我要完成一个任务:从一个传感器接收连续不断发送来的数据,格式为“0xff .. .. .. ..”即以OxFF为开头的五个字节数据,后四个字节是一个32位浮点数,然后将其显示在LCD屏幕上。在接收数据时用中断方式,我设置了一个共用体union data r,然后将原子哥的代码改了改,
usart.c部分代码如下:
int j,n,l;//用来接收、显示用的计数
char str[15]; //存放浮点数转化为char型数据,以便LCD显示
union data
{
u8 rxdata[4];
float f;
}r; //存放发送来的浮点数
void USART1_IRQHandler(void)
{
u8 res;
if(USART1->SR&(1<<5))//接收到数据
{ res=USART1->DR;
//如果接收到0xff就进入{}内,先接收四个字节,再转化类型,再LCD显示
if(res==255)
{
//USART1->CR1&=~(1<<5);//本来想禁止接收非空使能中断,后发现有无此句无影响
n=0;
j=0;
l=30;
//接收四个字节存共用体里
while(1)
{
if(USART1->SR&(1<<5))
{
r.rxdata[n]=USART1->DR;
n++;
}
if(n==4)break;
}
//显示部分,注释掉了,我的疑惑不在这
// sprintf(str,"%6.2f",r.f);
// while(str[j]!='\0')
// {
// LCD_ShowChar(l,110,str[j],32,0);
// l+=16;
// j++;
// }
}
// USART1->CR1|=1<<5;
}
}
//初始化IO 串口1
//pclk2CLK2时钟频率(Mhz)
//bound:波特率
//CHECK OK
//091209
void uart_init(u32 pclk2,u32 bound)
{
float temp;
u16 mantissa;
u16 fraction;
temp=(float)(pclk2*1000000)/(bound*16);//得到USARTDIV
mantissa=temp; //得到整数部分
fraction=(temp-mantissa)*16; //得到小数部分
mantissa<<=4;
mantissa+=fraction;
RCC->APB2ENR|=1<<2; //使能PORTA口时钟
RCC->APB2ENR|=1<<14; //使能串口时钟
GPIOA->CRH=0X444444B4;//IO状态设置
RCC->APB2RSTR|=1<<14; //复位串口1
RCC->APB2RSTR&=~(1<<14);//停止复位
//波特率设置
USART1->BRR=mantissa; // 波特率设置
USART1->CR1|=0X200C; //1位停止,无校验位.
#ifdef EN_USART1_RX //如果使能了接收
// //使能接收中断
USART1->CR1|=1<<8; //PE中断使能
USART1->CR1|=1<<5; //接收缓冲区非空中断使能
MY_NVIC_Init(3,3,USART1_IRQChannel,2);//组2,最低优先级
#endif
}
我想问两个问题是,串口收接在PORTA.10上,接收中断算外部中断吧,这里需要在进入中断后清除外部中断挂起位吗?再读USART_DR后,RXNE会自动清零,这个和清除中断标志是一回事吗?还有,在RXNEIE置位情况下,每发来一个字节,RXNE都会触发中断,那后来的中断是不是不允许打断这个正在接收四个字节并显示的中断函数啊?(因为在LCD屏上显示很耗时)。我在最初编程时,想着如果收到了0xff那么我就禁止非空使能中断,不让第二个第三个四节的RXNE触发中断,后来发现注释掉USART1->CR1&=~(1<<5);没有区别。
求解惑。
谢谢!! |