完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
一、SysTick简介
系统定时器-系统定时器是属于CM3内核中的一个外设,内嵌在NVIC。中系统定时器是一个24位的向下递减的计数器,计数器每计数一次的时间为1 / SYSCLK,一般我们设置系统时钟SYSCLK等于72M。当重装载数值寄存器的值递减到0的时候,系统定时器就产生一次中断,以此循环往复。 因为系统定时器是属于CM3内核的外设,所以所有基于CM3内核的单片机都具有这个系统唤醒,使用软件在CM3中可以很容易的移植。系统日常用于日常,用于时基,维持睡眠的呼吸。 二、新建工程 1. 打开STM32CubeMX软件,点击“新建工程” 2.选择MCU和封装 3。配置时钟 RCC设置,选择HZ外部高速 时钟)为/CeramicReCrystalReCrystal(晶振/陶瓷器)选择时钟配置,系统时钟 SYS为72MHz HCLK的值为72后,输入回,软件会自动修改修改 4.所有配置 配置调试 非常重要的一步,否则会造成第一次烧录视频程序无法识别调试器 ,选择调试为串口线 5.配置GPIO GPIO设置,在右边靠近LED灯对应模式,选择GPIO_Output模式,输出低触发,可以添加自定义标签 6. 生成代码 输入项目名和项目路径 选择应用的IDE 开发环境MDK-ARM V5 外设生成独立的‘.c/.h’ 文件 不勾:所有初始化代码都生成在main.c :初始化代码生成在对应的外设文件。如GPIO初始化代码生成在gpio.c中 点击GENERATE CODE生成代码 三、普通加上 3.1修改主函数,实现流水灯 在while()循环中加入输出置反函数HAL_GPIO_TogglePin。 () 和其他函数 HAL_Delay()。 /** * @brief The application entry point. * @retval int */ int main(void) { /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ /* MCU Configuration--------------------------------------------------------*/ /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ HAL_Init(); /* USER CODE BEGIN Init */ /* USER CODE END Init */ /* Configure the system clock */ SystemClock_Config(); /* USER CODE BEGIN SysInit */ /* USER CODE END SysInit */ /* Initialize all configured peripherals */ MX_GPIO_Init(); /* USER CODE BEGIN 2 */ /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { /* USER CODE END WHILE */ HAL_GPIO_TogglePin(LED_G_GPIO_Port,LED_G_Pin); HAL_Delay(500); HAL_GPIO_TogglePin(LED_G_GPIO_Port,LED_G_Pin); HAL_GPIO_TogglePin(LED_B_GPIO_Port,LED_B_Pin); HAL_Delay(500); HAL_GPIO_TogglePin(LED_B_GPIO_Port,LED_B_Pin); /* USER CODE BEGIN 3 */ } /* USER CODE END 3 */ } 3.2 HAL库与标准库代码比较 STM32CubeMX使用HAL库生成的代码: /** * @brief The application entry point. * @retval int */ int main(void) { /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ /* MCU Configuration--------------------------------------------------------*/ /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ HAL_Init(); /* USER CODE BEGIN Init */ /* USER CODE END Init */ /* Configure the system clock */ SystemClock_Config(); /* USER CODE BEGIN SysInit */ /* USER CODE END SysInit */ /* Initialize all configured peripherals */ MX_GPIO_Init(); /* USER CODE BEGIN 2 */ /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { /* USER CODE END WHILE */ HAL_GPIO_TogglePin(LED_G_GPIO_Port,LED_G_Pin); HAL_Delay(500); HAL_GPIO_TogglePin(LED_G_GPIO_Port,LED_G_Pin); HAL_GPIO_TogglePin(LED_B_GPIO_Port,LED_B_Pin); HAL_Delay(500); HAL_GPIO_TogglePin(LED_B_GPIO_Port,LED_B_Pin); /* USER CODE BEGIN 3 */ } /* USER CODE END 3 */ } HAL_StatusTypeDef HAL_Init(void) { /* Configure Flash prefetch */ #if (PREFETCH_ENABLE != 0) #if defined(STM32F101x6) || defined(STM32F101xB) || defined(STM32F101xE) || defined(STM32F101xG) || defined(STM32F102x6) || defined(STM32F102xB) || defined(STM32F103x6) || defined(STM32F103xB) || defined(STM32F103xE) || defined(STM32F103xG) || defined(STM32F105xC) || defined(STM32F107xC) /* Prefetch buffer is not available on value line devices */ __HAL_FLASH_PREFETCH_BUFFER_ENABLE(); #endif #endif /* PREFETCH_ENABLE */ /* Set Interrupt Group Priority */ HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4); /* Use systick as time base source and configure 1ms tick (default clock after Reset is HSI) */ HAL_InitTick(TICK_INT_PRIORITY); /* Init the low level hardware */ HAL_MspInit(); /* Return function status */ return HAL_OK; } __weak HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority) { /* Configure the SysTick to have interrupt in 1ms time basis*/ if (HAL_SYSTICK_Config(SystemCoreClock / (1000U / uwTickFreq)) 》 0U) { return HAL_ERROR; } /* Configure the SysTick IRQ priority */ if (TickPriority 《 (1UL 《《 __NVIC_PRIO_BITS)) { HAL_NVIC_SetPriority(SysTick_IRQn, TickPriority, 0U); uwTickPrio = TickPriority; } else { return HAL_ERROR; } /* Return function status */ return HAL_OK; } /** * @brief This function handles System tick timer. */ void SysTick_Handler(void) { /* USER CODE BEGIN SysTick_IRQn 0 */ /* USER CODE END SysTick_IRQn 0 */ HAL_IncTick(); /* USER CODE BEGIN SysTick_IRQn 1 */ /* USER CODE END SysTick_IRQn 1 */ } 使用STM32标准库的代码: /** * @brief 主函数 * @param 无 * @retval 无 */ int main(void) { /* LED 端口初始化 */ LED_GPIO_Config(); /* 配置SysTick 为10us中断一次 */ SysTick_Init(); for(;;) { LED1( ON ); SysTick_Delay_Ms( 1000 ); LED1( OFF ); LED2( ON ); SysTick_Delay_Ms( 1000 ); LED2( OFF ); } } /** * @brief 启动系统滴答定时器 SysTick * @param 无 * @retval 无 */ void SysTick_Init(void) { /* SystemFrequency / 1000 1ms中断一次 * SystemFrequency / 100000 10us中断一次 * SystemFrequency / 1000000 1us中断一次 */ // if (SysTick_Config(SystemFrequency / 100000)) // ST3.0.0库版本 if (SysTick_Config(SystemCoreClock / 100000)) // ST3.5.0库版本 { /* Capture error */ while (1); } } // couter 减1的时间 等于 1/systick_clk // 当counter 从 reload 的值减小到0的时候,为一个循环,如果开启了中断则执行中断服务程序, // 同时 CTRL 的 countflag 位会置1 // 这一个循环的时间为 reload * (1/systick_clk) void SysTick_Delay_Us( __IO uint32_t us) { uint32_t i; SysTick_Config(SystemCoreClock/1000000); for(i=0;i《us;i++) { // 当计数器的值减小到0的时候,CRTL寄存器的位16会置1 while( !((SysTick-》CTRL)&(1《《16)) ); } // 关闭SysTick定时器 SysTick-》CTRL &=~SysTick_CTRL_ENABLE_Msk; } void SysTick_Delay_Ms( __IO uint32_t ms) { uint32_t i; SysTick_Config(SystemCoreClock/1000); for(i=0;i《ms;i++) { // 当计数器的值减小到0的时候,CRTL寄存器的位16会置1 // 当置1时,读取该位会清0 while( !((SysTick-》CTRL)&(1《《16)) ); } // 关闭SysTick定时器 SysTick-》CTRL &=~ SysTick_CTRL_ENABLE_Msk; } HAL_InitTick(TICK_INT_PRIORITY); SysTick_Init(); HAL_SYSTICK_Config(SystemCoreClock / (1000U / uwTickFreq)) 对应 SysTick_Config(SystemCoreClock/1000000) HAL_Delay(500); 对应SysTick_Delay_Ms(500); 四,中中断延时 在ESP8266学习笔记(3) - GPIO使用接口的HAL_GPIO_EXTI_Callback中加入按键消抖 /* USER CODE BEGIN 1 */ void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) { if(GPIO_Pin==KEY1_Pin) { HAL_Delay(100); if(HAL_GPIO_ReadPin(KEY1_Pin_Port,KEY1_Pin)==1) { HAL_GPIO_TogglePin(LED_G_GPIO_Port,LED_G_Pin); } } } /* USER CODE END 1 */ 现在下载进单片机只会让它在按键按下后没有任何反应,这又是为什么呢,其实问题出在HAL_Delay()上。 在进入回调函数之后就一直在HAL_Delay陷入了死循环中,原因是SYSTICK优先级太低造成的。 SYSTICK中断的抢占优先级和外部中断的抢占优先级是一样的,那么在外部中断触发时肯定不能接着触发系统定时器中断了,问题已经找到了,只需要简单地将外部破坏的抢占优先级低分类。 抢占优先级,数字越小,优先级 如果抢占优先级相同,判断子优先级,同样,数字越小,优先级等级 五、注意事项 用户代码要加在 USER CODE BEGIN N 和 USER CODE END N 之间,否则可以使用 STM32CubeMX 重生成代码后,会被删除。 |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1609 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1540 浏览 1 评论
970 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
681 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1587 浏览 2 评论
1861浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
643浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
515浏览 3评论
528浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
503浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-20 15:21 , Processed in 0.882586 second(s), Total 78, Slave 62 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号