单片机与嵌入式系统原理与应用 课件 李刚 第5-9章 UART串行通信 -ADC模块_第1页
单片机与嵌入式系统原理与应用 课件 李刚 第5-9章 UART串行通信 -ADC模块_第2页
单片机与嵌入式系统原理与应用 课件 李刚 第5-9章 UART串行通信 -ADC模块_第3页
单片机与嵌入式系统原理与应用 课件 李刚 第5-9章 UART串行通信 -ADC模块_第4页
单片机与嵌入式系统原理与应用 课件 李刚 第5-9章 UART串行通信 -ADC模块_第5页
已阅读5页,还剩222页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

单片机与嵌入式系统原理与应用ByYangJ.X.1模块5UART模块5UART串行通信串行通信项目5自报家门项目6远程彩灯项目7远程报警主要内容和学习重点项目5:自报家门知识准备认识STM32的通信接口认识STM32的串行通信接口USARTSTM32USART的挂载总线和功能STM32USART的复用引脚和GPIO模式——重点实训设备有关USART1的电路图——重点项目实施:自报家门习题项目探究UART通信复用引脚UART结构体和初始化HAL_UART_Transmit()函数用法重定义printf()实现异步串行发送知识拓展STM32F1波特率生成HAL_UART_Transmit()函数分析项目6:远程彩灯知识准备uart中断UART标准中断接收HAL函数项目实施:远程彩灯习题/拓展任务项目探究HAL_UART_Receive_IT()用法UART标准中断接收的处理知识拓展HAL_UART_Receive_IT()解读接收到的数据如何写入到指定地址中项目7:远程报警项目基础IDLE中断下需使用的HAL函数项目实施:

远程报警习题/拓展任务项目探究HAL_UARTEx_ReceiveToIdle_IT()用法和回调函数知识拓展HAL_UARTEx_ReceiveToIdle_IT()用法和回调函数模块小结制作者或logo目录2项目5知识准备:认识STM32的通信接口制作者或logo项目5:自报家门3F103闪存大容量MCUSPI(SerialPeripheralInterface):MOTOROLA公司提出的同步串行总线方式I2S接口(Inter-IC

Sound)--

PHILIPS公司最早推出的集成音频接口SPI可配置为支持SPI协议(默认)或I2S音频协议I2C(Inter-IntegratedCircuit):由PHILIPS公司开发的两线式串行总线USART:UART(通用异步串行口)及同步通信↖来自数据手册USB(UniversalSerialBus):通用串行总线CAN(ControllerAreaNetwork):控制器局域网,是国际上应用最广泛的串行通信现场总线之一。最初用于汽车工业。SDIO是SD型的扩展接口,除了可以接SD卡外,还可以接支持SDIO接口的设备,插口的用途不止是插存储卡,所有支持SDIO的设备都可连接。——不是串行通信接口F1小容量MCU↓SPI知识准备:认识STM32的串行通信接口USARTUSART1挂载总线APB2-----------------------------------------USART2USART3UART4UART5挂载总线APB1制作者或logo项目5:自报家门4来自数据手册APB2↓APB1↓知识准备:“M3主控模块”串行通信电路图要使M3模块与PC机进行UART串行通信,需通过M3模块J3接口连接NEWLAB实训平台或智慧盒左边的10针接口

→如下图可看出,USART1串行通信使用的复用引脚是PA9和PA10制作者或logo项目5:自报家门5MCU知识准备:STM32USART功能关注重点是UART功能制作者或logo项目5:自报家门6←UART←SPI-25.3.9←25.3.11智能卡←25.3.8LIN局部互联网←25.3.12红外功能←25.3.6多处理器通信←↑来自参考手册来自STM32CUBEMX↘←25.3.10单线半双工通信25.3.14硬件流控制↗①②②③知识准备:STM32USART功能注意UART4和UART5的功能制作者或logo项目5:自报家门7来自参考手册↓知识准备:STM32F1UART配置制作者或logo项目5:自报家门8←波特率←字长←奇偶校验←停止位←数据方向字长可选8位或9位奇偶校验可选无、奇校验和偶校验停止位可选1位或2位←对接收信号的采样倍率①②③①②③摘自英文参考手册27.4和中文参考手册25.4↓知识准备:常用的UART发送和接收HAL函数HAL_UART_Transmit()HAL_UART_Receive()HAL_UARTEx_ReceiveToIdle()Blockingmode阻塞模式/Pollingmode轮询模式HAL_UART_Transmit_IT()HAL_UART_Receive_IT()HAL_UARTEx_ReceiveToIdle_IT()Non-blockingmode非阻塞模式HAL_UART_Transmit_DMA()HAL_UART_Receive_DMA()HAL_UARTEx_ReceiveToIdle_DMA()DMAmodeDMA模式制作者或logo项目5:自报家门9异步串行通信的发送一般可以不使用中断!项目实施:基于M3主控模块项目5:自报家门使MCU每隔5s通过串口USART1发送”这是发送自STM32F103的信息!”,在PC机上的串口助手中显示波特率使用115200定时方式采用非阻塞模式。制作者或logo项目5:自报家门10↓摘自M3主控模块电路图↓项目实施:

STM32CUBEMX的设置MCU选型、RCC和SYS,时钟ClockConfiguration和项目ProjectManager根据M3主控模块电路图判断出需要使用MCU的USART1,并映射到PA9和PA10选中STM32CUBEMX中“Connectivity”中的“USART1”选择异步方式、设置波特率其他参数可使用默认值由于本任务使用轮询模式UART发送数据,因而可以不开启USART中断制作者或logo项目5:自报家门11↖按照任务1-1的设置项目实施:代码编写非阻塞模式定时可通过HAL_GetTick()来实现;在主循环中调用HAL_UART_Transmit()实现数据发送函数原型函数参数huart:Handle的结构体变量-指定使用哪个串口--注意这是指针变量pData:发送数据的保存地址--注意这是指针变量Size:发送数据的长度--可以使用sizeof()运算符自动计算字符串长度Timeout:超时–多长时间发送不成功就停止发送,单位是ms参考代码制作者或logo项目5:自报家门12HAL_StatusTypeDefHAL_UART_Transmit(UART_HandleTypeDef*huart,uint8_t*pData,uint16_tSize,uint32_tTimeout);①②项目实施:请将代码添加到正确的位置

/*Initializeallconfiguredperipherals*/MX_GPIO_Init();MX_USART1_UART_Init();

/*USERCODEBEGIN2*/

/*USERCODEEND2*/

/*Infiniteloop*/

/*USERCODEBEGINWHILE*/while(1){

/*USERCODEENDWHILE*/

/*USERCODEBEGIN3*/}

/*USERCODEEND3*/如果KEILMDK编辑窗口的中文显示为乱码或不显示中文字符制作者或logo项目5:自报家门13①②项目实施:结果验证根据你使用的是NewLab实训平台或智慧盒判断连接到PC机上的串口号如果使用NewLab——COM1如果使用智慧盒——打开设备管理器查看↓注意串口调试助手的串口设置(红框)参数与你STM32CUBEMX的设置↖要一致通过“打开/关闭”按钮启停串口制作者或logo项目5:自报家门14注意:PC机上的每个串口只能一个软件/程序占用!项目实施:基于Proteus仿真项目5:自报家门使MCU每隔5s通过串口USART1发送”这是发送自STM32F103的信息!”,在Protues的虚拟终端中显示波特率使用115200,定时方式采用非阻塞模式。异步串行通信UART参数设置制作者或logo项目5:自报家门15未仿真的状态下双击虚拟终端打开此窗口进行设置→双击项目实施:STM32CUBEMX的设置MCU选型、RCC和SYS,时钟ClockConfiguration和项目ProjectManager根据Proteus电路图看出虚拟终端连接到PA9和PA10,由此判断出需要使用MCU的USART1选中STM32CUBEMX中“Connectivity”中的“USART1”选择异步方式、设置波特率其他参数可使用默认值由于本任务使用阻塞模式UART发送数据,因而可以不开启USART中断制作者或logo项目5:自报家门16↖按照任务1-4的设置项目实施:代码编写非阻塞模式定时可通过HAL_GetTick()来实现;在主循环中调用HAL_UART_Transmit()实现数据发送函数原型函数参数huart:Handle的结构体变量-指定使用哪个串口--注意这是指针变量pData:发送数据的保存地址--注意这是指针变量Size:发送数据的长度--可以使用sizeof()运算符或strlen()函数自动计算字符串长度Timeout:超时–多长时间发送不成功就停止发送,单位是ms参考代码制作者或logo项目5:自报家门17HAL_StatusTypeDefHAL_UART_Transmit(UART_HandleTypeDef*huart,uint8_t*pData,uint16_tSize,uint32_tTimeout);注意:Proteus的虚拟终端接受的换行符与Windows/Linux系统不同,是’\r’①②项目实施:请将代码添加到正确的位置

/*Initializeallconfiguredperipherals*/MX_GPIO_Init();MX_USART1_UART_Init();

/*USERCODEBEGIN2*/

/*USERCODEEND2*/

/*Infiniteloop*/

/*USERCODEBEGINWHILE*/while(1){

/*USERCODEENDWHILE*/

/*USERCODEBEGIN3*/}

/*USERCODEEND3*/如果KEILMDK编辑窗口的中文显示为乱码或不显示中文字符制作者或logo项目5:自报家门18①②项目实施:结果验证加载程序后开启仿真,可在跳出的虚拟终端窗口中看到MCU发送的信息。如果虚拟终端

未自行弹出:仿真时→注意:虚拟终端的串行通信参数要与STM32CUBEMX的参数一致↓制作者或logo项目5:自报家门19双击-波特率设置关闭仿真时虚拟终端→STM32CUBEMX→习题使用printf()函数重定向的方法实现UART发送按①②③④操作拓展任务按下KEY1后MCU通过UART每隔5秒发送出“火警发生,请迅速撤离!”的报警信息,同时令蜂鸣器发出报警音(放开KEY1仍继续报警);按下KEY2后关闭蜂鸣器,并且MCU每隔5秒通过UART发送“火警已解除!”,发送6次后停止。习题/拓展任务制作者或logo项目5:自报家门20①usart.h文件中添加30行代码→②usart.c文件中添加106-110行代码↓③main.c文件中添加这些代码↓④结果项目探究:USART复用引脚USART的复用引脚制作者或logo项目5:自报家门21任何MCU的任何外设都需要时钟,STM32为了更好地控制功耗,对每个外设的时钟都设置了开关,方便精确控制功耗。来自参考手册↕项目探究:USART复用引脚USART的复用引脚制作者或logo项目5:自报家门22来自参考手册↑来自数据手册↓→来自STM32CUBEMX↕项目探究:USART复用引脚USART外设GPIO配置制作者或logo项目5:自报家门23来自参考手册↓来自STM32CUBEMX↓项目探究:USART复用引脚GPIO_MODE_OUTPUT_OD:开漏输出模式GPIO_MODE_OUTPUT_PP:推挽输出模式GPIO_MODE_AF_PP:复用推挽输出GPIO_MODE_AF_OD:复用开漏输出GPIO_MODE_AIN:模拟输入GPIO_MODE_IN_FLOAT:浮空输入GPIO_MODE_IPD:下拉输入GPIO_MODE_IPU:上拉输入制作者或logo项目5:自报家门24项目探究:UART结构体UART_HandleTypeDefUART_InitTypeDefUSART_TypeDef制作者或logo项目5:自报家门25①②③①②←③①②⑥项目探究:HAL_UART_Transmit()用法参数huart:Handle的结构体变量-指定使用哪个串口--注意这里要求的是指针pData:发送数据的保存地址--注意这里要求的是指针Size:发送数据的长度--可以使用sizeof()运算符或strlen()函数自动计算字符串长度Timeout:超时–多长时间发送不成功就停止发送,单位是ms返回值类型:HAL_StatusTypeDef制作者或logo项目5:自报家门26举例:HAL_UART_Transmit(&huart1,(uint8_t*)"ILOVEMCU!\n",sizeof("ILOVEMCU!\n"),1000);举例:uint8_tsendbuf[]="ILOVEMCU!\n";HAL_UART_Transmit(&huart1,sendbuf,strlen((constchar*)sendbuf),1000);通过两次HAL_GetTick()获取的uwTick之差即可知两次执行HAL_GetTick()之间消逝的时长项目探究:HAL_GetTick()用法制作者或logo项目5:自报家门27来自stm32f1xx_it.c文件↓↓来自stm32f1xx_hal.c文件↓STM32CUBEMX↓项目探究:将USART发送函数重定向到printf()函数printf()函数是格式化输出函数printf()函数通过调用fputc()函数来实现格式化输出,所以“将UART串口重定向到printf()”通过对fputc()函数重定义,让fputc()从指定UART串口输出fputc()的头文件是stdio.h,所以需要添加#include<stdio.h>制作者或logo项目5:自报家门28注意1:fputc()函数中已指定了固定的UART串口!注意2:也可以在其他文件中添加重定义fputc的代码,如main.c注意3:如果printf不显示,注意查看右图Options中的设置是否勾选“UseMicroLIB”知识拓展:STM32F1波特率生成制作者或logo项目5:自报家门29摘自中文参考手册25.3.4↓知识拓展:HAL_UART_Transmit()解读制作者或logo项目5:自报家门30来自参考手册↕摘自参考手册图248USART框图→①③④⑤⑥串口初始化时已对TE进行设置②⑤⑦⑦⑦HAL_UART_Transmit(&huart1,(uint8_t*)"ILOVEMCU!\n",sizeof("ILOVEMCU!\n"),1000);函数调用↑函数定义↓②项目6知识准备:回顾UART结构体Handle结构体-UART_HandleTypeDefUSART_TypeDef结构体↑注意:小写的huart1(或huart2,huart3,…)是结构体变量,不是指针大写的USART1(或USART2,USART3,…)是指向结构体的指针变量的符号常量用做函数实参时请注意类型是否匹配判断是否需要加取地址符“&”制作者或logo项目6:远程彩灯31知识准备:中断方式UART接收的HAL函数制作者或logo项目6:远程彩灯32HAL_UART_Receive_IT()

知识准备:STM32F1系列USART支持的中断事件串行通信的发送一般可以不使用中断串行通信接收使用RXNE中断时当USART_SR的RXNE位被置1,表明数据已经被接收并可以读出。如果USART_CR1的RXNEIE位被置1,将产生RXNE中断制作者或logo项目6:远程彩灯33摘自英文参考手册27.4和中文参考手册25.4↓项目实施:基于M3主控模块

项目6:远程彩灯使用STM32的UART中断接收,从PC机串口助手软件接收指令“xy”,并按以下要求实现LED灯亮灭效果,实现后向串口发送“操作成功!”。x为数字1-8中的一个,表示LED1-8中的一盏灯;y为0或1,0表示灭,1表示亮;例如指令“31”使LED3点亮;如果指令字符不在以上指定的范围内,向串口发送“指令有误!”提示由于指令固定为2个字符,HAL_UART_Receive_IT()注册时可指定Size为2可在重定义HAL_UART_RxCpltCallback(huart)的语句块中实现对LED进行控制,也可以在主循环中根据接收到的数据进行控制。别忘了在HAL_UART_RxCpltCallback(huart)的最后,要再次注册HAL_UART_Receive_IT()——下次再发指令才能收到制作者或logo项目6:远程彩灯34项目实施:STM32CUBEMX的设置MCU选型、RCC和SYS,时钟ClockConfiguration和项目ProjectManagerUSART1的参数设置(ParameterSettings)GPIO配置所有8个LED连接的引脚开启USART中断↓——重要NVIC抢占优先级最好不要设置为0制作者或logo项目6:远程彩灯35↖按照任务1-1的设置↖按照任务5-1的设置↖按照任务2-1的设置项目实施:代码编写声明一个uint8_t类型的数组来存放接收的数据,根据任务要求,每次接收2个字符,因此数组的大小可以设置为2在主函数的while之前调用HAL_UART_Receive_IT()进行中断接收设置参考代码↗重定义UARTRXNE接收回调函数来接收远程指令并实现LED效果参考代码→别忘了pin_num的声明switch语句参考链接↓制作者或logo项目6:远程彩灯36/cprogramming/c-switch.html①②①②项目实施:请将代码添加到正确的位置/*Privatevariables-----------------------------------*//*USERCODEBEGINPV*//*USERCODEENDPV*/…略…intmain(void){HAL_Init();SystemClock_Config();/*Initializeallconfiguredperipherals*/MX_GPIO_Init();MX_USART1_UART_Init();

/*USERCODEBEGIN2*/

/*USERCODEEND2*/

/*Infiniteloop*/

/*USERCODEBEGINWHILE*/while(1){

/*USERCODEENDWHILE*/

/*USERCODEBEGIN3*/}

/*USERCODEEND3*/}/*注main()到此结束*/…略…/*USERCODEBEGIN4*//*USERCODEEND4*/制作者或logo项目6:远程彩灯37请注意:HAL_UART_Receive_IT()必须在UART初始化之后才能调用!项目实施:结果验证制作者或logo项目6:远程彩灯38①③④⑥⑤②项目实施:基于Proteus仿真项目6:远程彩灯使用STM32的UART中断接收,从电脑串口助手软件接收指令“xy”,并按以下要求实现LED灯亮灭效果,实现后向串口发送“操作成功!”。x为数字1-8中的一个,表示LED1-8中的一盏灯;y为0或1,0表示灭,1表示亮;例如指令“31”使LED3点亮;如果指令中的数字不在以上指定的范围内,向串口发送“指令有误!”提示由于指令固定为2个字符,HAL_UART_Receive_IT()注册时可指定Size为2可在重定义HAL_UART_RxCpltCallback(huart)的语句块中实现对LED进行控制,也可以在主循环中根据接收到的数据进行控制。别忘了在HAL_UART_RxCpltCallback(huart)的最后,要再次注册HAL_UART_Receive_IT()——下次再发指令才能收到制作者或logo项目6:远程彩灯39项目实施:STM32CUBEMX的设置MCU选型、RCC和SYS,时钟ClockConfiguration和项目ProjectManagerUSART1的参数设置(ParameterSettings)GPIO配置LED1~LED8连接的引脚开启USART中断↓——重要NVIC抢占优先级最好不要设置为0制作者或logo项目6:远程彩灯40↖按照任务1-4的设置↖按照任务5-4的设置↖按照任务2-1的设置项目实施:代码编写声明一个uint8_t类型的数组来存放接收的数据,根据任务要求,每次接收2个字符,因此数组的大小可以设置为2在主函数的while之前调用HAL_UART_Receive_IT()进行中断接收注册参考代码↗重定义UARTRXNE接收回调函数来接收远程指令并实现LED效果参考代码→别忘了pin_num的声明switch语句参考链接制作者或logo项目6:远程彩灯41①②①②项目实施:请将代码添加到正确的位置/*Privatevariables-----------------------------------*//*USERCODEBEGINPV*//*USERCODEENDPV*/…略…intmain(void){HAL_Init();SystemClock_Config();/*Initializeallconfiguredperipherals*/MX_GPIO_Init();MX_USART1_UART_Init();

/*USERCODEBEGIN2*/

/*USERCODEEND2*/

/*Infiniteloop*/

/*USERCODEBEGINWHILE*/while(1){

/*USERCODEENDWHILE*/

/*USERCODEBEGIN3*/}

/*USERCODEEND3*/}/*注main()到此结束*/…略…/*USERCODEBEGIN4*//*USERCODEEND4*/制作者或logo项目6:远程彩灯42请注意:要令键盘输入的字符显示在虚拟终端上,应进行以下操作:↓请注意:HAL_UART_Receive_IT()必须在UART初始化之后才能调用!项目实施:结果验证制作者或logo项目6:远程彩灯43①③④②习题/拓展任务习题拓展任务修改项目代码,注册并使用自己命名的回调函数名而非HAL弱定义的回调函数来实现项目结果。提示:使用HAL的API:HAL_UART_RegisterCallback()制作者或logo项目6:远程彩灯44项目探究:UART初始化MX_USART1_UART_Init();三个结构体都应用制作者或logo项目6:远程彩灯45①②③③④④⑤找到定义→项目探究:UART初始化MSP即MCUSpecificPackage,是和具体的MCU相关的一些配置制作者或logo项目6:远程彩灯46①②①HAL_UART_MspInit()在HAL_UART_Init()中被调用项目5

↙项目探究↘MX_USART1_UART_Init中调用//配置USARTx中断优先级//使能NVICUSART中断项目探究:HAL_UART_Receive_IT()用法返回值:HAL_StatusTypeDef参数huart:Handle的结构体变量-指定使用哪个串口--注意这是指针变量pData:接收数据的保存地址--注意这是指针变量Size:接收数据的长度制作者或logo项目6:远程彩灯47举例:uint8_trec_buf[5];HAL_UART_Receive_IT(&huart1,rec_buf,5);举例:uint8_trxByte;HAL_UART_Receive_IT(&huart1,&rxByte,1);项目探究:RXNE中断处理函数

制作者或logo项目6:远程彩灯48中间部分代码略去中间部分代码略去①③④它的定义在⑤②⑤用户重定义↑①③⑤HAL弱定义知识拓展:HAL_UART_Receive_IT()解读制作者或logo项目6:远程彩灯49①②摘自HAL驱动文档HAL_UART_Receive_IT(&huart1,RxByte,2)②⑴②⑴知识拓展:HAL_UART_Receive_IT()解读制作者或logo项目6:远程彩灯50调用HAL_UART_Init()串口初始化时已完成这些←步骤②⑴摘自参考手册图248↘摘自中文参考手册25.3.2↕摘自中文参考手册目录↑知识拓展:接收数据如何被存放到*pData制作者或logo项目6:远程彩灯51②↖HAL_UART_Receive_IT()调用的函数,pData是HAL_UART_Receive_IT()中存放接收数据的参数;Size是指定接收长度的参数;④①③④④④//当接收完成HAL_UART_Receive_IT(&huart1,RxByte,2)↙注意:本函数的语句块未完整包含在此截图中①C语言指针基础知识请回顾项目五知识储备!知识拓展:关闭和开启RXNE中断制作者或logo项目6:远程彩灯52⑤↓用户重定义回调函数时需要在语句块最后再次调用HAL_UART_Receive_IT()④⑤⑤⑥⑥摘自中英文参考手册表198↓⑦⑦HAL_UART_Receive_IT(&huart1,RxByte,2)项目7知识准备:STM32F1系列USART支持的中断事件制作者或logo项目7:选程报警53摘自英文参考手册27.4和中文参考手册25.4↓串行通信的发送一般不使用中断串行通信接收使用IDLE中断如果USART_CR1的IDLEIE位被置1,当所有数据接收完毕,线路进入空闲状态时,将产生“检测到空闲线路”的中断知识准备:

IDLE中断下需使用的HAL函数摘自STM32F4系列HAL驱动文档制作者或logo项目7:选程报警54知识准备:

IDLE中断下需使用的HAL函数左图为stm32f1xx_hal_uart.c文件前面部分的注释内容中的一部分制作者或logo项目7:选程报警55项目实施:基于M3主控模块

项目7:远程报警使用STM32的UARTIDLE中断接收,从电脑串口助手软件接收指令。当接收到“start”时,令蜂鸣器发出500Hz音频的报警声,实现后向串口发送“正在报警!”;当接收到“stop”时,蜂鸣器停止报警,实现后向串口发送“已停止报警!”;接收到其他信息时向串口发送“指令有误!”。制作者或logo项目7:选程报警56项目实施:STM32CUBEMX的设置MCU选型、RCC和SYS,时钟ClockConfiguration和项目ProjectManagerUSART1的参数设置(ParameterSettings)GPIO配置蜂鸣器连接的引脚开启USART中断NVIC抢占优先级最好不要设置为0制作者或logo项目7:选程报警57↖按照任务1-1的设置↖按照任务5-1的设置↖按照任务3-1的设置↖按照任务6-1的设置项目实施:代码编写声明一个uint8_t类型的数组来存放接收的数据在主函数的while之前调用HAL_UARTEx_ReceiveToIdle_IT()进行中断接收注册参考代码↗第3个参数为接收的最大长度重定义UARTIDLE接收回调函数来接收远程指令并实现蜂鸣器效果参考代码→注意头文件包含指令的添加注意BUZZ_flag的声明在主函数的while之中添加蜂鸣器代码制作者或logo项目7:选程报警58①②①②strcmp用法可参考/cprogramming/c-function-strcmp.html项目实施:请将代码添加到正确的位置/*Privateincludes---------------------------------------------*//*USERCODEBEGINIncludes*//*USERCODEENDIncludes*/…略…/*Privatevariables--------------------------------------------*//*USERCODEBEGINPV*//*USERCODEENDPV*/…略…intmain(void){HAL_Init();SystemClock_Config();/*Initializeallconfiguredperipherals*/MX_GPIO_Init();MX_USART1_UART_Init();

/*USERCODEBEGIN2*/

/*USERCODEEND2*/

/*Infiniteloop*/

/*USERCODEBEGINWHILE*/while(1){

/*USERCODEENDWHILE*/

/*USERCODEBEGIN3*/}}/*注main()到此结束*/

/*USERCODEEND3*/…略…/*USERCODEBEGIN4*//*USERCODEEND4*/制作者或logo项目7:选程报警59请注意:

HAL_UARTEx_ReceiveToIdle_IT()必须在UART初始化之后才能调用!项目实施:结果验证制作者或logo项目7:选程报警60①③②习题习题操作题在STM32中实现:当接收到远程UART指令“快闪”时,全部LED灯同时以1Hz的频率快闪1次(亮50ms,灭950ms);当接收到远程指令“慢闪”时,全部LED灯同时以0.5Hz的频率闪烁;当接收到远程指令“流水灯”时,LED灯呈现流水灯效果(每盏灯保持亮250ms);当接收到远程指令“停”时,LED灯停止动作,全部处于点亮的状态。制作者或logo项目7:选程报警61项目探究:HAL_UARTEx_ReceiveToIdle_IT()用法返回值:HAL_StatusTypeDef参数huart:Handle的结构体变量-指定使用哪个串口--注意这是指针变量pData:接收数据的保存地址--注意这是指针变量Size:接收数据长度(最大长度)制作者或logo项目7:选程报警62用法与HAL_UART_Receive_IT()函数类似项目探究:IDLE中断处理制作者或logo项目7:选程报警63①②③③项目探究:IDLE中断处理制作者或logo项目7:选程报警64②④⑴④⑵知识拓展:HAL_UARTEx_ReceiveToIdle_IT()解读制作者或logo项目7:选程报警65使用IDLE中断也需要使能RXNE中断摘自stm32f1xx_hal_uart.c文件的注释内容↓HAL_UARTEx_ReceiveToIdle_IT(&huart1,RxData,20)知识拓展:IDLE中断处理解读产生IDLE中断制作者或logo项目7:选程报警66①②⑴②⑵↓HAL_UARTEx_ReceiveToIdle_IT(&huart1,RxData,20)知识拓展:IDLE中断处理解读产生RXNE中断且指定长度的数据已全部接收制作者或logo项目7:选程报警67后面的代码略去⑤②③⑴③⑵式位HAL_UARTEx_ReceiveToIdle_IT(&huart1,RxData,4)知识拓展:UARTHAL宏制作者或logo项目7:选程报警68__HAL_UART_GET_FLAG(huart,UART_FLAG_IDLE);__HAL_UART_DISABLE_IT(huart,UART_IT_RXNE);__HAL_UART_CLEAR_IDLEFLAG(huart);__HAL_UART_ENABLE(huart);__HAL_UART_DISABLE(huart);UART_HandleTypeDef*huart图片均摘自HAL库驱动文档STM32F1_HAL_LL_Drivers.pdf用法:无法使用__HAL_UART_CLEAR_FLAG清除的中断标志位有专门的宏定义来实现,例如:↓↑摘自HAL驱动文档38.2.2节模块小结了解STM32F103大容量和小容量MCU的通信接口;了解STM32F103MCU的USART组成、挂载总线和功能;掌握STM32F103MCU有关USART的复用引脚和GPIO模式;读懂实训设备和(或)Proteus仿真电路的USART接口电路;掌握STM32CubeMX有关UART的配置方法;能按要求在STM32CubeMX进行UART配置;掌握STM32UART轮询方式发送的HAL函数用法,能编程实现串口数据的轮询模式发送;掌握STM32UART中断接收的HAL函数用法及回调函数的选择和用法,能编程实现RXNE和IDLE两种中断方式串口数据接收;熟悉范例中一些嵌入式开发中常用函数用法和编程方法,提升自身编程能力;制作者或logo.模块小结69谢谢!单片机与嵌入式系统原理与应用制作者或logo目录70模块模块6定时器控制6定时器控制主要内容和学习重点项目8:整点报时音知识准备认识STM32的定时器定时器时钟TIMx_CLK时基单元和计数模式——重点定时时长计算——重点STM32TIM基础定时功能的HAL函数项目实施:整点报时音习题项目探究TIM结构体TIM初始化TIM启停函数用法TIM中断处理知识拓展TIM的APB挂载HALTIM宏及寄存器实现项目9:简易八音盒知识准备影子寄存器在程序中更改TIMx_PSC和TIMx_ARR—重点项目实施:简易八音盒习题知识拓展TIM的TRGO和TIM主从模式STM32定时器通道模式STM32定时器时钟源项目10:呼吸灯知识准备PWM-脉冲宽度调制使用STM32定时器PWM模式实现LED呼吸灯STM32定时器PWM模式的HALAPI项目实施:呼吸灯习题项目探究STM32TIM通道模式复用引脚定时器PWM初始化STM32TIMPWM模式参数设置HAL_TIM_PWM_Start()函数用法知识拓展HAL_TIM_PWM_Start()解读KEILMDK内部仿真器用法模块小结制作者或logo目录71项目8知识准备:认识STM32的定时器制作者或logo项目8:整点报时音72F103闪存大容量产品4个通用定时器2个高级控制定时器2个基本定时器定时器类型定时器编号计数器位数计数器模式捕获/比较通道数挂载总线/接口时钟定时器时钟最大支持高级定时器TIM1、TIM816位向上、向下、向上/向下4APB2/72MHz72MHz通用定时器TIM2、TIM3、TIM4、TIM516位向上、向下、向上/向下4APB1/36MHz72MHz基本定时器TIM6、TIM716位向上无APB1/36MHz72MHz摘自数据手册Table2→F1小容量MCU↓无FSMC功能没有基本定时器知识准备:通用定时器和基本定时器制作者或logo项目8:整点报时音73↑摘自F1xx中文参考手册↗→通用定时器基本定时器摘自STM32CUBEMX摘自STM32CUBEMX通用定时器基本定时器本项目关注使用内部时钟的定时器基础定时功能知识准备:定时器时钟TIMx_CLK当APB1和APB2选择1分频或2分频时TIMx_CLK和SYSCLK的频率一致↑TIMx_CLK的频率永远小于等于SYSCLK的频率制作者或logo项目8:整点报时音74使用1+X考证设备时建议使用主时钟频率72MHz使用Proteus仿真时建议使用主时钟频率8MHz摘自STM32CUBEMXClockConfiguration摘自STM32CUBEMXClockConfiguration知识准备:定时器TIMx_CLK当APB1和APB2选择1分频或2分频时TIMx_CLK和SYSCLK的频率一致当APB1和APB2选择4分频及以上时,TIMx_CLK和SYSCLK的频率不同制作者或logo项目8:整点报时音75截自中文参考手册图11时钟树→摘自STM32CUBEMXClockConfiguration摘自STM32CUBEMXClockConfiguration知识准备:时基单元Time-baseUnit以基本定时器框图为例来学习定时器的基础定时功能制作者或logo项目8:整点报时音76摘自中文参考手册↔通用定时器基本定时器摘自英文参考手册←基本定时器只能向上计数高级和通用定时器可以向上、向下、向上/向下计数知识准备:定时器计数模式向上模式UP发生溢出时的计数次数:自动加载值+1向下模式DOWN发生溢出时的计数次数:自动加载值+1制作者或logo项目8:整点报时音77摘自中文参考手册14.3.2摘自中文参考手册14.3.2摘自中文参考手册14.3.2向上/向下模式摘自英文参考手册知识准备:STM32定时时长的计算时基单元重要寄存器TIMx_CNT-计数器TIMx_PSC-预分频TIMx_ARR-自动加载向上和向下计数模式发生溢出时的计数次数:自动加载值+1=>TIMx_ARR+1分频系数1~65536分频系数=TIMx_PSC+1定时时长=(TIMx_CLK时钟周期*分频系数)*计数次数=分频系数*计数次数*(1/定时器时钟频率)=(TIMx_PSC+1)*(TIMx_ARR+1)/72MHz2s=7200*20000/72000000Hz

TIMx_PSC=7200-1TIMx_ARR=20000-1制作者或logo项目8:整点报时音78↖↑摘自中文参考手册↓↓摘自STM32CUBEMX↙计数周期TIMx_PSC=800-1TIMx_ARR=20000-1可以吗?

通用定时器基本定时器思考:如果TIMx_CLK为8MHz,定时2s时,如何设置PSC和ARR?

本项目关注使用内部时钟的定时器基础定时功能图144TIMx_CLK知识准备:TIM基础定时功能的HAL函数←TIM基础定时功能的HAL函数TIM回调函数↓制作者或logo项目8:整点报时音79↔摘自HAL驱动文档STM32F1_HAL_LL_Drivers.pdf项目实施:基于M3主控模块

项目8:整点报时音根据“广播报时信号”国家标准,使用MCU的TIM2和TIM3实现:每次按下KEY1键播放1次整点报时音使用TIM2实现800Hz的低音使用TIM3实现1600Hz的高音间隔时间使用HAL_Delay()来控制同时,使MCU每隔2s通过串口USART1发送你的完整学号和中文姓名播报时可不发制作者或logo项目8:整点报时音80项目实施:

STM32CUBEMX的设置MCU选型、RCC和SYS,时钟ClockConfiguration和项目ProjectManager蜂鸣器的配置KEY1的配置UART1的配置TIM2和TIM3的配置:如左图请务必开启2个定时器的中断↓制作者或logo项目8:整点报时音81↙按照任务1-1的设置←按照任务3-1的设置按照任务4-1的设置→↑按照任务5-1的设置项目实施:代码编写制作者或logo项目8:整点报时音82↖TIM回调函数的参考代码:本任务中将TIM2设置为每隔0.625ms发生一次中断,每次TIM2发生中断时,令蜂鸣器连接的GPIO引脚翻转一次,正好可使蜂鸣器发出低音800Hz的嘀声;本任务中将TIM3设置为每隔0.3125ms发生一次中断,每次TIM3发生中断时,令蜂鸣器连接的GPIO引脚翻转一次,正好可使蜂鸣器发出高音1600Hz的嘀声;整点报时音参考代码→轮询方式检测到按键被按下时的参数代码↓UART串口发送的代码请自行添加提示:两个if可以合并成1个思考:外部中断检测按键时的代码项目实施:请将代码添加到正确的位置并完成结果验证/*Privatevariables-----------------------------------*//*USERCODEBEGINPV*//*USERCODEENDPV*/…略…intmain(void){HAL_Init();SystemClock_Config();/*Initializeallconfiguredperipherals*/MX_GPIO_Init(); MX_TIM2_Init(); MX_TIM3_Init();MX_USART1_UART_Init();

/*USERCODEBEGIN2*/

/*USERCODEEND2*/

/*Infiniteloop*/

/*USERCODEBEGINWHILE*/while(1){

/*USERCODEENDWHILE*/

/*USERCODEBEGIN3*/}

/*USERCODEEND3*/}/*注main()到此结束*/…略…/*USERCODEBEGIN4*//*USERCODEEND4*/制作者或logo项目8:整点报时音83请注意:TIM初始化之后才能调用以下TIM的HAL函数:HAL_TIM_Base_Start_IT()HAL_TIM_Base_Stop_IT()HAL_TIM_Base_Start()HAL_TIM_Base_Stop()①②项目实施:基于proteus仿真

项目8:整点报时音根据“广播报时信号”国家标准,使用MCU的TIM2和TIM3实现:每次按下KEY11键播放1次整点报时音使用TIM2实现800Hz的低音使用TIM3实现1600Hz的高音间隔时间使用HAL_Delay()来控制同时,使MCU每隔2s通过串口USART1发送你的完整学号和中文姓名播报时可不发制作者或logo项目8:整点报时音84项目实施:

STM32CUBEMX的设置MCU选型、RCC和SYS,时钟ClockConfiguration和项目ProjectManager蜂鸣器的配置KEY11的配置UART1的配置TIM2和TIM3的配置:如左图请务必开启2个定时器的中断↓制作者或logo项目8:整点报时音85↙按照任务1-4的设置←按照任务3-5的设置按照任务4-5的设置→↑按照任务5-4的设置项目实施:代码编写制作者或logo项目8:整点报时音86↖TIM回调函数的参考代码:本任务中将TIM2设置为每隔0.625ms发生一次中断,每次TIM2发生中断时,令蜂鸣器连接的GPIO引脚翻转一次,正好可使蜂鸣器发出低音800Hz的嘀声;本任务中将TIM3设置为每隔0.3125ms发生一次中断,每次TIM3发生中断时,令蜂鸣器连接的GPIO引脚翻转一次,正好可使蜂鸣器发出高音1600Hz的嘀声;整点报时音参考代码→轮询方式检测到按键被按下时的参数代码↓思考:外部中断检测按键时的代码提示:两个if可以合并成1个项目实施:请将代码添加到正确的位置并完成结果验证/*Privatevariables------------------------*//*USERCODEBEGINPV*//*USERCODEENDPV*/…略…intmain(void){HAL_Init();SystemClock_Config();/*Initializeallconfiguredperipherals*/MX_GPIO_Init(); MX_TIM2_Init(); MX_TIM3_Init();MX_USART1_UART_Init();

/*USERCODEBEGIN2*/

/*USERCODEEND2*/

/*Infiniteloop*/

/*USERCODEBEGINWHILE*/while(1){

/*USERCODEENDWHILE*/

/*USERCODEBEGIN3*/}

/*USERCODEEND3*/}/*注:main()到此结束*/…略…/*USERCODEBEGIN4*//*USERCODEEND4*/制作者或logo项目8:整点报时音87←如果Proteus中的SOUNDER无法正常发音,可双击该器件进行如左图的设置。但经过以下设置后,声音会延迟出现!↓请注意:TIM初始化之后才能调用以下TIM的HAL函数:HAL_TIM_Base_Start_IT()HAL_TIM_Base_Stop_IT()HAL_TIM_Base_Start()HAL_TIM_Base_Stop()①②习题习题操作题使用定时器控制LED9以1Hz的频率闪烁(亮灭保持相同时间)提示:参考项目3和项目4计算LED9亮和灭保持的时长

注意:当亮灭保持相同时间,每隔半周期切换一次LED状态制作者或logo项目8:整点报时音88项目探究:与基础定时功能相关的TIM结构体TIM_HandleTypeDef①结构体的第1个成员类型为TIM_TypeDef②结构体;第2个成员类型为TIM_Base_InitTypeDef③结构体;制作者或logo项目8:整点报时音89摘自HAL驱动文档STM32F1_HAL_LL_Drivers.pdf①③①KEILMDK项目窗口②②摘自HAL驱动文档STM32F1_HAL_LL_Drivers.pdf①注意:除了这三个结构体,stm32的HAL库还有其他与TIM相关的结构体,但本项目未涉及那些功能。②项目探究:TIM初始化TIM结构体:TIM_HandleTypeDefTIM_TypeDefTIM_Base_InitTypeDefMSP:与具体MCU型号相关制作者或logo项目8:整点报时音90②③①④摘自STM32HAL库

驱动文档TIM2挂载在APB1还是APB2?HAL_TIM_Base_MspInit()在HAL_TIM_Base_Init()中被调用项目探究:定时器中断启停函数参数:指向TIMHandle结构体的指针HAL_TIM_Base_Start_IT()在开启定时器中断的同时也开启了定时器返回值→制作者或logo项目8:整点报时音91HAL_TIM_Base_Start_IT(&htim2);①HAL_TIM_Base_Start(&htim2);③

HAL_TIM_Base_Stop_IT(&htim3);②

HAL_TIM_Base_Stop(&htim3);④①②④项目探究:TIM中断的处理函数注意:若STM32CUBEMX没有设置启动定时器中断,将找不到TIMx_IRQHandler函数的定义从①->②⑤用户重定义中断回调函数↓制作者或logo项目8:整点报时音92使用右键菜单的GotoDefinitionOfxxx…略……略……略…①③↖默认的回调函数定义,使用__weak关键字②④HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef*htim)if(htim->Instance==TIM2){}⑥↑知识拓展:TIM挂载总线制作者或logo项目8:整点报时音93←摘自F1xx中文参数手册图1系统结构图知识拓展:STM32HAL库TIM的宏带参数的宏用法1个参数:__HAL_TIM_ENABLE(htim)TIM_HandleTypeDef结构体的Instance成员是TIM_TypeDef结构体,TIM_TypeDef的成员为TIM各相关寄存器。制作者或logo项目8:整点报时音94__HAL_TIM_ENABLE(__HANDLE__)摘自中文参考手册14.4.1通过左边初始化中的代码已获取TIM2的寄存器内存映射地址摘自STM32F1系列HAL驱动文档→GPIOA知识拓展:STM32HAL库TIM的宏带参数的宏用法(续)2个参数:__HAL_TIM_ENABLE_IT(htim,TIM_IT_UPDATE)制作者或logo项目8:整点报时音95摘自→STM32F1系列HAL驱动文档__HAL_TIM_ENABLE_IT(__HANDLE__,__INTERRUPT__)摘自中文参考手册③知识拓展:STM32HAL库TIM的宏带参数的宏用法(续)--读取和清除中断标志位2个参数:__HAL_TIM_GET_FLAG(htim,TIM_FLAG_UPDATE)制作者或logo项目8:整点报时音96__HAL_TIM_GET_FLAG(__HANDLE__,__FLAG__)__HAL_TIM_CLEAR_FLAG(__HANDLE__,__FLAG__)摘自STM32F1系列HAL驱动文档图中带有阴影的寄存器是预装载寄存器,这类寄存器在物理上还包括另一寄存器:影子寄存器。设置值写入后,其值只是保存在预装载寄存器中,仅当设置值被写入影子寄存器,才真正生效。具有缓冲:预装载寄存器的值变化之后要等到下一次更新中断发生,其值才写入影子寄存器——新值暂缓生效。没有缓冲:写入预装载寄存器的值马上被写入影子寄存器——新值即刻生效项目9知识准备:影子寄存器制作者或logo项目9:简易八音盒97↖来自参考手册知识准备:自动重装载寄存器ARR的修改和影子寄存器Disable

:变化后的TIMx_ARR马上生效Enable:变化后的TIMx_ARR将在下次更新事件时生效制作者或logo项目9:简易八音盒98↑摘自STM32CUBEMX↑摘自中文参考手册14.3.1摘自中文参考手册基本定时器高级定时器和通用定时器的TIMx_CR1寄存器的ARPE位和UDIS位具有同样功能

用户可控制TIMx_ARR是否具有缓冲知识准备:自动重装载寄存器的修改和影子寄存器制作者或logo项目9:简易八音盒99用法说明:__HAL_TIM_SET_AUTORELOAD(&htim3,999);TIM3->ARR=999;htim3.Instance->ARR=999;if(__HAL_TIM_GET_AUTORELOAD(&htim3)==999){}摘自F1xxHAL驱动文档↘知识准备:预分频器PSC的修改和影子寄存器制作者或logo项目9:简易八音盒100__HAL_TIM_SET_PRESCALER(&htim2,999);TIMx_PSC控制寄存器具有缓冲,可以在运行过程中改变它的数值,新的预分频数值在下一个更新事件时起作用(写入影子寄存器)↙摘自中文参考手册14.3.1TIM2->PSC=999;htim2.Instance->PSC=999;摘自F1xxHAL驱动文档项目实施:基于M3主控模块

项目9:简易八音盒上电后播出一段乐曲;乐曲播放结束后等待3秒后再重复下次播放。F调低音Sol的半周期956us;——STM32CUBEMX中配置TIM定时时长__HAL_TIM_SET_AUTORELOAD(&htim6,955);//↖程序中修改TIM定时时长F调低音La的半周期____;F调低音Si的半周期____;F调中音Do的半周期____;F调中音Re的半周期____;F调中音Mi的半周期____;F调中音Fa的半周期____;制作者或logo项目9:简易八音盒10112345671←C大调

高音C大

调→注:下图摘自百度图片C大调的半音——黑键任务实施:任务分析此曲为4/4拍:使用TIM3来控制节拍,取每分钟100拍的中速,则每拍的时长0.6sTIM3设置为1/4拍的时长,即150ms使用TIM2控制蜂鸣器发声频率,STM32CUBEMX的初始设置为每隔1275us蜂鸣器引脚翻转(低音So的频率)编写代码实现TIM3经过2次中断后将TIM2自动装载器的值设为1136-1——低音La的频率TIM3再过2次中断后将TIM2自动装载器的值更改为按中音Me频率计算出来的值TIM3再过6次中断后将TIM2自动装载器的值更改为按中音So频率计算出来的值TIM3再过2次中断后将TIM2自动装载器的值更改为按中音Do频率计算出来的值…停止播放可以通过关闭TIM2中断和(或)TIM2计数器来实现制作者或logo项目9:简易八音盒102以四分音符为一拍,每小节有四拍任务实施:

STM32CUBEMX的设置MCU选型、RCC和SYS,时钟ClockConfiguration和项目ProjectManager蜂鸣器的配置UART1的配置TIM2和TIM3的配置:如左图请务必开启2个定时器的中断↓制作者或logo项目9:简易八音盒103↖按照任务1-1的设置↑按照任务3-1的设置↑按照任务5-1的设置将定时时长设置为150ms任务实施:代码编写在主循环之前调用HAL_TIM_Base_Start_IT()函数开启TIM

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论