-
“程序”为什么能控制微处理器?
-
摩尔定律能带来什么?
-
现在的NB-IOT跟今年推的CAT1哪种的应用前景会更好?
-
IoE与IoT有什么区别?
-
一、系统定时器1. 简介SysTick 叫做系统滴答时钟、系统定时器,属于 Cortex-M4 内核中的一个外设(外围设备),并且是24bit 向下递减 的计数器。RCC 向 Cortex 系统定时器 (SysTick) 馈送 8 分频的 AHB 时钟 (HCLK)。SysTick 可使用此时钟作为时钟源,也可使用 HCLK 作为时钟源,具体可在 SysTick 控制和状态寄存器中配置。注意:定时器的位数越多,定时时间更长。通过计数值间接计算定时时间,不能像操作系统直接调用函数实现延时或定时功能。计数值,就是要进行多少个计数。2.频率的概念物质在1s内完成周期性变化的次数叫做频率,常用f表示。为了纪念德国物理学家赫兹的贡献,人们把频率的单位命名为赫兹,简称“赫”,符号为HZ。二、库函数系统定时器配置/** \brief System Tick Configuration The function initializes the System Timer and its interrupt, and starts the System Tick Timer. Counter is in free running mode to generate periodic interrupts. \param [in] ticks Number of ticks between two interrupts. \return 0 Function succeeded. \return 1 Function failed. \note When the variable <b>__Vendor_SysTickConfig</b> is set to 1, then the function <b>SysTick_Config</b> is not included. In this case, the file <b><i>device</i>.h</b> must contain a vendor-specific implementation of this function. */__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)示例: //系统定时器触发1KHz的中断,中断周期时间T= 1/f = 1000ms/1000=1ms //系统定时器连接到PLL输出的168MHz时钟 //只要系统定时器进行168000000次计数,就是1秒时间的到达 //只要系统定时器进行168000次计数,就是1ms时间的到达 //只要系统定时器进行168次计数,就是1us时间的到达 SysTick_Config(SystemCoreClock/1000);三、最大定时时间1.确定最大的计数值2^24 -1,若计算到0,则进行2^24次计数。1000ms Tmax-------- = --------168000000 2^24Tmax = 2^24 *1000ms/168000000 = 99.86ms。2.测试结果初始化系统定时器,1S 内核触发 1000 次中断,定时 1ms,能够成功SysTick_Config(SystemCoreClock/1000);初始化系统定时器,1S 内核触发 10 次中断,定时 100ms,现象失败SysTick_Config(SystemCoreClock/10);初始化系统定时器,1S 内核触发 11 次中断,定时 90.90ms,能够成功SysTick_Config(SystemCoreClock/11);总结:填写中断频率值不能小于11,否则定时时间不准确。四、延时函数1.系统定时器的用途没有操作系统:只用于延时有操作系统(LiteOS):为操作系统提供精准的定时中断(1ms~50ms)2.官方示例In many cases you might not want to use the SysTick_Config function because you might want to use the reference clock or you might not want to enable the SysTick interrupt. In these cases you need to program the SysTick registers directly,and the following sequence is recommended:1). Disable the SysTick timer by writing 0 to SysTick->CTRL. This step is optional.It is recommended for reusable code because the SysTick could have been enabled previously.2). Write the new reload value to SysTick->LOAD.3). Write to the SysTick Current Value register SysTick->VAL with any value to clear the current value to 0.4). Write to the SysTick Control and Status register SysTick->CTRL to start the SysTick timer.If you want to use the SysTick timer in polling mode, you can use the count flag in the SysTick Control and Status Register (SysTick->CTRL) to determine when the timer reaches zero. For example, you can create a timed delay by setting the SysTick timer to a certain value and waiting until it reaches zero:SysTick->CTRL = 0; // Disable SysTickSysTick->LOAD = 0xFF; // Count from 255 to 0 (256 cycles)SysTick->VAL = 0; // Clear current value as well as count flagSysTick->CTRL = 5; // Enable SysTick timer with processor clockwhile ((SysTick->CTRL & 0x00010000)==0);// Wait until count flag is setSysTick->CTRL = 0; // Disable SysTick3.寄存器4.毫秒级延时函数void delay_ms(uint32_t ms){ while(ms --) { SysTick->CTRL = 0; // 关闭系统定时器后才能配置寄存器 SysTick->LOAD = 21000; // 设置计数值,用于设置定时的时间 SysTick->VAL = 0; // 清空当前值还有计数标志位 SysTick->CTRL = 1; // 使能系统定时器工作,且时钟源为系统时钟的8分频(168MHz/8=21MHz) while ((SysTick->CTRL & (1<<16))==0); // 等待系统定时器计数完毕 SysTick->CTRL = 0; // 关闭系统定时器 }}参考资料:《STM32F4x-中文参考手册》《野火F103-视频学习-【入门篇】》《【野火®】零死角玩转STM32—F103指南者》
-
一、中断中断,意味着中途打断现在干的事情,要立即处理紧急的事件。现实的例子:玩游戏的时,突然来电话。引脚编号决定了对应哪个外部中断。二、代码思路1.8051单片机外部中断的触发方式:低电平触发、下降沿触发 IT0=1允许外部中断引脚申请中断请求 EX0=1优先级的配置中断服务函数2.STM32端口硬件时钟使能SYSCFG硬件时钟使能配置引脚的工作模式将引脚连接到外部中断中断触发方式:电平触发、边沿触发允许外部中断引脚申请中断请求优先级的配置中断服务函数注:中断服务函数是不能被调用,编写格式不能随意编写,这是它特有的存在形式。不同的硬件平台,其编写方法是不一样的。三、函数接口1.为引脚选择使用哪个中断/** * @brief Selects the GPIO pin used as EXTI Line. * @param EXTI_PortSourceGPIOx : selects the GPIO port to be used as source for * EXTI lines where x can be (A..K) for STM32F42xxx/43xxx devices, (A..I) * for STM32F405xx/407xx and STM32F415xx/417xx devices or (A, B, C, D and H) * for STM32401xx devices. * * @param EXTI_PinSourcex: specifies the EXTI line to be configured. * This parameter can be EXTI_PinSourcex where x can be (0..15, except * for EXTI_PortSourceGPIOI x can be (0..11) for STM32F405xx/407xx * and STM32F405xx/407xx devices and for EXTI_PortSourceGPIOK x can * be (0..7) for STM32F42xxx/43xxx devices. * * @retval None */void SYSCFG_EXTILineConfig(uint8_t EXTI_PortSourceGPIOx, uint8_t EXTI_PinSourcex)2.配置外部中断/** * @brief Initializes the EXTI peripheral according to the specified * parameters in the EXTI_InitStruct. * @param EXTI_InitStruct: pointer to a EXTI_InitTypeDef structure * that contains the configuration information for the EXTI peripheral. * @retval None */void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct)3.中断优先级配置/** * @brief Initializes the NVIC peripheral according to the specified * parameters in the NVIC_InitStruct. * @note To configure interrupts priority correctly, the NVIC_PriorityGroupConfig() * function should be called before. * @param NVIC_InitStruct: pointer to a NVIC_InitTypeDef structure that contains * the configuration information for the specified NVIC peripheral. * @retval None */void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct)4.获取外部中断状态/** * @brief Checks whether the specified EXTI line is asserted or not. * @param EXTI_Line: specifies the EXTI line to check. * This parameter can be EXTI_Linex where x can be(0..22) * @retval The new state of EXTI_Line (SET or RESET). */ITStatus EXTI_GetITStatus(uint32_t EXTI_Line)5.清空外部中断标志位/** * @brief Clears the EXTI's line pending bits. * @param EXTI_Line: specifies the EXTI lines to clear. * This parameter can be any combination of EXTI_Linex where x can be (0..22) * @retval None */void EXTI_ClearITPendingBit(uint32_t EXTI_Line)四、中断优先级中断优先级的一个意义:出现多个中断同时触发,但是不能同时处理,所以先后顺序之分,要根据实际上的运行环境优先处理重要的中断。1.概述STM32 对中断优先级进行分组,共 5 组,组 0~4,这些分组是用于指定当前M4支持多少个抢占优先级和多少个响应优先级。同时,对每个中断设置一个抢占优先级和一个响应优先级。函数原型如下:/** * @brief Configures the priority grouping: pre-emption priority and subpriority. * @param NVIC_PriorityGroup: specifies the priority grouping bits length. * This parameter can be one of the following values: * @arg NVIC_PriorityGroup_0: 0 bits for pre-emption priority //不支持抢占优先级 * 4 bits for subpriority //支持16个响应优先级 * @arg NVIC_PriorityGroup_1: 1 bits for pre-emption priority //支持2个抢占优先级 * 3 bits for subpriority //支持8个响应优先级 * @arg NVIC_PriorityGroup_2: 2 bits for pre-emption priority //支持4个抢占优先级 * 2 bits for subpriority //支持4个响应优先级 * @arg NVIC_PriorityGroup_3: 3 bits for pre-emption priority //支持8个抢占优先级 * 1 bits for subpriority //支持2个响应优先级 * @arg NVIC_PriorityGroup_4: 4 bits for pre-emption priority //支持16个抢占优先级 * 0 bits for subpriority //不支持响应优先级 * @note When the NVIC_PriorityGroup_0 is selected, IRQ pre-emption is no more possible. * The pending IRQ priority will be managed only by the subpriority. * @retval None */void NVIC_PriorityGroupConfig(uint32_t, NVIC_PriorityGroup)只要开机初始化一次就可以了。2.抢占优先级与响应优先级区别1)高抢占优先级是可以打断正在进行的低抢占优先级的中断。抢占优先级若相同,则不会出现抢占的过程。2)抢占优先级相同的中断,高响应优先级不可以打断低响应优先级的中断。3)抢占优先级相同的中断,当两个中断同时发生的情况下,哪个响应优先级高,哪个先执行。4)抢占优先级相同且响应优先级相同的中断,假如同时发生,会按照硬件内部固定的优先级执行。5)无论是抢占优先级还是响应优先级,优先级数值越小,就代表优先级越高。参考资料:《STM32F4x-中文参考手册》《野火F103-视频学习-【入门篇】》《【野火®】零死角玩转STM32—F103指南者》
-
一、时钟体系给单片机提供一个时钟信号(一个非常稳定的频率信号),使单片机各内部组件同步工作,并且在和外部设备通信时是也能达到同步。动态调整运行频率,就可以控制性能与功耗!时钟源a.可以使用三种不同的时钟源来驱动系统时钟 (SYSCLK),CPU 运行的频率为 168MHz:● HSI 振荡器时钟,也就是高速内部时钟,一般来说很少用,因为精度没有外部高速时钟那么高。● HSE 振荡器时钟,也就是高速外部时钟。● 主 PLL (PLL) 时钟b.器件具有以下两个次级时钟源:● 32 kHz 低速内部 RC (LSI RC),该 RC 用于驱动独立看门狗,也可选择提供给 RTC 用于停机/待机模式下的自动唤醒。● 32.768 kHz 低速外部晶振(LSE 晶振),用于驱动 RTC 时钟 (RTCCLK)对于每个时钟源来说,在未使用时都可单独打开或者关闭,以降低功耗。二、PLL倍频公式不同的芯片,倍频(频率翻倍)公式是不一样的,需要查询芯片手册!三、SystemInit系统初始化函数1.其实第一个执行的文件是汇编文件栈的初始化,提供函数调用的时候进行现场保护和现场恢复堆的初始化,为申请内存提供空间,调用malloc执行Reset_Handler,意思说上电复位后执行的动作执行SystemInit函数跳转到main函数2.初始化Flash接口,更新PLL系统频率/** * @brief Setup the microcontroller system * Initialize the Embedded Flash Interface, the PLL and update the * SystemFrequency variable. * @param None * @retval None */void SystemInit(void){ ................ /* Configure the System clock source, PLL Multiplier and Divider factors, AHB/APBx prescalers and Flash settings ----------------------------------*/ SetSysClock(); ................ }3.调用SetSysClock函数设置PLL时钟,然后进行分频/** * @brief Configures the System clock source, PLL Multiplier and Divider factors, * AHB/APBx prescalers and Flash settings * @Note This function should be called only once the RCC clock configuration * is reset to the default reset state (done in SystemInit() function). * @param None * @retval None */static void SetSysClock(void){ ..................... /* Configure the main PLL */ RCC->PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) | (RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q << 24);.....................}system_stm32f4xx.c文件有以下倍频(PLL_N)与分频(PLL_M、PLL_P)因子:/* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */#define PLL_M 25 //(记得修改为8)/* USB OTG FS, SDIO and RNG Clock = PLL_VCO / PLLQ */#define PLL_Q 7 #if defined (STM32F40_41xxx)#define PLL_N 336/* SYSCLK = PLL_VCO / PLL_P */#define PLL_P 2#endif /* STM32F40_41xxx */四、时钟源在特殊的应用场景,为了达到最高的能效比,没有必要使用到PLL,可将HSE、HSI作为系统时钟源。例如,在智能手表锁屏的情况下,如果使用PLL配置过后输出的频率会造成过多的功耗,降低自身的续航能力;同时要维持计步与测量心率功能。因此,PLL在锁屏下的应用场景并不合适,在保证功能实现的前提下,尽可能降低功耗,可以切换频率更低的时钟源提供给系统时钟。1.选择PLL作为系统时钟源RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));RCC->CFGR |= RCC_CFGR_SW_PLL; 2.选择HSI作为系统时钟源RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));RCC->CFGR |= RCC_CFGR_SW_HSI; 3.选择HSE作为系统时钟源RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));RCC->CFGR |= RCC_CFGR_SW_HSE;参考资料:《STM32F4x-中文参考手册》《野火F103-视频学习-【入门篇】》《【野火®】零死角玩转STM32—F103指南者》
-
一、位带操作1.意义回想51单片机P0 = 0x10; //将P0端口设置为0x10P1_0=1; //将P1端口0号引脚设置为高电平a = P2_2; //获取P2端口2号引脚的电平根据上面的方法,我们可以快速定位修改某个引脚的电平还有获取引脚的状态2.原因GPIO_SetBits、GPIO_ResetBits操作IO口的性能没有达到极致,因为这些函数都需要进行现场保护和现场恢复的动作,比较耗时间,没有进行一步到位,使用位带操作则没有上述的烦恼,简单快速!示例1:GPIO_SetBits(GPIOF,GPIO_Pin_9);修改为PFout(9)=1;示例2: GPIO_ResetBits(GPIOF,GPIO_Pin_9);修改为PFout(9)=0;因为使用对引脚设置电平或读取电平,库函数效率是不高的,很难应付高性能的场合,如下代码,修改某引脚电平要执行起码3行代码,还不包括隐含的调用函数与函数返回的过程。void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin){ /* Check the parameters */ assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); assert_param(IS_GPIO_PIN(GPIO_Pin)); GPIOx->BSRRL = GPIO_Pin;}二、寄存器地址与别名地址转换技巧1.确定某端口访问起始地址,如端口F访问起始地址为GPIOF_BASE#define GPIOF ((GPIO_TypeDef *) GPIOF_BASE)typedef struct{ __IO uint32_t MODER; /*!< GPIO port mode register, Address offset: 0x00 */ __IO uint32_t OTYPER; /*!< GPIO port output type register, Address offset: 0x04 */ __IO uint32_t OSPEEDR; /*!< GPIO port output speed register, Address offset: 0x08 */ __IO uint32_t PUPDR; /*!< GPIO port pull-up/pull-down register, Address offset: 0x0C */ __IO uint32_t IDR; /*!< GPIO port input data register, Address offset: 0x10 */ __IO uint32_t ODR; /*!< GPIO port output data register, Address offset: 0x14 */ __IO uint16_t BSRRL; /*!< GPIO port bit set/reset low register, Address offset: 0x18 */ __IO uint16_t BSRRH; /*!< GPIO port bit set/reset high register, Address offset: 0x1A */ __IO uint32_t LCKR; /*!< GPIO port configuration lock register, Address offset: 0x1C */ __IO uint32_t AFR[2]; /*!< GPIO alternate function registers, Address offset: 0x20-0x24 */} GPIO_TypeDef;2.根据要访问的寄存器地址计算偏移值,如计算GPIOF的ODR寄存器地址 = GPIOF_BASE+0x14;3.根据以下公式进行换算寄存器的位带别名 = 0x42000000 + (寄存器的地址-0x40000000)*32 + 引脚编号*4详细示意图参考如下:4.设置PF9引脚电平代码如下uint32_t *PF9_BitBand = (uint32_t *)(0x42000000 + (GPIOF_BASE + 0x14 - 0x40000000)*32 + 9*4);更优解的方法:uint32_t *PF9_BitBand = (uint32_t *)(0x42000000 + ((uint32_t)&GPIOF->ODR - 0x40000000)*32 + 9*4); 三、代码调整将端口的访问封装为Pxout、Pxin,例如端口F引脚电平设置PFout,端口A引脚电平读取PAin。#define PFout(x) *(volatile uint32_t *)(0x42000000 + (GPIOF_BASE + 0x14 - 0x40000000)*32 + x*4)#define PAin(x) *(volatile uint32_t *)(0x42000000 + (GPIOA_BASE + 0x10 - 0x40000000)*32 + x*4)四、编译优化优化:编译器想尽办法去压缩程序存储空间,提高运行速度。一般编译器,优化有多个等级:-O0、-O1、-O2、-O3。 -O0:缺省优化级别,不压缩程序存储空间,不提高程序运行速度,保证程序的可靠执行。-O1:轻度优化,轻度压缩程序存储空间,轻度优化程序运行速度。-O2:推荐优化等级,在程序存储空间和程序运行速度取得平衡点。-O3:最高级别的优化等级,有可能导致程序不能运行,也会使用以空间换时间的方法,导致程序体积增大。示例1:-O0示例1:-O2按键例子1,任何时刻按下按键,灯无法响应:#define PAin(n) *((uint32_t *)(0x42000000 + (((uint32_t)&GPIOA->IDR) - 0x40000000)*32 + (n)*4))PFout(9) = PAin(0);经过编译阶段,会得到恒定的结果。PFout(9)=1;按键例子2,任何时刻按下按键,灯能够立即响应点亮或熄灭:#define PAin(n) *((volatile uint32_t *)(0x42000000 + (((uint32_t)&GPIOA->IDR) - 0x40000000)*32 + (n)*4))PFout(9) = PAin(0);编译器不会去优化而省略*((volatile uint32_t *)(0x42000000 + (((uint32_t)&GPIOA->IDR) - 0x40000000)*32 + (n)*4));而是每次都是小心翼翼地取执行*((volatile uint32_t *)(0x42000000 + (((uint32_t)&GPIOA->IDR) - 0x40000000)*32 + (n)*4))。PFout(9) = PAin(0);参考资料:《STM32F4x-中文参考手册》《野火F103-视频学习-【入门篇】》
-
物联网平台构建智慧路灯实验,显示设备未激活,应该怎么激活设备呢?
-
-
回复此贴进行答疑: 在课程中所遇到的疑问,可以在此贴处提问,会有专家进行解答 回帖格式:学号+姓名+华为云昵称 问题内容示例: 学号:1903020000 姓名:许久 华为云昵称:许久 在第x天的学习中,......
-
课程已经结束啦,今日份小作业如下: 请大家在评论区对本次课程进行总结(不少于100字) 总结格式不限,文本类型不限,欢迎大家畅所欲言注:积分相同时,根据总结的质量和有效提问次数确定最终排名
-
欢迎同学们来参加我们的小课堂,请查收今日份作业: 1.请将第六章《物联应用,无限未来》的完成进度截图+课后作业截图回复至本帖(两张截图右上角都必须包含华为云账号名); 2.请谈谈今日的观看感言~(不限字数,不限风格,表达真我) 3.回复格式:姓名+感想+截图
推荐直播
-
HDC深度解读系列 - Serverless与MCP融合创新,构建AI应用全新智能中枢2025/08/20 周三 16:30-18:00
张昆鹏 HCDG北京核心组代表
HDC2025期间,华为云展示了Serverless与MCP融合创新的解决方案,本期访谈直播,由华为云开发者专家(HCDE)兼华为云开发者社区组织HCDG北京核心组代表张鹏先生主持,华为云PaaS服务产品部 Serverless总监Ewen为大家深度解读华为云Serverless与MCP如何融合构建AI应用全新智能中枢
回顾中 -
关于RISC-V生态发展的思考2025/09/02 周二 17:00-18:00
中国科学院计算技术研究所副所长包云岗教授
中科院包云岗老师将在本次直播中,探讨处理器生态的关键要素及其联系,分享过去几年推动RISC-V生态建设实践过程中的经验与教训。
回顾中 -
一键搞定华为云万级资源,3步轻松管理企业成本2025/09/09 周二 15:00-16:00
阿言 华为云交易产品经理
本直播重点介绍如何一键续费万级资源,3步轻松管理成本,帮助提升日常管理效率!
回顾中
热门标签