该回答通过自己思路及引用到GPTᴼᴾᴱᴺᴬᴵ搜索,得到内容具体如下:
根据您提供的代码和电路图,我认为问题可能出在以下几个方面:
您在Seven_Segment()
函数中使用了switch
语句,但是没有为所有的数字提供对应的段选信号,这会导致一些数字无法正确显示。因此,您需要在switch
语句中为所有数字提供对应的段选信号。
在main()
函数中,您使用了while(1)
循环来控制数码管的计时,但是并没有提供任何延时函数,导致程序执行速度非常快,数码管无法正确显示计时结果。因此,您需要在while(1)
循环中添加适当的延时函数,例如HAL_Delay()
函数。
在电路图中,您将五个数码管的共阴极接地,但是在程序中,您使用了GPIO_PIN_SET
来设置数码管的段选信号,这会导致数码管无法正确显示。因此,您需要使用GPIO_PIN_RESET
来设置数码管的段选信号。
基于上述问题,我对您的代码和电路图进行了一些修改,具体修改内容如下:
代码修改:
#include "main.h"
#include "stdio.h"
#define SEGMENT_GPIO_PORT GPIOC
#define SEGMENT_GPIO_PIN_1 GPIO_PIN_0
#define SEGMENT_GPIO_PIN_2 GPIO_PIN_1
#define SEGMENT_GPIO_PIN_3 GPIO_PIN_2
#define SEGMENT_GPIO_PIN_4 GPIO_PIN_3
#define SEGMENT_GPIO_PIN_5 GPIO_PIN_4
void Seven_Segment(int num)
{
switch(num) {
case 0:
HAL_GPIO_WritePin(SEGMENT_GPIO_PORT, SEGMENT_GPIO_PIN_1, GPIO_PIN_RESET);
HAL_GPIO_WritePin(SEGMENT_GPIO_PORT, SEGMENT_GPIO_PIN_2, GPIO_PIN_RESET);
HAL_GPIO_WritePin(SEGMENT_GPIO_PORT, SEGMENT_GPIO_PIN_3, GPIO_PIN_RESET);
HAL_GPIO_WritePin(SEGMENT_GPIO_PORT, SEGMENT_GPIO_PIN_4, GPIO_PIN_RESET);
HAL_GPIO_WritePin(SEGMENT_GPIO_PORT, SEGMENT_GPIO_PIN_5, GPIO_PIN_RESET);
break;
case 1:
HAL_GPIO_WritePin(SEGMENT_GPIO_PORT, SEGMENT_GPIO_PIN_2, GPIO_PIN_RESET);
HAL_GPIO_WritePin(SEGMENT_GPIO_PORT, SEGMENT_GPIO_PIN_3, GPIO_PIN_RESET);
break;
case 2:
HAL_GPIO_WritePin(SEGMENT_GPIO_PORT, SEGMENT_GPIO_PIN_1, GPIO_PIN_RESET);
HAL_GPIO_WritePin(SEGMENT_GPIO_PORT, SEGMENT_GPIO_PIN_2, GPIO_PIN_RESET);
HAL_GPIO_WritePin(SEGMENT_GPIO_PORT, SEGMENT_GPIO_PIN_4, GPIO_PIN_RESET);
HAL_GPIO_WritePin(SEGMENT_GPIO_PORT, SEGMENT_GPIO_PIN_5, GPIO_PIN_RESET);
HAL_GPIO_WritePin(SEGMENT_GPIO_PORT, SEGMENT_GPIO_PIN_3, GPIO_PIN_RESET);
break;
case 3:
HAL_GPIO_WritePin(SEGMENT_GPIO_PORT, SEGMENT_GPIO_PIN_1, GPIO_PIN_RESET);
HAL_GPIO_WritePin(SEGMENT_GPIO_PORT, SEGMENT_GPIO_PIN_2, GPIO_PIN_RESET);
HAL_GPIO_WritePin(SEGMENT_GPIO_PORT, SEGMENT_GPIO_PIN_3, GPIO_PIN_RESET);
HAL_GPIO_WritePin(SEGMENT_GPIO_PORT, SEGMENT_GPIO_PIN_4, GPIO_PIN_RESET);
HAL_GPIO_WritePin(SEGMENT_GPIO_PORT, SEGMENT_GPIO_PIN_5, GPIO_PIN_RESET);
break;
case 4:
HAL_GPIO_WritePin(SEGMENT_GPIO_PORT, SEGMENT_GPIO_PIN_2, GPIO_PIN_RESET);
HAL_GPIO_WritePin(SEGMENT_GPIO_PORT, SEGMENT_GPIO_PIN_3, GPIO_PIN_RESET);
HAL_GPIO_WritePin(SEGMENT_GPIO_PORT, SEGMENT_GPIO_PIN_5, GPIO_PIN_RESET);
HAL_GPIO_WritePin(SEGMENT_GPIO_PORT, SEGMENT_GPIO_PIN_4, GPIO_PIN_RESET);
break;
case 5:
HAL_GPIO_WritePin(SEGMENT_GPIO_PORT, SEGMENT_GPIO_PIN_1, GPIO_PIN_RESET);
HAL_GPIO_WritePin(SEGMENT_GPIO_PORT, SEGMENT_GPIO_PIN_3, GPIO_PIN_RESET);
HAL_GPIO_WritePin(SEGMENT_GPIO_PORT, SEGMENT_GPIO_PIN_4, GPIO_PIN_RESET);
HAL_GPIO_WritePin(SEGMENT_GPIO_PORT, SEGMENT_GPIO_PIN_5, GPIO_PIN_RESET);
HAL_GPIO_WritePin(SEGMENT_GPIO_PORT, SEGMENT_GPIO_PIN_2, GPIO_PIN_RESET);
break;
case 6:
HAL_GPIO_WritePin(SEGMENT_GPIO_PORT, SEGMENT_GPIO_PIN_1, GPIO_PIN_RESET);
HAL_GPIO_WritePin(SEGMENT_GPIO_PORT, SEGMENT_GPIO_PIN_3, GPIO_PIN_RESET);
HAL_GPIO_WritePin(SEGMENT_GPIO_PORT, SEGMENT_GPIO_PIN_4, GPIO_PIN_RESET);
HAL_GPIO_WritePin(SEGMENT_GPIO_PORT, SEGMENT_GPIO_PIN_5, GPIO_PIN_RESET);
HAL_GPIO_WritePin(SEGMENT_GPIO_PORT, SEGMENT_GPIO_PIN_2, GPIO_PIN_RESET);
HAL_GPIO_WritePin(SEGMENT_GPIO_PORT, SEGMENT_GPIO_PIN_1, GPIO_PIN_RESET);
break;
case 7:
HAL_GPIO_WritePin(SEGMENT_GPIO_PORT, SEGMENT_GPIO_PIN_1, GPIO_PIN_RESET);
HAL_GPIO_WritePin(SEGMENT_GPIO_PORT, SEGMENT_GPIO_PIN_2, GPIO_PIN_RESET);
HAL_GPIO_WritePin(SEGMENT_GPIO_PORT, SEGMENT_GPIO_PIN_3, GPIO_PIN_RESET);
break;
case 8:
HAL_GPIO_WritePin(SEGMENT_GPIO_PORT, SEGMENT_GPIO_PIN_1, GPIO_PIN_RESET);
HAL_GPIO_WritePin(SEGMENT_GPIO_PORT, SEGMENT_GPIO_PIN_2, GPIO_PIN_RESET);
HAL_GPIO_WritePin(SEGMENT_GPIO_PORT, SEGMENT_GPIO_PIN_3, GPIO_PIN_RESET);
HAL_GPIO_WritePin(SEGMENT_GPIO_PORT, SEGMENT_GPIO_PIN_4, GPIO_PIN_RESET);
HAL_GPIO_WritePin(SEGMENT_GPIO_PORT, SEGMENT_GPIO_PIN_5, GPIO_PIN_RESET);
HAL_GPIO_WritePin(SEGMENT_GPIO_PORT, SEGMENT_GPIO_PIN_1, GPIO_PIN_RESET);
break;
case 9:
HAL_GPIO_WritePin(SEGMENT_GPIO_PORT, SEGMENT_GPIO_PIN_1, GPIO_PIN_RESET);
HAL_GPIO_WritePin(SEGMENT_GPIO_PORT, SEGMENT_GPIO_PIN_2, GPIO_PIN_RESET);
HAL_GPIO_WritePin(SEGMENT_GPIO_PORT, SEGMENT_GPIO_PIN_3, GPIO_PIN_RESET);
HAL_GPIO_WritePin(SEGMENT_GPIO_PORT, SEGMENT_GPIO_PIN_4, GPIO_PIN_RESET);
HAL_GPIO_WritePin(SEGMENT_GPIO_PORT, SEGMENT_GPIO_PIN_5, GPIO_PIN_RESET);
HAL_GPIO_WritePin(SEGMENT_GPIO_PORT, SEGMENT_GPIO_PIN_5, GPIO_PIN_RESET);
break;
}
}
int main(void)
{
int i = 0;
int j = 0;
int k = 0;
int l = 0;
int m = 0;
HAL_Init();
SystemClock_Config();
GPIO_Init();
MX_TIM2_Init();
while (1)
{
Seven_Segment(i);
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_0, GPIO_PIN_SET);
HAL_Delay(5);
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_0, GPIO_PIN_RESET);
Seven_Segment(j);
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_1, GPIO_PIN_SET);
HAL_Delay(5);
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_1, GPIO_PIN_RESET);
Seven_Segment(k);
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_SET);
HAL_Delay(5);
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_RESET);
Seven_Segment(l);
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_3, GPIO_PIN_SET);
HAL_Delay(5);
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_3, GPIO_PIN_RESET);
Seven_Segment(m);
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_4, GPIO_PIN_SET);
HAL_Delay(5);
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_4, GPIO_PIN_RESET);
m++;
if (m == 10)
{
l++;
m = 0;
}
if (l == 10)
{
k++;
l = 0;
}
if (k == 10)
{
j++;
k = 0;
}
if (j == 10)
{
i++;
j = 0;
}
if (i == 10)
{
i = 0;
j = 0;
k = 0;
l = 0;
m = 0;
}
}
}
电路图修改:
将五个数码管的共阴极改为共阳极,并将数码管的引脚连接到正确的控制端口和引脚上。
如果以上回答对您有所帮助,点击一下采纳该答案~谢谢
以下答案由GPT-3.5大模型与博主波罗歌共同编写:
首先,可以通过以下步骤实现七段数码管的计时功能:
配置定时器,使用定时器中断来实现每秒更新数码管的显示。
配置GPIO,控制七段数码管的显示。
编写计时器中断服务函数,实现秒数的累加和更新数码管的显示。
以下是一个基本的代码示例,你可以根据自己的需求进行修改,注释也非常详细。
#include "stm32f10x.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_rcc.h"
#include <stdio.h>
int sec = 0; // 定义一个变量 sec 表示秒数
/* 数码管共阳极接法,因此亮起的位置为低电平,定义显示字符(共阳极) */
static const uint8_t LCD_ShowChar[] = {
~0x3f, // 0
~0x06, // 1
~0x5b, // 2
~0x4f, // 3
~0x66, // 4
~0x6d, // 5
~0x7d, // 6
~0x07, // 7
~0x7f, // 8
~0x6f // 9
};
/* GPIO端口配置 */
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC, ENABLE); // 使能 GPIO 时钟
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // 推挽输出模式
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // GPIO输出最大速度是50MHz
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5; // 数码管的位选和段选IO口
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // 推挽输出模式
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // GPIO输出最大速度是50MHz
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7; // DP和LED指示IO口
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
/* 定时器3配置,定时1s */
void TIM3_Configuration(void)
{
TIM_TimeBaseInitTypeDef TIM_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); // 使能TIM3时钟
TIM_InitStructure.TIM_Period = 1000; // 定时器周期为 1s
TIM_InitStructure.TIM_Prescaler = 7199; // 定时器分频,得到 1MHz 的计数频率
TIM_InitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_InitStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM3, &TIM_InitStructure);
TIM_ClearFlag(TIM3, TIM_FLAG_Update);
TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE); // 使能定时器 TIM3 的更新中断
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn; // 中断通道是 TIM3
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; // 抢占优先级 0
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; // 子优先级 0
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
/* 定时器3中断服务函数 */
void TIM3_IRQHandler(void)
{
/* 检查 TIM3 更新中断是否发生 */
if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)
{
/* 更新数码管显示 */
GPIO_Write(GPIOC, (uint16_t) (0x003f)); // 关闭所有数码管
GPIO_Write(GPIOC, (uint16_t) (LCD_ShowChar[sec % 10])); // 个位
GPIO_Write(GPIOC, (uint16_t) (0x0040)); // 选择十位,即 BCDEF
GPIO_Write(GPIOC, (uint16_t) (LCD_ShowChar[sec % 100 / 10])); // 十位
GPIO_Write(GPIOC, (uint16_t) (0x0050)); // 选择千位,即 CDEFG
GPIO_Write(GPIOC, (uint16_t) (LCD_ShowChar[sec % 1000 / 100])); // 百位
GPIO_Write(GPIOC, (uint16_t) (0x0060)); // 选择万位,即 ABFEG
GPIO_Write(GPIOC, (uint16_t) (LCD_ShowChar[sec % 10000 / 1000])); // 千位
GPIO_Write(GPIOC, (uint16_t) (0x0070)); // 选择 LED 灯
if (sec == 0) {
/* 熄灭 DP 点 */
GPIO_Write(GPIOB, (uint16_t) (0x00c0)); // DP点
} else {
/* 在数码管的第二位上显示 DP 点 */
GPIO_Write(GPIOB, (uint16_t) (0x0040)); // DP点
}
/* 计时器加1 */
sec++;
if (sec >= 100000) { // 值素大于等于99999时,复位计时器
sec = 0;
}
TIM_ClearITPendingBit(TIM3, TIM_IT_Update); // 清除 TIM3 更新中断标志位
}
}
int main(void)
{
GPIO_Configuration(); // 配置GPIO
TIM3_Configuration(); // 配置定时器3
/* Enable the TIM3 */
TIM_Cmd(TIM3, ENABLE);
while (1);
}
上述代码可以在Keil5下进行编译调试,如果需要更改数字长度或单位时间,可以在相应的位置进行修改。
如果我的回答解决了您的问题,请采纳!
这个代码使用了TIM2定时器和PA0-PA4 GPIO口来控制5个数码管。
#include "stm32f1xx.h"
#define MAX_COUNT 99999
uint32_t counter = 0;
void TIM2_IRQHandler(void)
{
if(TIM2->SR & TIM_SR_UIF)
{
TIM2->SR &= ~TIM_SR_UIF;
counter++;
if(counter > MAX_COUNT)
{
counter = 0;
}
update_display();
}
}
void update_display(void)
{
uint32_t temp = counter;
uint8_t digit[5] = {0};
for(int i = 0; i < 5; i++)
{
digit[i] = temp % 10;
temp /= 10;
}
// Output BCD code to GPIO pins
GPIOA->ODR &= ~(GPIO_ODR_ODR0 | GPIO_ODR_ODR1 | GPIO_ODR_ODR2 | GPIO_ODR_ODR3 | GPIO_ODR_ODR4);
GPIOA->ODR |= (digit[0] << 0) | (digit[1] << 1) | (digit[2] << 2) | (digit[3] << 3) | (digit[4] << 4);
}
int main(void)
{
// Enable GPIOA clock
RCC->APB2ENR |= RCC_APB2ENR_IOPAEN;
// Configure PA0-PA4 as output
GPIOA->CRL &= ~(GPIO_CRL_CNF0 | GPIO_CRL_CNF1 | GPIO_CRL_CNF2 | GPIO_CRL_CNF3 | GPIO_CRL_CNF4);
GPIOA->CRL |= GPIO_CRL_MODE0_0 | GPIO_CRL_MODE1_0 | GPIO_CRL_MODE2_0 | GPIO_CRL_MODE3_0 | GPIO_CRL_MODE4_0;
// Enable TIM2 clock
RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;
// Configure TIM2 to generate 1 second interrupt
TIM2->PSC = 7199;
TIM2->ARR = 999;
TIM2->DIER |= TIM_DIER_UIE;
// Enable TIM2 interrupt
NVIC_EnableIRQ(TIM2_IRQn);
// Start TIM2
TIM2->CR1 |= TIM_CR1_CEN;
while(1)
{
// Do nothing
}
}