使用STM32制作简易数字时钟

以下是一个使用STM32制作简易数字时钟的示例代码,以及详细的解释。

硬件准备

  1. STM32开发板(本例使用STM32F103C8T6)
  2. 七段数码管模块(本例使用共阳极的4位数码管)
  3. 杜邦线若干

硬件连接

将数码管模块连接到STM32开发板的GPIO引脚,具体的连接方式根据数码管模块的引脚定义而定。在本例中,将数码管的四个段(A、B、C、D、E、F、G)连接到STM32的PB0、PB1、PB2、PB3、PB4、PB5、PB6引脚上,将数码管的四个位选择引脚(COM1、COM2、COM3、COM4)连接到STM32的PA4、PA5、PA6、PA7引脚上。

软件准备

  1. STM32CubeIDE:用于编写、调试和烧录STM32的开发环境。
  2. STM32Cube HAL库:提供对STM32外设的API接口。

创建工程

  1. 打开STM32CubeIDE,选择“File”->“New”->“STM32 Project”创建一个新的工程。
  2. 选择适合你的STM32型号和硬件平台。
  3. 选择一个合适的C编译器(通常为GNU ARM GCC)。
  4. 选择一个合适的调试器(通常为ST-Link)。
  5. 选择“基于Nothing生成”的配置项。
  6. 设置工程的名字和存放路径。
  7. 点击“Finish”完成创建。

编写代码

1. 初始化GPIO

首先,我们需要初始化GPIO引脚,将其配置为输出模式。在main.c文件中添加以下代码:

#include "stm32f1xx_hal.h"

/* 开发板上连接数码管的引脚定义 */
#define LED_A_Pin GPIO_PIN_0
#define LED_A_GPIO_Port GPIOB
#define LED_B_Pin GPIO_PIN_1
#define LED_B_GPIO_Port GPIOB
#define LED_C_Pin GPIO_PIN_2
#define LED_C_GPIO_Port GPIOB
#define LED_D_Pin GPIO_PIN_3
#define LED_D_GPIO_Port GPIOB
#define LED_E_Pin GPIO_PIN_4
#define LED_E_GPIO_Port GPIOB
#define LED_F_Pin GPIO_PIN_5
#define LED_F_GPIO_Port GPIOB
#define LED_G_Pin GPIO_PIN_6
#define LED_G_GPIO_Port GPIOB

#define LED_COM1_Pin GPIO_PIN_4
#define LED_COM1_GPIO_Port GPIOA
#define LED_COM2_Pin GPIO_PIN_5
#define LED_COM2_GPIO_Port GPIOA
#define LED_COM3_Pin GPIO_PIN_6
#define LED_COM3_GPIO_Port GPIOA
#define LED_COM4_Pin GPIO_PIN_7
#define LED_COM4_GPIO_Port GPIOA

void GPIO_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};

    /* 初始化数码管的段引脚为输出模式 */
    GPIO_InitStruct.Pin = LED_A_Pin | LED_B_Pin | LED_C_Pin | LED_D_Pin |
                          LED_E_Pin | LED_F_Pin | LED_G_Pin;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

    /* 初始化数码管的位选择引脚为输出模式 */
    GPIO_InitStruct.Pin = LED_COM1_Pin | LED_COM2_Pin |
                          LED_COM3_Pin | LED_COM4_Pin;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}

2. 定义数字和字符映射表

为了显示不同的数字和字符,我们需要定义一个数字和字符的映射表。在main.c文件中添加以下代码:

/* 数字和字符的映射表 */
uint8_t num_table[10] = {
    0x3F,   // 0
    0x06,   // 1
    0x5B,   // 2
    0x4F,   // 3
    0x66,   // 4
    0x6D,   // 5
    0x7D,   // 6
    0x07,   // 7
    0x7F,   // 8
    0x6F    // 9
};

uint8_t char_table[26] = {
    0x77,   // A
    0x7C,   // B
    0x39,   // C
    0x5E,   // D
    0x79,   // E
    0x71,   // F
    // remaining letters
};

3. 定义显示函数

我们需要定义一个显示函数,用于在数码管上显示数字或字符。在main.c文件中添加以下代码:

void displayNumber(uint8_t number)
{
    /* 数码管的位选择,每次只有一个位为低电平 */
    HAL_GPIO_WritePin(LED_COM1_GPIO_Port, LED_COM1_Pin, GPIO_PIN_SET);
    HAL_GPIO_WritePin(LED_COM2_GPIO_Port, LED_COM2_Pin, GPIO_PIN_SET);
    HAL_GPIO_WritePin(LED_COM3_GPIO_Port, LED_COM3_Pin, GPIO_PIN_SET);
    HAL_GPIO_WritePin(LED_COM4_GPIO_Port, LED_COM4_Pin, GPIO_PIN_SET);

    /* 根据输入的数字,在对应的位上设置为低电平 */
    switch(number)
    {
        case 1:
            HAL_GPIO_WritePin(LED_COM1_GPIO_Port, LED_COM1_Pin, GPIO_PIN_RESET);
            break;
        case 2:
            HAL_GPIO_WritePin(LED_COM2_GPIO_Port, LED_COM2_Pin, GPIO_PIN_RESET);
            break;
        case 3:
            HAL_GPIO_WritePin(LED_COM3_GPIO_Port, LED_COM3_Pin, GPIO_PIN_RESET);
            break;
        case 4:
            HAL_GPIO_WritePin(LED_COM4_GPIO_Port, LED_COM4_Pin, GPIO_PIN_RESET);
            break;
    }
}

4. 定义主函数和显示循环

最后,我们需要在main函数中创建一个显示循环,在其中不断刷新要显示的数字。在main.c文件中添加以下代码:

int main(void)
{
    HAL_Init();
    SystemClock_Config();
    GPIO_Init();

    uint8_t digit = 0;

    while (1)
    {
        /* 在数码管上显示数字 */
        displayNumber(num_table[digit]);

        /* 延迟一段时间 */
        HAL_Delay(1000);

        /* 切换到下一个数字 */
        digit++;
        if(digit > 9)
        {
            digit = 0;
        }
    }
}

编译和烧录

  1. 点击“Project”->“Build All”编译代码。
  2. 将STM32开发板与电脑连接,并通过ST-Link将代码烧录到STM32中。
  3. 点击“Run”->“Debug”进行调试。

结果

现在,当你启动STM32开发板时,你应该能够看到数码管上不断切换显示数字0-9的功能。

这只是一个简单的示例程序,你可以根据需要进行修改和扩展,例如添加时钟功能、显示日期等。

希望这个示例能够帮助你开始使用STM32制作数字时钟!

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实现一个基于STM32简易数字频率计需要以下步骤: 1.选择合适的STM32单片机,并配置好开发环境,比如Keil或者IAR。 2.接入输入信号,可以用一个信号发生器作为输入信号源,也可以用一个普通的信号发生器加上一个输入电路。 3.编写程序,首先需要配置定时器,选择合适的计数模式,并设置计数器溢出中断。 4.在计数器溢出中断服务函数中,记录计数器的值,并清零计数器。 5.计算输入信号的频率,可以用一个计算公式,例如:频率=计数器值*计数器时钟频率/输入信号周期。 6.将计算出的频率显示在LCD等输出设备上。 7.调试程序,测试功能是否正常,优化程序性能。 参考代码如下: ``` #include "stm32f10x.h" #include "lcd.h" #define TIMER_CLK_FREQ 72000000 // 定时器时钟频率 #define INPUT_FREQ_MAX 100000 // 输入信号最大频率 #define TIMER_PERIOD 0xFFFF // 定时器周期 volatile uint32_t counter; // 计数器值 void TIM2_IRQHandler(void) { if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) { counter = TIM_GetCounter(TIM2); // 记录计数器值 TIM_SetCounter(TIM2, 0); // 清零计数器 TIM_ClearITPendingBit(TIM2, TIM_IT_Update); } } int main(void) { SystemInit(); LCD_Init(); LCD_Clear(); RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); // 使能TIM2时钟 TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_TimeBaseStructure.TIM_Period = TIMER_PERIOD; TIM_TimeBaseStructure.TIM_Prescaler = 0; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); TIM_Cmd(TIM2, ENABLE); TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE); NVIC_InitTypeDef NVIC_InitStructure; NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); while (1) { uint32_t freq = counter * TIMER_CLK_FREQ / INPUT_FREQ_MAX; LCD_GotoXY(0, 0); LCD_Printf("Freq: %lu Hz ", freq); } } ``` 此代码使用STM32的TIM2定时器实现计数功能,输入信号的最大频率为100kHz,计算出的频率值通过LCD显示。当输入信号频率超过100kHz时,计数器会溢出,导致计算出的频率值不准确。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值