[RISC-V MCU 应用开发] 第九十八章、CH32V103应用教程——RTC-脉冲

[复制链接]
 楼主| RISCVLAR 发表于 2021-6-11 14:25 | 显示全部楼层 |阅读模式
本帖最后由 RISCVLAR 于 2021-6-11 14:24 编辑

CH32V103应用教程——RTC-脉冲

本章教程主要在原有RTC教程的基础上,通过PC13,使其产生脉冲。PC13作为侵入检测引脚,可以用来输出RTC秒脉冲、闹钟脉冲或者是时钟频率为RTC时钟除以64的脉冲,后者在系统下电的情况下无法输出。

1、RTC简介
关于RTC,在前面章节已经进行过介绍,在此不再赘述。
关于RTC具体介绍,可参考前面章节及CH32V103应用手册。

2、硬件设计
本章教程主要使用PC13引脚产生脉冲,同时使用逻辑分析仪进行脉冲采集,CH32V103测试板与逻辑分析仪连接方式如下:
  • CH32V103开发板的GND引脚与逻辑分析仪的GND引脚连接
  • CH32V103开发板的PC13引脚与逻辑分析仪的采集通道引脚连接

3软件设计
本章教程主要进行产生脉冲实验,需要用到PC13引脚,具体程序如下:
rtc.h文件
  1. #ifndef __RTC_H
  2. #define __RTC_H

  3. #include "ch32v10x_conf.h"

  4. #define  SEC_IRQ  1
  5. //#define  ALR_IRQ  1
  6. //#define  OWE_IRQ  1

  7. /* Exported_Functions */
  8. u8 RTC_Init(u32 SetCnt, u32 SetAlarm);
  9. u8 RTC_Get(void);

  10. #endif<span style="font-family: 宋体; font-size: large; text-indent: 21pt; background-color: rgb(255, 255, 255);"> </span>
rtc.h文件主要进行相关定义和函数声明;
rtc.c文件
  1. #include "rtc.h"

  2. void RTC_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));

  3. /*******************************************************************************
  4. * Function Name  : RTC_NVIC_Config
  5. * Description    : Initializes RTC Int.
  6. * Input          : None
  7. * Return         : None
  8. *******************************************************************************/
  9. static void RTC_NVIC_Config(void)
  10. {
  11.     NVIC_InitTypeDef NVIC_InitStructure;
  12.     NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQn;            //RTC全局中断
  13.     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //设置抢占优先级
  14.     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;        //设置响应优先级
  15.     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;           //使能该通道中断
  16.     NVIC_Init(&NVIC_InitStructure);                           //根据NVIC_InitStructure中指定的参数初始化外设NVIC寄存器
  17. }

  18. /*******************************************************************************
  19. * Function Name  : RTC_Init
  20. * Description    : Initializes RTC collection.
  21. * Input          : None
  22. * Return         : 1:Init Fail
  23. *                  0:Init Success
  24. *******************************************************************************/
  25. u8 RTC_Init(u32 SetCnt, u32 SetAlarm)
  26. {
  27.     //检查是不是第一次配置时钟
  28.     u8 temp=0;
  29.     RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);//使能PWR和BKP外设时钟
  30.     PWR_BackupAccessCmd(ENABLE);//使能后备寄存器访问
  31.     BKP_DeInit();//复位备份区域
  32.     RCC_LSEConfig(RCC_LSE_ON);//设置外部低速晶振(LSE),使用外设低速晶振
  33.     while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET&&temp<250)//检查指定的RCC标志位设置与否,等待低速晶振就绪
  34.     {
  35.         temp++;
  36.         Delay_Ms(10);
  37.     }
  38.     if(temp>=250)
  39.     {
  40.         printf("time error..\n");
  41.         return 1;//初始化时钟失败,晶振有问题
  42.     }
  43.     RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE); //设置RTC时钟(RTCCLK),选择LSE作为RTC时钟

  44.     RCC_RTCCLKCmd(ENABLE); //使能RTC时钟
  45.     RTC_WaitForLastTask(); //等待最近一次对RTC寄存器的写操作完成

  46.     RTC_WaitForSynchro();  //等待RTC寄存器同步
  47.     RTC_WaitForLastTask(); //等待最近一次对RTC寄存器的写操作完成


  48.     //以下三个中断根据需要开启,三者触发时都是进入RTC_IRQHandler中断函数,通过RTC_GetITStatus判断具体是哪个中断触发
  49.     #if SEC_IRQ   //(可选)
  50.       RTC_ITConfig(RTC_IT_SEC, ENABLE);//秒中断使能秒,用来产生一个可编程的周期性中断信号(最长可达1秒)。
  51.       RTC_WaitForLastTask();
  52.     #endif

  53.     #if ALR_IRQ   //(可选)
  54.       RTC_ITConfig(RTC_IT_ALR, ENABLE);//闹钟中断使能,用来产生一个软件可编程的闹钟中断。
  55.       RTC_WaitForLastTask();
  56.     #endif

  57.     #if OWE_IRQ   //(可选)
  58.       RTC_ITConfig(RTC_IT_OW, ENABLE);//溢出中断使能,指示内部可编程计数器溢出并回转为0的状态。
  59.       RTC_WaitForLastTask();
  60.     #endif

  61.     RTC_EnterConfigMode(); //允许配置
  62.     RTC_WaitForLastTask(); //等待最近一次对RTC寄存器的写操作完成

  63.     RTC_SetPrescaler(32768);//设置RTC预分频的值
  64.     RTC_WaitForLastTask();  //等待最近一次对RTC寄存器的写操作完成

  65.     RTC_SetCounter(SetCnt); //设置RTC计数器值
  66.     RTC_WaitForLastTask();  //等待最近一次对RTC寄存器的写操作完成

  67.     RTC_SetAlarm(SetAlarm); //配置闹钟值
  68.     RTC_WaitForLastTask();  //等待最近一次对RTC寄存器的写操作完成

  69.     RTC_ExitConfigMode();   //退出配置模式
  70.     BKP_WriteBackupRegister(BKP_DR1, 0X5A5A); //向指定的后备寄存器中写入用户程序数据

  71.     RTC_NVIC_Config();//RCT中断分组设置
  72.     return 0; //ok
  73. }


  74. /*******************************************************************************
  75. * Function Name  : RTC_IRQHandler
  76. * Description    : This function handles RTC Handler.
  77. * Input          : None
  78. * Return         : None
  79. *******************************************************************************/
  80. void RTC_IRQHandler(void)
  81. {
  82.     if (RTC_GetITStatus(RTC_IT_SEC) != RESET)  //秒钟中断
  83.     {
  84.         printf("second interrupt!\n");
  85.     }
  86.     if(RTC_GetITStatus(RTC_IT_ALR)!= RESET)    //闹钟中断
  87.     {
  88.         printf("Alarm interrupt!\n");
  89.     }
  90.     if(RTC_GetITStatus(RTC_IT_OW)!= RESET)     //溢出中断中断
  91.     {
  92.         printf("Overloop interrupt!\n");
  93.     }
  94.     RTC_ClearITPendingBit(RTC_IT_SEC|RTC_IT_ALR|RTC_IT_OW); //清除秒钟中断、闹钟中断、溢出中断标志位
  95.     RTC_WaitForLastTask(); //等待RTC寄存器上的最后一次写入操作完成
  96. }
rtc.c文件主要进行rtc脉冲初始化配置。
main.c文件
  1. /********************************** (C) COPYRIGHT *******************************
  2. * File Name          : main.c
  3. * Author             : WCH
  4. * Version            : V1.0.0
  5. * Date               : 2020/11/10
  6. * Description        : Main program body.
  7. *******************************************************************************/
  8. #include "debug.h"
  9. #include "rtc.h"

  10. /*******************************************************************************
  11. * Function Name  : main
  12. * Description    : Main program.
  13. * Input          : None
  14. * Return         : None
  15. *******************************************************************************/
  16. int main(void)
  17. {
  18.     NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
  19.     Delay_Init();
  20.     USART_Printf_Init(115200);

  21.     printf("SystemClk:%d\r\n",SystemCoreClock);
  22.     printf("RTC Test\r\n");

  23.     RTC_Init(3,6);

  24.     /*(PC13引脚输出脉冲)*/
  25.     BKP_RTCOutputConfig(BKP_RTCOutputSource_Second);  //秒脉冲输出
  26. //    BKP_RTCOutputConfig(BKP_RTCOutputSource_Alarm);   //闹钟脉冲输出
  27. //    BKP_RTCOutputConfig(BKP_RTCOutputSource_CalibClock); //RTC时钟除以64脉冲

  28.     while(1)
  29.     {
  30.         ;
  31.     }
  32. }
main.c文件主要进行函数初始化以及配置相关脉冲输出。

4下载验证
将编译好的程序下载到开发板并复位,配置好各脉冲模式产生脉冲如下:
秒脉冲(大约每一秒产生一次脉冲):
图片1.png
闹钟脉冲(当计数器值与闹钟值相同产生脉冲):
图片2.png
RTCCLK除以64产生的脉冲(RTCCLK为32.768KHz):
图片3.png

97、RTC-脉冲.rar

477.13 KB, 下载次数: 48

asmine 发表于 2021-6-15 11:03 | 显示全部楼层
什么叫侵入检测引脚
 楼主| RISCVLAR 发表于 2021-6-15 11:26 | 显示全部楼层
asmine 发表于 2021-6-23 14:10 | 显示全部楼层
RISCVLAR 发表于 2021-6-15 11:26
看下面链接帖子:https://bbs.21ic.com/icview-3050068-1-1.html

边沿检测,又貌似有点区别
您需要登录后才可以回帖 登录 | 注册

本版积分规则

133

主题

296

帖子

44

粉丝
快速回复 在线客服 返回列表 返回顶部

133

主题

296

帖子

44

粉丝
快速回复 在线客服 返回列表 返回顶部