糖尿病康复,内容丰富有趣,生活中的好帮手!
糖尿病康复 > stm32中断方式的串口通信——上位机控制串口收发

stm32中断方式的串口通信——上位机控制串口收发

时间:2023-10-15 13:36:06

相关推荐

stm32中断方式的串口通信——上位机控制串口收发

文章目录

前言一、什么是串口通信二、什么是中断——STM321.中断的概念2.STM32下NVIC的介绍3.中断优先级的介绍4.外部中断的介绍三、串口通信keil工程文件1.新建工程模板2.串口初始化函数,以及串口发送函数定义。3.中断服务程序的编写4.主程序的编写四、烧板&Debug总结

前言

前面介绍的串口通信的方式主要有3种

轮询方式的串口通信中断方式的串口通信DMA方式的串口通信

这里我将介绍的是中断方式的串口通信,相较于之前的轮询式的串口通信,中断式的串口通信有许多的优点,当接收或者发送一个数据时就申请中断,同时cpu可以执行其它任务,CPU的利用率更高了。

提示:以下是本篇文章正文内容,下面案例可供参考

一、什么是串口通信

关于什么是串口通信这里就不过多的赘述了,因为我前面的博客都有说明,如果还不明白的可以去看看我之前的博客。

链接:

/wer4567/article/details/127374342?spm=1001..3001.5501

二、什么是中断——STM32

大家可能还不是很了解什么是中断,这里我就来介绍介绍有关中断的相关知识,以及stm32下的中断的一些说明。

1.中断的概念

中断实质上就是在CPU正常执行程序时,遇到了内部或者外部的异常情况需要紧急处理,CPU暂时停止正在运行的程序,转而去处理发生的异常事件,当该异常事件处理完毕之后又返回之前暂停的程序处继续执行。**举个简单的例子:**当你在看电视的时候,你妈叫你去买酱油,你妈叫你买酱油就是发生的异常事件,当你买完酱油回来又继续看你的电视。

STM32F10x芯片内有84个中断通道,包括16个内核中断和68个可屏蔽中断,这些中断通道已经按照不同优先级顺序固定分配相应的外部设备。这一部分就不过多说明,大家可以自己去参考《stm32f0x中文参考手册》,上面都有详细的介绍。

2.STM32下NVIC的介绍

NVIC英文全称是Nested Vectored Interrupt Controller,中文意思就是嵌套向量中断控制器,它属于M3内核的一个外设,控制着芯片的中断相关功能。由于ARM给NVIC预留了非常多的功能,但对于使用M3内核设计芯片的公司可能就不需要这么多功能,于是就需要在NVIC上裁剪。ST公司的STM32F103芯片内部中断数量就是NVIC裁剪后的结果。中断控制相关的寄存器在固件库core_cm3.h

3.中断优先级的介绍

当CPU在正常执行程序的过程种总是会收到许多的中断,这么的中断如果一股脑的处理的话显然不现实,每个中断都应该有个优先级,优先级高的先执行,执行完之后再跳回之前的程序,这样程序才能井然有序的执行。

STM32F103芯片支持60个可屏蔽中断通道,每个中断通道都具备自己的中断优先级控制字节(8位,但是STM32F103中只使用4位,高4位有效),用于表达优先级的高4位又被分为组成抢占式优先级和响应式优先级,每个中断源都需要被指定这两种优先级。当两个中断源的抢占式优先级相同时,这两个中断将没有嵌套关系,当一个中断到来后,如果正在处理另一个中断,这个后到来的中断就要等待前一个中断处理完之后才能被处理。如果这两个中断同时到达,则中断控制器根据他们的响应优先级高低来决定先处理哪一个;如果他们的抢占式优先级和响应优先级都相等,则根据他们在中断表中的排位顺序决定先处理哪一个。高抢占式优先级的中断事件会打断当前的主程序或中断程序运行,俗称中断嵌套。在抢占式优先级相同的情况下,高响应优先级的中断优先被响应。

4.外部中断的介绍

STM32F10x外部中断/事件控制器(EXTI)包含多达20个用于产生事件/中断请求的边沿检测器。EXTI的每根输入线都可单独进行配置,以选择类型(中断或事件)和相应的触发事件(上升沿触发、下降沿触发或边沿触发),还可独立地被屏蔽。

外部中断/事件的线映射

三、串口通信keil工程文件

1.新建工程模板

关于在keil下新建一个stm32f103的的工程模板这里就不过多的说明了,相信大家通过前面的学习,都已经非常清楚了。新建工程模板之后再添加相应的.c,.h文件就可以了

注意!下面的代码只是.c文件的相关代码,如果同学们要借鉴的话,需要自己添加相应的.h文件和头文件

2.串口初始化函数,以及串口发送函数定义。

void My_Uart_Init(uint32_t Bound)//这里时配置的串口1,如果配置其它串口也可自己改引脚{GPIO_InitTypeDef GPIO_InitStructure;USART_InitTypeDef USART_InitStructure;NVIC_InitTypeDef NVIC_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART1,ENABLE);//TX口的初始化GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStructure);//RX的初始化GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化USARTNVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);USART_InitStructure.USART_BaudRate = Bound;USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;USART_InitStructure.USART_Parity = USART_Parity_No;USART_InitStructure.USART_StopBits = USART_StopBits_1;USART_InitStructure.USART_WordLength = USART_WordLength_8b;USART_Init(USART1,&USART_InitStructure);//初始化USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);//开启串口接收中断USART_Cmd(USART1,ENABLE);}//发送一个字节void Usart_SendByte(USART_TypeDef *USARTx,uint8_t ch){USART_SendData(USARTx,ch);while(USART_GetFlagStatus(USARTx,USART_FLAG_TXE) == RESET);}//发送8位数组void Usart_SendArray(USART_TypeDef *USARTx,uint8_t *arry,uint16_t num){uint8_t i;for(i=0; i<num; i++){Usart_SendByte(USARTx,arry[i]);}while(USART_GetFlagStatus(USARTx,USART_FLAG_TC) == RESET);}void Usart_SendByts(USART_TypeDef *USARTx,char *p){while(*p != '\0'){Usart_SendByte(USARTx,*p);p++;}while(USART_GetFlagStatus(USARTx,USART_FLAG_TC) == SET);}

3.中断服务程序的编写

void USART1_IRQHandler(){uint8_t Rx_cnt= 0;char ch[100];if(USART_GetITStatus(USART1,USART_IT_RXNE) != RESET){GPIO_SetBits(GPIOA,GPIO_Pin_5);ch[Rx_cnt++] = USART1->DR;Usart_SendByts(USART1,ch);if(ch[Rx_cnt-1] == '\0') Rx_cnt = 0;USART_ClearITPendingBit(USART1,USART_IT_RXNE);}if(strcmp(ch,"s") == 0) {GPIO_ResetBits(GPIOA,GPIO_Pin_5);Global_flag = 1;}if(strcmp(ch,"t") == 0) Global_flag = 0;}

4.主程序的编写

if(Global_flag == 0)//Global_flag为定义的全局变量,在中断服务程序中也会用到Usart_SendByts(USART1,str);Delay_ms(500);//自己编写的延时函数

将上诉代码添加到自己创建的工程文件目录下编译生成hex文件烧板测试!

四、烧板&Debug

总结

通过本次的学习,我也学习到了许多知识。在做字符串控制的实验中,因为理解错中断的相关知识,导致一直卡壳,当时一位字符串的接收是一个字符串进一次中断,不知道当时是怎么想的,导致一直没做出来,其实是收到一个字符就进一次中断,一直到字符接收完。

如果觉得《stm32中断方式的串口通信——上位机控制串口收发》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。