www.pudn.com > ZLG_GUI_spilcd.zip > usart.c, change:2011-04-17,size:3342b


#include "sys.h" 
#include "usart.h" 
//////////////////////////////////////////////////////////////////////////////////	  
//本程序只供学习使用,未经作者许可,不得用于其它任何用途 
//Mini STM32开发板 
//串口1初始化		    
//正点原子@ALIENTEK 
//技术论坛:www.openedv.com 
//修改日期:2010/5/27 
//版本:V1.3 
//版权所有,盗版必究。 
//Copyright(C) 正点原子 2009-2019 
//All rights reserved 
//******************************************************************************** 
//V1.3修改说明  
//支持适应不同频率下的串口波特率设置. 
//加入了对printf的支持 
//增加了串口接收命令功能. 
//修正了printf第一个字符丢失的bug 
////////////////////////////////////////////////////////////////////////////////// 	   
  
 
////////////////////////////////////////////////////////////////// 
//加入以下代码,支持printf函数,而不需要选择use MicroLIB	   
#if 1 
#pragma import(__use_no_semihosting)              
//标准库需要的支持函数                  
struct __FILE  
{  
	int handle;  
	/* Whatever you require here. If the only file you are using is */  
	/* standard output using printf() for debugging, no file handling */  
	/* is required. */  
};  
/* FILE is typedef’ d in stdio.h. */  
FILE __stdout;        
//定义_sys_exit()以避免使用半主机模式     
_sys_exit(int x)  
{  
	x = x;  
}  
//重定义fputc函数  
int fputc(int ch, FILE *f) 
{       
	while((USART1->SR&0X40)==0);//循环发送,直到发送完毕    
	USART1->DR = (u8) ch;       
	return ch; 
} 
#endif  
//end 
////////////////////////////////////////////////////////////////// 
 
#ifdef EN_USART1_RX   //如果使能了接收 
//串口1中断服务程序 
//注意,读取USARTx->SR能避免莫名其妙的错误   	 
u8 USART_RX_BUF[64];     //接收缓冲,最大64个字节. 
//接收状态 
//bit7,接收完成标志 
//bit6,接收到0x0d 
//bit5~0,接收到的有效字节数目 
u8 USART_RX_STA=0;       //接收状态标记	   
   
void USART1_IRQHandler(void) 
{ 
	u8 res;	     
	if(USART1->SR&(1<<5))//接收到数据 
	{	  
		res=USART1->DR;  
		if((USART_RX_STA&0x80)==0)//接收未完成 
		{ 
			if(USART_RX_STA&0x40)//接收到了0x0d 
			{ 
				if(res!=0x0a)USART_RX_STA=0;//接收错误,重新开始 
				else USART_RX_STA|=0x80;	//接收完成了  
			}else //还没收到0X0D 
			{	 
				if(res==0x0d)USART_RX_STA|=0x40; 
				else 
				{ 
					USART_RX_BUF[USART_RX_STA&0X3F]=res; 
					USART_RX_STA++; 
					if(USART_RX_STA>63)USART_RX_STA=0;//接收数据错误,重新开始接收	   
				}		  
			} 
		}  		 									      
	}  											  
}  
#endif										  
//初始化IO 串口1 
//pclk2:PCLK2时钟频率(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&=0XFFFFF00F;  
	GPIOA->CRH|=0X000008B0;//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 
}