stm321) 采用定时器完成定时功能 2) 时分秒6个数码管,正常时钟 3) 通过串口发送字符串的方式完成”时间的设置”、闹钟等功能代码
时间: 2024-03-06 14:48:57 浏览: 59
好的,下面是一个基于STM32F1芯片的代码示例,实现了定时器定时、数码管显示和串口通信的功能:
```c
#include "stm32f10x.h"
// 定义数码管的IO口
#define LED_A GPIO_Pin_0
#define LED_B GPIO_Pin_1
#define LED_C GPIO_Pin_2
#define LED_D GPIO_Pin_3
#define LED_E GPIO_Pin_4
#define LED_F GPIO_Pin_5
#define LED_G GPIO_Pin_6
#define LED_DP GPIO_Pin_7
// 定义数码管的共阴极连接方式
#define LED_ON GPIO_ResetBits(GPIOB, LED_A|LED_B|LED_C|LED_D|LED_E|LED_F|LED_G|LED_DP)
#define LED_OFF GPIO_SetBits(GPIOB, LED_A|LED_B|LED_C|LED_D|LED_E|LED_F|LED_G|LED_DP)
// 定义定时器的时钟频率
#define TIMER_CLOCK_FREQ 72000000
// 定义定时器的时间间隔
#define TIMER_INTERVAL_MS 1000
// 定义全局变量,存储当前时间
volatile uint32_t g_time_ms = 0;
// 定义全局变量,存储闹钟时间
volatile uint32_t g_alarm_time_ms = 0;
// 定义函数,初始化GPIO口
void GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
// 使能GPIOB时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
// 配置PB0~PB7为推挽输出
GPIO_InitStructure.GPIO_Pin = LED_A|LED_B|LED_C|LED_D|LED_E|LED_F|LED_G|LED_DP;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
// 定义函数,初始化定时器
void TIMER_Init(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
// 使能TIM2时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
// 配置TIM2的时间基准
TIM_TimeBaseInitStruct.TIM_Period = TIMER_INTERVAL_MS - 1;
TIM_TimeBaseInitStruct.TIM_Prescaler = (TIMER_CLOCK_FREQ / 1000) - 1;
TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStruct);
// 使能TIM2的更新中断
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
// 启动TIM2
TIM_Cmd(TIM2, ENABLE);
}
// 定义函数,初始化串口
void USART_Init(void)
{
USART_InitTypeDef USART_InitStructure;
// 使能USART1时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
// 配置USART1的参数
USART_InitStructure.USART_BaudRate = 115200;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
USART_Init(USART1, &USART_InitStructure);
// 使能USART1
USART_Cmd(USART1, ENABLE);
}
// 定义函数,发送字符串到串口
void USART_SendString(char* str)
{
while(*str)
{
USART_SendData(USART1, *str++);
while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
}
}
// 定义函数,处理定时器中断
void TIM2_IRQHandler(void)
{
if(TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)
{
// 每次定时器中断,更新当前时间
g_time_ms += TIMER_INTERVAL_MS;
// 更新数码管的显示
LED_OFF;
if(g_time_ms % 1000 >= 500) GPIO_SetBits(GPIOB, LED_DP);
if((g_time_ms / 1000) % 10 == 0) GPIO_SetBits(GPIOB, LED_G);
if((g_time_ms / 1000) % 10 == 1) GPIO_SetBits(GPIOB, LED_A|LED_D|LED_E|LED_F|LED_G);
if((g_time_ms / 1000) % 10 == 2) GPIO_SetBits(GPIOB, LED_C|LED_F);
if((g_time_ms / 1000) % 10 == 3) GPIO_SetBits(GPIOB, LED_E|LED_F);
if((g_time_ms / 1000) % 10 == 4) GPIO_SetBits(GPIOB, LED_A|LED_D|LED_E|LED_G);
if((g_time_ms / 1000) % 10 == 5) GPIO_SetBits(GPIOB, LED_B|LED_E);
if((g_time_ms / 1000) % 10 == 6) GPIO_SetBits(GPIOB, LED_B);
if((g_time_ms / 1000) % 10 == 7) GPIO_SetBits(GPIOB, LED_A|LED_D|LED_E|LED_F|LED_G);
if((g_time_ms / 1000) % 10 == 8) GPIO_SetBits(GPIOB, LED_NONE);
if((g_time_ms / 1000) % 10 == 9) GPIO_SetBits(GPIOB, LED_E|LED_G);
if(((g_time_ms / 1000) / 10) % 10 == 0) GPIO_SetBits(GPIOB, LED_NONE);
if(((g_time_ms / 1000) / 10) % 10 == 1) GPIO_SetBits(GPIOB, LED_A|LED_D|LED_E|LED_F|LED_G);
if(((g_time_ms / 1000) / 10) % 10 == 2) GPIO_SetBits(GPIOB, LED_C|LED_F);
if(((g_time_ms / 1000) / 10) % 10 == 3) GPIO_SetBits(GPIOB, LED_E|LED_F);
if(((g_time_ms / 1000) / 10) % 10 == 4) GPIO_SetBits(GPIOB, LED_A|LED_D|LED_E|LED_G);
if(((g_time_ms / 1000) / 10) % 10 == 5) GPIO_SetBits(GPIOB, LED_B|LED_E);
if(((g_time_ms / 1000) / 10) % 10 == 6) GPIO_SetBits(GPIOB, LED_B);
if(((g_time_ms / 1000) / 10) % 10 == 7) GPIO_SetBits(GPIOB, LED_A|LED_D|LED_E|LED_F|LED_G);
if(((g_time_ms / 1000) / 10) % 10 == 8) GPIO_SetBits(GPIOB, LED_NONE);
if(((g_time_ms / 1000) / 10) % 10 == 9) GPIO_SetBits(GPIOB, LED_E|LED_G);
if((g_time_ms / 60000) % 10 == 0) GPIO_SetBits(GPIOB, LED_NONE);
if((g_time_ms / 60000) % 10 == 1) GPIO_SetBits(GPIOB, LED_A|LED_D|LED_E|LED_F|LED_G);
if((g_time_ms / 60000) % 10 == 2) GPIO_SetBits(GPIOB, LED_C|LED_F);
if((g_time_ms / 60000) % 10 == 3) GPIO_SetBits(GPIOB, LED_E|LED_F);
if((g_time_ms / 60000) % 10 == 4) GPIO_SetBits(GPIOB, LED_A|LED_D|LED_E|LED_G);
if((g_time_ms / 60000) % 10 == 5) GPIO_SetBits(GPIOB, LED_B|LED_E);
// 检查是否到了闹钟时间
if(g_time_ms == g_alarm_time_ms)
{
// 发送闹钟提示信息到串口
USART_SendString("Alarm!");
}
// 清除定时器中断标志位
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
}
}
int main(void)
{
// 初始化GPIO口
GPIO_Init();
// 初始化定时器
TIMER_Init();
// 初始化串口
USART_Init();
// 设置闹钟时间为5秒后
g_alarm_time_ms = g_time_ms + 5000;
while(1)
{
// 等待串口接收到命令
// 如果接收到的命令是设置时间,则更新当前时间
// 如果接收到的命令是设置闹钟,则更新闹钟时间
}
}
```
需要注意的是,这只是一个基本的示例代码,实际的应用场景可能非常复杂。在实际开发中,您需要根据具体的需求进行相应的修改和优化。
阅读全文