51单片机c程序用定时器控制两个数码管显示0到59,一直没弄懂段位和位选

Python021

51单片机c程序用定时器控制两个数码管显示0到59,一直没弄懂段位和位选,第1张

数码管 的 一位 数字 称一个位,两个数字为 两位,三个----,

每个数字 有 八个段 为 a  b  c  d  e  f  g  h,(h  为小数点)

数码管 有 两位一体的、三位一体的,四位一体的等,如四位一体的数码管有12个脚,

分为  a  b  c  d  e  f  g  h 八个 段码脚,四个 位码脚(四个数字位)

数码管 的 显示 方法 需要 扫描显示,就是每次 只能 显示 一位数字,四位数字 分 四次显示,

这样 要让人 眼 能 同时 看到 四位数字,并且 不闪烁,需要每个数字 每秒钟 显示 50 次 以上,这样 就有了 扫描显示的方法 去 解决了 这个 问题,就是 需要 段位和位选 的选择,

如 第一位 显示 一个数字 先 把 段代码 写入 段码 驱动口,再选择显示 第一位 的 位码写入位码 驱动口,延时一个 时间 再显示 第二位 ------,就可以了。

union中,所有元素都从该union的开头分配,就是说存储是覆盖的。

以你的s为例,s总的长度是最长的元素int i的长度,对32位编译器来说,s占4个字节,s.i从s的第0字节到第3字节;s.a则占s的第0字节处的1个字节。即,s.a与s.i的最低的8位那个字节是存放在同一个内存字节中的,因此改变s.a,也会导致s.i发生变化。

给s.i赋值512后,s的0-3字节分别为:0x00,0x02,0x00,0x00 (intel格式是低位在前)

给s.a赋值2后,改变了s的第0字节,s的0-3字节分别为:0x02,0x02,0x00,0x00

这样,再输出s.i时,输出的就是0x00000202,即十进制514了。

这是数字时钟的C程序,如果要实现对继电器的开关控制,就可以在主程序中加入对时间的控制。也就是说,在你定义的某个时间上,继电器会实现开或者合的状态!由于单片机对数码管的控制引脚有别,程序还得自己加以修改。

#include<reg52.h>

//#include<absacc.h>

#define uchar unsigned char

#define uint unsigned int

uchar code table[]={0xc0,0xf9,0xa4,0xb0,

0x99,0x92,0x82,0xd8,

0x80,0x90}//数字显示

sbit duan=P2^1//段选定义

sbit wei=P2^2//位选定义

sbit k1=P3^2//选择 秒/分/时 调试定义

sbit k2=P3^3//增减调试定义

/*定义初始化变量*/

uchar miao=0

uchar fen=0

uchar shi=0

uchar mst=0//标准化时间

uchar key=0

void display()//显示子程序

void delay(uchar z)

void time_pro()

void keyscan()

main()

{

mst=0

miao=0

TMOD=0x01//time0为定时器,选择方式1

TH0=(65535-50000)/256

TL0=(65535-50000)%256

EA=1

ET0=1

TR0=1

wei=1

P0=0x3f

wei=0

duan=1

P0=table[0]

duan=0

P1=0x55//点亮流水灯

while(1)

{

display()

time_pro()

if(k1==0) keyscan()

//继电器开合控制加在此处:时间可以根据自己的需求任意定义

//例如:if(shi==17&&fen==21&&miao==52)

{

jidianqi=0//0就表示继电器关闭

}

if(shi==23&&fen==57&&miao==34)

{

jidianqi=1//1就表示继电器开启

}

}

}

/*显示子程序*/

void display()

{

wei=1

P0=0x01

wei=0

P0=0xff//清屏

duan=1

P0=table[miao%10]//显示秒钟的个位

duan=0

delay(1)

wei=1

P0=0x02

wei=0

P0=0xff

duan=1

P0=table[miao/10]//显示秒钟的十位

duan=0

delay(1)

wei=1

P0=0x04

wei=0

P0=0xff

duan=1

P0=table[fen%10]//显示分钟的个位

duan=0

delay(1)

wei=1

P0=0x08

wei=0

P0=0xff

duan=1

P0=table[fen/10]//显示分钟的十位

duan=0

delay(1)

wei=1

P0=0x10

wei=0

P0=0xff

duan=1

P0=table[shi%10]//显示小时的个位

duan=0

delay(1)

wei=1

P0=0x20

wei=0

P0=0xff

duan=1

P0=table[shi/10]//显示小时的十位

duan=0

delay(1)

}

/*延时子程序*/

void delay(uchar z)

{

uchar x,y

for(x=0x<=zx++)

for(y=0y<=107y++)

}

/*时间处理子程序*/

void time_pro()

{

if(miao>=60)

{ miao=0

fen++

if(fen>=60)

{

fen=0

shi++

if(shi>=24)

shi=0

}

}

}

/*键盘扫描子程序*/

void keyscan()

{

//第一次检测 k1 按键

while(!key)

{

display()P1=~P1

while(k1==0)

{

delay(1)

if(k1==0)

key=0

key=1

}

}

key=0

//第一次检测 k2 按键

while(!key)

{

display()P1=~P1

while(k2==0)

{

delay(220)

if(k2==0)

{ key=0

miao++

if(miao>=60) miao=0

display()

delay(220)

}

key=1

}

}

key=0

//第二次检测 k1 按键

while(!key)

{

display()P1=0x55

while(k1==0)

{

delay(220)

if(k1==0)

{

key=0

display()

P1=~P1

}

key=1

}

}

key=0

//第二次检测 k2 按键

while(!key)

{

display()P1=~P1

while(k2==0)

{

delay(220)

if(k2==0)

{ key=0

fen++

if(fen>=60) fen=0

display()

delay(220)

}

key=1

}

}

key=0

//第三次检测 k1 按键

while(!key)

{

display()P1=~0x55

while(k1==0)

{

delay(220)

if(k1==0)

{

key=0

P1=~P1

display()

}

key=1

}

}

key=0

//第三次检测 k2 按键

while(!key)

{

display()P1=~P1

while(k2==0)

{

delay(220)

if(k2==0)

{ key=0

shi++

if(shi>=24) shi=0

display()

delay(220)

}

key=1

}

}

}

/*中断延时子程序*/

void time() interrupt 1 //定时器0方式1,50ms中断一次

{

TH0=(65535-50000)/256

TL0=(65535-50000)%256

mst++

if(mst==20)

{

mst=0//记数机器清零

P1=~P1

miao++

time_pro()

}

}