在51单片机上如何让数码管流水式的显示16进制数,

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在51单片机上如何让数码管流水式的显示16进制数,相关的知识,希望对你有一定的参考价值。

就是刚开始第一个数码管显0,然后下面的灯依次亮显示10,210,3210,43210,543210,654321 765432。。一直让其循环下去,这个程序怎么编写,求解
我用的是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;
;

参考技术A

今天回来没有多少事情,看看百度问问,然后就用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);

            

        

    

本回答被提问者采纳
参考技术B #include<reg52.h> #define uchar unsigned char #define uint unsigned int uchar code tab_disp[]= 0x3f,0x06,0x5b,0x4f, 0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c, 0x39,0x5e,0x79,0x71; uchar code tabwela[]= 0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f; uchar i,k,flag; uint b,num1[2]; uchar num[5]; void delay(uint z) uint x,y; for(x=z;x>0;x--) for(y=10;y>0;y--); void display() uchar j; for(j=0;j<5;j ) P0=tabwela[j]; P2=tab_disp[num[j]]; delay(1); P2=0x00; void main() TMOD=0x20;//定时器1的工作方式2 TH1=0xfd; //装数,设定波特率 9600 TL1=0xfd; TR1=1;//启动定时器1 REN=1;//启动串口接收数据 SM0=0;//串口工作方式1 SM1=1; EA=1;//开总中断 ES=1;//开串口中 while(1) if(flag==1) num[0]=b/ 10000; num[1]=b% 10000/1000; num[2]=b00/100; num[3]=b0/10; num[4]=b; flag=0; SBUF=b; while(TI==1) TI=0; display(); void ser() interrupt 4 while(RI==1) RI=0; num1[i]=SBUF; i ; if(i==2) i=0; k ; if(k==2) k=0; b=(num1[0]*256) num1[1]; flag=1; 追问

那个串口我还没学,不用那个怎么写啊

追答

额,不知道了,采纳我吧

参考技术C 楼主给出一个显示固定数字的程序,如:12345678。
大家帮你改一改,就行了。

以上是关于在51单片机上如何让数码管流水式的显示16进制数,的主要内容,如果未能解决你的问题,请参考以下文章

单片机 怎么用位移的方法实现乘除法

51单片机怎么编程,有什么好的课程?

关于51单片机的外部中断使用方法

51单片机——数码管静态显示

51单片机——数码管静态显示

利用51单片机,4个数码管设计一个计时器,要求在数码管上显示的数据从0开始每1秒钟加1。