STM32F767控制7位数码管0-9-a-f显示

实验设计电路

  1. 数码管连接:

    在这里插入图片描述

    • 5161AS 通常是共阴极数码管。共阴极数码管是指将所有数码管的阴极(一般是小段的负极)连接在一起接地。当给特定的阳极(小段的正极)施加高电平的时候,对应的小段就会发光。

    • 段选引脚连接:使用共阴极数码管,数码管的段选引脚(通常标记为 a - g 以及可能有的小数点 dp)连接到 STM32F767 开发板的 GPIOA 的 0 - 7 引脚。即 a 段对应 GPIOA Pin 0b 段对应 GPIOA Pin 1,以此类推,直到 g 段对应 GPIOA Pin 7。这样可以通过控制这些引脚的电平来输出不同的段码,进而显示出相应的数字或字符(0 - 9、A - F)。

    • 电源连接:共阴极数码管的公共阴极引脚需要接地,保证数码管能正常工作,由开发板通过 GPIOA 引脚输出的电平来控制各段的亮灭从而实现显示功能。其电源部分(一般为 5V 供电,具体取决于数码管规格要求,这里假设开发板能提供合适的电源来驱动数码管)为数码管提供必要的电能,以点亮内部的发光二极管段。

  2. 系统供电
    通过 USB 接口或者电源适配器为 STM32F767 开发板提供电源,开发板内部的电源电路会将输入的电源进行相应的转换和稳压等处理,为芯片以及连接的外部设备(如数码管)提供稳定合适的工作电压,例如为 GPIO 引脚输出提供 3.3V 的电平参考等。

工作原理

  1. 数码管显示原理:
    • 初始化部分:在 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 - 9A - F)时,就将 index 重新置为 0,实现循环显示段码表中的字符内容。

引脚使用

  1. GPIOA 引脚(用于数码管段选):

    • GPIOA Pin 0 - GPIOA Pin 7:被配置为输出模式,用于输出数码管段码对应的电平信号,以控制数码管各段(a - g)的亮灭,从而显示出不同的数字或字符。

      例如,当要显示数字 “0” 时,按照 seg_code 段码表中 0 对应的 0x3F(二进制 0011 1111),会将 GPIOA Pin 0GPIOA Pin 1GPIOA Pin 2GPIOA Pin 3GPIOA Pin 4GPIOA Pin 5 这几个引脚设置为高电平,GPIOA Pin 6GPIOA Pin 7 设置为低电平,使数码管对应的段点亮,呈现出数字 “0” 的显示效果。

  2. 系统相关引脚(时钟配置等内部使用)
    SystemClock_Config 函数中,涉及到对一些与时钟配置相关的内部引脚及寄存器的操作(虽然代码中没有直接体现出具体引脚操作,但底层硬件是通过这些来实现时钟源选择、分频等功能的),比如配置 HSE 相关引脚作为外部时钟输入引脚,以及内部的 PLL 相关电路连接的引脚等,这些引脚按照设定的参数(如 PLL 的各个分频因子)来协同工作,实现最终的系统时钟生成与分配到不同总线(AHBAPB1APB2)上,为整个系统以及 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**********************/

需要完整工程可以私信我

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值