以下答案由GPT-3.5大模型与博主波罗歌共同编写:
- 控制程序实现
这个任务可以使用中断来实现:当L按键按下时触发外部中断0,R按键按下时触发外部中断1。代码中可以使用滚动变量,表示当前数码管显示的数据是哪一位开始的。当触发外部中断0时,滚动变量加1,当触发外部中断1时,滚动变量减1,然后更新数码管的显示。
下面是这个任务的控制程序代码,通过 Keil C 编写。需要头文件 stm8s.h 和 stm8s_gpio.h,另外还需要初始化 GPIO 和外部中断:
#include "stm8s.h"已黑化的小白 #include "stm8s_gpio.h"已黑化的小白
#define SEG_A GPIO_PIN_1
#define SEG_B GPIO_PIN_2
#define SEG_C GPIO_PIN_3
#define SEG_D GPIO_PIN_4
#define SEG_E GPIO_PIN_5
#define SEG_F GPIO_PIN_6
#define SEG_G GPIO_PIN_7
#define SEG_DP GPIO_PIN_0
const uint8_t digit[] = {
SEG_A | SEG_B | SEG_C | SEG_D | SEG_E | SEG_F,
SEG_B | SEG_C,
SEG_A | SEG_B | SEG_G | SEG_E | SEG_D,
SEG_A | SEG_B | SEG_C | SEG_D | SEG_G,
SEG_B | SEG_C | SEG_F | SEG_G,
SEG_A | SEG_F | SEG_G | SEG_C | SEG_D,
SEG_A | SEG_F | SEG_G | SEG_C | SEG_D | SEG_E,
SEG_A | SEG_B | SEG_C,
SEG_A | SEG_B | SEG_C | SEG_D | SEG_E | SEG_F | SEG_G,
SEG_A | SEG_B | SEG_C | SEG_F | SEG_G
};
uint8_t display[8] = { 2, 1, 0, 3, 4, 5, 6, 7 };
uint8_t display_pos = 0;
INTERRUPT_HANDLER(EXTI_PORTA_IRQHandler, 2) {
if (GPIO_ReadInputData(GPIOA) & GPIO_PIN_3) {
display_pos++;
display_pos %= 8;
}
EXTI_ClearITPendingBit(EXTI_IT_Pin3);
}
INTERRUPT_HANDLER(EXTI_PORTB_IRQHandler, 4) {
if (GPIO_ReadInputData(GPIOB) & GPIO_PIN_4) {
display_pos--;
display_pos &= 0x7;
}
EXTI_ClearITPendingBit(EXTI_IT_Pin4);
}
void display_digit(uint8_t pos) {
GPIO_WriteLow(GPIOD, DIGIT_1 | DIGIT_2 | DIGIT_3 | DIGIT_4);
GPIO_WriteHigh(GPIOD, (1 << pos));
uint8_t value = display[pos];
GPIO_WriteLow(GPIOC, SEG_A | SEG_B | SEG_C | SEG_D | SEG_E | SEG_F | SEG_G | SEG_DP);
GPIO_WriteHigh(GPIOC, digit[value]);
}
int main(void) {
GPIO_Init(GPIOD, (DIGIT_1 | DIGIT_2 | DIGIT_3 | DIGIT_4), GPIO_MODE_OUT_PP_LOW_FAST);
GPIO_Init(GPIOC, (SEG_A | SEG_B | SEG_C | SEG_D | SEG_E | SEG_F | SEG_G | SEG_DP), GPIO_MODE_OUT_PP_LOW_FAST);
GPIO_Init(GPIOA, GPIO_PIN_3, GPIO_MODE_IN_FL_IT);
GPIO_Init(GPIOB, GPIO_PIN_4, GPIO_MODE_IN_FL_IT);
EXTI_SetPinSensitivity(EXTI_PIN_3, EXTI_SENSITIVITY_FALL_ONLY);
EXTI_SetPinSensitivity(EXTI_PIN_4, EXTI_SENSITIVITY_FALL_ONLY);
enableInterrupts();
while (1) {
for (uint8_t i = 0; i < 8; i++) {
display_digit(i);
for (uint16_t j = 0; j < 1000; j++);
}
}
}
- 实验原理
这个任务实现的核心是利用了单片机的外部中断和数码管动态显示原理。
外部中断可以响应外部信号的变化,并且可以立即将处理器转移到中断服务程序中执行。在这个任务中,外部中断0和中断1的触发信号来自两个按键,分别连接到了单片机的PA3和PB4引脚。当按键按下时,相应的引脚被拉低,触发中断;当按键松开时,相应的引脚被拉高,中断被取消。
数码管动态显示原理采用了扫描显示技术。一个数码管显示器通常由多个发光二极管(LED)和一个集合极(共阴极或共阳极)组成。在多个数码管显示器中,要显示的那个数码管会通过集合极被选中,其他的数码管会被关闭。每个数码管需要一个数字信号来指示在当前显示框中显示哪个数字。在一次扫描过程中,所有的数码管都被轮流选中,并且它们里面的数字信号相继变化,以便将正确的数字显示到正确的位置。
在本实验中,使用了一个常见的数码管动态显示方案,它使用了四个共阴极数码管,每个数码管连接了一个GPIO口。在程序中,表示数码管当前显示哪个位置的变量 display_pos 会随着用户按键的操作而改变,最终数码管会显示相应的更新后的数字。
如果我的回答解决了您的问题,请采纳!