【stm32】F407ZGT6 - 串口通讯

240 阅读2分钟

使用步骤

① 串口时钟使能,GPIO 时钟使能

② 设置引脚复用器映射

③ GPIO 端口初始化设置

④ 串口参数初始化

⑤ 初始化 NVIC 并且开启中断

⑥ 使能串口

实现代码

usart.c

void uart_init(u32 bound)

{

    GPIO_InitTypeDef GPIO_InitStructure;

    USART_InitTypeDef USART_InitStructure;

    NVIC_InitTypeDef NVIC_InitStructure;

    //GPIOA 和 USART1 时钟使能①

    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE); //使能 GPIOA 时钟

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);//使能 USART1 时钟

    //USART_DeInit(USART1); //复位串口 1 ②

    GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_USART1); //PA9 复用为 USART1

    GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_USART1); //PA10复用为USART1

    //USART1_TX PA.9 PA.10 ③

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10; //GPIOA9 与 GPIOA10

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用功能

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //速度 50MHz

    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽复用输出

    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉

    GPIO_Init(GPIOA,&GPIO_InitStructure); //初始化 PA9,PA10

    //USART 初始化设置 ④

    USART_InitStructure.USART_BaudRate = bound;//一般设置为 9600;

    USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为 8 位数据格式

    USART_InitStructure.USART_StopBits = USART_StopBits_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(USART1, &USART_InitStructure); //初始化串口
    

#if EN_USART1_RX

    //NVIC 设置,使能中断 ⑤

    USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启中断

    //Usart1 NVIC 配置

    NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;//抢占优先级 2
    NVIC_InitStructure.NVIC_IRQChannelSubPriority =2; //响应优先级 2
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;     //IRQ 通道使能
    NVIC_Init(&NVIC_InitStructure);    //根据指定的参数初始化 VIC 寄存器
    
#endif

}
USART_Cmd(USART1, ENABLE); //使能串口 ⑥


void USART1_IRQHandler(void)                	//串口1中断服务程序
{
	u8 Res;
#if SYSTEM_SUPPORT_OS 		//如果SYSTEM_SUPPORT_OS为真,则需要支持OS.
	OSIntEnter();    
#endif
	if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  //接收中断(接收到的数据必须是0x0d 0x0a结尾)
	{
		Res =USART_ReceiveData(USART1);//(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;
				else
				{
					USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ;
					USART_RX_STA++;
					if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//接收数据错误,重新开始接收	  
				}		 
			}
		}   		 
  } 
#if SYSTEM_SUPPORT_OS 	//如果SYSTEM_SUPPORT_OS为真,则需要支持OS.
	OSIntExit();  											 
#endif
} 
#endif	

main.c

int main(void)
{ 
 
	u8 t;
	u8 len;	
	u16 times=0;  
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
	delay_init(168);		//延时初始化 
	uart_init(115200);	//串口初始化波特率为115200
	LED_Init();		  		//初始化与LED连接的硬件接口  
	while(1)
	{
		if(USART_RX_STA&0x8000)
		{					   
			len=USART_RX_STA&0x3fff;//得到此次接收到的数据长度
			printf("\r\n您发送的消息为:\r\n");
			for(t=0;t<len;t++)
			{
				USART_SendData(USART1, USART_RX_BUF[t]);         //向串口1发送数据
				while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//等待发送结束
			}
			printf("\r\n\r\n");//插入换行
			USART_RX_STA=0;
		}else
		{
			times++;
			if(times%5000==0)
			{
				printf("\r\nALIENTEK 探索者STM32F407开发板 串口实验\r\n");
				printf("正点原子@ALIENTEK\r\n\r\n\r\n");
			}
			if(times%200==0)printf("请输入数据,以回车键结束\r\n");  
			if(times%30==0)LED0=!LED0;//闪烁LED,提示系统正在运行.
			delay_ms(10);   
		}
	}
}