SysTick是内核系统的定时器,先来看看SysTick来源在哪,下图stm32f030cc的时钟树
SysTick的时钟为HCLK的8分频,systick = HCLK/8
先提一下标准库的大概运作方式,标准库有写好自动判断要用外部石因还是内部,外部不正常或没接上的话会自动使用内部HSI,有挂外部的话石中的进行路线如下图,
可以看到红色路径是有挂8M时会跑的路径,重点来了!! PREDIV和PLLMUL是除多少和乘上多少,要来看看system_stm32f0xx.c,这个是标准库刚方写好的,建议不要去动了,官方写的算完整了。以下是系统时钟配置的函示
static void SetSysClock(void)这函是底下的一部份:
/*PLL configuration */
RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL));
RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_PREDIV1 | RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLMULL6);
应该有看到除1和乘6吧,这个看法也可以套运在其他MCU上,标准库都差不多的。
再来要看看STM32F0xxx Cortex-M0 programming manual M0编程手册,要看这是因为我们是用操作内核的暂存器
手册网址:https://www.st.com/resource/en/programming_manual/pm0215-stm32f0xxx-cortexm0-programming-manual-stmicroelectronics.pdf
先来看看程序吧:
#ifndef __SYSTICK_H
#define __SYSTICK_H
#include "stm32f0xx.h"
#define STK_CSR (*(volatile unsigned long*)0xE00E010)
#define STK_RVR (*(volatile unsigned long*)0xE00E014)
#define STK_CVR (*(volatile unsigned long*)0xE00E018)
void delay_ms(uint16_t nms);//16
void delay_us(uint16_t nus);//16
void SysTick_Init(uint8_t SYSCLK);//8
#endif /* __SYSTICK_H */
上面可以看到我有定义三个暂存器指标,这三个位置在第四章节
再来看看
#include "bsp_SysTick.h"
static uint8_t fac_us=0;
static uint16_t fac_ms=0;
void SysTick_Init(uint8_t SYSCLK)
{
SysTick->CTRL = 0xfffffffb;
fac_us=SYSCLK/8;
fac_ms=(uint16_t)fac_us*1000;
}
void delay_ms(uint16_t nms)
{
uint32_t temp;
SysTick->LOAD = (uint32_t)nms*fac_ms;
SysTick->VAL =0x00;
SysTick->CTRL =0x01;
do
{
temp = SysTick->CTRL;
}
while((temp&0x01)&&(!(temp&(1<<16))));
SysTick->CTRL = 0x00;
SysTick->VAL =0x00;
}
void delay_us(uint16_t nus)
{
uint32_t temp;
SysTick->LOAD = (uint32_t)nus*fac_us;
SysTick->VAL =0x00;
SysTick->CTRL =0x01;
do
{
temp = SysTick->CTRL;
}
while((temp&0x01)&&(!(temp&(1<<16))));
SysTick->CTRL = 0x00;
SysTick->VAL =0x00;
}
这些操作方法M0编程手册里的说明很清楚了,有兴趣的就自己看看吧,绝对不会看不懂很好理解。
再来是看主程序要如何使用?
#include "bsp_SysTick.h"
int main(void)
{
SysTick_Init(48);//初始化
delay_ms(20);
}
初始化後就可以使用了,我打48是因为我有挂外部石因震荡8M除1在乘6倍频就会变48M,才会输入48,还是不知道为甚麽在往前看看,假如不外挂石因用内部的话这边要改成8
这绝对会比用回圈计数还准。
<<: Day 0x16 - 代码建立 (Part 2: 交易状态、退款状态)
>>: EP20 - 整合 Jenkins 自动部署到 EKS
虽然还有一天...有点怀念ESO...收拾一下东西,等会要往车站移动了。 收拾完行李check ou...
在学习完SQL之後,接下来让我们进入下一个阶段:Python的学习! 先说为什麽你需要学Python...
接下来我们要开始运用APM Agent的函式库来去做应用程序方面的监控。 APM 安装 kibana...
前言 在我们完成一项产品的时候都需要做到各种测试,并完成相关测试计画,才是一个完整的产品。 单元测试...
大部分的开发人员在面对前端後端是不同网域的时候,会碰上一个名叫 跨来源资源共享 (Cross-Ori...