STM32F10X USART 中断接受+发送,测试无误

发布者:EtherealLight最新更新时间:2018-06-10 来源: eefocus关键字:STM32F10X  USART  中断接受  发送 手机看文章 扫描二维码
随时随地手机看文章

硬件平台:STM32F10X  USART模块 + JLink+USB转TTL小板

软件平台:Keil 4 

前一个程序只是作为下位机的MCU将数据发送给串口助手,也就是上位机,相当于单工通信,对于一个完整的通信来说只是完成了一半的功能。

这是一个完整的通信例程,作为下位机的单片机可以将数据发送给上位机,也可以检测上位机是否发了数据回来。中断方式检测,如果接收到数据,则将数据发送给上位机,相当于半双工模式。

其实与基础的51串口通信无实质区别,只是STM32相关寄存器配置稍微复杂些而已。相比于前一个发送程序,只是在中断检测和主函数里做了相应的修改而已,RCC模块、USART模块与GPIO模块配置基本没变。

二、发送程序例程

程序涉及的模块有:

RCC:复位及时钟控制模块,用于初始化STM32 USART外设时钟及IO口复用时钟;

USART:通用同步异步收发器,即串口,用于发送数据至上位机显示已发送的数据;

GPIO:通用输入输出口复用配置模块。

1、RCC(复位和时钟控制 RESET CLOCK Controller)配置:常规时钟配置+USART相对应的IO口时钟+USART时钟              + 管脚功能复用时钟

  2、GPIO(通用输出输入口)配置 AFIO 复用...:发送端推挽输出,接收端浮空输入

3、USART配置:通用同步异步收发器:8bits一帧,通过缓存区交换

4、NVIC配置(Nest Vector Interrupt Controller):嵌入中断向量控制器

中断响应

中断优先级:优先级编号小者优先级高

查询优先级+执行优先级

多个中断挂起时,执行优先级高者先执行

若执行优先级同,先执行查询优先级高的,在中断向量表的位置决定

中断嵌套:优先级低着被打断,CPU先执行优先级高者

中断挂起:执行高的时候,低者来了,低者被挂起,等待执行

NVIC 管理中断优先级,256个中断分配优先级,次占优先级不会造成中断嵌套

5、发送接收数据

RCC

  1. //RCC时钟配置  

  2. void RCC_cfg(void)  

  3. {      

  4.      ErrorStatus HSEStartUpStatus;  

  5.     //定义错误状态变量    

  6.        

  7.      RCC_DeInit();////将RcC初始化,重新设置为默认值  

  8.           

  9.      RCC_HSEConfig(RCC_HSE_ON);  

  10.      //打开外部高速时钟晶振,使能HSE  

  11.     /*RCC_HSE_ON  开  

  12.      _off 关  _bypass hse晶振被外部时钟旁路*/   

  13.        

  14.     HSEStartUpStatus = RCC_WaitForHSEStartUp();  

  15.     /*RCC_WaitForHSEStartUp()返回一个ErrorStatus枚举值,  

  16.     success好,error未好*/  

  17.       

  18.      if(HSEStartUpStatus == SUCCESS)//HES就绪  

  19.      {         

  20.          RCC_HCLKConfig(RCC_SYSCLK_Div1);  

  21.          //AHB时钟(HCLK)=系统时钟       

  22.   

  23.             RCC_PCLK1Config(RCC_HCLK_Div2);  

  24.          //设置低速AHB时钟(APB1)为HCLK的2分频            

  25.            

  26.          RCC_PCLK2Config(RCC_HCLK_Div1);  

  27.          //设置高速AHB时钟(APB2)=HCLK时钟                 

  28.            

  29.          FLASH_SetLatency(FLASH_Latency_2);  

  30.          //设置FLASH代码延时  

  31.            

  32.          //使能领取指缓存  

  33.          FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);  

  34.            

  35.          RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);  

  36.          //设置PLL时钟源及倍频系数,为HSE的9倍频 8MHz * 9 = 72MHz  

  37.          /*void RCC_PLLConfig(u32 RCC_PLLSource, u32 RCC_PLLMul)  

  38.          RCC_PLLSource_HSI_Div2   pll输入时钟=hsi/2;  

  39.          RCC_PLLSource_HSE_Div1   pll输入时钟 =hse  

  40.          RCC_PLLSource_HSE_Div2   pll输入时钟=hse/2  

  41.            

  42.          RCC_PLLMul_2  ------_16       pll输入时钟*2---16  

  43.          pll输出时钟不得超过72MHZ*/    

  44.            

  45.          RCC_PLLCmd(ENABLE);  

  46.          //ENABLE  / DISABLE  

  47.            

  48.          while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);//等待就绪  

  49.          /*FlagStatus RCC_GetFlagStatus(u8 RCC_FLAG)  检查指定RCC标志位  

  50.          返回SET OR RESET  

  51.          RCC_FLAG_HSIRDY  HSI晶振就绪  

  52.          RCC_FLAG_HSERDY  

  53.          RCC_FLAG_PLLRDY  

  54.          RCC_FLAG_LSERDY   

  55.          RCC_FLAG_LSIRDY.......*/          

  56.            

  57.          RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);  

  58.          //设置PLL为系统时钟源  

  59.          /*void RCC_SYSCLKConfig(u32 RCC_SYSCLKSource)  设置系统时钟  

  60.          RCC_SYSCLKSource_HSI   

  61.          RCC_SYSCLKSource_HSE   

  62.          RCC_SYSCLKSource_PLLCLK  选HSI  HSE PLL 作为系统时钟*/           

  63.            

  64.          while(RCC_GetSYSCLKSource() != 0x08);  

  65.          //判断PLL是否是系统时钟  

  66.          /*u8 RCC_GetSYSCLKSource(void)  返回用作系统时钟的时钟源  

  67.          0x00:HSI   0x04:HSE 0x08:PLL */  

  68.      }     

  69.      RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO , ENABLE);  

  70.      RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3,ENABLE);  

  71.      //打开GPIO时钟,复用功能,串口1的时钟  

  72.      /*void RCC_APB2PeriphClockCmd(u32 RCC_APB2Periph, FunctionalState NewState)   

  73.         enable 或 disable apb2 外设时钟  

  74.      RCC_APB2Periph_AFIO  功能复用IO 时钟  

  75.      RCC_APB2Periph_GPIOA/B/C/D/E   GPIOA/B/C/D/E 时钟  

  76.      RCC_APB2Periph_ADC1/ADC2           ADC1/2 时钟  

  77.      RCC_APB2Periph_TIM1   

  78.      RCC_APB2Periph_SPI1  

  79.      RCC_APB2Periph_USART1   

  80.      RCC_APB2Periph_ALL         全部APB2外设时钟*/  

  81. }  


GPIO



  1. //IO口配置  

  2. void GPIO_cfg(void)  

  3. {  

  4.      GPIO_InitTypeDef GPIO_InitStructure;  

  5.     //GPIO_InitStructure初始化结构体为GPIO_InitTypeDef结构  

  6.       

  7.      //PA9作为US1的TX端,打开复用,负责发送数据  

  8.       

  9.      GPIO_StructInit(&GPIO_InitStructure);  

  10.     /*typedef struct   

  11.         {   

  12.         u16 GPIO_Pin;   

  13.         GPIOSpeed_TypeDef GPIO_Speed;   

  14.         GPIOMode_TypeDef GPIO_Mode;   

  15.         } GPIO_InitTypeDef;*/  

  16.     //函数:指向结构GPIO_InitTypeDef的指针,待初始化  

  17.     //GPIO_StructInit中的成员:GPIO_PIN/SPEED/MODE  

  18.       

  19.      GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;  

  20.     //1、选中引脚GPIO_PIN_0--15 OR GPIO_PIN_ALL 选中全部管脚  

  21.       

  22.     //2、GPIO_SPEED:GPIO_SPEED_10MHz/_2MHz/_50MHz   最高输出速率  

  23.      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  

  24.     /*Mode,工作状态:GPIO_MODE_AIN  ----- 模拟输入  

  25.                                                         _IN_FLOATING  ----- 浮空输入  

  26.                                                         _IPD  ----- 上拉输出  

  27.                                                         _IPU  ----- 上拉输入  

  28.                                                         _OUT_OD  ----- 开漏输出  

  29.                                                         _OUT_PP  ----- 推挽输出  

  30.                                                         _AF_OD  ----- 复用开漏输出  

  31.                                                         _AF_PP  ----- 复用推挽输出*/  

  32.       

  33.      GPIO_Init(GPIOB , &GPIO_InitStructure);  

  34.      //选择A,初始化  

  35.       

  36.      //PA10作为US1的RX端,负责接收数据  

  37.      GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;  

  38.      //选择10脚  

  39.        

  40.      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;  

  41.      //IO浮空输入  

  42.      GPIO_Init(GPIOB, &GPIO_InitStructure);  

  43.      //初始化  

  44.        

  45.      //提示标示:LED显示串口正在发送数据/接收数据  

  46.      GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;  

  47.      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  

  48.      //推挽输出  

  49.      GPIO_Init(GPIOA, &GPIO_InitStructure);  

  50. }  


USART


  1. //串口初始化  

  2. void USART_cfg(void)  

  3. {  

  4.      USART_InitTypeDef USART_InitStructure;  

  5.        

  6.      USART_StructInit(&USART_InitStructure);  

  7.     //将结构体设置为缺省状态  

  8.     /*USART_StructInit通用同步异步串行口初始结构成员:  

  9.     USART_BaudRate----9600,默认9600  

  10.     IntegerDivider = ((APBClock) / (16 *  (USART_InitStruct->USART_BaudRate)))   

  11. FractionalDivider = ((IntegerDivider - ((u32) IntegerDivider)) * 16) + 0.5  

  12.       

  13.              _WordLength  帧中传输的数据位----USART_WordLength_8b/_9b,字长宽8位  

  14.              _StopBits  停止位  可为 USART_StopBits_1 ---帧结尾传输1个停止位  

  15.                                                                 USART_StopBits_0.5  0.5个  

  16.                                                                 USART_StopBits_2  

  17.                                                                 USART_StopBits_1.5  

  18.                  _parity  奇偶模式  USART_Parity_No//奇偶失能,无奇偶  

  19.                                                         USART_Parity_even oumoshi  

  20.                                                         USART_Parity_odd  jimoshi  

  21.            奇偶使能时,在数据的MSB位插入奇偶位,字长9位时的第九位,8位时的第八位  

  22.                  _HardwareFlowControl  //  _none,硬件流控制失能  

  23.                                                                     _rts 发送请求rts使能  

  24.                                                                     _cts 清除发送cts使能  

  25.                                                                     _rts_cts rts and cts 使能*/  

  26.                   

  27.      //波特率设置为115200  

  28.      USART_InitStructure.USART_BaudRate = 115200;  

  29.      //一帧数据的宽度设置为8bits  

  30.      USART_InitStructure.USART_WordLength = USART_WordLength_8b;  

  31.      //在帧尾传输1个停止位  

  32.      USART_InitStructure.USART_StopBits = USART_StopBits_1;  

  33.      //奇偶检验失能模式,无奇偶校验位  

  34.      USART_InitStructure.USART_Parity = USART_Parity_No;  

  35.      //发送/接收使能  

  36.      USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;  

  37.      //硬件流控制失能  

  38.      USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;  

  39.      //设置串口3  

  40.      USART_Init(USART3, &USART_InitStructure);  

  41.       

  42.      //打开串口3的中断响应函数  

  43.        

  44.      USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);  

  45.      /*void USART_ITConfig(USART_TypeDef* USARTx, u16 USART_IT, FunctionalState NewState)   

  46.         失能或使能相应的USART中断,x---1/2/3  

  47.         _IT : _IT_PE  奇偶错误中断  

  48.                     _IT_TXE FASONG中断  

  49.                     _IT_TC  传输完成中断  

  50.                     _IT_RXNE  接收中断  

  51.                     _IT_IDLE  空闲总线中断  

  52.                     _IT_LBD  LIN中断检测中断  

  53.                     _IT_CTS  CTS中断  

  54.                     _IT_ERR  错误中断*/  

  55.                       

  56.      USART_Cmd(USART3, ENABLE);  

  57.      /*void USART_Cmd(USART_TypeDef* USARTx, FunctionalState NewState)  

  58.      失能或使能外设 x--1/2/3  

  59.      NewState: USARTx ENABLE /DISABLE*/  

  60. }  

NVIC


  1. //配置中断  

  2. void NVIC_cfg(void)  

  3. {     

  4.      NVIC_InitTypeDef NVIC_InitStructure;  

  5.     //定义NVIC初始化结构体 NVIC_InitStructure  

  6.       

  7.      NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);      

  8.     /*优先级分组:先占优先级与从优先级,只可设置一次  

  9.     NVIC_PriorityGroup_0  先0位从4位 0  0--15  NVIC_IRQChannelPreemptionPriority 对中断通道设置不产生影响  

  10.     NVIC_PriorityGroup_1    先1位从3位  0-1 0--7  NVIC_IRQChannelSubPriority 不影响中断  

  11.     NVIC_PriorityGroup_2    先2从2        0-3  0-3  

  12.     NVIC_PriorityGroup_3    先3从1        0-7 0-1  

  13.     NVIC_PriorityGroup_4    先4从0    0-15  0  

  14.     选择中断优先级分组2  */   

  15.       

  16.      NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;   

  17.     //UA=SART1 全局中断  

  18.     //用3.5的库的时候,所有的USART1_IRQChannel全部换成    USART1_IRQn;!!!!!         

  19.     /*typedef struct   

  20.         {   

  21.         u8 NVIC_IRQChannel; //enable/disable 相应的IRQ通道,3.5库的时候,IRQChannel全部换成IRQn  

  22.         u8 NVIC_IRQChannelPreemptionPriority;//成员 NVIC_IRQChannel先占优先级  

  23.         u8 NVIC_IRQChannelSubPriority; //成员 NVIC_IRQChannel从占优先级  

  24.         FunctionalState NVIC_IRQChannelCmd; //成员 NVIC_IRQChannel 使能还是失能  

  25.         } NVIC_InitTypeDef;*/     

  26.       

  27.     //选择串口1中断  

  28.      NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;    

  29.     //抢占式,先占   中断优先级设置为0  

  30.      NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;           

  31.     //响应式,从  中断优先级设置为0  

  32.      NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;  

  33.     //使能中断  

  34.      NVIC_Init(&NVIC_InitStructure);  

  35. }  

  36.   

  37. #include "stm32f10x_it.h"  

  38.   

  39. extern FlagStatus RX_status;  

  40. extern char urt_flag;  

  41. void USART3_IRQHandler(void)  

  42. {  

  43.      GPIO_SetBits(GPIOA, GPIO_Pin_4);  

  44.       

  45.      RX_status = USART_GetFlagStatus(USART3, USART_FLAG_RXNE);    

  46.      //确认是否收到数据  

  47.        

  48.          //USART_ClearFlag(USART3,USART_FLAG_TC);//清除usart1-3 待处理标志位  

  49.            

  50.        

  51.         if(USART_GetITStatus(USART3,USART_IT_RXNE)==SET)  

  52.             //中断发生与否,接收中断  

  53.         {   

  54.             USART_ClearITPendingBit(USART3,USART_IT_RXNE);  

  55.             //清除usart1-3的中断待处理位        

  56.             urt_flag=1;           

  57.         }    

  58.         if(USART_GetFlagStatus(USART3,USART_FLAG_ORE)==SET)  

  59.         //溢出,若溢出,先读取SR,再读取 DR ,寄存器可清除不断入中断的问题  

  60.         {   

  61.             USART_ClearFlag(USART3,USART_FLAG_ORE);   

  62.             //读取SR ,清除溢出错误标志位  

  63.             USART_ReceiveData(USART3);//读取DR  

  64.               

  65.          /*USART_SendData(USART3, USART_ReceiveData(USART3));  

  66.             //将数据发送到上位机  

  67.             while(USART_GetFlagStatus(USART3, USART_FLAG_TC) == RESET);  

  68.             //等待数据发送完毕  

  69.             //USART3_Puts("\r\n");  

  70.             GPIO_ResetBits(GPIOA, GPIO_Pin_4);  

  71.             //发送完后亮灯*/  

  72.             urt_flag=1;   

  73.         }   

  74.   

  75. }  


关键字:STM32F10X  USART  中断接受  发送 引用地址:STM32F10X USART 中断接受+发送,测试无误

上一篇:STM32 使用HAL库做串口的DMA发送和中断接收
下一篇:stm32串口中断收发数据环形缓冲区的设计

推荐阅读最新更新时间:2024-03-16 16:05

STM32F10X启动文件笔记
目前为止我都是在STM32裸机开发,而不管是裸机还是带操作系统,单片机上电后都会做一些初始化工作,所以写一篇文章记录一下。本文章参考《野火零死角玩转STM32F103》 此文章代码较多,所以重要的内容是用红色和蓝色文字写的,代码中也有对汇编操作符的注释。同时如果有新的内容,会实时更新。 1.启动文件简介 启动文件由汇编编写,是系统上电复位后第一个执行的程序。主要做了以下工作: ①初始化堆栈指针 SP=_initial_sp。 ②初始化 PC指针=Reset_Handler。 ③初始化中断向量表。 ④配置系统时钟。 ⑤调用 C库函数_main 初始化用户堆栈,从而最
[单片机]
<font color='red'>STM32F10X</font>启动文件笔记
关于STM32串口通信使用printf发送数据的配置方法
开发环境: Keil RVMDK 在 STM32 串口通信程序中使用printf发送数据,非常的方便。可在刚开始使用的时候总是遇到问题,常见的是硬件访真时无法进入main主函数,其实只要简单的配置一下就可以了。 下面就说一下使用printf需要做哪些配置。 有两种配置方法: 一、对工程属性进行配置,详细步骤如下 1、首先要在你的main 文件中 包含 stdio.h (标准输入输出头文件)。 2、在main文件中重定义 fputc 函数。如下: // 发送数据 int fputc(int ch, FILE *f) { USART_SendData(USART1, (unsigned char)
[单片机]
关于STM32串口通信使用printf<font color='red'>发送</font>数据的配置方法
STM32之USART串口接收数据处理
//原帖http://bbs.elecfans.com/forum.php?mod=viewthread&tid=445463 //在学习过程中发现几处编译错误,并改正; //主要贴出定义、和中断函数部分; uint8_t usart_rx_buf ; //接收缓冲,最大40个字节 uint8_t usart_rx_temporary ; //数据保存暂存器,最多能够缓存40个字节 uint8_t usartrxbuf_pagebuf=0; //最上面接受缓存的页码(5)缓存 uint8_t usart_rd_len=0; //有用信息的数据长度 uint8_t usart_rd_lentemp=0; //用来记录已
[单片机]
ATMEGA48的USART串口与PC通讯例子
/***************************************************** CodeWizardAVR http://www.avrdiy.com Chip type : ATmega48V Clock frequency : 7.372800 MHz Memory model : Small External SRAM size : 0 Data Stack size : 128 波特率9600/8个数据位 /1个停止位 /无校验 M8V20实验板硬件设置 1: J5的2个跳线帽短接,使用外部晶振7.3728MHz 2: J6与J7的4个跳线帽短接,使用MAX232,其
[单片机]
无线通信RF直接变频发送
引言 无线电发射器在经历了若干年的发展后,逐步从简单中频发射架构过渡到正交中频发送器、零中频发送器。而这些架构仍然存在局限性,最新推出的RF直接变频发送器能够克服传统发送器的局限性。本文比较了无线通信中不同发射架构的特点,RF直接变频发送器采用高性能数/模转换器(DAC),比传统技术具有明显优势。RF直接变频发送器也具有自身挑战,但为实现真正的软件无线电发射架构铺平了道路。 RF DAC,例如14位2.3Gsps MAX5879,是RF直接变频架构的关键电路。这种DAC能够在1GHz带宽内提供优异的杂散和噪声性能。器件在第二和第三奈奎斯特频带采用创新设计,支持信号发射,能够以高达3GHz的输出频率合成射频信号,测量结果验证了D
[模拟电子]
无线通信RF直接变频<font color='red'>发送</font>器
基于单片机的温度采集及无线发送系统
  0 引言   随着数字化脚步的加快,越来越多的数字化产品取代了原有的机械式仪表,从而大大提高了数据的准确率。然而,多数情况下,温度的采集过程只在现场实时显示,在增加了工作量的同时,也可能会造成很多不便,如进入危险区域。因此,将无线网络应用在工业生产中,不仅能大大提高工作效率,同时也在一定程度上降低了劳动强度。   本设计基于以上两点,将工业生产中常用到的温度进行数字化,并通过无线模块将数据发送出去,在接收方利用无线接收设备接收实时的数据,从而大大降低劳动强度。   1 系统组成   系统由单片机、温度传感器、串口通信模块和无线传输模块等几部分组成。测温系统将测得的温度通过单片机在数码管上实时显示,同时,通过串口通信部分
[单片机]
基于单片机的温度采集及无线<font color='red'>发送</font>系统
中国移动3月份发送业务扣费提醒短信超4亿条
透明消费是消费者长期以来最为关注的问题之一。为了切实做到让客户“明明白白消费”,中国移动推出“业务扣费主动提醒”、“0000查询自由退订”等多项为民服务举措。据中国移动透露,仅2012年3月份,中国移动业务扣费提醒短信下发量达4.06亿条,退费笔数3700万;“0000”查询总量5552.5万次,退订总量1601万次。 中国移动还结合各地实际情况,不断深化、丰富各项透明消费服务举措,提升客户感知。针对客户关注的GPRS流量收费问题,上海移动门户网站客户服务专区推出了“GPRS手机上网问答”板块,重点为客户解答国际漫游流量管理、国内流量提醒服务、手机上网科普知识等内容及手机上网中碰到的各类问题,及时、快捷回复客户的咨询及留言。
[网络通信]
双通道发送DAC系列产品为宽带通信应用提供一流的性能
—— AD974x和 AD978x系列DAC具有快速吞吐率、低噪声和直接射频转换的特点, 以便在宽带通信系统中增加动态范围并且降低失真程度。 关于AD974x和AD978x系列产品 AD974x 和AD978x系列产品是ADI公司TxDAC系列数模转换器(DAC)增加的最新成员,它们适合于通信系统中的发送信道。这种最新的双通道、高速DAC产品包括两个系列,一个系列是AD974x系列的8 bit、10 bit、12 bit、14 bit和16 bit DAC,采样速率高达250 MSPS(每秒百万次采样),使用LVCMOS(低电压CMOS)输入:另一个系列是AD978x系列的12 bit、14 bit和16 bit DAC,它
[新品]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
热门活动
换一批
更多
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

更多精选电路图
换一换 更多 相关热搜器件
更多每日新闻
随便看看
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved