//如果想串口中断接收,请不要注释以下宏定义
#define EN_USART1_RX 1 //使能串口1接收
#define EN_USART3_RX 1 //使能串口1接收
void uart1_init(u32 pclk2,u32 bound);
void uart3_init(u32 pclk2,u32 bound);
//////////////////////////////////////////////////////////////////
//加入以下代码,支持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
//////////////////////////////////////////////////////////////////
#if EN_USART1_RX //如果使能了接收
//串口1中断服务程序
//注意,读取USARTx->SR能避免莫名其妙的错误
u8 USART1_RX_BUF[64]; //接收缓冲,最大64个字节.
u8 USART1_RX_STA=0; //接收状态标记
u8 USART3_RX_BUF[64]; //接收缓冲,最大64个字节.
u8 USART3_RX_STA=0; //接收状态标记
//bit7,接收完成标志
//bit6,接收到0x0d
//bit5~0,接收到的有效字节数目
void USART1_IRQHandler(void)
{
u8 res;
if(USART1->SR&(1<<5))//接收到数据
{
res=USART1->DR;
if((USART1_RX_STA&0x80)==0)//接收未完成
{
if(USART1_RX_STA&0x40)//接收到了0x0d
{
if(res!=0x0a)USART1_RX_STA=0;//接收错误,重新开始
else USART1_RX_STA|=0x80; //接收完成了
}
else //还没收到0X0D
{
if(res==0x0d)
USART1_RX_STA|=0x40;
else
{
USART1_RX_BUF[USART1_RX_STA&0X3F]=res;
USART1_RX_STA++;
if(USART1_RX_STA>63)
USART1_RX_STA=0;//接收数据错误,重新开始接收
}
}
}
}
}
#endif
//初始化IO 串口1
//pclk2 CLK2时钟频率(Mhz)
//bound:波特率
void uart1_init(u32 pclk2,u32 bound)
{
float temp;
u16 mantissa;
u16 fraction;
temp=(float)(pclk2*1000000)/(bound*16);//得到USARTDIV 16MHZ
mantissa=temp; //得到整数部分
fraction=(temp-mantissa)*16; //得到小数部分
mantissa<<=4;
mantissa+=fraction;
RCC->APB2ENR|=1<<2; //使能PORTA口时钟
RCC->APB2ENR|=1<<14; //使能串口1时钟
GPIOA->CRH&=0XFFFFF00F;
GPIOA->CRH|=0X000008B0;//IO状态设置
RCC->APB2RSTR|=1<<14; //复位串口1
RCC->APB2RSTR&=~(1<<14);//停止复位
//波特率设置
USART1->BRR=mantissa; // 波特率设置
USART1->CR1|=0X200C; //1位停止,无校验位.
#if EN_USART1_RX //如果使能了接收
//使能接收中断
USART1->CR1|=1<<8; //PE中断使能
USART1->CR1|=1<<5; //接收缓冲区非空中断使能
MY_NVIC_Init(1,1,USART1_IRQChannel,2);//组2,最低优先级
#endif
}
#if EN_USART3_RX
void USART3_IRQHandler(void)
{
u8 res;
if(USART3->SR&(1<<5))//接收到数据
{
LED_DUG = 1;
res=USART3->DR;
if((USART3_RX_STA&0x80)==0)//接收未完成
{
if(USART3_RX_STA&0x40)//接收到了0x0d
{
if(res!=0x0a)USART3_RX_STA=0;//接收错误,重新开始
else USART3_RX_STA|=0x80; //接收完成了
}
else //还没收到0X0D
{
if(res==0x0d)
USART3_RX_STA|=0x40;
else
{
USART3_RX_BUF[USART3_RX_STA&0X3F]=res;
USART3_RX_STA++;
if(USART3_RX_STA>63)
USART3_RX_STA=0;//接收数据错误,重新开始接收
}
}
}
}
}
#endif
void uart3_init(u32 pclk2,u32 bound)
{
float temp;
u16 mantissa;
u16 fraction;
temp=(float)(pclk2*1000000)/(bound*16);//得到USARTDIV 16MHZ
mantissa=temp; //得到整数部分
fraction=(temp-mantissa)*16; //得到小数部分
mantissa<<=4;
mantissa+=fraction;
RCC->APB2ENR|=1<<3; //使能PORTB口时钟
RCC->APB1ENR|=1<<18; //使能串口3时钟
GPIOB->CRH&=0XFFFF00FF;
GPIOB->CRH|=0X0000B800;//IO状态设置
RCC->APB1RSTR|=1<<18; //复位串口3
RCC->APB1RSTR&=~(1<<18);//停止复位
//波特率设置
USART3->BRR=mantissa; // 波特率设置
USART3->CR1|=0X200C; //1位停止,无校验位.
#if EN_USART3_RX //如果使能了接收
//使能接收中断
USART3->CR1|=1<<8; //PE中断使能
USART3->CR1|=1<<5; //接收缓冲区非空中断使能
MY_NVIC_Init(1,2,USART3_IRQChannel,2);//组2,最低优先级
#endif
}
我是按照demo板进行修改UART3的!这里面UART1还是可以正常工作的,可是UART3就是不行,规格书上也查了没有讲到区别。
|