我用C语言为微 Controller 8051架构编写了程序,该程序从串行端口接收数据并显示在7段显示器上,但数字在闪烁。你能帮我解决这个问题吗?处理器是80C32。 4051多路复用器与微 Controller 连接并选择显示器。有5个7段显示器,通过ULN2803与单片机连接。谢谢。 这是我的代码:
enter code here
#include <reg51.h>
#include <stdio.h>
#include <stdlib.h>
void displayDigit(unsigned char cifra);
void delayTimer();
void showNumber(); //receive data from serial port and store data in buffer buff
void initSerial(); // serial port initialization
char receiveData();
void delay(unsigned int msdelay);
char buff[20]; // store data from serial port
unsigned int tmp1,tmp2,tmp3,tmp4,tmp5;
int tail=0; // index of element in buffer buff
sbit A=P3^4; // A is pin on 4051 Multiplexer
sbit BB=P3^5; // BB is pin on 4051 Multiplexer
sbit C=P3^6; // C is pin on 4051 Multiplexer
sbit INH=P3^7; // INH pin on 4051 Multiplexer
void main(void)
{
P1=0x00;
P3=0x03;
PT0=1;
while(1)
{
initSerial();
showNumber();
delayTimer();
}
}
// mask
void displayDigit(unsigned char cifra)
{
switch(cifra)
{
case 0: P1=0x3F; break;
case 1: P1=0x06; break;
case 2: P1=0x5B; break;
case 3: P1=0x4F; break;
case 4: P1=0x66; break;
case 5: P1=0x6D; break;
case 6: P1=0x7D; break;
case 7: P1=0x07; break;
case 8: P1=0x7F; break;
case 9: P1=0x6F; break;
}
}
// refresh display - a
void delayTimer()
{
TMOD&=0xF0;
TMOD|=0x01;
TH0=0xFF;
TL0=0xFF;
ET0=1;
EA=1;
TR0=1;
while(TF0==0);
TF0=0;
TR0=0;
}
// serial port initialization
void initSerial()
{
SCON=0xD0;
TMOD&=0x0F;
TMOD|=0x20;
TH1=0xFD;
TR1=1;
}
// receive data
char receiveData()
{
char el;
while(RI==0);
el=SBUF;
RI=0;
return el;
}
// receive data from serial port and store data in buffer
void showNumber()
{
int tail=0;
char el;
el=receiveData();
if(el==0x02) // start of communication
{
buff[tail]=el;
tail++;
while(el!=0x03)
{
el=receiveData();
if(el!=0x03)
{
buff[tail]=el;
tail++;
}
else
{
buff[tail]=el;
tail++;
buff[tail]='\0';
}
if(tail==20)
tail=0;
}
}
else if(el==0x03) // end of communication
{
buff[tail]=el;
tail++;
buff[tail]='\0';
}
}
// show on display
void timer0(void) interrupt 1
{
int i;
tmp5=buff[3]-'0';
tmp4=buff[4]-'0';
tmp3=buff[5]-'0';
tmp2=buff[6]-'0';
tmp1=buff[7]-'0';
if(tmp5==0 && tmp4==0 && tmp3==0 && tmp2==0) // 1 digit on display
{
for(i=0;i<40;i++)
{
INH=0;
C=0;
BB=0;
A=1;
displayDigit(tmp1);
delay(8);
}
}
else if(tmp5==0 && tmp4==0 && tmp3==0) // 2 digits on display
{
for(i=0;i<40;i++)
{
INH=0;
C=0;
BB=0;
A=1;
displayDigit(tmp1);
delay(8);
INH=0;
C=0;
BB=1;
A=0;
displayDigit(tmp2);
delay(8);
}
}
else if(tmp5==0 && tmp4==0) // 3 digits on display
{
for(i=0;i<40;i++)
{
INH=0;
C=0;
BB=0;
A=1;
displayDigit(tmp1);
delay(8);
INH=0;
C=0;
BB=1;
A=0;
displayDigit(tmp2);
delay(8);
INH=0;
C=0;
BB=1;
A=1;
displayDigit(tmp3);
delay(8);
}
}
else if(tmp5==0) // 4 digits on display
{
for(i=0;i<40;i++)
{
INH=0;
C=0;
BB=0;
A=1;
displayDigit(tmp1);
delay(8);
INH=0;
C=0;
BB=1;
A=0;
displayDigit(tmp2);
delay(8);
INH=0;
C=0;
BB=1;
A=1;
displayDigit(tmp3);
delay(8);
INH=0;
C=1;
BB=0;
A=0;
displayDigit(tmp4);
delay(8);
}
}
else // 5 digits on display
{
for(i=0;i<40;i++)
{
INH=0;
C=0;
BB=0;
A=1;
displayDigit(tmp1);
delay(8);
INH=0;
C=0;
BB=1;
A=0;
displayDigit(tmp2);
delay(8);
INH=0;
C=0;
BB=1;
A=1;
displayDigit(tmp3);
delay(8);
INH=0;
C=1;
BB=0;
A=0;
displayDigit(tmp4);
delay(8);
INH=0;
C=1;
BB=0;
A=1;
displayDigit(tmp5);
delay(8);
}
}
}
void delay(unsigned int msdelay)
{
unsigned int i,j;
for(i=0;i<msdelay;i++)
{
for(j=0;j<100;j++);
}
}
最佳答案
以下是一些可以帮助您的建议:
- 使能 UART RX 中断。让中断处理程序执行此操作 == 禁用中断 == 如果接收到的字节是 0x02 那么: ==== 将 buffIndex 设置为 0 ==== 设置全局标志指示接收下一条消息 == 否则,如果接收到的字节是 0x03,则设置指示完整消息可用的标志 == 否则将 char 保存在 buff[] 中的下一个位置并增加 buffIndex ==清除UART RX中断挂起标志 ==退出
- 代码应该实现“双缓冲区”,以便后台处理“main”有时间处理新消息。
- 无论哪个缓冲区正在接收字节都应被视为“事件”缓冲区 哪个缓冲区正在显示消息应被视为“非事件”缓冲区
main
位于一个自旋循环上,等待可用的消息。 然后 main 将立即重置“消息可用”标志- 为了获得最大的鲁棒性,消息的显示应在不到 1 毫秒的时间内完成,因此字符的显示必须具有足以让多路复用器稳定下来的延迟。 这样的多路复用器稳定时间应该以微秒为单位,而不是毫秒 消息的显示是“串行”的,没有计时(除了等待多路复用器稳定),因此建议不要将其置于中断上。
- 您的硬件是否有每个数字的数据锁存器?如果是这样,那么就不需要多次写入一个数字,这样就可以消除那些一遍又一遍地写入相同数据的循环。
关于c - 8051 微 Controller 的 7 段显示屏上的数字闪烁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49875788/