天天看点

stm32f4 串口设置

注意事项

1 好多串口包括都是收发的寄存器都是用 DR 一个寄存器,

2 这个寄存器是一个双寄存器,包含了 TDR 和 RDR。当向 DR 寄存器写数据的时候,实际是写入 TDR,串

口就会自动发送数据;当收到数据,读 DR 寄存器的时候,实际读取的是 RDR。(这是一个发送器,一个接收器)

3 DR 寄存器的有效位为低9位,所以可能会出现 DR|1ff 。

4 串口 CR1

Bit 5 RXNEIE: RXNE interrupt enable

This bit is set and cleared by software.

0: Interrupt is inhibited

1: An USART interrupt is generated whenever ORE=1 or RXNE=1 in the USART_SR

register

5 串口

Bit 5 RXNE: Read data register not empty

This bit is set by hardware when the content of the RDR shift register has been transferred

to the USART_DR register. An interrupt is generated if RXNEIE=1 in the USART_CR1

register. It is cleared by a read to the USART_DR register. The RXNE flag can also be

cleared by writing a zero to it. This clearing sequence is recommended only for multibuffer

communication.

0: Data is not received

1: Received data is ready to be read

void uart_init(u32 pclk2,u32 bound)
{  	 
	float temp;
	u16 mantissa;
	u16 fraction;	   
	temp=(float)(pclk2*1000000)/(bound*16);//得到[email protected]=0
	mantissa=temp;				 //得到整数部分
	fraction=(temp-mantissa)*16; //得到小数部分@OVER8=0 
    mantissa<<=4;
	mantissa+=fraction;     //得到串口初始化的寄存器值
	RCC->AHB1ENR|=1<<0;   	//使能PORTA口时钟  
	RCC->APB2ENR|=1<<4;  	//使能串口1时钟 
	GPIO_Set(GPIOA,PIN9|PIN10,GPIO_MODE_AF,GPIO_OTYPE_PP,GPIO_SPEED_50M,GPIO_PUPD_PU);//PA9,PA10,复用功能,上拉输出
 	GPIO_AF_Set(GPIOA,9,7);	//PA9,AF7
	GPIO_AF_Set(GPIOA,10,7);//PA10,AF7  	   
	//波特率设置
 	USART1->BRR=mantissa; 	//波特率设置	 
	USART1->CR1&=~(1<<15); 	//设置OVER8=0 
	USART1->CR1|=1<<3;  	//串口发送使能 
#if EN_USART1_RX		  	//如果使能了接收
	//使能接收中断 
	USART1->CR1|=1<<2;  	//串口接收使能
	USART1->CR1|=1<<5;    	//接收缓冲区非空中断使能	    	
	MY_NVIC_Init(3,3,USART1_IRQn,2);//组2,最低优先级 
#endif
	USART1->CR1|=1<<13;  	//串口使能
}
           

中断处理函数

void USART1_IRQHandler(void)
{
	u8 res;	
#if SYSTEM_SUPPORT_OS 		//如果SYSTEM_SUPPORT_OS为真,则需要支持OS.
	OSIntEnter();    
#endif
	if(USART1->SR&(1<<5))//接收到数据    判断中断类型
	{	 
		res=USART1->DR; 
		if((USART_RX_STA&0x8000)==0)//接收未完成
		{
			if(USART_RX_STA&0x4000)//接收到了0x0d
			{
				if(res!=0x0a)USART_RX_STA=0;//接收错误,重新开始
				else USART_RX_STA|=0x8000;	//接收完成了 
			}else //还没收到0X0D
			{	
				if(res==0x0d)USART_RX_STA|=0x4000;//设置标志位   接收到0x0d
				else
				{
					USART_RX_BUF[USART_RX_STA&0X3FFF]=res;
					USART_RX_STA++;
					if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//接收数据错误,重新开始接收	  
				}		 
			}
		}  
		USART1->SR&=~(1<<5);//正点原子没写这一句,感觉如果不写就那 USART1->SR&(1<<5) 判断就没有意义									     
	} 
#if SYSTEM_SUPPORT_OS 	//如果SYSTEM_SUPPORT_OS为真,则需要支持OS.
	OSIntExit();  											 
#endif
} 
           
m