网站模板切换seo职位具体做什么
引言
本次,继续对前面寄存器实现的串口通讯中断案例使用HAL库进行二次实现,因此这里会省略一些重复内容,如果大家不清楚的话请参考下面链接:USART_串口通讯中断案例(一)(寄存器实现)-CSDN博客https://blog.csdn.net/2301_79475128/article/details/145233910https://blog.csdn.net/2301_79475128/article/details/145233910https://blog.csdn.net/2301_79475128/article/details/145233910
一、需求分析
二、硬件电路设计与分析
与寄存器实现案例一模一样,直接参考上面链接即可,这里不再赘述。
三、软件设计
前面,我们使用HAL库实现了串口通讯的轮询案例,接下来,我们基于前面轮询的工程进行修改,来实现本次串口通讯的中断案例。
怎么做呢?步骤如下。当然如果没看过前面HAL库实现的轮询案例的话,这里可参见下方链接跳转:USART_串口通讯轮询案例(HAL库实现)-CSDN博客https://blog.csdn.net/2301_79475128/article/details/145263748?spm=1001.2014.3001.5501https://blog.csdn.net/2301_79475128/article/details/145263748?spm=1001.2014.3001.5501
接下来,我们就开始串口通讯中断案例的HAL库实现:
3.1 STM32CubeMX工程配置
找到上一次轮询案例的工程目录,然后打开.ioc后缀的文件,可打开其STM32CubeMX中所做的配置。
这个过程就相当于是将这个工程复制了另存为另一个新的工程,然后新的工程名我叫10_usart_interrupt_hal,表示这是串口通讯中断案例的HAL库实现。
这时候,我们发现在STM32CubeMX中对应工程管理配置部分的名字和路径已经变成我们重新命名的新工程,如下图所示
我们保险起见,可以再过一遍本来需要配的内容看看是不是都还是配好的
工程管理部分中第二个的勾选
系统部分调试器的设置
时钟配置汇总外部时钟的设置
系统内部时钟的配置
串口部分,模式设置异步功能,不开启硬件流控
串口配置中参数的设置
由于本次是使用串口中断,所以我们将多开启一个串口中断的NVIC使能
再看看串口配置中的GPIO设置
最后生成代码、在keil中打开工程即可
然后在keil中进行配置一下就行,就是魔法棒中debug的settings中常见的量大配置——复位并运行以及取消勾选打印日志的enable。
3.2 程序补充
把上面的配置做好以后,我们就可以进入VSCode导入工程开始代码补充了。
关于这里自动生成的东西因为和前面轮询差不多,所以就不再赘述。
这里需要说的是,由于本次借助串口中断,因此我们需要注意一下stm32f1xx_it.c文件,因为关于32的中断处理函数主要就是放在这里面
进入该文件,我们翻到下面就能看见一个关于USART1的中断处理函数,和前面按键中断案例的HAL库实现的时候一样,这里也是放了一个函数调用。在这里,这个调用的函数实际上是总的串口中断处理函数,按理说进入应该主要就是一些弱实现的中断回调函数,然后我们对其进行重写就行。我们进去看看
会发现和我们想的不太一样,这个总串口中断处理函数里面有很多东西,所以我们想去找到我们想要重写的中断函数可能还需要仔细看看。更合适的办法就是查看这个函数头上提供的关于该文件的详细介绍,我们翻到最上面看看
可以发现全是英文的,可能看的会比较头疼,但是咱还是不能退缩,去看看。我们现在是想找一下串口中断相关的回调函数,所以先得知道怎么样用该文件中定义的内容,如上图有描述“如何使用这个driver”,大概就是会涉及到咱要找的回调函数了。我们继续往下翻看看
可以看见有一部分提到【Callback registration】回调注册,就是对于相关回调函数的名称定义,可以看见里面有大量的回调函数名并在旁边给出了解释。当然本次我们主要是借助中断实现数据的接收,所以看看关于数据接收的中断回调函数即可,其他的我们有时间自己去同理试一试也可以的。由上图可以看见关于接收数据的中断回调函数应该是【RxCpltCallback】
然后,我们继续往下翻,可以看见更清楚地描述
如上图所示,这里直接地介绍了三种数据发送和接收的模式,并告诉我们要使用那些函数。其中我们就可以知道要重写的弱实现中断回调函数了,同时还提示中断模式下还需要使用一个中断处理的函数。所以我们现在就直接找到这两个接收中断的函数
由这个中断处理的函数可以看出,这对接收中断他只能接受一定长度的字符串,而不能接收变长数据,其传入的参数Size就是给接收到字符的长度。这样说来,我们此时仍旧需要分两种情况进行测试了,即接收定长数据或者变长数据,他们对应不同的两种函数。
3.2.1 定长数据接收测试
接下来,我们就来补充一下定长数据接收情况的代码并进行测试。了解了要用到的函数,那么就来写呗。首先我们对接收中断回调函数在中断文件中进行重写。
里面写一些什么呢?就是写当数据接收完成后要做的事,我们想数据接收完了以后就是继续把数据发给电脑呗,同时我们要把发送函数放在主程序运行,所以在中断回调函数中我们就写一个标志位变量就行了,这里我在main.c中设置存放数据的全局缓冲区buffer[100]存放接收的数据,大小自己定,这里我们给100;同时再定义一个全局标志位isToSend,初值为0,当触发接收中断时值置为1即可。
所以此时重写的接收数据完成的中断回调函数代码如下
// 中代码处理程序 定长接收中断
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{isToSend = 1;
}
然后,我们再去main.c中while循环里面添加接收完成后标志位置1时的发送函数调用代码,同时发送完以后注意清零标志位。
// 定长数据发送if (isToSend){HAL_UART_Transmit(&huart1, buffer, 10, 2000);isToSend = 0;}
最后,我们在main.c中的while循环中加接收中断处理的函数调用,这可以看作是中断处理的使能
// 开启中断处理使能 定长接收HAL_UART_Receive_IT(&huart1, buffer, 10);
OK,这样我们定长数据接收代码就写好了,按理说是发送接收的10个字符,然后我们编译烧录看效果
显然,测试成功,可以接受到。当然,由于只能接受定长数据,所以当给的不是规定长度的字符时,发送到电脑上看见的字符就会不符合预期了。这时候我们就需要用更灵活的变长数据接收方式进行更合适。
3.2.2 变长数据接收测试
接下来,我们再来进行变长数据接收测试。首先回过头来继续往下翻文件描述
继续往下翻时有如上图描述,这里说了文件中还提供了额外的函数,例如可以用在被接受数据的长度未知的地方。这就意味着下面提供了我们变长数据接收中断的相关函数。
所以咱继续往下翻着看看,如下图
根据描述可以发现这里给出了变长数据接收的中断回调函数名以及对应的中断处理函数名。接下来我们找到对应函数位置
可见,这俩函数中参数的变化,其中断回调函数介绍也表明了提供的参数Size实际上是获取到的实际接收的数据长度,这就说明我们此时不是自己给长度了,其会自动检测数据长度,因此我们可以直接从中断回调函数中拿到我们接受到的数据的长度,然后在发送接收数据时传进去即可。
所以,这里我们在主程序中需要继续再定义一个全局变量size存放接收数据长度。接着在接受变长数据的中断回调函数中我们此时除了修改发送标志位以外,还要将自动获取到的数据长度Size给到我们存放长度的全局变量size,代码如下
// 中断处理函数 变长数据接收
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{isToSend = 1;size = Size;
}
然后,我们进入main.c中,在while循环中添加发送标志位置1后执行的发送函数,同时执行后清零标志位,代码如下
// 变长数据发送if (isToSend){HAL_UART_Transmit(&huart1, buffer, size, 2000);isToSend = 0;}
最后,我们再在这之前加上对应的中断处理函数调用,相当于开启变长数据接收中断使能。
// 开启中断处理使能 变长接收HAL_UARTEx_ReceiveToIdle_IT(&huart1, buffer, 100);
这样,关于变长数据接收的代码就写完了,下面开始编译烧录测试看效果
很显然,我们此时可以接收到任意长度的字符了,说明测试成功!
四、总结
到目前为止,我们关于变长数据接收的测试就进行完毕,同时也意味着本次使用HAL库实现的串口通讯中断案例(中断主要在于数据接收)也实现完成了。我们可以明显发现代码编写上简单了很多,唯一麻烦的是我们不知道相关函数的调用,需要在进入相应函数所在文件稍微看看对应的描述才好。当然了,后面我们使用多了以后,自然就会熟悉,因此这里不是问题。
以上便是本次文章的所有内容,欢迎各位朋友在评论区讨论,本人也是一名初学小白,愿大家共同努力,一起进步吧!
鉴于笔者能力有限,难免出现一些纰漏和不足,望大家在评论区批评指正,谢谢!