万年历简单设计,基于lcd液晶显示屏和ds18b20,以及时钟电路和八位键盘,实现它的闹钟,年月日和温度功能
单片机源程序如下:
- /*******************************************************
- /*******************************************************
- 程序功能:DS1302时钟走时
- 开发环境:Keil3
- 硬件环境:CEPARK多功能开发学习板/实验箱(2013版),STC12C5A60S2,11.0592M晶振
-
- 接线说明:单片机P10~P14口与底板JP51相连,分别为:P10-DIN,P11-SCK,P12-DC,P13-RES,P14-CS.
- 单片机P20~P22口与底板JP45相连 ,分别为:P20-SCLK,P21-IO,P22-RST
- 将OLED屏插到相应接口
- 跳线说明:无
- 实验现象:OLED第一行显示:“ -DS1302 TEST- ”
- 第二行显示:年-月-日
- 第三行显示:时:分:秒
- 第四行显示:电子园
- *******************************************************/
- #include "STC12C5A60S2.h"
- //秒、分、时、日、月、星期、年的读地址
- #define ADDR_SEC_R 0x81
- #define ADDR_MIN_R 0x83
- #define ADDR_HOUR_R 0x85
- #define ADDR_DAY_R 0x87
- #define ADDR_MONTH_R 0x89
- #define ADDR_WEEK_R 0x8B
- #define ADDR_YEAR_R 0x8D
- //秒、分、时、日、月、星期、年的写地址
- #define ADDR_SEC_W 0x80
- #define ADDR_MIN_W 0x82
- #define ADDR_HOUR_W 0x84
- #define ADDR_DAY_W 0x86
- #define ADDR_MONTH_W 0x88
- #define ADDR_WEEK_W 0x8A
- #define ADDR_YEAR_W 0x8C
- #define uchar unsigned char
- #define uint unsigned int
- sbit DS1302_CLK = P2^0;
- sbit DS1302_IO = P2^1;
- sbit DS1302_RST = P2^2;
- sbit ACC0=ACC^0;
- sbit ACC7=ACC^7;
- sbit SEG_DS = P2^3; //74HC595芯片的数据引脚
- sbit SEG_SHCP = P2^4; //74HC595芯片的控制引脚,上升沿移入数据
- sbit SEG_STCP = P2^5; //74HC595芯片的控制引脚,上升沿更新数据
- //各时间的个位和十位
- char years,yearg,months,monthg,days,dayg,week,hours,hourg,minutes,minuteg,seconds,secondg;
- uchar a[8];// 存放要在数码管显示的时间
- uchar resettime[7];//存放要重设的时间
- uchar b[2]={0,0};
- uchar d=1;
- uchar i,key,num,change_key1,change_key2,c;
- char pos=8;//闪烁位标志
- void DisplayOneCharOnAddr(unsigned char Data,unsigned char Addr);//单位显示函数,那个数码管Addr显示那个数Data
- void displayHour();//显示时分秒
- void displayYear();//显示年月日
- void displayHour1();//修改时显示的时分秒(静止)
- void displayYear1();//修改时显示的年月日(静止)
- void SEG_Send595OneByte(unsigned char ucData); //向74HC595写入一个8位的数据
- void delayms(uint xms);//延时函数
- void matrixkeyscanz();//行列反转扫描矩阵键盘及相关按键功能的实现
- void reset();//重设时间函数
- unsigned char code Seg_Data[]={ //共阳数码管的编码,并将数据定义在CODE区
- 0xc0,/*0*/
- 0xF9,/*1*/
- 0xA4,/*2*/
- 0xB0,/*3*/
- 0x99,/*4*/
- 0x92,/*5*/
- 0x82,/*6*/
- 0xF8,/*7*/
- 0x80,/*8*/
- 0x90,/*9*/
- 0x88,/*A*/
- 0x83,/*b*/
- 0xC6,/*C*/
- 0xA1,/*d*/
- 0x86,/*E*/
- 0x8E,/*F*/
- 0xff, //数码管灭
- 0x7f //小数点亮
- };
- unsigned char code Seg_Addr[]={ //数码管位选编码,控制显示8位中的第几位
- 0x01,
- 0x02,
- 0x04,
- 0x08,
- 0x10,
- 0x20,
- 0x40,
- 0x80,
- 0xFF,//ALL ON
- 0x00 //OFF
- };
- unsigned char code ucInitTime[7]={0x55,0x53,0x11,0x31,0x10,0x01,0x16}; //初始化后设置为:16年10月31日星期1 11点53分55秒
- void DS1302_WriteOneByte(unsigned char d); //向DS1302中写入一个数据
- unsigned char DS1302_ReadOneByte(void); //从DS1302读出一个数据
- void DS1302_WriteOneByteAtAddr(unsigned char ucAddr, unsigned char ucDa); //在指定地址写入一个数据
- unsigned char DS1302_ReadOneByteAtAddr(unsigned char ucAddr); //从指定一个位置读取一个数据
- void DS1302_SetInit(unsigned char *pClk); //初始化时间
- /******************************************************************************
- 函数名称:main
- 函数功能:程序主函数
- 入口参数:无
- 返回值:无
- 备注:无
- *******************************************************************************/
- void main(void)
- {
- DS1302_WriteOneByteAtAddr(0x8e,0x00); /* 控制命令,WP=0,写操作*/
- DS1302_SetInit(ucInitTime);
- P1=0xff;
- TMOD=0x01;
- TH0=(65536-45872)/256;
- TL0=(65536-45872)%256;
- EA=1;
- ET0=1;
- while(1) //程序循环
- {
- matrixkeyscanz();
- switch(change_key2)
- {
- case 0://修改键没有被按下
- switch(change_key1)
- { //change_key1=0表示显示时分秒,change_key1=1表示显示年月日
- case 0:displayHour();break;
- case 1:displayYear();break;
- }
- break;
-
- case 1://修改键被按下
- switch(change_key1)
- {
- case 0:displayHour1();break;
- case 1:displayYear1();break;
- }
- break;
- }
- }
- }
- //显示时分秒的函数,从左到右依次为星期、时、分、秒
- void displayHour()
- {
- hours=DS1302_ReadOneByteAtAddr(ADDR_HOUR_R)/16;
- hourg=DS1302_ReadOneByteAtAddr(ADDR_HOUR_R)%16;
- minutes=DS1302_ReadOneByteAtAddr(ADDR_MIN_R)/16;
- minuteg=DS1302_ReadOneByteAtAddr(ADDR_MIN_R)%16;
- seconds=DS1302_ReadOneByteAtAddr(ADDR_SEC_R)/16;
- secondg=DS1302_ReadOneByteAtAddr(ADDR_SEC_R)%16;
- week=DS1302_ReadOneByteAtAddr(ADDR_WEEK_R)%16;
- a[0]=week;
- a[1]=16;//空一格不显示
- a[2]=hours;
- a[3]=hourg;
- a[4]=minutes;
- a[5]=minuteg;
- a[6]=seconds;
- a[7]=secondg;
- for(i=0;i<8;i++)
- {
- if(i==3||i==5)
- DisplayOneCharOnAddr(17,i);//显示小数点
- DisplayOneCharOnAddr(a[i],i);
- }
- }
- //显示按下修改键时的时分秒
- void displayHour1()
- {
- a[0]=week;
- a[1]=16;
- a[2]=hours;
- a[3]=hourg;
- a[4]=minutes;
- a[5]=minuteg;
- a[6]=seconds;
- a[7]=secondg;
- for(i=0;i<pos;i++)
- {
- if(i==3||i==5)
- DisplayOneCharOnAddr(17,i);
- DisplayOneCharOnAddr(a[i],i);
- //num的值由定时器1控制,不断闪烁要修改的两位数字
- if(num>0)
- {
- if(num<=10)
- {
- DisplayOneCharOnAddr(a[pos],pos);
- DisplayOneCharOnAddr(a[pos+1],pos+1);
- }
- else
- {
- DisplayOneCharOnAddr(16,pos);
- DisplayOneCharOnAddr(16,pos+1);
- }
- }
- }
-
- for(i=pos+2;i<8;i++)
- {
- if(i==3||i==5)
- DisplayOneCharOnAddr(17,i);
- DisplayOneCharOnAddr(a[i],i);
- if(num>0)
- {
- if(num<=10)
- {
- DisplayOneCharOnAddr(a[pos],pos);
- DisplayOneCharOnAddr(a[pos+1],pos+1);
- }
- else
- {
- DisplayOneCharOnAddr(16,pos);
- DisplayOneCharOnAddr(16,pos+1);
- }
- }
- }
- }
- //显示年月日的函数,从左到右依次为年、月、日
- void displayYear()
- {
- years=DS1302_ReadOneByteAtAddr(ADDR_YEAR_R)/16;
- yearg=DS1302_ReadOneByteAtAddr(ADDR_YEAR_R)%16;
- months=DS1302_ReadOneByteAtAddr(ADDR_MONTH_R)/16;
- monthg=DS1302_ReadOneByteAtAddr(ADDR_MONTH_R)%16;
- days=DS1302_ReadOneByteAtAddr(ADDR_DAY_R)/16;
- dayg=DS1302_ReadOneByteAtAddr(ADDR_DAY_R)%16;
- a[0]=2;
- a[1]=0;
- a[2]=years;
- a[3]=yearg;
- a[4]=months;
- a[5]=monthg;
- a[6]=days;
- a[7]=dayg;
- for(i=0;i<8;i++)
- {
- if(i==3||i==5)
- DisplayOneCharOnAddr(17,i);
- DisplayOneCharOnAddr(a[i],i);
- }
- }
- //显示按下修改键时的年月日
- void displayYear1()
- {
- a[0]=2;
- a[1]=0;
- a[2]=years;
- a[3]=yearg;
- a[4]=months;
- a[5]=monthg;
- a[6]=days;
- a[7]=dayg;
- for(i=0;i<pos;i++)
- {
- if(i==3||i==5)
- DisplayOneCharOnAddr(17,i);
- DisplayOneCharOnAddr(a[i],i);
- if(num>0)
- {
- if(num<=10)
- {
- DisplayOneCharOnAddr(a[pos],pos);
- DisplayOneCharOnAddr(a[pos+1],pos+1);
- }
- else
- {
- DisplayOneCharOnAddr(16,pos);
- DisplayOneCharOnAddr(16,pos+1);
- }
- }
- }
-
- for(i=pos;i<8;i++)
- {
- if(i==3||i==5)
- DisplayOneCharOnAddr(17,i);
- DisplayOneCharOnAddr(a[i],i);
- if(num>0)
- {
- if(num<=10)
- {
- DisplayOneCharOnAddr(a[pos],pos);
- DisplayOneCharOnAddr(a[pos+1],pos+1);
- }
- else
- {
- DisplayOneCharOnAddr(16,pos);
- DisplayOneCharOnAddr(16,pos+1);
- }
- }
- }
- }
- /*******************************************************
- 行列反转,判断是哪个按键按下,并在相应的键中实现相关的功能
- *******************************************************/
- void matrixkeyscanz()
- {
- uchar temp,col,row;
- P0=0xff;
- P0=0xf0;
- temp=P0;
- if(temp!=0xf0)
- {
- delayms(50);
- temp=P0;
- if(temp!=0xf0)
- {
- switch(temp)
- { //判断列
- case 0xe0:col=0;break;
- case 0xd0:col=1;break;
- case 0xb0:col=2;break;
- case 0x70:col=3;break;
- }
- P0=0xff;
- P0=0x0f;
- temp=P0;
- if(temp!=0x0f)
- {
- switch(temp)
- { //判断行
- case 0x0e:row=0;break;
- case 0x0d:row=1;break;
- case 0x0b:row=2;break;
- case 0x07:row=3;break;
- }
- }
-
- key=(row<<2)+col+1; //按键key的值为1到16
- d=1;
- switch(key)
- {
- case 1://按键1:切换时分秒和年月日
- {
- change_key1=change_key1+1; //切换按钮
- if(change_key1==2)
- change_key1=0;
- if(change_key2==1);
- change_key2=0;
- pos=8;
- }
- break;
-
- case 2://按键2:修改或修改确认按键
- {
- change_key2++;//修改/确认变量
- if(change_key2==2)
- change_key2=0;
- c=0;
- switch(change_key2)
- {
- case 0://确认
- {
- pos=8;
- TR0=0;
- reset();
- }
- break;
- case 1://修改
- {
- //读当前的时间
- years=DS1302_ReadOneByteAtAddr(ADDR_YEAR_R)/16;
- yearg=DS1302_ReadOneByteAtAddr(ADDR_YEAR_R)%16;
- months=DS1302_ReadOneByteAtAddr(ADDR_MONTH_R)/16;
- monthg=DS1302_ReadOneByteAtAddr(ADDR_MONTH_R)%16;
- days=DS1302_ReadOneByteAtAddr(ADDR_DAY_R)/16;
- dayg=DS1302_ReadOneByteAtAddr(ADDR_DAY_R)%16;
- hours=DS1302_ReadOneByteAtAddr(ADDR_HOUR_R)/16;
- hourg=DS1302_ReadOneByteAtAddr(ADDR_HOUR_R)%16;
- minutes=DS1302_ReadOneByteAtAddr(ADDR_MIN_R)/16;
- minuteg=DS1302_ReadOneByteAtAddr(ADDR_MIN_R)%16;
- seconds=DS1302_ReadOneByteAtAddr(ADDR_SEC_R)/16;
- secondg=DS1302_ReadOneByteAtAddr(ADDR_SEC_R)%16;
- week=DS1302_ReadOneByteAtAddr(ADDR_WEEK_R)%16;
- pos=6;//闪烁位标志为6、7位
- TR0=1;//启动定时器1
- }
- break;
- }
- }
- break;
-
- case 3://按键3:左移按键(改变闪烁位的值)
- {
- c=0;
- pos=pos-2;
- if((pos<2)&&(change_key1==1)) //若当前显示年月日
- pos=6;
- else if((pos<0)&&(change_key1==0)) //若当前显示时分秒
- pos=6;
- }
- break;
-
- case 4://按键4:右移按键(改变闪烁位的值)
- {
- c=0;
- pos=pos+2;
- if((pos>6)&&(change_key1==1))
- pos=2;
- else if((pos>6)&&(change_key1==0))
- pos=0;
- }
- break;
-
- case 5://按键5:加
- {
- //若按下了修改键且当前显示时分秒
- if((change_key1==0)&&(change_key2==1)&&(d==1))
- {
- d=2;
- //根据当前闪烁的位置改变对应的时间
- switch(pos)
- {
- case 6://秒位置
- {
- secondg++;
- if(secondg==10)
- {
- secondg=0;
- seconds++;
- if(seconds==6)
- seconds=0;
- }
- }
- break;
- case 4://分位置
- {
- minuteg++;
- if(minuteg==10)
- {
- minuteg=0;
- minutes++;
- if(minutes==6)
- minutes=0;
- }
- }
- break;
- case 2://时位置
- {
- hourg++;
- if(hourg==10)
- {
- hourg=0;
- hours++;
- if(hours==3)
- hours=0;
- }
- }
- break;
- case 0://星期位置
- {
- week++;
- if(week==8)
- week=0;
- }
- break;
- }
- }
- //若按下了修改键且当前显示年月日
- if((change_key1==1)&&(change_key2==1)&&(d==1))
- {
- d=2;
- switch(pos)
- {
- case 6://日位置
- {
- dayg++;
- if(dayg==10)
- {
- dayg=0;
- days++;
- if(days==4)
- days=0;
- }
- }
- break;
- case 4://月位置
- {
- monthg++;
- if(monthg==10)
- {
- monthg=0;
- months++;
- if(months==2)
- months=0;
- }
- }
- break;
- case 2:
- {
- yearg++;
- if(yearg==10)
- {
- yearg=0;
- years++;
- if(years==10)
- years=0;
- }
- }
- break;
- }
- }
- }
- break;
-
- case 6://按键6:减
- {
- //若按下了修改键且当前显示时分秒
- if((change_key1==0)&&(change_key2==1)&&(d==1))
- {
- d=2;
- switch(pos)
- {
- case 6://秒位置
- {
- secondg--;
- if(secondg==-1)
- {
- secondg=9;
- seconds--;
- if(seconds==-1)
- seconds=5;
- }
- }
- break;
- case 4://分位置
- {
- minuteg--;
- if(minuteg==-1)
- {
- minuteg=9;
- minutes--;
- if(minutes==-1)
- minutes=5;
- }
- }
- break;
- case 2://时位置
- {
- hourg--;
- if(hourg==-1)
- {
- hourg=9;
- hours--;
- if(hours==-1)
- hours=2;
- }
- }
- break;
- case 0:
- {
- week--;
- if(week==-1)
- week=7;
- }
- break;
- }
- }
- //若按下了修改键且当前显示年月日
- if((change_key1==1)&&(change_key2==1)&&(d==1))
- {
- d=2;
- switch(pos)
- {
- case 6://日的位置
- {
- dayg--;
- if(dayg==-1)
- {
- dayg=9;
- days--;
- if(days==-1)
- days=3;
- }
- }
- break;
- case 4://月的位置
- {
- monthg--;
- if(monthg==-1)
- {
- monthg=9;
- months--;
- if(months==-1)
- months=1;
- }
- }
- break;
- case 2://年的位置
- {
- yearg--;
- if(yearg==-1)
- {
- yearg=9;
- years--;
- if(years==-1)
- years=9;
- }
- }
- break;
- }
- }
- }
- break;
-
- case 7://按键7:数字键0
- {
- c++;//输入的数是个位还是十位,c%2==1为个位,c%2==0为十位
- if(c%2==1)
- b[0]=0;
- else if(c%2==0)
- {
- b[1]=b[0];
- b[0]=0;
- }
- }
- break;
-
- case 8://按键8:数字键1
- {
- c++;
- if(c%2==1)
- b[0]=1;
- else if(c%2==0)
- {
- b[1]=b[0];
- b[0]=1;
- }
- }
- break;
-
- case 9://按键9:数字键2
- {
- c++;
- if(c%2==1)
- b[0]=2;
- else if(c%2==0)
- {
- b[1]=b[0];
- b[0]=2;
- }
- }
- break;
-
- case 10://按键10:数字键3
- {
- c++;
- if(c%2==1)
- b[0]=3;
- else if(c%2==0)
- {
- b[1]=b[0];
- b[0]=3;
- }
- }
- break;
-
- case 11://按键11:数字键4
- {
- c++;
- if(c%2==1)
- b[0]=4;
- else if(c%2==0)
- {
- b[1]=b[0];
- b[0]=4;
- }
- }
- break;
-
- case 12://按键12:数字键5
- {
- c++;
- if(c%2==1)
- b[0]=5;
- else if(c%2==0)
- {
- b[1]=b[0];
- b[0]=5;
- }
- }
- break;
-
- case 13://按键13:数字键6
- {
- c++;
- if(c%2==1)
- b[0]=6;
- else if(c%2==0)
- {
- b[1]=b[0];
- b[0]=6;
- }
- }
- break;
-
- case 14://按键14:数字键7
- {
- c++;
- if(c%2==1)
- b[0]=7;
- else if(c%2==0)
- {
- b[1]=b[0];
- b[0]=7;
- }
- }
- break;
-
- case 15://按键15:数字键8
- {
- c++;
- if(c%2==1)
- b[0]=8;
- else if(c%2==0)
- {
- b[1]=b[0];
- b[0]=8;
- }
- }
- break;
-
- case 16://按键16:数字键9
- {
- c++;
- if(c%2==1)
- b[0]=9;
- else if(c%2==0)
- {
- b[1]=b[0];
- b[0]=9;
- }
- }
- break;
- }
-
- //将数组b中的值赋给各时间数
- if((change_key1==0)&&(change_key2==1)&&(key>6))
- {
- switch(pos)
- {
- case 6:
- {
- secondg=b[0];
- seconds=b[1];
- }
- break;
- case 4:
- {
- minuteg=b[0];
- minutes=b[1];
- }
- break;
- case 2:
- {
- hourg=b[0];
- hours=b[1];
- }
- break;
- case 0:
- {
- if(c%2==1)
- week=b[0];
- else if(c%2==1)
- week=b[1];
- }
- break;
- }
- }
-
- if((change_key1==1)&&(change_key2==1)&&(key>6))
- {
- switch(pos)
- {
- case 6:
- {
- dayg=b[0];
- days=b[1];
- }
- break;
- case 4:
- {
- monthg=b[0];
- months=b[1];
- }
- break;
- case 2:
- {
- yearg=b[0];
- years=b[1];
- }
- break;
- }
- }
- P0=0x0f;
- temp=P0;
- temp=temp&0x0f;
- while(temp!=0x0f)
- {
- temp=P0;
- temp=temp&0x0f;
- }
- }
- }
- }
- //重设时间函数,将修改后的时间再次设置
- void reset()
- {
- uchar year,month,day,week1,hour,minute,second;
- //将时间数转换为16进制
- year=years*16+yearg;
- month=months*16+monthg;
- day=days*16+dayg;
- week1=week;
- hour=hours*16+hourg;
- minute=minutes*16+minuteg;
- second=seconds*16+secondg;
- resettime[0]=second;
- resettime[1]=minute;
- resettime[2]=hour;
- resettime[3]=day;
- resettime[4]=month;
- resettime[5]=week1;
- resettime[6]=year;
- DS1302_SetInit(resettime);
- }
- //延时函数
- void delayms(uint xms)
- {
- uint i,j;
- for(i=xms;i>0;i--)
- for(j=110;j>0;j--);
- }
- void T0_time() interrupt 1
- {
- TH0=(65536-45872)/256;
- TL0=(65536-45872)%256;
- num++;
- if(num==20)
- num=0;
- }
-
- /******************************************************************************
- 函数名称:DS1302_WriteOneByte
- 函数功能:向DS1302写入一个字符
- 入口参数:ucData-数据
- 返回值:无
- 备注:无
- *******************************************************************************/
- void DS1302_WriteOneByte(unsigned char ucData)
- {
- unsigned char i;
- ACC = ucData;
- DS1302_RST = 1;
- for(i=8; i>0; i--)
- {
- DS1302_IO = ACC0;
- DS1302_CLK = 0;
- DS1302_CLK = 1; //先写入最低位,上升沿写入
- ACC = ACC >> 1;
- }
- }
- /******************************************************************************
- 函数名称:DS1302_ReadOneByte
- 函数功能:从DS1302读取一个数据
- 入口参数:无
- 返回值:读取的数据
- 备注:无
- *******************************************************************************/
- unsigned char DS1302_ReadOneByte(void)
- {
- unsigned char i;
- DS1302_RST = 1;
- for(i=8; i>0; i--)
- {
- ACC = ACC >>1; //相当于汇编中的 RRC
- DS1302_IO = 1;
- DS1302_CLK = 1;
- DS1302_CLK = 0; //下降沿读取,先读最低位
- ACC7 = DS1302_IO;
- }
- return(ACC);
- }
- /******************************************************************************
- 函数名称:DS1302_WriteOneByteAtAddr
- 函数功能:在DS1302的指定位置写入一个数据
- 入口参数:ucAddr-地址 ; ucData-数据
- 返回值:无
- 备注:无
- *******************************************************************************/
- void DS1302_WriteOneByteAtAddr(unsigned char ucAddr, unsigned char ucData)
- {
- DS1302_RST = 0;
- DS1302_CLK = 0;
- DS1302_RST = 1;
- DS1302_WriteOneByte(ucAddr);
- DS1302_WriteOneByte(ucData);
- DS1302_CLK = 1;
- DS1302_RST = 0;
- DS1302_IO = 0;
- }
- /******************************************************************************
- 函数名称:DS1302_ReadOneByteAtAddr
- 函数功能:在指定的位置读取一个数据
- 入口参数:ucAddr-地址
- 返回值:读取的数据
- 备注:无
- *******************************************************************************/
- unsigned char DS1302_ReadOneByteAtAddr(unsigned char ucAddr)
- {
- unsigned char ucBackValue;
- DS1302_RST = 0;
- DS1302_CLK = 0;
- DS1302_RST = 1;
- DS1302_WriteOneByte(ucAddr);
- ucBackValue = DS1302_ReadOneByte();
- DS1302_CLK = 1;
- DS1302_RST = 0;
- return(ucBackValue);
- }
- /******************************************************************************
- 函数名称:DS1302_SetInit
- 函数功能:设置初始化
- 入口参数:pClk-初始化数组的指针
- 返回值:无
- 备注:无
- *******************************************************************************/
- void DS1302_SetInit(unsigned char *pClk)
- {
- unsigned char i;
- unsigned char ucAddr = 0x80;
- DS1302_WriteOneByteAtAddr(0x8e,0x00); /* 控制命令,WP=0,写操作*/
- for(i =7; i>0; i--)
- {
- DS1302_WriteOneByteAtAddr(ucAddr,*pClk); /* 秒 分 时 日 月 星期 年 */
- pClk++;
- ucAddr +=2;
- }
- DS1302_WriteOneByteAtAddr(0x8e,0x80); /* 控制命令,WP=1,写保护*/
- }
- //向HC595发送一个字节
- void SEG_Send595OneByte(unsigned char ucData)
- {
- unsigned char i;
-
- for(i = 0;i < 8;i++) //8位数据依次写入,先写最低位
- {
- SEG_DS = (ucData & 0x80); //先读入高位 x&0x80;
- SEG_SHCP = 0;
- SEG_SHCP = 1;
- SEG_SHCP = 0; //SHCP引脚的上升沿移入数据
- ucData <<=1; //数据左移
- }
- }
- /*******************************************************
- 函数功能:在指定位置显示一个数据
- 参数说明:Data是要显示的数据,Addr是在第几位显示。
- Addr取值范围是0~9。
- Addr=0~7时,选择的是显示在第几位数码管上;
- Addr=8 时,同时选中8位数码管,即打开所有数码管
- Addr=9 时,关闭8位数码管
- 8位数码管,左数依次为第0位,第1位...第7位。
- *******************************************************/
- void DisplayOneCharOnAddr(unsigned char Data,unsigned char Addr)
- {
- SEG_Send595OneByte(Seg_Addr[Addr]); //显示在哪一个数码管上
- SEG_Send595OneByte( Seg_Data[Data]); //显示的数据
- SEG_STCP = 0;
- SEG_STCP = 1; //STCP引脚的上升沿更新数据
- SEG_STCP = 0;
-
- }
-
复制代码
所有资料51hei提供下载:
万年历.rar
(71.02 KB, 下载次数: 9)
|