手把手教毫秒级和秒级延时函数编写!Hbird E203 v1和v2通用!


本文将讲解如何利用 hbird e203的 RTC 实现毫秒级和秒级延时,感兴趣的话继续看下去吧!
(原创教学文章,转载请注明出处!)
更多教学资源分享,可加入此群获取!
在这里插入图片描述

十二、RTC的使用

RTC的功能列出如下。

  • HBirdv2 SoC在常开域中包含一个RTC模块。
  • 可编程计数器的比较阈值,一旦RTC计数器的比较值达到比较阈值则可以产生中断
  • RTC本质上是一个48位的计数器
    下表列出了RTC模块5个寄存器。
    在这里插入图片描述

注:所有的RTC寄存器都是32位的

12.1 RTC寄存器

12.1.1. RTCCFG

RTCCFG寄存器用于对 RTC 进行配置,具体各比特域的作用如下:
在这里插入图片描述

12.1.2. RTCHI和RTCLO

RTCHI和RTCLO 都是反映RC计数器(共48位)的值,其中RTCHI反映高16位,RTCLO反映低32位
在这里插入图片描述

12.1.3 RTCS

RTCS寄存器中的值是来自RTC计数器计数值(RTCHI/RTCLO寄存器)中取出的32位,而RTCCFG寄存器 rtcscale 域的值指定了RTC计数器计数值中取出32位的低位起始位置,即计数值的缩放比例。
在这里插入图片描述

这样说可能不好理解,举个例子:

  • rtcscale = 0,则直接取出RTC计数器计数值低32位作为RTCS的值;若rtcscale = 5,则直接取出RTC计数器计数值除以2^5(32)作为RTCS的值

12.1.4 RTCCMP

该寄存器的值将作为比较阈值与RTC计数器比较值(RTCS寄存器的值)进行比较。一旦RTCS寄存器的值大于或者等于RTCCMP寄存器的值,便会产生中断。
在这里插入图片描述

12.2 延时函数编写

我的需求是通过RTC实现毫秒级和秒级延时(常开域为低速时钟,无法实现微妙级延时)
(1)思路: 使能RTC,使计数器从0开始计数,然后计算 1ms 和 1s 对应的计数值,当到达此计数值时才退出空循环.(具体可看代码,注释很详细)
(2)文件结构:
我的扩展包是放在SoC/hbirdv2/Common下,需要添加下头文件路径
在这里插入图片描述
添加头文件路径方法:

  1. 先在Project Explorer 栏下选中 hello_world 项目,点击鼠标右键,选择"Properties"
    在这里插入图片描述

  2. 在弹出的窗口中,展开 C/C++ Build 菜单 --> Setting --> Tool Settings菜单 --> GNU RISC-v Cross Assembler
    –> Includes
    在这里插入图片描述

  3. 将 Include path 拉到最右边,添加新路径,我添加路径为:

${workspace_loc:/${ProjName}/hbird_sdk/SoC/hbirdv2/Common/Include_user}

在这里插入图片描述

注:添加头文件包含路径时发现似乎要填头文件所在的文件夹的路径,而不能填父级文件夹路径
在这里插入图片描述

同理添加此路径到下图所示的两个 Includes路径设置中
在这里插入图片描述

然后点Apply and Close 即可

(3)main中的循环:
每隔 0.5s 打印 Hello World From RISC-V Processor! ,隔 2s 打印 NucleiStudio yyds!
在这里插入图片描述

(4)下载测试:
详情请看测试视频(放在群文件中,可自行加群下载查看)

(5)代码文件:

  • rtc.h
#include "type_user.h"

#ifndef RTC_H_
#define RTC_H_
// 寄存器偏移地址
#define AON_RTCCFG      0x040
#define AON_RTCLO       0x048
#define AON_RTCHI       0x04C
#define AON_RTCS        0x050
#define AON_RTCCMP      0x060

void rtc_init();
void rtc_off();
void rtc_delay_s(uint s);   // 秒级延时
void rtc_delay_ms(uint ms); // 毫秒级延时
void rtc_timer_irq_handler();

#endif /* RTC_H_ */
  • rtc.c
#include "platform.h"
#include "rtc.h"
// 延时函数需先使能 rtc 后才能使用

// 低速时钟实际频率为:32765 Hz,即周期为30.52037 us
uint rtc_freq = 32765;

rtc_init(){
	AON_REG(AON_RTCCFG) = 0x1000; // 使能 rtc
}

rtc_off(){
	AON_REG(AON_RTCCFG) = 0x0000; // 关闭 rtc
}

//1s,即32765.0025个周期;按32765计算,即为0.9999999235 s,误差可忽略不计
rtc_delay_s(uint s){
	AON_REG(AON_RTCLO) = 0x0;  // 计数值清零
	rtc_init();
	while(AON_REG(AON_RTCLO) <= (32765*s)){} // 延时 32765*s 周期
	rtc_off();
}

// 1ms,即32.765个周期;按33个周期计算,即为1007.17us,即此函数的实际延时时间
rtc_delay_ms(uint ms){
	AON_REG(AON_RTCLO) = 0x0;  // 计数值清零
	rtc_init();
	while(AON_REG(AON_RTCLO) <= (33*ms)){} // 延时 33*ms 周期
	rtc_off();
}

rtc_timer_irq_handler(){

}
  • type_user.h
#ifndef TYPE_USER_H_
#define TYPE_USER_H_

typedef unsigned int uint;

#endif /* TYPE_USER_H_ */
  • platform.h
#ifndef _HBIRD_PLATFORM_H
#define _HBIRD_PLATFORM_H

#include 
/****************************************************************************
 * Platform definitions
 *****************************************************************************/
#define _AC(X,Y)        (X##Y)
#define AON_CTRL_ADDR           _AC(0x10000000,UL)

// Helper functions
#define _REG8(p, i)             (*(volatile uint8_t *) ((p) + (i)))
#define _REG32(p, i)            (*(volatile uint32_t *) ((p) + (i)))
#define _REG32P(p, i)           ((volatile uint32_t *) ((p) + (i)))
#define AON_REG(offset)         _REG32(AON_CTRL_ADDR, offset)

#endif /* _HBIRD_PLATFORM_H */

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

雪天鱼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值