1.新手读代码很痛苦
delay.h
#ifndef __DELAY_H__
#define __DELAY_H__
#include "sys.h"
void delay_ms(uint32_t nms); /* 延时nms */
void delay_us(uint32_t nus); /* 延时nus */
void delay_s(uint32_t ns); /* 延时ns */
void HAL_Delay(uint32_t nms); /* 延时nms */
#endif
2.自己查阅资料 加上注释 delay.c
#include "delay.h"
/**
* @brief 微秒级延时
* @param nus 延时时长,范围:0~233015
* @retval 无
*/
void delay_us(uint32_t nus) /*addhx 是一个32位的无符号整型*/
{
uint32_t temp; //定义一个temp 指出变量的类型 uint32_t
//https://mcu.eetrend.com/content/2019/100044093.html
//SysTick->LOAD为24位寄存器,所以最大延时为:nms<=0xffffff*8*1000/SYSCLK;SYSCLK单位为Hz,nms单位为ms
SysTick->LOAD = 72 * nus; /* 设置定时器重装值 */
SysTick->VAL = 0x00; /* 清空当前计数值 */
//https://blog.csdn.net/L20130316/article/details/50254951
SysTick->CTRL |= 1 << 2; /* 设置分频系数为1分频 */
//https://www.eeworld.com.cn/mcu/eic664499.html
/*位0:SysTick时钟使能*/
SysTick->CTRL |= 1 << 0; /* 启动定时器 */
do
{
temp = SysTick->CTRL;
} while ((temp & 0x01) && !(temp & (1 << 16))); /* 等待计数到0 */
SysTick->CTRL &= ~(1 << 0); /* 关闭定时器 */
}
/**
* @brief 毫秒级延时
* @param nms 延时时长,范围:0~4294967295
* @retval 无
*/
void delay_ms(uint32_t nms)
{
while(nms--)
delay_us(1000);
}
/**
* @brief 秒级延时
* @param ns 延时时长,范围:0~4294967295
* @retval 无
*/
void delay_s(uint32_t ns)
{
while(ns--)
delay_ms(1000);
}
/**
* @brief 重写HAL_Delay函数
* @param nms 延时时长,范围:0~4294967295
* @retval 无
*/
void HAL_Delay(uint32_t nms)
{
delay_ms(nms);
}
3.发现 嵌入式这块csdn并不是很多
参考了 eeworld
示例代码
#include "delay.h"
#define Value_us 21
#define Value_ms 21000
void delay_init(void){
SysTick->CTRL &= (1 << 2); //控制寄存器位2置0,选择8分频时钟
SysTick->CTRL &= ~(1 << 0); //关闭计数器
}
void delay_us(u32 num){
SysTick->LOAD = num * Value_us;
SysTick->VAL = 0;
SysTick->CTRL |= (1 << 0); //使能计数器
while (!(SysTick->CTRL & 1<<16)); //判断是否计数完毕
SysTick->VAL = 0;
SysTick->CTRL &= ~(1 << 0); //关闭计数器
}
void delay_ms(u32 num){
SysTick->LOAD = num * Value_ms;
SysTick->VAL = 0;
SysTick->CTRL |= (1 << 0); //使能计数器
while (!(SysTick->CTRL & 1<<16));
SysTick->VAL = 0;
SysTick->CTRL &= ~(1 << 0); //关闭计数器
}
4.新手主要是不懂底层的原理
SysTick逻辑图
5.操作层次
SysTick->LOAD = 72 * nus; /* 设置定时器重装值 */
SysTick->VAL = 0x00; /* 清空当前计数值 */
SysTick->CTRL |= 1 << 2; /* 设置分频系数为1分频 */
SysTick->CTRL |= 1 << 0; /* 启动定时器 */
5.1 写法有差异
SysTick->CTRL &= (1 << 2); //控制寄存器位2置0,选择8分频时钟
SysTick->CTRL &= ~(1 << 0); //关闭计数器
直接引用:
https://www.eeworld.com.cn/mcu/eic664499.html
相对引用:
https://www.eeworld.com.cn/mcu/eic664499.html
发布者:安静的夜晚