
在51单片机上如何让数码管流水式的显示16进制数,
我用的是TX的板 展开
数码管用动态扫描。下面是AVR的代码,你参考一下就行了。
#include <iom64v.h>
#include <macros.h>
#define SEG PORTA // 数码管段码
#define SCAN PORTC // 数码管位选
#define uchar unsigned char
#define uint unsigned int
///////////////////////////////////////////////////////////
// Name : 段码和位选
// In :
// Out :
// Function :
// Explain : 数码管为共阳,低电平时选通数码管
///////////////////////////////////////////////////////////
uchar seg[]={ 0xc0,0xf9,0xa4,0xb0,0x99, // 0-4 (共阳)
0x92,0x82,0xf8,0x80,0x98, // 5-9
0xff }; // 灭
uchar sel[]={ 0xfe,0xfd,0xfb,0xf7, // 从右向左选择(低电平选通)
0xef,0xdf,0xbf,0x7f };
///////////////////////////////////////////////////////////
// Name : 8个数码管的状态
// In :
// Out :
// Function :
// Explain : 10代表灭,其它数字代表真实的显示值
///////////////////////////////////////////////////////////
uchar display[]={ 7,10,10,10,10,10,10,10, // 右边第一个数码管显示7,第二个灭……
6,7,10,10,10,10,10,10, // 右边第一个数码管显示6,第二个显示7,第三个灭……
5,6,7,10,10,10,10,10, // 右边第一个数码管显示5,第二个显示6,第三个显示7,第四个灭……
4,5,6,7,10,10,10,10, // 以此类推,得到76543210向左移动的效果!
3,4,5,6,7,10,10,10,
2,3,4,5,6,7,10,10,
1,2,3,4,5,6,7,10,
0,1,2,3,4,5,6,7
};
///////////////////////////////////////////////////////////
// Name : 延时函数
// In :
// Out :
// Function : 用于延时一定时间
// Explain : 用12M晶振时,大概延时1ms,
///////////////////////////////////////////////////////////
void delay_1ms(uint x) // 用12M晶振时,延时1ms,
{
uint i,j;
for(i=0; i<x; i++)
for(j=0; j<1720; j++);
}
///////////////////////////////////////////////////////////
// Name : 端口定义
// In :
// Out :
// Function : 用于定义端口方向等
// Explain :
///////////////////////////////////////////////////////////
void port_init(void)
{
PORTA = 0x00;
DDRA = 0xff; // PA口设置成输出,数码管段码
PORTB = 0x00;
DDRB = 0x00;
PORTC = 0x00; // m103 output only
DDRC = 0xff; // PC口设置成输出,数码管位选
PORTD = 0x00;
DDRD = 0x00;
PORTE = 0x00;
DDRE = 0x00;
PORTF = 0x00;
DDRF = 0x00;
PORTG = 0x00;
DDRG = 0x00;
}
///////////////////////////////////////////////////////////
// Name : 初始化函数
// In :
// Out :
// Function :
// Explain :
///////////////////////////////////////////////////////////
// call this routine to initialize all peripherals
void init_devices(void)
{
// stop errant interrupts until set up
CLI(); // disable all interrupts
XDIV = 0x00; // xtal divider
XMCRA = 0x00; // external memory
port_init(); // 端口初始化
MCUCR = 0x00;
EICRA = 0x00; // extended ext ints
EICRB = 0x00; // extended ext ints
EIMSK = 0x00;
TIMSK = 0x00; // timer interrupt sources
ETIMSK = 0x00; // extended timer interrupt sources
SEI(); // re-enable interrupts
// all peripherals are now initialized
}
///////////////////////////////////////////////////////////
// Name : 主函数
// In :
// Out :
// Function :
// Explain :
///////////////////////////////////////////////////////////
void main(void)
{
uint a,b,c,cnt;
init_devices(); // 初始化
delay_1ms(500);
while(1)
{
for(b=0; b<8; b++) // 总共显示8幅(8个左移效果)
for(c=0; c<500; c++) // 显示一幅,一幅包括8个数码管的显示值
{
SCAN=0xff; // 送数据时,先关闭显示,以避免重影现象
SEG=seg[display[cnt+b*8]]; // 送数据
SCAN=~sel[cnt]; // 送出数据后,打开显示
delay_1ms(1); // 延时1ms,动态扫描,让人看得到
cnt++; // 指向下一个状态
if(cnt==8) // 判断是否取完8个数码管的状态
cnt=0;
};
}
}

2021-01-14 广告
今天回来没有多少事情,看看百度问问,然后就用avr单片机写了一个和你程序差不多的程序。可能还有点差距,但是稍微调整一下就好了。数码管事动态扫描显示的,如原理图所示。顺便录了一个视频,可以看看一下啊!希望可以给你一点思路。
http://www.tudou.com/programs/view/0GmdlNj9rF4/
#define F_CPU 12000000UL
#include <avr/io.h>
#include <util/delay.h>
#define INT8U unsigned char
#define INT16 unsigned int
#define LATCH_B0 PORTC&=~_BV(0)
#define LATCH_B1 PORTC|=_BV(0)
#define LATCH_A0 PORTC&=~_BV(1)
#define LATCH_A1 PORTC|=_BV(1)
INT8U SMG_Wei[9]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0xff};/*位1,2,3,4,5,6,7,8,off*/
INT8U SMG_Cde[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};/*0,1,2,3,4,5,6,7,8,9*/
INT8U DataBuf[8]={0,1,2,3,4,5,6,7,};
int main(void)
{
INT8U i,j;
INT16 uDelay;
DDRA=0xff,PORTA=0x00; /*设置端口B为输出模式,输出为0x00*/
DDRC=0x03,PORTC=0x00;
while(1)
{
//TODO:: Please write your application code
for(j=7;j!=0xff;j--)
{
uDelay=10;
while(uDelay--)
{
for (i=0;i<8;i++)
{
PORTA=SMG_Cde[DataBuf[i]];
LATCH_B1;
LATCH_B0;
if(i+j<8)
{
PORTA=~SMG_Wei[i+j];
LATCH_A1;
LATCH_A0;
}
else
{
PORTA=0xff;
LATCH_A1;
LATCH_A0;
}
_delay_ms(1);
PORTA=0x00;
LATCH_B1;
LATCH_B0;
PORTA=0xff;
LATCH_A1;
LATCH_A0;
_delay_us(10);
}
}
}
////////////////////////////////////////////////////////////
for(j=0;j<8;j++)
{
uDelay=10;
while(uDelay--)
{
for (i=0;i<8;i++)
{
PORTA=SMG_Cde[DataBuf[i]];
LATCH_B1;
LATCH_B0;
if(i+j<8)
{
PORTA=~SMG_Wei[i+j];
LATCH_A1;
LATCH_A0;
}
else
{
PORTA=0xff;
LATCH_A1;
LATCH_A0;
}
_delay_ms(1);
PORTA=0x00;
LATCH_B1;
LATCH_B0;
PORTA=0xff;
LATCH_A1;
LATCH_A0;
_delay_us(10);
}
}
}
}
}
那个串口我还没学,不用那个怎么写啊
额,不知道了,采纳我吧
大家帮你改一改,就行了。