第8周-定时器与日历时钟

本文介绍了如何使用STM32的定时器实现时间控制,通过设置TIM2和TIM3来分别实现5秒间隔的串口消息发送和2秒周期的LED闪烁。同时,讲解了STM32的RTC实时时钟功能,包括初始化、读取及设置当前时间,并以指定格式通过串口输出。最后,实现了每秒更新时间并显示星期的功能。
摘要由CSDN通过智能技术生成
  1. 之前作业中的延时功能都是通过循环、delay/Hal_delay函数等实现,本次作业通过定时器Timer方式实现时间的精准控制,相当于给CPU上了一个闹钟,CPU平时处理其它任务,当定时时间到了以后,处理定时相关的任务。请设置一个5秒的定时器,每隔5秒从串口发送“hello windows!”;同时设置一个2秒的定时器,让LED等周期性地闪烁。
    1.Stm32cubemx项目创建
    1.新建项目后,选择芯片,我用的是stm32f103c8t6芯片。
    2.配置RCC
    在这里插入图片描述
    3.配置sys
    在这里插入图片描述
    4.配置输出引脚PA1
    在这里插入图片描述
    5.配置定时器TIM2和TIM3分别作为串口通信和翻转Led灯状态的定时器,并使能中断
    在这里插入图片描述
    两个时钟配置都一样
    注意;分频系数那里虽然写的是71,但系统处理的时候会自动加上1,所以实际进行的是72分频。由于时钟我们一般会配置为72MHZ,所以72分频后得到1MHZ的时钟。1MHZ的时钟,计数5000次,得到时间5000/1000000=0.005秒。也就是每隔0.005秒定时器2会产生一次定时中断。
    6.配置串口用于向上位机发送信息
    在这里插入图片描述
    7.时钟配置
    在这里插入图片描述
    8.项目设置
    在这里插入图片描述
    在这里插入图片描述
    9.点击GENRATE CODE创建项目

2、打开创建的项目
1.启动定时器
在main.c中添加代启动定时器TIM2和TIM3

HAL_TIM_Base_Start_IT(&htim2);
HAL_TIM_Base_Start_IT(&htim3);
2.串口通信
在main.c中编辑串口发送的信息

uint8_t hello[20]=“hello windows! \n”;
3.在main.c中重定义中断回调函数

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
static uint32_t time_cnt =0;
static uint32_t time_cnt3 =0;
if(htim->Instance == TIM2)
{
if(++time_cnt >= 400)
{
time_cnt =0;
HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_1);
}
}
if(htim->Instance == TIM3)
{
if(++time_cnt3 >= 1000)
{
time_cnt3 =0;
HAL_UART_Transmit(&huart1,hello,20,100000);
}

}

}
该函数为定时器的中断回调函数,当产生定时中断的时候,会自动调用这个函数。在函数内部定义了定时器的一个静态变量:time_cnt与定时器3 的time_cnt3。
例如time_cnt,当它大于等于100的时候,才会执行if里面的代码。也就是说需要发生400次中断,才会让LED的状态翻转。前面已经算过了,一次定时中断的时间是0.005秒,所以400次中断的时间是0.005400=2秒。也就是说每隔2秒,LED的状态翻转一次。
例如time_cnt3,当它大于等于1000的时候,才会执行if里面的代码。也就是说需要发生1000次中断,才会让串口发一次消息。0.0051000=5秒,符合题目要求。
3、结果演示
在这里插入图片描述
在这里插入图片描述
2. 了解实时时钟RTC的原理。STM32芯片自带RTC,因此不须像其他MCU需外接RTC模块。请编程实现STM32的日历读取、设置和输出。要求:
1)读取RTC初始时间,验证是否为 1970年1月1日零分零秒;
1、创建项目
1.设置串口
在这里插入图片描述
2.配置RTC
在这里插入图片描述
3.配置时钟
在这里插入图片描述
4.项目设置
在这里插入图片描述
在这里插入图片描述
2.打开项目
1.修改main.c主函数中的while循环

while (1)
{
/* USER CODE END WHILE */

/* USER CODE BEGIN 3 */
		  /* Get the RTC current Time */
    HAL_RTC_GetTime(&hrtc, &GetTime, RTC_FORMAT_BIN);
  /* Get the RTC current Date */
  HAL_RTC_GetDate(&hrtc, &GetData, RTC_FORMAT_BIN);

  /* Display date Format : yy/mm/dd */
  printf("%02d/%02d/%02d\r\n",2000 + GetData.Year, GetData.Month, GetData.Date);
  /* Display time Format : hh:mm:ss */
  printf("%02d:%02d:%02d\r\n",GetTime.Hours, GetTime.Minutes, GetTime.Seconds);

  printf("\r\n");

  HAL_Delay(1000);

}
2.在main.c中重写printf函数

#include “stdio.h”
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------/
/
USER CODE BEGIN PTD */
int fputc(int ch,FILE *f){
uint8_t temp[1]={ch};
HAL_UART_Transmit(&huart1,temp,1,2);
return ch;
}
3.勾选Use MiscroLiB
在这里插入图片描述
4.效果演示
在这里插入图片描述
2)将RTC时间调整为当前时间,并以 2021年x月x日x分x秒的格式从串口输出(或输出到OLED屏),每1s改变一次;
1.rtc.c中修改为当前时间
在这里插入图片描述
2.修改main.c主函数中的while循环

while (1)
{
/* USER CODE END WHILE */

/* USER CODE BEGIN 3 */
		  /* Get the RTC current Time */
    HAL_RTC_GetTime(&hrtc, &GetTime, RTC_FORMAT_BIN);
  /* Get the RTC current Date */
  HAL_RTC_GetDate(&hrtc, &GetData, RTC_FORMAT_BIN);

  /* Display date Format : yy/mm/dd */
  printf("%02d年%02d月%02d日 \n",2000 + GetData.Year, GetData.Month, GetData.Date);
  /* Display time Format : hh:mm:ss */
  printf("%02d时%02d分%02d秒 \n",GetTime.Hours, GetTime.Minutes, GetTime.Seconds);

  printf(" \n");

  HAL_Delay(1000);

3.效果演示在这里插入图片描述
3)如果输出内容中需加入“星期x”,请修改代码。
1.修改main.c主函数中while循环

while (1)
{
/* USER CODE END WHILE */

/* USER CODE BEGIN 3 */
		  /* Get the RTC current Time */
    HAL_RTC_GetTime(&hrtc, &GetTime, RTC_FORMAT_BIN);
  /* Get the RTC current Date */
  HAL_RTC_GetDate(&hrtc, &GetData, RTC_FORMAT_BIN);

  /* Display date Format : yy/mm/dd */
  printf("%02d年%02d月%02d日 \n",2000 + GetData.Year, GetData.Month, GetData.Date);
  /* Display time Format : hh:mm:ss */
  printf("%02d时%02d分%02d秒 \n",GetTime.Hours, GetTime.Minutes, GetTime.Seconds);
  printf("星期%0d",GetData.WeekDay);
  printf(" \n");

  HAL_Delay(1000);

2.效果演示
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值