时钟及温度用74hc164+74ls145数码管显示单片机程序
电路图很简单我就不画了 数码管用74hc164串行转并行芯片+74ls145这2个芯片驱动一个负责段选一个负责位选,具体看程序顶部的引脚定义.完整的keil工程文件下载地址:http://www.51hei.com/f/164smg.rar 下面是程序源码.
#include
#include
#define uchar unsigned char
#define uint unsigned int
sbit iicclk=P1^0;////总线存储时钟引脚定义
sbit iicdat=P1^1;////总线存储数据引脚定义
sbit hc164dat=P1^2;//段显串行数据引脚定义
sbit hc164clk=P1^3;//段显串行时钟引脚定义
/*sbit hc164clr=P1^4;*///段显芯片清零引脚,低电平时,全部输出引脚清零,即低电平
sbit ls145p0=P1^5;///位选译码芯片P0
sbit ls145p1=P1^6;///位选译码芯片P1
sbit ls145p2=P1^7;///位选译码芯片P2
sbit ls145p3=P3^7;///位选译码芯片P2,用于在74HC164移入数据时P0~P3全置高,关闭所有数码管
sbit DS1820DQ=P0^0;
sbit ADD=P0^4;///////加一
sbit MINUS=P0^5;/////减一
sbit ENTER=P0^6;/////确定
sbit SET=P0^7;///////设定键
uchar code tabledu[]={0xed,0x21,0x8f,0xab,0x63,0xea,0xee,0xa1,0xef,0xeb,0x0};//垃圾显示板0~~9段显数据
uchar code tablewe[]={0x0,0x20,0x40,0x60,0x80,0xa0,0xc0,0xe0,0x10};//位选编码,P2口高八位产生编码值,0x10为关闭所有位选
char dateshu[8];
uchar tim,sec,ming,mins,hourg,hours,min,hour,setflag,seta,dqflag,temperl,temperh,dat;
void delay1ms(uint x)//0.5毫秒延时函数
{
uint y,z;
for(y=x;y>0;y--)
for(z=60;z>0;z--);
}
void delayns()
{
_nop_();
_nop_();
}
void delay10us(uchar z)//z为3是定时10微秒
{
while(z)
z--;
}
void DelayX0us(uchar n)
{
while (n--)
{
_nop_();
_nop_();
}
}
void dqrsr()//1820初始化函数
{
dqflag=0;
DS1820DQ=1;
delayns();
DS1820DQ=0;
DelayX0us(48);//时序延时500US
DS1820DQ=1;
delay10us(6);//时序延时20us
if(DS1820DQ==0)dqflag=1;
DelayX0us(42);
}
void dqwrite(uchar a)
{
uchar i;
dqflag=0;
DS1820DQ=1; //to释放总线
delayns();//时序延时
for(i=8;i>0;i--)//写一个字节的数据
{
DS1820DQ=0;//总线置低
_nop_();
_nop_();
a=a>>1;//右移时,逸出位保存到CY中
DS1820DQ=CY;//发送送据
DelayX0us(6);//延时70us
DS1820DQ=1; //to释放总线
}
}
uchar dqread(void)//1820读函数
{
uchar i;
DS1820DQ=1; //to释放总线
delayns();//时序延时
for(i=0;i<8;i++)
{
dat>>=1;
DS1820DQ=0;
_nop_();
_nop_();
DS1820DQ=1;
delayns();
if(DS1820DQ)dat|=0x80; //如果读回的数据为1则作与处理移入DAT变量
DelayX0us(6);//延时70us
}
return dat;
}
void write164(uchar x)
{
uchar y;
hc164clk=0;//时钟置低
_nop_();
_nop_();
for(y=0;y<8;y++)
{
hc164dat=(x&0x80);
delayns();
hc164clk=1;
delayns();
hc164clk=0;
delayns();
x<=1;
}
}
void init()
{
P0=0xff;//输入接口P0全置一,让按键读回输入信息
P2=tablewe[8];//关闭所有数码管的位选
hc164clk=0;//时钟置低,以产生上升沿移入数据
IE=0X82; //EA=1开总中断ET0=1定时器零中断允许
TCON=0X10;//TR0=1定时零中断启动
TMOD=0X01;//M1M0=01 T0 工作方式1,16位定时器
TH0=(65636-50000)/256;
TL0=(65636-50000)%256;//50ms定时初值
DS1820DQ=1;
}
void iicstart()//暂未使用
{
}
void iicstop()//暂未使用
{
}
void display(uchar a,uchar b,uchar c,uchar d,uchar e,uchar f,uchar g,uchar h)//显示函数
{
P2=tablewe[8];
write164(tabledu[a]);
P2=tablewe[0];
delay1ms(2);
P2=tablewe[8];
write164(tabledu[b]);
P2=tablewe[1];
delay1ms(2);
P2=tablewe[8];
write164(tabledu[c]);
P2=tablewe[2];
delay1ms(2);
P2=tablewe[8];
write164(tabledu[d]);
P2=tablewe[3];
delay1ms(2);
P2=tablewe[8];
write164(tabledu[e]);
P2=tablewe[4];
delay1ms(2);
P2=tablewe[8];
write164(tabledu[f]);
P2=tablewe[5];
delay1ms(2);
P2=tablewe[8];
write164(tabledu[g]);
P2=tablewe[6];
delay1ms(2);
P2=tablewe[8];
write164(tabledu[h]);
P2=tablewe[7];
delay1ms(2);
}
void timer()//24小时时间计算函数
{
if(sec>59)
{
sec=0;
min++;
if(min>59)
{
min=0;
hour++;
if(hour>23)
{
hour=0;
}
}
}
dateshu[0]=sec%10;
dateshu[1]=sec/10;
dateshu[2]=min%10;
dateshu[3]=min/10;
dateshu[4]=hour%10;
dateshu[5]=hour/10;
}
void key()//设定程序入口
{
if(SET==0)
{
setflag=1;
}
}
void keyshu()//设定键函数
{
bit b,d,e;
b=MINUS;d=ADD;//变量B,D,E分别读回P0。4~P0。6的状态。分别为加一,减一,确认键
e=ENTER;
if(b==0)//减一按键按下
{
dateshu[seta]--;
if(dateshu[seta]<0)dateshu[seta]=9;//减到零时自动循环回九
b=MINUS;//再读回键值,做松手查检测
while(b==0){b=MINUS;display(dateshu[0],dateshu[1],10,seta+1,dateshu[2],dateshu[3],dateshu[4],dateshu[5]);}//松手检测
}
else if(d==0)//加一按键按下
{
dateshu[seta]++;
if(dateshu[seta]>9)dateshu[seta]=0;//加到九时自动循环回零
d=ADD;//做松手检测
while(d==0){d=ADD;display(dateshu[0],dateshu[1],10,seta+1,dateshu[2],dateshu[3],dateshu[4],dateshu[5]);}//松手检测
}
else if(e==0)//确认键按下
{
seta++;
e=ENTER;
while(e==0){e=ENTER;display(dateshu[0],dateshu[1],10,seta+1,dateshu[2],dateshu[3],dateshu[4],dateshu[5]);}
if(seta>5)//如果六位数值已设定完毕,测退出设定状态
{
seta=0;sec=0;setflag=0;
sec=dateshu[1]*10+dateshu[0];//分别将设定好的值,赋给时秒变量,设定生效
min=dateshu[3]*10+dateshu[2];//分别将设定好的值,赋给分变量,设定生效
hour=dateshu[5]*10+dateshu[4];//分别将设定好的值,赋给时变量,设定生效
}
}
}
void main()
74hc16474ls145数码管显示单片 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)