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

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.效果演示

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值