动态数码管的显示,由浅入深,原理
(一)视觉暂留:
code存储在程序存储器里,表示只读,不加code的数组存在内存里可读可写。
#include"reg52.h"
typedef signed char int8;
typedef signed int int16;
typedef signed long int32;
typedef unsigned char uint8; //字符型
typedef unsigned int uint16;
typedef unsigned long uint32;
sbit duanxuan=P2^5; //段选控制数字显示
sbit weixuan=P2^6; //位选控制有几个或者第几个显示数字
sbit JDQ = P2 ^ 0;
sbit SHIFT_CLOCK_595 = P1 ^ 4;
sbit data_A_595 = P1 ^ 0;
sbit LATCH_CLOCK_595 = P2 ^ 3;
//自加变量,用来测试编码表
uint8 zifu_test; //用来计数
uint8 zifu_test2;
uint8 code zifu2[19]={0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90,0X88,0X83,0XC6,0XA1,0X86,0X8E,0X89,0X7F,0XBF};
uint8 code zifu[16]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78, 0x00,0x10,0x08,0x03,0x46,0x21,0x06,0x0e};
void delay(uint16 x_ms) //延时毫秒
{
uint16 i,j;
for(i=x_ms;i>0;i--)
for(j=114;j>0;j--);
}
void xp74H595(uint16 dat)
{
uint16 i;
for (i = 0; i < 8; i++)
{
data_A_595 = (dat << i) & 0X80;
SHIFT_CLOCK_595 = 0; //时钟上升沿
SHIFT_CLOCK_595 = 1;
}
LATCH_CLOCK_595 = 0; //给锁存器脉冲,上升沿
LATCH_CLOCK_595 = 1;
}
void shumaguan()
{
duanxuan=0; //首先归零
weixuan=0;
P0= zifu2[zifu_test2++]; //控制输入 , 自加变量,测试编码表
duanxuan=1;
duanxuan=0; //以上是我们锁存器芯片段选的控制
delay(200);
duanxuan=0; //再次归零
weixuan=0;
P0= 0X01; //位选输入
weixuan=1; //位选控制
weixuan=0; //位选锁存
delay(200);
if(zifu_test2>=16)
{
zifu_test2=0; //将变量清零
}
}
void shumaguan2()
{
duanxuan=0; //首先归零
weixuan=0;
P0= zifu[1]; //控制输入 , 自加变量,测试编码表
duanxuan=1;
duanxuan=0; //以上是我们锁存器芯片段选的控制
duanxuan=0; //再次归零
weixuan=0;
P0= 0X01; //位选输入
weixuan=1; //位选控制
weixuan=0; //位选锁存
delay(1000); //通过计算得出,视觉暂留的时间为5.2毫秒
/*************************************************/
duanxuan=0; //首先归零
weixuan=0;
P0= zifu[2]; //控制输入 , 自加变量,测试编码表
duanxuan=1;
duanxuan=0; //以上是我们锁存器芯片段选的控制
duanxuan=0; //再次归零
weixuan=0;
P0= 0X02; //位选输入
weixuan=1; //位选控制
weixuan=0; //位选锁存
delay(1000); //通过计算得出,视觉暂留的时间为5.2毫秒
/*****************************************************/
duanxuan=0; //首先归零
weixuan=0;
P0= zifu[3]; //控制输入 , 自加变量,测试编码表
duanxuan=1;
duanxuan=0; //以上是我们锁存器芯片段选的控制
duanxuan=0; //再次归零
weixuan=0;
P0= 0X04; //位选输入
weixuan=1; //位选控制
weixuan=0; //位选锁存
delay(1000); //通过计算得出,视觉暂留的时间为5.2毫秒
/*****************************************************/
duanxuan=0; //首先归零
weixuan=0;
P0= zifu[4]; //控制输入 , 自加变量,测试编码表
duanxuan=1;
duanxuan=0; //以上是我们锁存器芯片段选的控制
duanxuan=0; //再次归零
weixuan=0;
P0= 0X08; //位选输入
weixuan=1; //位选控制
weixuan=0; //位选锁存
delay(1000); //通过计算得出,视觉暂留的时间为5.2毫秒 、
/*****************************************************/
duanxuan=0; //首先归零
weixuan=0;
P0= zifu[5]; //控制输入 , 自加变量,测试编码表
duanxuan=1;
duanxuan=0; //以上是我们锁存器芯片段选的控制
duanxuan=0; //再次归零
weixuan=0;
P0= 0X10; //位选输入
weixuan=1; //位选控制
weixuan=0; //位选锁存
delay(1000); //通过计算得出,视觉暂留的时间为5.2毫秒 、
/*****************************************************/
duanxuan=0; //首先归零
weixuan=0;
P0= zifu[6]; //控制输入 , 自加变量,测试编码表
duanxuan=1;
duanxuan=0; //以上是我们锁存器芯片段选的控制
duanxuan=0; //再次归零
weixuan=0;
P0= 0X20; //位选输入
weixuan=1; //位选控制
weixuan=0; //位选锁存
delay(1000); //通过计算得出,视觉暂留的时间为5.2毫秒 、
/*****************************************************/
duanxuan=0; //首先归零
weixuan=0;
P0= zifu[7]; //控制输入 , 自加变量,测试编码表
duanxuan=1;
duanxuan=0; //以上是我们锁存器芯片段选的控制
duanxuan=0; //再次归零
weixuan=0;
P0= 0X40; //位选输入
weixuan=1; //位选控制
weixuan=0; //位选锁存
delay(1000); //通过计算得出,视觉暂留的时间为5.2毫秒 、
/*****************************************************/
duanxuan=0; //首先归零
weixuan=0;
P0= zifu[8]; //控制输入 , 自加变量,测试编码表
duanxuan=1;
duanxuan=0; //以上是我们锁存器芯片段选的控制
duanxuan=0; //再次归零
weixuan=0;
P0= 0X80; //位选输入
weixuan=1; //位选控制
weixuan=0; //位选锁存
delay(1000); //通过计算得出,视觉暂留的时间为5.2毫秒 、
/*****************************************************/
}
void main(void)
{
P1=0XFF;
xp74H595(0X04); //流水灯
xp74H595(0X00); //关掉74H595所控制的所有电器
zifu_test=0; //先让数组为0
zifu_test2=1;
while(1)
{
//shumaguan();
shumaguan2();
}
}
(二)消影:
影子产生的代码变动,相比之前的源代码,多了以下内容:(使其产生影子)
(三)写一个任意数的数码管函数:(拓展:)
(1)段选取数:
如果取12345678中的6,首先对12345678这个数取1000的余数,678,再对678取100的整数6,如下图依次将number的各个位数给存入数组。
(2)位选取数:
(3).代码讲解:
动态扫描代码:(可运行)
#include"reg52.h"
typedef signed char int8;
typedef signed int int16;
typedef signed long int32;
typedef unsigned char uint8; //字符型
typedef unsigned int uint16;
typedef unsigned long uint32;
sbit duanxuan=P2^5; //段选控制数字显示
sbit weixuan=P2^6; //位选控制有几个或者第几个显示数字
//自加变量,用来测试编码表
uint8 zifu_test; //用来计数
uint8 zifu_test2;
uint8 number[8]; //用来存入各个位数
uint8 code zifu[19]={0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90,0X88,0X83,0XC6,0XA1,0X86,0X8E,0X89,0X7F,0XBF};
uint8 code wei_test[8]={0X01,0X02,0X04,0X08,0X10,0X20,0X40,0X80};//位选数组
void delay(uint16 x_ms) //延时毫秒
{
uint16 i,j;
for(i=x_ms;i>0;i--)
for(j=114;j>0;j--);
}
void Disp_smag_number(uint8 x, uint8 count, uint32 numb, uint16 time) //位置,几位数,数值,时间
{
uint8 i=0;
number[0]=numb%10; //个 //将对应数的每一位考入数组
number[1]=numb%100/10; //十
number[2]=numb%1000/100; //百
number[3]=numb%10000/1000; //千
number[4]=numb%100000/10000; //万
number[5]=numb%1000000/100000; //十万
number[6]=numb%10000000/1000000; //百万
number[7]=numb%100000000/10000000; //千万
for( i=0; i<count; i++)
{
duanxuan=0;
weixuan =0;
P0= zifu[number[count-i-1]]; //数码管段选显示段码数据
duanxuan=1;
duanxuan=0;
duanxuan=0;
weixuan =0;
P0= wei_test[x+i-1]; //位选控制
weixuan= 1;
weixuan= 0;
delay(time); //延迟时间
//**********消影**********//
duanxuan=0;
weixuan= 0;
P0= 0X00;
weixuan =1;
weixuan= 0;
}
}
void main(void)
{
P1=0XFF;
zifu_test=0; //先让数组为0
zifu_test2=1;
while(1)
{
// scanf("%d",numb);
Disp_smag_number(2,7,5219632,1);
}
}