以下是一个使用STM32制作简易数字时钟的示例代码,以及详细的解释。
硬件准备
- STM32开发板(本例使用STM32F103C8T6)
- 七段数码管模块(本例使用共阳极的4位数码管)
- 杜邦线若干
硬件连接
将数码管模块连接到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引脚上。
软件准备
- STM32CubeIDE:用于编写、调试和烧录STM32的开发环境。
- STM32Cube HAL库:提供对STM32外设的API接口。
创建工程
- 打开STM32CubeIDE,选择“File”->“New”->“STM32 Project”创建一个新的工程。
- 选择适合你的STM32型号和硬件平台。
- 选择一个合适的C编译器(通常为GNU ARM GCC)。
- 选择一个合适的调试器(通常为ST-Link)。
- 选择“基于Nothing生成”的配置项。
- 设置工程的名字和存放路径。
- 点击“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;
}
}
}
编译和烧录
- 点击“Project”->“Build All”编译代码。
- 将STM32开发板与电脑连接,并通过ST-Link将代码烧录到STM32中。
- 点击“Run”->“Debug”进行调试。
结果
现在,当你启动STM32开发板时,你应该能够看到数码管上不断切换显示数字0-9的功能。
这只是一个简单的示例程序,你可以根据需要进行修改和扩展,例如添加时钟功能、显示日期等。
希望这个示例能够帮助你开始使用STM32制作数字时钟!