在Protues原理图中放置四位动态显示共阳极数码管7SEG-MPX4-CA,先后两次按下矩阵键盘中数字键,让十位和个位的数码管分别显示十进制十位数和个位数,而千位和百位的数码管一直显示0,按下字符F键,把十位和个位的数码管都熄灭,如果再次按下两个数字键,则数码管再次显示两位十进制数。写出stm32代码
时间: 2024-02-17 17:00:04 浏览: 361
以下是大致的STM32代码实现思路:
```c
#include "stm32f10x.h"
#define ROW1 GPIO_Pin_0
#define ROW2 GPIO_Pin_1
#define ROW3 GPIO_Pin_2
#define ROW4 GPIO_Pin_3
#define COLUMN1 GPIO_Pin_4
#define COLUMN2 GPIO_Pin_5
#define COLUMN3 GPIO_Pin_6
#define COLUMN4 GPIO_Pin_7
#define DIGIT1 GPIO_Pin_8
#define DIGIT2 GPIO_Pin_9
#define DIGIT3 GPIO_Pin_10
#define DIGIT4 GPIO_Pin_11
uint8_t digit[4] = {0, 0, 0, 0}; // 数码管显示的四位数字
uint8_t key = 0; // 键盘输入值
uint8_t key_flag = 0; // 键盘输入标志
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB, ENABLE);
// 数码管显示引脚配置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Pin = DIGIT1 | DIGIT2 | DIGIT3 | DIGIT4;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_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;
GPIO_Init(GPIOB, &GPIO_InitStructure);
// 矩阵键盘引脚配置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Pin = ROW1 | ROW2 | ROW3 | ROW4;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Pin = COLUMN1 | COLUMN2 | COLUMN3 | COLUMN4;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
void TIM_Configuration(void)
{
TIM_TimeBaseInitTypeDef TIM_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
TIM_InitStructure.TIM_Period = 2000 - 1; // 数码管显示周期为2ms
TIM_InitStructure.TIM_Prescaler = 72 - 1; // 定时器预分频为72,定时器时钟为1MHz
TIM_InitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_InitStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM2, &TIM_InitStructure);
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
TIM_Cmd(TIM2, ENABLE);
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
void TIM2_IRQHandler(void)
{
static uint8_t digit_index = 0;
static uint16_t digit_count = 0;
static uint8_t scan_row = 0;
// 数码管显示
GPIOB->ODR &= ~(ROW1 | ROW2 | ROW3 | ROW4);
GPIOB->ODR |= (1 << scan_row);
GPIOB->ODR &= ~(COLUMN1 | COLUMN2 | COLUMN3 | COLUMN4);
GPIOB->ODR |= (digit[digit_index] << 4);
digit_index++;
if (digit_index >= 4)
{
digit_index = 0;
}
digit_count++;
if (digit_count >= 500) // 数码管显示周期2ms*500=1s
{
digit_count = 0;
if (key_flag) // 如果有键盘输入
{
if (key >= '0' && key <= '9') // 如果是数字键
{
digit[0] = digit[1];
digit[1] = key - '0';
}
else if (key == 'F') // 如果是字符F键
{
digit[0] = 0;
digit[1] = 0;
}
key_flag = 0; // 清除键盘输入标志
}
}
scan_row++;
if (scan_row >= 4)
{
scan_row = 0;
}
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
}
void EXTI9_5_IRQHandler(void)
{
if (EXTI_GetITStatus(EXTI_Line5) != RESET)
{
key = '1';
key_flag = 1;
EXTI_ClearITPendingBit(EXTI_Line5);
}
}
void EXTI15_10_IRQHandler(void)
{
if (EXTI_GetITStatus(EXTI_Line11) != RESET)
{
key = '2';
key_flag = 1;
EXTI_ClearITPendingBit(EXTI_Line11);
}
}
int main(void)
{
GPIO_Configuration();
TIM_Configuration();
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource5);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource11);
EXTI_InitTypeDef EXTI_InitStructure;
EXTI_InitStructure.EXTI_Line = EXTI_Line5;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
EXTI_InitStructure.EXTI_Line = EXTI_Line11;
EXTI_Init(&EXTI_InitStructure);
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;
NVIC_Init(&NVIC_InitStructure);
while (1);
}
```
需要注意的是,以上代码只是一个大致的思路,具体实现还需要进行调试和优化。
阅读全文