zoukankan      html  css  js  c++  java
  • STM32F407 串口通信实验 视频第27节 个人笔记

    前言

    第26节也是串口,笔记链接在此:https://www.cnblogs.com/YuQiao0303/p/10019362.html
    github地址:https://github.com/YuQiao0303/STM32F407-Examples

    基本把27节的新内容都写在代码注释里了,只有一点:
    在串口调试助手中,选“发送新行“,则这一条数据会以0x0d,0x0a 结尾(ascii码)

    代码

    usart.c

    #include "sys.h"
    #include "usart.h"	
    ////////////////////////////////////////////////////////////////////////////////// 	 
    //如果使用ucos,则包括下面的头文件即可.
    #if SYSTEM_SUPPORT_OS
    #include "includes.h"					//ucos 使用	  
    #endif
    //////////////////////////////////////////////////////////////////////////////////	 
    //本程序只供学习使用,未经作者许可,不得用于其它任何用途
    //ALIENTEK STM32F4探索者开发板
    //串口1初始化		   
    //正点原子@ALIENTEK
    //技术论坛:www.openedv.com
    //修改日期:2014/6/10
    //版本:V1.5
    //版权所有,盗版必究。
    //Copyright(C) 广州市星翼电子科技有限公司 2009-2019
    //All rights reserved
    //********************************************************************************
    //V1.3修改说明 
    //支持适应不同频率下的串口波特率设置.
    //加入了对printf的支持
    //增加了串口接收命令功能.
    //修正了printf第一个字符丢失的bug
    //V1.4修改说明
    //1,修改串口初始化IO的bug
    //2,修改了USART_RX_STA,使得串口最大接收字节数为2的14次方
    //3,增加了USART_REC_LEN,用于定义串口最大允许接收的字节数(不大于2的14次方)
    //4,修改了EN_USART1_RX的使能方式
    //V1.5修改说明
    //1,增加了对UCOSII的支持
    ////////////////////////////////////////////////////////////////////////////////// 	  
     
    
    //////////////////////////////////////////////////////////////////
    //加入以下代码,支持printf函数,而不需要选择use MicroLIB	  
    #if 1
    #pragma import(__use_no_semihosting)             
    //标准库需要的支持函数                 
    struct __FILE 
    { 
    	int handle; 
    }; 
    
    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;      //*************************************这里决定了printf输出到串口1*********************************************//
    	return ch;
    }
    #endif
     
    #if EN_USART1_RX   //如果使能了接收
    //串口1中断服务程序
    //注意,读取USARTx->SR能避免莫名其妙的错误   	
    u8 USART_RX_BUF[USART_REC_LEN];     //接收缓冲,最大USART_REC_LEN个字节.
    //接收状态
    //bit15,	接收完成标志
    //bit14,	接收到0x0d
    //bit13~0,	接收到的有效字节数目
    u16 USART_RX_STA=0;       //接收状态标记	
    
    //初始化IO 串口1 
    //bound:波特率
    void uart_init(u32 bound){
       //GPIO端口设置
    	GPIO_InitTypeDef GPIO_InitStructure;
    	USART_InitTypeDef USART_InitStructure;
    	NVIC_InitTypeDef NVIC_InitStructure;
    	
    	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE); //使能GPIOA时钟
    	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);//使能USART1时钟
     
    	//串口1对应引脚复用映射
    	GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_USART1); //GPIOA9复用为USART1
    	GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_USART1); //GPIOA10复用为USART1
    	
    	 //USART1端口配置
    	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
    
       //USART1 初始化设置
    	USART_InitStructure.USART_BaudRate = bound;//波特率设置
    	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); //初始化串口1
    	
    	USART_Cmd(USART1, ENABLE);  //使能串口1 
    	
    	//USART_ClearFlag(USART1, USART_FLAG_TC);
    	
    #if EN_USART1_RX	
    	USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启相关中断
    
    	//Usart1 NVIC 配置
    	NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;//串口1中断通道
    	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3;//抢占优先级3
    	NVIC_InitStructure.NVIC_IRQChannelSubPriority =3;		//子优先级3
    	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			//IRQ通道使能
    	NVIC_Init(&NVIC_InitStructure);	//根据指定的参数初始化VIC寄存器、
    
    #endif
    	
    }
    
    
    void USART1_IRQHandler(void)                	//串口1中断服务程序:收发数据 & 给USART_RX_STA赋值  (每次读完一波数据,USART_RX_STA需要在外界清零)
    {
    	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)//USART_RX_STA最高位为0:接收未完成
    		{
    			if(USART_RX_STA&0x4000)//USART_RX_STA次高位为1:接收到了0x0d
    			{
    				if(Res!=0x0a)USART_RX_STA=0;//接收到的上一个字符是0x0d,这一个却不是0x0a:接收错误,重新开始
    				else USART_RX_STA|=0x8000;	//接收到的上一个字符是0x0d,这一个是0x0a:接收完成了 
    			}
    			else //还没收到0X0D
    			{	
    				if(Res==0x0d)USART_RX_STA|=0x4000;  //这一个字符是0x0d:标志位置一
    				else
    				{
    					USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ;   //之前没收到0x0d,现在这个也不是0x0d:这是个普通数据字符,把他放进buffer
    					USART_RX_STA++;                                 //已经接收到的数据(字节)个数加一
    					if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//已经接受到的数据字节数大于buffer容量:接收数据错误,重新开始接收	  
    				}		 
    			}
    		}   		 
      } 
    #if SYSTEM_SUPPORT_OS 	//如果SYSTEM_SUPPORT_OS为真,则需要支持OS.
    	OSIntExit();  											 
    #endif
    } 
    #endif	
    
     
    
    

    main.c

    #include "sys.h"
    #include "delay.h"
    #include "usart.h"
    #include "led.h"
    #include "beep.h"
    #include "key.h"
    
    
    //ALIENTEK 探索者STM32F407开发板 实验4
    //串口通信实验 -库函数版本
    //技术支持:www.openedv.com
    //淘宝店铺:http://eboard.taobao.com
    //广州市星翼电子科技有限公司  
    //作者:正点原子 @ALIENTEK
    
    
    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)    //最高位为1,说明这次数据已经接收完了,现在我们就显示接收到的该数据
    		{					   
    			len=USART_RX_STA&0x3fff;//得到此次接收到的数据长度
    			printf("
    您发送的消息为:
    ");    //注意了:printf默认输出到usart1 , 要想改输出串口,到usart.c里的fputc中改
    			for(t=0;t<len;t++)
    			{
    				USART_SendData(USART1, USART_RX_BUF[t]);         //向串口1发送数据
    				while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//等待发送结束
    			}
    			printf("
    
    ");//插入换行
    			USART_RX_STA=0;
    		}else                     //数据还没接收完,我们让对方给我们发一点儿数据吧
    		{
    			times++;
    			if(times%5000==0)   //一个小延时
    			{
    				printf("
    ALIENTEK 探索者STM32F407开发板 串口实验
    ");
    				printf("正点原子@ALIENTEK
    
    
    ");
    			}
    			if(times%200==0)printf("请输入数据,以回车键结束
    ");  
    			if(times%30==0)LED0=!LED0;//闪烁LED,提示系统正在运行.
    			delay_ms(10);   
    		}
    	}
    }
    
    
  • 相关阅读:
    Atitit  atiMail atiDns新特性 v2  q39
    Atitit  atiMail atiDns新特性 v2  q39
    Atitit.aticmd v4  新特性q39 添加定时器释放功能
    Atitit.aticmd v4  新特性q39 添加定时器释放功能
    Atitit. Atiposter 发帖机 新特性 poster new feature   v7 q39
    Atitit. Atiposter 发帖机 新特性 poster new feature   v7 q39
    Atitit.编程语言and 自然语言的比较and 编程语言未来的发展
    Atitit.编程语言and 自然语言的比较and 编程语言未来的发展
    atitit.解决struts2 SpringObjectFactory.getClassInstance NullPointerException  v2 q31
    知也atitit.解决struts2 SpringObjectFactory.getClassInstance NullPointerException  v2 q31无涯 - I
  • 原文地址:https://www.cnblogs.com/YuQiao0303/p/10027102.html
Copyright © 2011-2022 走看看