STM32 串口 通信 中断

发布者:pcwg最新更新时间:2021-11-22 来源: eefocus关键字:STM32  串口  通信  中断 手机看文章 扫描二维码
随时随地手机看文章

一、数据发送与接收。

(1)、STM32 的发送与接收是通过数据寄存器 USART_DR 来实现的,这是一个双寄存器,包含了 TDR 和 RDR。


当向该寄存器写数据的时候,串口就会自动发送;

当收到数据的时候,也是存在该寄存器内。

1)STM32 库函数操作 USART_DR 寄存器发送数据的函数是:

void USART_SendData(USART_TypeDef* USARTx, uint16_t Data);通过该函数向串口寄存器 USART_DR 写入一个数据。

2)STM32 库函数操作 USART_DR 寄存器读取串口接收到的数据的函数是:

uint16_t USART_ReceiveData(USART_TypeDef* USARTx);通过该函数可以读取串口接受到的数据。


(2)、获取相应 串口状态,串口的状态可以通过状态寄存器 USART_SR 读取。

1)在我们固件库函数里面,读取串口状态的函数是:

FlagStatus USART_GetFlagStatus(USART_TypeDef* USARTx, uint16_t USART_FLAG);

这个函数的第二个入口参数非常关键,它是标示我们要查看串口的哪种状态,比如上面讲解的RXNE(读数据寄存器非空)以及 TC(发送完成)。

例如:

【1】我们要判断读寄存器是否非空(RXNE),操作库函数的方法是:

USART_GetFlagStatus(USART1, USART_FLAG_RXNE);

【2】我们要判断发送是否完成(TC),操作库函数的方法是:

USART_GetFlagStatus(USART1, USART_FLAG_TC);

等等,这些标识号在 MDK 里面是通过宏定义定义的。


(3)、获取相应 中断状态 (注意区别(2)和(3))


1)当我们使能了某个中断的时候,当该中断发生了,就会设置状态寄存器中的某个标志位。经常我们在中断处理函数中,要判断该中断是哪种中断,使用的函数是:

ITStatus USART_GetITStatus(USART_TypeDef* USARTx, uint16_t USART_IT)

比如我们使能了串口发送完成中断,那么当中断发生了, 我们便可以在中断处理函数中调用这个函数来判断到底是否是串口发送完成中断。

【1】方法是:USART_GetITStatus(USART1, USART_IT_TC)

返回值是 SET,说明是串口发送完成中断发生。


2)这里要注意区分的是中断的不同种类:

有:【1】串口中断 {void uart2_init(u32 bound)、void USART2_IRQHandler(void)};

【2】外部中断 {void EXTIX_Init(void)、void EXT10_IRQHandler(void)}

【3】 定时器中断


(4)串口配置的一般步骤:


串口时钟 和 GPIO时钟 使能{RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

到底什么时候用APB1,什么时候用APB2,到 stm32f10x.h 里找匹配 }


GPIO端口模式的设置 {包括:GPIO_Pin、GPIO_Mode 、GPIO_Speed}


串口设置 {包括:1)串口复位(这一步不是必须的,省略了);

2)串口参数初始化(主要注意:USART_BaudRate、 USART_Mode、 USART_ITConfig);

3)串口使能}


开启中断,初始化NVIC{需要中断,才要这一步}


编写中断处理函数{即: void USART2_IRQHandler(void) };


编写串口数据收发函数{即:void ult_receive() }


注意:对于复用功能的GPIO,要先使能GPIO时钟,同时设置GPIO模式为 复用功能对应的模式。


二、程序编写


int main(void)

 {

 

   NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);   

   uart2_init(115200);      //串口通信时的波特率设置(可以用串口助手来测试具体是多少)

while(1)

      ult_receive();

  }

 }


//对串口2进行初始化

void uart2_init(u32 bound){  

    GPIO_InitTypeDef GPIO_InitStructure;

USART_InitTypeDef USART_InitStructure;

NVIC_InitTypeDef NVIC_InitStructure;

//到底什么时候用APB1,什么时候用APB2,到 stm32f10x.h 里找匹配

//GPIOx、ADCx、TIMx、USARTx 的时钟来源都不同

RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

    

    //USART2_TX   GPIOA.2

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; 

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

    GPIO_Init(GPIOA, &GPIO_InitStructure);   

        //USART2_RX   GPIOA.3

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;//PA3

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;

    GPIO_Init(GPIOA, &GPIO_InitStructure);


       //USART 参数初始化

USART_InitStructure.USART_BaudRate = bound;

USART_InitStructure.USART_WordLength = USART_WordLength_8b;

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(USART2, &USART_InitStructure);      //初始化串口

    USART_Cmd(USART2, ENABLE);         //使能串口 

   

      //这个函数的第二个入口参数是标示使能串口的类型,也就是使能哪种中断,因为串口的中断类型有很多种。  

      //USART_ITConfig(USART2, USART_IT_IDLE, ENABLE);

      //USART_ITConfig(USART1,USART_IT_TC,ENABLE); //发送数据结束的时候(TC,发送完成)产生中断

    USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);  //开启接收中断,接收到数据中断

         

      //Usart2 NVIC设置

    NVIC_InitStructure.NVIC_IRQChannel =USART2_IRQn;  //正确选择 第几号串口

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);  

}


//void USART2_IRQHandler(void)函数是串口 1 的中断响应函数,当串口 1 发生了相应的中断后,就会跳到该函数执行。

//串口中断服务程序,这一段是 接收数据服务

void USART2_IRQHandler(void){

if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET){    //判断 接收中断

Res2 =USART_ReceiveData(USART2);

if(USART2_RX_STA==0){   //  USART2_RX_STA 是接收状态标记,0 代表未接收完成

UART2_DATA[RxCounter++]=Res2 ;

if(RxCounter > GET_REC_LEN){

USART2_RX_STA  = 1;   //接收完成了

RxCounter = 0;

}

}

        }

 

//串口数据接收程序

void  ult_receive()

{

if(USART2_RX_STA==1) {   // 如果接收完成了,可以复位后,接着接收;也可以先把数据发送到其它串口, 再复位这个串口,接着接收。

RxCounter = 0;   

USART2_RX_STA = 0;

}

if(UART2_DATA[16]==11 && UART2_DATA[17]==7) {

i=0;

Counter = USART2_REC_LEN;

count_flag =1;

UART2_DATA[16] = 0;

UART2_DATA[17] = 0;

}

}


补充:串口的发送

这个地方那个之所以把这个写出来主要是想说发送中断和接受中断其实是共用一个中断函数的,到底是那个中断发生了呢,这就需要我们读取中断状态标志来识别了。


//发送数据

//使用函数USART_SendData(USART1, char data),一次只能发送一个字符。


1)当然我们可以用如下函数发送字符串。

void USART1_Puts(char * str){ 

     while(*str) { 

            USART_SendData(USART1, *str++);  //发送一个字符

            while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);  //等待发送完毕

      } 

}


2)当然我们也可以循环发送字符串数组

for(i = 0; TxBuf1 != ''; i++) {       // TxBuf1为定义好的字符串数组

       USART_SendData(USART2 , TxBuf1);

       while(USART_GetFlagStatus(USART2, USART_FLAG_TC)==RESET);  //等待发送完毕

}


int main(void){

  while(1){

if(USART_RX_STA&0x8000){    

len=USART_RX_STA&0x3fff;

            //循环发送字符串数组  要明确的是 发送字符数组的长度

            //发送的程序可以写在 main 函数里,也可以写在 中断服务函数 里 

for(t=0;t USART_SendData(USART1, USART_RX_BUF[t]);

while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);

}

USART_RX_STA=0;

}

else{

times++;

if(times%5000==0){

printf("rnÕ½½¢STM32¿ª·¢°å ´®¿ÚʵÑérn");

printf("ÕýµãÔ­×Ó@ALIENTEKrnrn");

}

if(times%200==0) 

     printf("ÇëÊäÈëÊý¾Ý,ÒԻسµ¼ü½áÊøn");  

if(times%30==0)

     LED0=!LED0;

delay_ms(10);   

}

}  

}


关键字:STM32  串口  通信  中断 引用地址:STM32 串口 通信 中断

上一篇:意法半导体端口保护 IC为STM32USB-C双角色输电量身定制
下一篇:STM32F103x 485通信

推荐阅读最新更新时间:2024-11-08 20:21

工控机在无线通信系统硬件终端行业中的应用
一、无线通信系统介绍 科技的发展,会到达一个信息高度发达,软硬件高度智能化的时代,一切事物的完成都通过智能化系统来进行,而此时的认知无线电更是在一个高度智能的机器上进行设计,更加充分的利用人工智能技术,通过智能感知,智能组网,智能通信来实现频谱感知、数据和多媒体的通信,进而达到真正意义上的有效利用频谱和高度可靠通信。 二、基于工控机的主体硬件架构为平台,在其上加入各种专业的模块(如认知、通信、射频模块),进而达到所要求的智能感知和通信功能。 在智能硬件平台(其中包含工控机操作系统、传感器控制系统、输入输出控制系统、智能显示交互界面等)的作用下,加上专业的智能认知通信射频系统,就可以完全智能化的实现自动感知频谱、组网、
[嵌入式]
labview实现单PC双串口通信
今天尝试了一下单PC双串口通信,实验前需要一个虚拟串口驱动软件,还可以用一个串口调试助手测试串口性能。但是系统运行时要把串口调试助手关了,否则会报错。 实验的前面板程序框图分别是
[测试测量]
STM32的BootLoader升级
从串口升级固件 ①Jump_To_Application = (pFunction)(*(vu32*) (IAPSTART + 4)); __MSR_MSP(*(vu32*) IAPSTART); Jump_To_Application(); 跟踪__MSR_MSP(一般这个函数都在库文件里有,跟踪不到就用搜索找)找到汇编函数为 __MSR_MSP MSR MSP, r0 ; set Main Stack value BX r14 ②//跳转到应用程序段 //appxaddr:用户代码起始地址. void iap_load_app(u32 appxaddr) { if(((*(vu32*)appxa
[单片机]
<font color='red'>STM32</font>的BootLoader升级
基于Mesh技术的无线语音通信系统设计
  越来越多的大型企业建立自己的符合ITERET国际标准的VOIP通信系统。如同电子邮件系统不会被淘汰一样,SIP系统只会越来越被广泛地使用,是企业既跨入信息交流的先进行列,投资又得以保护。通过SIP协议支撑的多媒体通信平台作为其信息服务支撑系统,同时配合无线Mesh网络,可以将覆盖范围跨越室内外的办公楼宇和厂区,提供广泛的无线语音接入服务。   无线语音通信系统提供了了语音调度功能,在现有的固定电话终端基础上,加入无线网络系统中接入的无线电话终端;这样,在内部固定电话语音调度和通话的基础上,实现无线电话终端之间的语音调度和通话,并且令固定电话和无线移动电话终端之间可以无缝的进行语音通话,满足日常工作、管理和运行维护等多个部门之
[模拟电子]
STM32学习笔记】USART 新特性
支持RXD和TXD管脚互换 很多时候,我们在外接RS232芯片时,很容易将RXD和TXD两根线接反。这类低级错误,一般是老司机才会犯。如果大家知道USART的TXD和RXD管脚可以互换,那么在连接外设RS232芯片时,如果发生错误,就不必再修改硬件,只需直接在软件中将RXD和TXD的管脚反转过来即可修正错误。 参考上图,设置SWAP位,即可将RXD和TXD管脚互换。 支持接收和发送的电平极性反转 第二个特性是,接收和发送的电平极性是可以反转的。通常默认串口电平是高电平为逻辑1,低电平为逻辑0;而在ST的USART中是可以将高电平设置为逻辑0,低电平设置为逻辑1的。这一特性,让我们在一些特殊的场景下灵活使用,举
[单片机]
stm32串口的学习
串口的基本配置 (使用固件库) 根据这图我们可以知道 stm32 至少会有3个串口 由于自己是使用串口一 所以配置的为usart1 1 时钟使能(用到哪个串口`和GPIO要把相应的时钟开启) 2 串口复位;(一般在系统刚开始配置外设的时候,都会先执行复位该外设的操作。) 3 GPIO口配置; 4 串口参数配置; 5 根据需要开启中断 下面的代码部分 一 时钟使能 由于UART的TX和RX和AFIO都挂在APB2桥上,因此采用固件库函数RCC_APB2PeriphClockCmd()进行初始化。UARTx需要分情况讨论,如果是UART1,则挂在APB2桥上,因此采用RCC_APB2PeriphClockCmd()进行初始化,
[单片机]
<font color='red'>stm32</font><font color='red'>串口</font>的学习
Keil软件仿真的串口调试技巧
引言 在单片机系统中,串口(UART,通用异步收发接口)是一个非常重要的组成部分。通常使用单片机串口通过RS232/RS485电平转换芯片与上位机连接,以进行上位机与下位机的数据交换、参数设置、组成网络以及各种外部设备的连接等。RS232/RS485串行接口总线具有成本低、简单可靠、容易使用等特点,加上其历史悠久,所以目前应用仍然非常广泛;特别对于数据量不是很大的场合,串口通信仍然是很好的选择,有着广阔的使用前景。 在单片机编程中,串口占了很重要的地位。传统方式串口程序的调试,往往是利用专用的单片机硬件仿真器。在编写好程序后,利用仿真器来设置断点,观察变量和程序的流程,逐步对程序进行调试,修正错误。使用硬件仿真器的确是很有效的
[嵌入式]
UART学习笔记
串口(UART) DIV_VAL = (PCLK / (bps x 16 ) ) −1 35 = 115200/66.5/16-1 查看芯片手册: GPACON 0x7F008000 R/W Port A Configuration Register 0x0000 GPA0 0000 = Input 0001 = Output 0010 = UART RXD 0011 = Reserved 0100 = Reserved 0101 = Reserved 0110 = Reserved 0111 = External Interrupt Group 1 0000 GPA1 0000 =
[单片机]
小广播
设计资源 培训 开发板 精华推荐

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

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

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved