DS1302+AT24C02+按键数码管显示程序 (原创)
2017-03-25 15:25
477 查看
#include<reg52.h> #include<intrins.h> #define uint unsigned int #define uchar unsigned char bit write=0; sbit led0=P1^5; sbit led1=P1^6; sbit led2=P1^7; sbit sda=P1^1; sbit scl=P1^0; sbit SCLK=P3^5; sbit DATA=P3^6; sbit RST=P3^7; sbit sg=P2^7; sbit ss=P2^6; sbit sb=P2^5; sbit sq=P2^4; uchar code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; uchar second,minute=0; uchar sec; sbit beep=P3^4; // 0 uint state=0; // 0:时钟状态 1:设置秒 2:设置分 3:初始设置状态 sbit key1=P2^1; // 进入设定模式以及 确认设置 先设置秒 后设置分 sbit key3=P2^0; // ++ sbit key4=P2^2; // -- uchar count=0; void display(); void delay() {;;} void delayms(uint ms) { uint i,j; for(i=ms;i>0;i--); for(j=110;j>0;j--); } /******************/ void start() { sda=1; delay(); scl=1; _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); sda=0; _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); } void stop() { sda=0; _nop_(); scl=1; _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); sda=1; _nop_(); _nop_(); _nop_(); _nop_(); } void respons() { uchar i; scl=1; delay(); while((sda==1)&&(i<100))i++; scl=0; delay(); } void initAT() { sda=1; delay(); scl=1; delay(); } void write_byte(uchar date) { uchar i,temp; temp=date; for(i=0;i<8;i++) { temp=temp<<1; scl=0; delay(); sda=CY; delay(); scl=1; delay(); } scl=0; delay(); sda=1; delay(); } uchar read_byte() { uchar i,k; scl=0; delay(); sda=1; delay(); for(i=0;i<8;i++) { scl=1; delay(); k=(k<<1)|sda; scl=0; delay(); } return k; } void write_add(uchar address,uchar date) { start(); write_byte(0xa0); //1010 000 0 0为读 1为写 respons(); write_byte(address); respons(); write_byte(date); respons(); stop(); } uchar read_add(uchar address) { uchar date; start(); write_byte(0xa0); respons(); write_byte(address); respons(); start(); write_byte(0xa1); //1010 000 1 respons(); date=read_byte(); stop(); return date; } /*************************************************/ void write1302(uchar dat) { uchar i; SCLK=0; //拉低SCLK,为脉冲上升沿写入数据做好准备 delay(); //稍微等待,使硬件做好准备 for(i=0;i<8;i++) //连续写8个二进制位数据 { DATA=dat&0x01; //取出dat的第0位数据写入1302 低位在前,高位在后 delay(); //稍微等待,使硬件做好准备 SCLK=1; //上升沿写入数据 delay(); //稍微等待,使硬件做好准备 SCLK=0; //重新拉低SCLK,形成脉冲 dat>>=1; //将dat的各数据位右移1位,准备写入下一个数据位 } } void writeset1302(uchar Cmd,uchar dat) { RST=0; //禁止数据传递 SCLK=0; //确保写数居前SCLK被拉低 RST=1; //启动数据传输 delay(); //稍微等待,使硬件做好准备 write1302(Cmd); //写入命令字 write1302(dat); //写数据 SCLK=1; //将时钟电平置于高电平状态 RST=0; //禁止数据传递 } uchar Read1302() { uchar i,dat; delayms(2); //稍微等待,使硬件做好准备 for(i=0;i<8;i++) //连续读8个二进制位数据 { dat>>=1; if(DATA==1) //如果读出的数据是1 dat|=0x80; //将1取出,写在dat的最高位 SCLK=1; //将SCLK置于高电平,为下降沿读出 _nop_(); //稍微等待 SCLK=0; //拉低SCLK,形成脉冲下降沿 _nop_(); } return dat; //将读出的数据返回 } uchar ReadSet1302(uchar Cmd) { uchar dat; RST=0; //拉低RST SCLK=0; //确保写数居前SCLK被拉低 RST=1; //启动数据传输 write1302(Cmd); //写入命令字 dat=Read1302(); //读出数据 SCLK=1; //将时钟电平置于已知状态 RST=0; //禁止数据传递 return dat; //将读出的数据返回 } void confirm() { uchar ReadValue; ReadValue = ReadSet1302(0x81); //从秒寄存器读数据 second=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);//将读出数据转化 //0x70=01110000 &同为同 异为0 保留111位 0x0f=1111 保留后四位 ReadValue = ReadSet1302(0x83); //从分寄存器读 minute=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); //将读出数据转化 } /********************************************************************************************************************/ void init_DS1302() { uchar flag; flag= ReadSet1302(0x81); if(flag&0x80) { //判断时钟芯片是否关闭 writeset1302(0x8E,0x00); //根据写状态寄存器命令字,写入不保护指令 writeset1302(0x80,((second/10)<<4|(second%10))); //根据写秒寄存器命令字,写入秒的初始值 writeset1302(0x82,((minute/10)<<4|(minute%10))); //根据写分寄存器命令字,写入分的初始值 writeset1302(0x84,((23/10)<<4|(23%10))); //根据写小时寄存器命令字,写入小时的初始值 writeset1302(0x86,((18/10)<<4|(18%10))); //根据写日寄存器命令字,写入日的初始值 writeset1302(0x88,((6/10)<<4|(6%10))); //根据写月寄存器命令字,写入月的初始值 writeset1302(0x8c,((9/10)<<4|(9%10))); //根据写年寄存器命令字,写入年的初始值 writeset1302(0x90,0xa5); //打开充电功能 选择2K电阻充电方式 writeset1302(0x8E,0x80); //根据写状态寄存器命令字,写入保护指令 } } void bee() { beep=0; delayms(100); beep=1; } void display() //先秒后分 { if(state==0||state==3) { uchar ge0,ge1,shi1,shi0; ge0=second%10; shi0=second/10; ge1=minute%10; shi1=minute/10; sq=0; P0=table[ge0]; delayms(5); sq=1; P0=0xff; sb=0; P0=table[shi0]; delayms(5); sb=1; P0=0xff; ss=0; P0=table[ge1]; delayms(5); ss=1; P0=0xff; sg=0; P0=table[shi1]; delayms(5); sg=1; P0=0xff; } else { uchar ge,shi; ge=count%10; shi=count/10; sq=0; P0=table[ge]; delayms(5); sq=1; P0=0xff; sb=0; P0=table[shi]; delayms(5); sb=1; P0=0xff; } } void steins() // 将设置后的数据存入时钟模块内 { writeset1302(0x8E,0x00); //根据写状态寄存器命令字,写入不保护指令 writeset1302(0x80,((second/10)<<4|(second%10))); //根据写秒寄存器命令字,写入秒的初始值 writeset1302(0x82,((minute/10)<<4|(minute%10))); //根据写分寄存器命令字,写入分的初始值 writeset1302(0x8E,0x80); //根据写状态寄存器命令字,写入保护指令 } void keyscan() { if(key1==0) // 进入设定模式0 1 2 &确认设置 PS:先设置秒 后设置分 { delayms(10); if(key1==0) { while(!key1)display(); display(); bee(); if(state==0) { led0=0; led1=1; led2=1; state=3; } else { if(state==3) { led0=1; led1=0; led2=1; state=1; count=second; } else { if(state==1) //s { led0=1; led1=1; led2=0; state=2; second=count; count=minute; } else { if(state==2) //m { led2=0; led1=0; led0=0; state=0; minute=count; count=0; steins(); } } } } } } if(key3==0) //++ { delayms(10); if(key3==0) { while(!key3)display();; display(); bee(); if(state==1||state==2) { if(count==60) count=0; else count++; } } } if(key4==0) //-- { delayms(10); if(key4==0) { while(!key4)display(); display(); bee(); if(state==1||state==2) { if(count==0) count=60; else count--; } } } } void main() { beep=1; led0=0; led1=0; led2=0; state=0; //引脚初始化 initAT(); //AT24c02初始化 sec=read_add(2); second=sec%60; minute=sec/60; d 4000 elayms(1); init_DS1302(); //DS1302初始化 delayms(1); steins(); //获取时钟数据 while(1) { display(); confirm(); sec=minute*60+second; write_add(2,sec); keyscan(); } }
相关文章推荐
- 整理2010年51单片机程序--4*4按键与数码管显示
- 设计程序,用数码管显示按键编号
- 【原创】基于FPGA的数码管按键显示(two_key)
- 这是个完整的万年历程序,用数码管显示
- 51单片机动态数码管显示C程序不解
- 《FPGA零基础入门到精通视频教程》-第005讲数码管显示(按键去抖,状态机,BCD码转换)
- PIC16F883实现按键行列扫描,准确识别按键,数码管显示按键编号
- 并行口实现数字0~9、A~F、L、U、P、n总共19个键盘,将按键的结果用7段数码管(例如:7SEG-MPX-CA-BLUE)显示(可选——按键控制移位)出来
- 按键数码管显示实验
- DS1302实时时钟模块显示到数码管(共阳极)
- 数码管循环显示程序
- 数码管显示矩阵键盘扫描程序
- 外中断(按键)控制数码管显示
- 按键控制数码管显示
- 按键+串口修改时间(数码管显示)
- 独立按键数码管显示键值
- [原创]Qt显示MessageBox对话框程序
- 求SM1623B的数码管显示程序
- 1~99秒倒计时数码管显示C程序+Proteus仿真
- 数码管动态显示程序