一、定时器
(1)串口通信
HAL库配置:
main函数中添加下面代码:
HAL_TIM_Base_Start_IT(&htim2);
以及回调函数:
#define COUNTOF(a) (sizeof(a)/sizeof(*(a)))
uint8_t str[] = "hello windows!\r\n";
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim){
uint8_t time=0; //设置时间变量
if(htim->Instance == TIM2){
time++;
if(time%2000 == 0){
HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_13);
}
if(time%5000 == 0){
HAL_UART_Transmit(&huart1,str,COUNTOF(str),0xFFFF);
if(time%10000 == 0 && time != 0){
time = 0;
}
}
}
}
(2)LED灯
1、新建工程,进行基本配置。
通过点击“ACCESS TO MCU SELECTOR”来创建一个新的工程:
芯片选择“STM32F103C8”。
打开外部时钟,点击“System Core”,选择RCC,在右侧弹出的菜单栏中选择“Crystal/Ceramic Resonator”。
选择调试接口,点击“System Core”,选择SYS。,在右侧弹出的菜单栏中选择“Serial Wire”。
2、配置IO。
配置PC15,并命名为D1。这里我们只使用一个LED,做演示用。
3、配置定时器2。
这里我们使用定时器2来实现定时的功能。如图所示选中定时器2,配置定时器2的时钟源为内部时钟,分频系数为71,向上计数模式,计数周期为5000,使能自动重载模式。
4、配置中断。
如下图所示,开启定时器2的中断。
5、时钟配置。
6、生成工程文件。
7、修改工程。
生成工程后,打开,添加中断响应之后所需的一些代码。在main.c文件中添加如下内容
1:
HAL_TIM_Base_Start_IT(&htim2);
该函数表示启动相应的定时器,“h”表示HAL库,“tim2”表示定时器2。所以这行代码的意思就是启动定时器2。
2.回调函数:
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
static uint32_t time_cnt =0;
if(htim->Instance == TIM2)
{
if(++time_cnt >= 400)
{
time_cnt =0;
HAL_GPIO_TogglePin(D1_GPIO_Port,D1_Pin);
}
}
}
当产生定时中断的时候,会自动调用这个函数。在函数内部定义了一个静态变量:time_cnt。当它大于等于400的时候,才会执行if里面的代码。也就是说需要发生400次中断,才会让LED的状态翻转。前面已经算过了,一次定时中断的时间是0.005秒,所以400次中断的时间是0.005*400=2秒。也就是说每隔2秒,LED的状态翻转一次。
8、运行
编译并烧录后的运行效果:
二、日历时钟
创建STM32F103C8工程
配置RCC(设置高速外部时钟,使能外部晶振LSE)
配置RTC(激活时钟源(Activate Clock Source)和日历(Activate Calendar))
使能串口
时钟树配置
创建项目后添加代码:
在main.c文件中重写fputc函数,完成printf函数的重定向
//添加头文件#include "stdio.h"
int fputc(int ch,FILE *f){
uint8_t temp[1]={ch};
HAL_UART_Transmit(&huart1,temp,1,2);
return ch;
}
在main.c中定义时间和日期的结构体用来获取时间和日期
RTC_DateTypeDef GetData; //获取日期结构体
RTC_TimeTypeDef GetTime; //获取时间结构体
在main函数的while循环中添加以下代码
/* 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);
添加输出星期几
在
/* Display date Format : yy/mm/dd */
printf("%02d/%02d/%02d\r\n",2000 + GetData.Year, GetData.Month, GetData.Date);
后面添加以下代码
/* Display date Format : weekday */
if(GetData.WeekDay==1){
printf("星期一\r\n");
}else if(GetData.WeekDay==2){
printf("星期二\r\n");
}else if(GetData.WeekDay==3){
printf("星期三\r\n");
}else if(GetData.WeekDay==4){
printf("星期四\r\n");
}else if(GetData.WeekDay==5){
printf("星期五\r\n");
}else if(GetData.WeekDay==6){
printf("星期六\r\n");
}else if(GetData.WeekDay==7){
printf("星期日\r\n");
}
编译运行:
三、总结
本次实验主要学习掌握关于定时器和日历时钟的基本知识,利用HAL库完成了所要求内容。