实验设计电路
-
数码管连接:
-
5161AS 通常是共阴极数码管。共阴极数码管是指将所有数码管的阴极(一般是小段的负极)连接在一起接地。当给特定的阳极(小段的正极)施加高电平的时候,对应的小段就会发光。
-
段选引脚连接:使用共阴极数码管,数码管的段选引脚(通常标记为
a - g
以及可能有的小数点dp
)连接到STM32F767
开发板的GPIOA
的 0 - 7 引脚。即a
段对应GPIOA Pin 0
,b
段对应GPIOA Pin 1
,以此类推,直到g
段对应GPIOA Pin 7
。这样可以通过控制这些引脚的电平来输出不同的段码,进而显示出相应的数字或字符(0 - 9、A - F)。 -
电源连接:共阴极数码管的公共阴极引脚需要接地,保证数码管能正常工作,由开发板通过
GPIOA
引脚输出的电平来控制各段的亮灭从而实现显示功能。其电源部分(一般为 5V 供电,具体取决于数码管规格要求,这里假设开发板能提供合适的电源来驱动数码管)为数码管提供必要的电能,以点亮内部的发光二极管段。
-
-
系统供电:
通过USB
接口或者电源适配器为STM32F767
开发板提供电源,开发板内部的电源电路会将输入的电源进行相应的转换和稳压等处理,为芯片以及连接的外部设备(如数码管)提供稳定合适的工作电压,例如为GPIO
引脚输出提供3.3V
的电平参考等。
工作原理
- 数码管显示原理:
- 初始化部分:在
main
函数里,先是调用__HAL_RCC_GPIOA_CLK_ENABLE
函数使能GPIOA
的时钟,接着配置GPIOA
的 0 - 7 引脚为推挽输出模式(GPIO_MODE_OUTPUT_PP
),无上拉或下拉电阻(GPIO_NOPULL
),输出速度为低速(GPIO_SPEED_FREQ_LOW
),以便后续能向数码管的段选引脚输出高低电平信号。 - 显示循环部分:在
while(1)
无限循环中,每次循环先通过HAL_GPIO_WritePin
函数将GPIOA
的 0 - 7 引脚全部置低电平(GPIO_PIN_RESET
),这样做是为了防止数码管显示出现残影等异常情况。然后根据变量index
的值从seg_code
段码表中取出对应的段码值(比如index
为 0 时,取出0x3F
,对应数码管显示数字 “0” 的段码),再通过HAL_GPIO_WritePin
函数将该段码值输出到GPIOA
的相应引脚(也就是数码管的段选引脚),实现对应的数字或字符显示。之后使用HAL_Delay(1000)
函数进行1
秒的延时,方便肉眼观察显示效果,接着将index
变量自增1
,准备显示下一个字符。当index
的值大于15
(因为段码表中定义了16
个值,对应0 - 9
、A - F
)时,就将index
重新置为0
,实现循环显示段码表中的字符内容。
- 初始化部分:在
引脚使用
-
GPIOA 引脚(用于数码管段选):
-
GPIOA Pin 0 - GPIOA Pin 7
:被配置为输出模式,用于输出数码管段码对应的电平信号,以控制数码管各段(a - g
等)的亮灭,从而显示出不同的数字或字符。例如,当要显示数字 “0” 时,按照
seg_code
段码表中0
对应的0x3F
(二进制0011 1111
),会将GPIOA Pin 0
、GPIOA Pin 1
、GPIOA Pin 2
、GPIOA Pin 3
、GPIOA Pin 4
、GPIOA Pin 5
这几个引脚设置为高电平,GPIOA Pin 6
、GPIOA Pin 7
设置为低电平,使数码管对应的段点亮,呈现出数字 “0” 的显示效果。
-
-
系统相关引脚(时钟配置等内部使用):
在SystemClock_Config
函数中,涉及到对一些与时钟配置相关的内部引脚及寄存器的操作(虽然代码中没有直接体现出具体引脚操作,但底层硬件是通过这些来实现时钟源选择、分频等功能的),比如配置HSE
相关引脚作为外部时钟输入引脚,以及内部的PLL
相关电路连接的引脚等,这些引脚按照设定的参数(如PLL
的各个分频因子)来协同工作,实现最终的系统时钟生成与分配到不同总线(AHB
、APB1
、APB2
)上,为整个系统以及GPIO
等外设的正常工作提供稳定且合适的时钟信号。
完整代码
#include "stm32f7xx.h"
#include "main.h"
#include "./led/bsp_led.h"
// 共阴极数码管段码表,顺序为0-9、A-F
const uint8_t seg_code[16] = {
0x3F, // 0
0x06, // 1
0x5B, // 2
0x4F, // 3
0x66, // 4
0x6D, // 5
0x7D, // 6
0x07, // 7
0x7F, // 8
0x6F, // 9
0x77, // A
0x7C, // B
0x39, // C
0x5E, // D
0x79, // E
0x71 // F
};
GPIO_InitTypeDef GPIO_InitStruct = {0};
// 新增一个全局变量,用于指定数码管连接的GPIO端口,初始化为GPIOA,方便后续修改
int main(void)
{
/* 系统时钟初始化成216 MHz */
SystemClock_Config();
/* LED 端口初始化 */
LED_GPIO_Config();
// 使能GPIOA时钟
__HAL_RCC_GPIOA_CLK_ENABLE();
// 配置PA0 - PA7为输出模式
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
// 熄灭红绿蓝灯
LED1_OFF;
LED2_OFF;
LED3_OFF;
uint8_t index = 0; // 用于索引段码表的变量
while (1)
{
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7, GPIO_PIN_RESET); // 先将所有引脚置低电平,防止残影
HAL_GPIO_WritePin(GPIOA, seg_code[index], GPIO_PIN_SET); // 根据索引输出对应的段码值到GPIO引脚
HAL_Delay(1000); // 延时1秒,方便观察显示效果
index++; // 索引加1,准备显示下一个字符
if (index > 15) { // 如果索引超出了段码表范围(0-15对应0-9、A-F),则重新从0开始
index = 0;;
}
}
}
/**
* @brief System Clock 配置
* system Clock 配置如下 :
* System Clock source = PLL (HSE)
* SYSCLK(Hz) = 216000000
* HCLK(Hz) = 216000000
* AHB Prescaler = 1
* APB1 Prescaler = 4
* APB2 Prescaler = 2
* HSE Frequency(Hz) = 25000000
* PLL_M = 25
* PLL_N = 432
* PLL_P = 2
* PLL_Q = 9
* VDD(V) = 3.3
* Main regulator output voltage = Scale1 mode
* Flash Latency(WS) = 7
* @param 无
* @retval 无
*/
void SystemClock_Config(void)
{
RCC_ClkInitTypeDef RCC_ClkInitStruct;
RCC_OscInitTypeDef RCC_OscInitStruct;
HAL_StatusTypeDef ret = HAL_OK;
/* 使能HSE,配置HSE为PLL的时钟源,配置PLL的各种分频因子M N P Q
* PLLCLK = HSE/M*N/P = 25M / 25 *432 / 2 = 216M
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLM = 25;
RCC_OscInitStruct.PLL.PLLN = 432;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = 9;
ret = HAL_RCC_OscConfig(&RCC_OscInitStruct);
if(ret != HAL_OK)
{
while(1) { ; }
}
/* 激活 OverDrive 模式以达到216M频率 */
ret = HAL_PWREx_EnableOverDrive();
if(ret != HAL_OK)
{
while(1) { ; }
}
/* 选择PLLCLK作为SYSCLK,并配置 HCLK, PCLK1 and PCLK2 的时钟分频因子
* SYSCLK = PLLCLK = 216M
* HCLK = SYSCLK / 1 = 216M
* PCLK2 = SYSCLK / 2 = 108M
* PCLK1 = SYSCLK / 4 = 54M
*/
RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
/* 在HAL_RCC_ClockConfig函数里面同时初始化好了系统定时器systick,配置为1ms中断一次 */
ret = HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_7);
if(ret != HAL_OK)
{
while(1) { ; }
}
}
/*********************************************END OF FILE**********************/
需要完整工程可以私信我