正规网站建设的公司香精香料网
news/
2025/10/8 3:37:39/
文章来源:
正规网站建设的公司,香精香料网,做网站的专业,网站规划设计说明书1. 独立看门狗IWDG介绍#xff08;341.45#xff09;
什么是看门狗#xff1f; 在由单片机构成的微型计算机系统中#xff0c;由于单片机的工作常常会受到来自外界电磁场的干扰#xff0c;造成程序的跑飞#xff0c;而陷入死循环#xff0c;程序的正常运行被打断#…1. 独立看门狗IWDG介绍341.45
什么是看门狗 在由单片机构成的微型计算机系统中由于单片机的工作常常会受到来自外界电磁场的干扰造成程序的跑飞而陷入死循环程序的正常运行被打断由单片机控制的系统无法继续工作会造成整个系统的陷入停滞状态发生不可预料的后果所以出于对单片机运行状态进行实时监测的考虑便产生了一种专门用于监测单片机程序运行状态的模块或者芯片俗称“看门狗”watchdog。独立看门狗工作在主程序之外能够完全独立工作它的时钟是专用的低速时钟LSI由 VDD 电压供电 在停止模式和待机模式下仍能工作。
独立看门狗本质
本质是一个 12 位的递减计数器当计数器的值从某个值一直减到 0 的时候系统就会产生一个复位信号即 IWDG_RESET 。如果在计数没减到 0 之前刷新了计数器的值的话那么就不会产生复位信号这个动作就是我们经常说的喂狗。
独立看门狗框图 独立看门狗时钟
独立看门狗的时钟由独立的 RC 振荡器 LSI 提供即使主时钟发生故障它仍然有效非常独立。启用 IWDG 后LSI 时钟会自动开启不能主动停止除非重置/重启。LSI 时钟频率并不精确F1 用 40kHz。LSI 经过一个 8 位的预分频器得到计数器时钟。 分频系数算法prer0–8 是IWDG_PR 的值
重装载寄存器
重装载寄存器是一个 32 位的寄存器用于存放重装载值低 12 位有效即最大值为 4096这个值的大小决定着独立看门狗的溢出时间。
键寄存器
键寄存器IWDG_KR可以说是独立看门狗的一个控制寄存器主要有三种控制方式往这个寄存器写入下面三个不同的值有不同的效果。
溢出时间计算公式RLR计数多少次 2. 独立看门狗实验342.46
需求 开启独立看门狗溢出时间为 1 秒使用按键1进行喂狗。硬件接线 KEY1 – PA0UART1 – PA9/PA10 溢出时间计算1000ms PSC64RLR625f40编程实现代码18.iwdg_test/MDK-ARM
#include string.h
int main()
{HAL_Init();SystemClock_Config();MX_GPIO_Init();MX_IWDG_Init();MX_USART1_UART_Init();HAL_UART_Transmit(huart1, 程序启动...\n, strlen(程序启动...\n), 100);while (1){if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) GPIO_PIN_RESET)//检测到key1被按下时低电平HAL_IWDG_Refresh(hiwdg);HAL_Delay(50);}
}STM32CubeMx工程配置
3. 窗口看门狗WWDG介绍343.47
什么是窗口看门狗
窗口看门狗用于监测单片机程序运行时效是否精准主要检测软件异常一般用于需要精准检测程序运行时 间的场合。窗口看门狗的本质是一个能产生系统复位信号和提前唤醒中断的6位计数器。产生复位条件 当递减计数器值从 0x40 减到 0x3F 时复位即T6位跳变到0计数器的值大于 W[6:0] 值时喂狗会复位。 产生中断条件 当递减计数器等于 0x40 时可产生提前唤醒中断 (EWI)。 在窗口期内重装载计数器的值防止复位也就是所谓的喂狗。
窗口看门狗工作原理 控制寄存器 配置寄存器 状态寄存器 超时时间计算 Tout 是 WWDG 超时时间没喂狗Fwwdg 是 WWDG 的时钟源频率最大36M4096 是 WWDG 固定的预分频系数2^WDGTB 是 WWDG_CFR 寄存器设置的预分频系数值T[5:0] 是 WWDG 计数器低 6 位最多 63
4. 窗口看门狗实验344.48
需求 开启窗口看门狗计数器值设置为 0X7F 窗口值设置为 0X5F 预分频系数为 8 。程序启动时点亮 LED1 300ms 后熄灭。在提前唤醒中断服务函数进行喂狗同时翻转 LED2 状态。 硬件接线 LED1 – PB8LED2 – PB9 超时时间计算ms 预分频系数8T[6:0]127W[6:0]95Fwwdg36MHz36000kHzWWDG配置 代码19.wwdg_test/MDK-ARM
void HAL_WWDG_EarlyWakeupCallback(WWDG_HandleTypeDef *hwwdg)
{HAL_WWDG_Refresh(hwwdg);//提前唤醒中断喂狗HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_9);//喂狗之后翻转led的状态
}
int main(void)
{HAL_Init();SystemClock_Config();MX_GPIO_Init();HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_RESET);HAL_Delay(300);//HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_SET);MX_WWDG_Init();while (1){HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_SET);HAL_Delay(40);}
}5. 独立看门狗和窗口看门狗异同点345.49 6. DMA介绍
什么是DMA
令人头秃的描述 DMA(Direct Memory Access直接存储器访问) 提供在外设与内存、存储器和存储器、外设与外设之间的高速数据传输使用。它允许不同速度的硬件装置来沟通而不需要依赖于 CPU在这个时间中CPU 对于内存的工作来说就无法使用。 简单描述就是一个数据搬运工
DMA的意义
代替 CPU 搬运数据为 CPU 减负。
数据搬运的工作比较耗时间数据搬运工作时效要求高有数据来就要搬走没啥技术含量CPU 节约出来的时间可以处理更重要的事。
搬运什么数据
存储器、外设 这里的外设指的是 spi、usart、iic、adc 等基于 APB1 、APB2 或 AHB 时钟的外设而这里的存储器包括自身的闪存flash或者内存SRAM以及外设的存储设备都可以作为访问地源或者目的。 三种搬运方式 存储器→存储器例如复制某特别大的数据 buf存储器→外设 例如将某数据 buf 写入串口 TDR 寄存器外设→存储器 例如将串口 RDR 寄存器写入某数据 buf
存储器→存储器 存储器→外设 外设→存储器 DMA 控制器
STM32F103 有 2 个 DMA 控制器DMA1 有 7 个通道DMA2 有 5 个通道。一个通道每次只能搬运一个外设的数据。如果同时有多个外设的 DMA 请求则按照优先级进行响应。DMA1 有 7 个通道 DMA2 有 5 个通道
DMA及通道的优先级
优先级管理采用软件硬件 软件 每个通道的优先级可以在 DMA_CCRx 寄存器中设置有 4 个等级 最高级 高级 中级 低级硬件 如果 2 个请求它们的软件优先级相同则较低编号的通道比较高编号的通道有较高的优先权。 比如如果软件优先级相同通道 2 优先于通道 4
DMA传输方式
DMA_Mode_Normal正常模式 一次 DMA 数据传输完后停止 DMA 传送 也就是只传输一次 DMA_Mode_Circular循环传输模式 当传输结束时硬件自动会将传输数据量寄存器进行重装进行下一轮的数据传输。 也就是多次传输 模式
指针递增模式
外设和存储器指针在每次传输后可以自动向后递增或保持常量。当设置为增量模式时下一个要传输的地址 将是前一个地址加上增量值。
7. DMA实验1内存到内存
实验要求和配置
使用 DMA 的方式将数组 A 的内容复制到数组 B 中搬运完之后将数组 B 的内容打印到屏幕。STM32CubeMx工程配置 重定向 printf 的话记得将下面这个勾打开
用到的库函数
HAL_DMA_Start
HAL_StatusTypeDef HAL_DMA_Start(DMA_HandleTypeDef *hdma, uint32_t SrcAddress,
uint32_t DstAddress, uint32_t DataLength)参数一DMA_HandleTypeDef *hdmaDMA通道句柄 参数二uint32_t SrcAddress源内存地址 参数三uint32_t DstAddress目标内存地址 参数四uint32_t DataLength传输数据长度。注意需要乘以sizeof(uint32_t) 返回值HAL_StatusTypeDefHAL状态OKbusyERRORTIMEOUT
__HAL_DMA_GET_FLAG
#define __HAL_DMA_GET_FLAG(__HANDLE__, __FLAG__) (DMA1-ISR (__FLAG__))参数一HANDLEDMA通道句柄 参数二FLAG数据传输标志。DMA_FLAG_TCx表示数据传输完成标志 返回值FLAG的值SET/RESET
代码实现
开启数据传输等待数据传输完成打印数组内容
代码20.dma_test1/MDK-ARM
#define BUF_SIZE 16
// 源数组
uint32_t srcBuf[BUF_SIZE] {0x00000000,0x11111111,0x22222222,0x33333333,0x44444444,0x55555555,0x66666666,0x77777777,0x88888888,0x99999999,0xAAAAAAAA,0xBBBBBBBB,0xCCCCCCCC,0xDDDDDDDD,0xEEEEEEEE,0xFFFFFFFF
};
// 目标数组
uint32_t desBuf[BUF_SIZE];
int fputc(int ch, FILE *f)
{ unsigned char temp[1]{ch};HAL_UART_Transmit(huart1,temp,1,0xffff); return ch;
}
int main(void)
{int i 0;HAL_Init();SystemClock_Config();MX_GPIO_Init();MX_DMA_Init();MX_USART1_UART_Init();// 开启数据传输HAL_DMA_Start(hdma_memtomem_dma1_channel1,(uint32_t)srcBuf, (uint32_t)desBuf, sizeof(uint32_t) * BUF_SIZE);// 等待数据传输完成while(__HAL_DMA_GET_FLAG(hdma_memtomem_dma1_channel1, DMA_FLAG_TC1) RESET);// 打印数组内容for (i 0; i BUF_SIZE; i)printf(Buf[%d] %x\r\n, i, desBuf[i]);//x大/小写即输出大/小写
}8. DMA实验2内存到外设
实验要求和配置
使用DMA的方式将内存数据搬运到串口1发送寄存器同时闪烁LED1。STM32CubeMx工程配置
用到的库函数
HAL_UART_Transmit_DMA
HAL_StatusTypeDef HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, uint8_t *pData,
uint16_t Size)参数一UART_HandleTypeDef *huart串口句柄 参数二uint8_t *pData待发送数据首地址 参数三uint16_t Size待发送数据长度 返回值HAL_StatusTypeDefHAL状态OKbusyERRORTIMEOUT
代码实现
准备数据将数据通过串口DMA发送
代码20.dma_test2/MDK-ARM
#define BUF_SIZE 1000
// 待发送的数据
unsigned char sendBuf[BUF_SIZE];
int main(void)
{int i 0;HAL_Init();SystemClock_Config();MX_GPIO_Init();MX_DMA_Init();MX_USART1_UART_Init();// 准备数据for (i 0; i BUF_SIZE; i)sendBuf[i] B;// 将数据通过串口DMA发送HAL_UART_Transmit_DMA(huart1, sendBuf, BUF_SIZE);while (1){HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_8);HAL_Delay(100);}
}9. DMA实验3外设到内存
实验要求和配置
使用 DMA 的方式将串口接收缓存寄存器的值搬运到内存中同时闪烁 LED1。STM32CubeMx工程配置
用到的库函数
__HAL_UART_ENABLE
#define __HAL_UART_ENABLE_IT(__HANDLE__, __INTERRUPT__) ((((__INTERRUPT__) 28U)UART_CR1_REG_INDEX)? ((__HANDLE__)-Instance-CR1 | ((__INTERRUPT__)
UART_IT_MASK)): \(((__INTERRUPT__) 28U)UART_CR2_REG_INDEX)? ((__HANDLE__)-Instance-CR2 | ((__INTERRUPT__)
UART_IT_MASK)): \((__HANDLE__)-Instance-
CR3 | ((__INTERRUPT__) UART_IT_MASK)))参数一HANDLE串口句柄 参数二INTERRUPT需要使能的中断 返回值无 2. HAL_UART_Receive_DMA
HAL_StatusTypeDef HAL_UART_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData,
uint16_t Size)参数一UART_HandleTypeDef *huart串口句柄 参数二uint8_t *pData接收缓存首地址 参数三uint16_t Size接收缓存长度 返回值HAL_StatusTypeDefHAL状态OKbusyERRORTIMEOUT 3. __HAL_UART_GET_FLAG
#define __HAL_UART_GET_FLAG(__HANDLE__, __FLAG__) (((__HANDLE__)-Instance-SR
(__FLAG__)) (__FLAG__))参数一HANDLE串口句柄 参数二FLAG需要查看的FLAG 返回值FLAG的值 4. __HAL_UART_CLEAR_IDLEFLAG
#define __HAL_UART_CLEAR_IDLEFLAG(__HANDLE__) __HAL_UART_CLEAR_PEFLAG(__HANDLE__)参数一HANDLE串口句柄 返回值无 5. HAL_UART_DMAStop
HAL_StatusTypeDef HAL_UART_DMAStop(UART_HandleTypeDef *huart)参数一UART_HandleTypeDef *huart串口句柄 返回值HAL_StatusTypeDefHAL状态OKbusyERRORTIMEOUT 6. __HAL_DMA_GET_COUNTER
#define __HAL_DMA_GET_COUNTER(__HANDLE__) ((__HANDLE__)-Instance-CNDTR)参数一HANDLE串口句柄 返回值未传输数据大小
代码实现
如何判断串口接收是否完成如何知道串口收到数据的长度使用串口空闲中断IDLE 串口空闲时触发空闲中断空闲中断标志位由硬件置1软件清零 利用串口空闲中断可以用如下流程实现DMA控制的任意长数据接收
使能 IDLE 空闲中断使能 DMA 接收中断收到串口接收中断DMA 不断传输数据到缓冲区一帧数据接收完毕串口暂时空闲触发串口空闲中断在中断服务函数中清除中断标志位关闭DMA传输防止干扰计算刚才收到了多少个字节的数据。处理缓冲区数据开启DMA传输开始下一帧接收。
有三个文件需要修改main.c
uint8_t rcvBuf[BUF_SIZE]; // 接收数据缓存数组
uint8_t rcvLen 0; // 接收一帧数据的长度
__HAL_UART_ENABLE_IT(huart1, UART_IT_IDLE); // 使能IDLE空闲中断
HAL_UART_Receive_DMA(huart1,rcvBuf,100); // 使能DMA接收中断
while (1)
{HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_8);HAL_Delay(300);
}main.h
#define BUF_SIZE 100stm32f1xx_it.c
extern uint8_t rcvBuf[BUF_SIZE];
extern uint8_t rcvLen;
void USART1_IRQHandler(void)
{/* USER CODE BEGIN USART1_IRQn 0 *//* USER CODE END USART1_IRQn 0 */HAL_UART_IRQHandler(huart1);/* USER CODE BEGIN USART1_IRQn 1 */if(__HAL_UART_GET_FLAG(huart1,UART_FLAG_IDLE) SET) // 判断IDLE标志位是否被置位{__HAL_UART_CLEAR_IDLEFLAG(huart1);// 清除标志位HAL_UART_DMAStop(huart1); // 停止DMA传输防止干扰uint8_t temp__HAL_DMA_GET_COUNTER(hdma_usart1_rx); rcvLen BUF_SIZE - temp; //计算数据长度HAL_UART_Transmit_DMA(huart1, rcvBuf, rcvLen);//发送数据HAL_UART_Receive_DMA(huart1, rcvBuf, BUF_SIZE);//开启DMA}/* USER CODE END USART1_IRQn 1 */
}
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/931084.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!