#include <reg52.h>
// 数码管段码口 (a b c d e f g dp) -- 共阴极
#define SMG_A_DP_PORT P0
// 数码管位选口 (D1 D2 D3 D4 D5 D6 D7 D8)
sbit LSA = P2^2;
sbit LSB = P2^3;
sbit LSC = P2^4;
// 按键定义 -- *** 按键功能已根据最新要求修改 ***
sbit KEY3 = P3^2; // 从机模式触发键 (原为K4主机,后改为K3主机,现改为K3从机)
sbit KEY4 = P3^3; // 主机模式触发键 (原为K3从机,后改为K4从机,现改为K4主机)
// 定义状态
#define MODE_IDLE 0
#define MODE_MASTER_PENDING_SEND 1 // K4按下,准备发送
#define MODE_MASTER_WAITING_ACK 2 // K4按下,已发送,等待从机应答
#define MODE_MASTER_RESULT_DISPLAY 3 // K4按下,显示发送结果
#define MODE_SLAVE_LISTENING 4 // K3按下,等待接收数据
#define MODE_SLAVE_ERROR_DISPLAY 5 // K3按下,接收到错误数据
#define MASTER_SEND_DATA 0x5A
#define SLAVE_ACK_DATA 0xA5
#define TIMEOUT_LIMIT 200
// 数码管显示缓冲区
unsigned char DisplayBuffer[8] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
// 共阴极数码管段码表
unsigned char SmgTable[] = {
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*/ 0x40, /*-*/ 0x0E, /*J*/
0x38, /*L*/ 0x3F, /*O*/ 0x50, /*r*/ 0x73, /*P*/ 0x76, /*H*/ 0x3E, /*U*/
0x00, /*空白*/0x80 /*.*/
};
#define SMG_0 0
#define SMG_1 1
#define SMG_6 6
#define SMG_C 12
#define SMG_F 15
#define SMG_J 17
#define SMG_L 18
#define SMG_O 19
#define SMG_HYPHEN 16
#define SMG_BLANK 23
#define TIMER0_RELOAD_HIGH (unsigned char)((65536 - 921) >> 8)
#define TIMER0_RELOAD_LOW (unsigned char)((65536 - 921) & 0xFF)
unsigned char current_mode = MODE_IDLE;
unsigned char last_mode = MODE_IDLE;
unsigned char uart_receive_data;
bit uart_receive_flag = 0;
bit master_send_success_flag = 0;
unsigned int timeout_counter = 0;
void UartInit();
void UartSendByte(unsigned char dat);
void Timer0Init();
void UpdateDisplayForMode();
unsigned char KeyScan();
void delay_ms(unsigned int ms);
void delay_ms(unsigned int ms) {
unsigned int i, j;
for (i = ms; i > 0; i--)
for (j = 110; j > 0; j--);
}
void SmgSelect(unsigned char pos) {
switch (pos) {
case 0: LSC=0; LSB=0; LSA=0; break;
case 1: LSC=0; LSB=0; LSA=1; break;
case 2: LSC=0; LSB=1; LSA=0; break;
case 3: LSC=0; LSB=1; LSA=1; break;
case 4: LSC=1; LSB=0; LSA=0; break;
case 5: LSC=1; LSB=0; LSA=1; break;
case 6: LSC=1; LSB=1; LSA=0; break;
case 7: LSC=1; LSB=1; LSA=1; break;
}
}
void SmgDisplay() {
static unsigned char i = 0;
SMG_A_DP_PORT = 0xFF;
SmgSelect(i);
SMG_A_DP_PORT = DisplayBuffer[7-i]; // 保持反向索引以修正显示顺序
i++;
if (i >= 8) i = 0;
}
void UartInit() {
SCON = 0x50;
TMOD = (TMOD & 0x0F) | 0x20;
TH1 = 0xFD;
TL1 = 0xFD;
TR1 = 1;
ES = 1;
}
void UartSendByte(unsigned char dat) {
SBUF = dat;
while (!TI);
TI = 0;
}
void UpdateDisplayForMode() {
unsigned char i;
for(i=0; i<8; i++) {
DisplayBuffer[i] = SmgTable[SMG_BLANK];
}
switch (current_mode) {
case MODE_IDLE: // K4 主机模式相关显示
DisplayBuffer[0] = SmgTable[SMG_HYPHEN];
DisplayBuffer[1] = SmgTable[SMG_HYPHEN];
DisplayBuffer[2] = SmgTable[SMG_HYPHEN];
DisplayBuffer[3] = SmgTable[SMG_HYPHEN];
break;
case MODE_MASTER_PENDING_SEND: // K4 主机
case MODE_MASTER_WAITING_ACK: // K4 主机
DisplayBuffer[0] = SmgTable[SMG_C];
DisplayBuffer[1] = SmgTable[SMG_HYPHEN];
DisplayBuffer[2] = SmgTable[SMG_0];
DisplayBuffer[3] = SmgTable[SMG_6];
break;
case MODE_MASTER_RESULT_DISPLAY: // K4 主机
DisplayBuffer[0] = SmgTable[SMG_C];
DisplayBuffer[1] = SmgTable[SMG_HYPHEN];
DisplayBuffer[2] = SmgTable[SMG_0];
DisplayBuffer[3] = SmgTable[SMG_6];
if (master_send_success_flag) {
DisplayBuffer[6] = SmgTable[SMG_O];
DisplayBuffer[7] = SmgTable[SMG_L];
} else {
DisplayBuffer[6] = SmgTable[SMG_F];
DisplayBuffer[7] = SmgTable[SMG_L];
}
break;
case MODE_SLAVE_LISTENING: // K3 从机模式相关显示
DisplayBuffer[0] = SmgTable[SMG_J];
DisplayBuffer[1] = SmgTable[SMG_HYPHEN];
DisplayBuffer[2] = SmgTable[SMG_0];
DisplayBuffer[3] = SmgTable[SMG_1];
break;
case MODE_SLAVE_ERROR_DISPLAY: // K3 从机
DisplayBuffer[0] = SmgTable[SMG_J];
DisplayBuffer[1] = SmgTable[SMG_HYPHEN];
DisplayBuffer[6] = SmgTable[SMG_0];
DisplayBuffer[7] = SmgTable[SMG_6];
break;
default:
break;
}
}
unsigned char KeyScan() {
unsigned char keyValue = 0;
// 注意:KEY3现在是从机,KEY4是主机
if (KEY3 == 0) { // K3 (从机)
delay_ms(20);
if (KEY3 == 0) {
keyValue = 3;
while (KEY3 == 0);
}
} else if (KEY4 == 0) { // K4 (主机)
delay_ms(20);
if (KEY4 == 0) {
keyValue = 4;
while (KEY4 == 0);
}
}
return keyValue;
}
void Timer0_ISR() interrupt 1 {
TH0 = TIMER0_RELOAD_HIGH;
TL0 = TIMER0_RELOAD_LOW;
SmgDisplay();
}
void Uart_ISR() interrupt 4 {
if (RI) {
RI = 0;
uart_receive_data = SBUF;
uart_receive_flag = 1;
}
}
void Timer0Init() {
TMOD = (TMOD & 0xF0) | 0x01;
TH0 = TIMER0_RELOAD_HIGH;
TL0 = TIMER0_RELOAD_LOW;
ET0 = 1;
TR0 = 1;
}
void main() {
unsigned char key_pressed;
EA = 0;
Timer0Init();
UartInit();
current_mode = MODE_IDLE;
UpdateDisplayForMode();
EA = 1;
while (1) {
key_pressed = KeyScan();
last_mode = current_mode;
// *** 修改点:根据最新要求调整按键对应的模式 ***
if (key_pressed == 3) { // K3 按下 -> 从机模式
current_mode = MODE_SLAVE_LISTENING;
} else if (key_pressed == 4) { // K4 按下 -> 主机模式
current_mode = MODE_MASTER_PENDING_SEND;
}
if (last_mode != current_mode) {
uart_receive_flag = 0;
master_send_success_flag = 0;
timeout_counter = 0;
if(RI) {
uart_receive_data = SBUF;
RI = 0;
}
UpdateDisplayForMode();
}
switch (current_mode) {
// 主机模式 (由K4触发)
case MODE_MASTER_PENDING_SEND:
UartSendByte(MASTER_SEND_DATA);
uart_receive_flag = 0;
timeout_counter = 0;
current_mode = MODE_MASTER_WAITING_ACK;
break;
case MODE_MASTER_WAITING_ACK:
if (uart_receive_flag) {
uart_receive_flag = 0;
if (uart_receive_data == SLAVE_ACK_DATA) {
master_send_success_flag = 1;
} else {
master_send_success_flag = 0;
}
current_mode = MODE_MASTER_RESULT_DISPLAY;
UpdateDisplayForMode();
} else if (timeout_counter >= TIMEOUT_LIMIT) {
master_send_success_flag = 0;
current_mode = MODE_MASTER_RESULT_DISPLAY;
UpdateDisplayForMode();
} else {
timeout_counter++;
}
break;
case MODE_MASTER_RESULT_DISPLAY:
break;
// 从机模式 (由K3触发)
case MODE_SLAVE_LISTENING:
if (uart_receive_flag) {
uart_receive_flag = 0;
if (uart_receive_data == MASTER_SEND_DATA) {
UartSendByte(SLAVE_ACK_DATA);
} else {
current_mode = MODE_SLAVE_ERROR_DISPLAY;
UpdateDisplayForMode();
}
}
break;
case MODE_SLAVE_ERROR_DISPLAY:
break;
case MODE_IDLE:
default:
break;
}
delay_ms(1);
}
}
在我测试的过程中,发现数码管显示的是C-06UUFL,改良一下代码,使数码管正确显示C-06FL,而不是C-06UUFL
最新发布