万年历时钟芯片代码

合集下载

单片机万年历程序带农历和闹钟

单片机万年历程序带农历和闹钟

#include < character.h >#include < lcd.h >#include < clock.h >#include < sensor.h>#include < calendar.h >#include < key.h >/*****************************预概念**************************************/#define uchar unsigned char#define uint unsigned int/****************************************************************************/ sbit bell = P2 ^ 0; //概念蜂鸣器端口sbit in = P2 ^ 7; //概念红外检测端口/***************************************************************************** * 名称: Timer0_Service() inturrupt 1* 功能: 中断效劳程序整点报时3声嘟嘟的声音* 入口参数:* 出口参数:*****************************************************************************/ void Timer0_Service() interrupt 1{static uchar count = 0;static uchar flag = 0; //记录鸣叫的次数count = 0;TR0 = 0; //关闭Timer0TH0 = 0x3c;TL0 = 0XB0; //延时50 msTR0 = 1 ; //启动Timer0count ++;if( count == 20 ) //鸣叫1 秒{bell = ~ bell;count = 0;flag ++;}if( flag == 6 ){flag = 0;TR0 = 0; //关闭Timer0}}/****************************************************************************** 名称: Timer2_Servie() interrupt 5* 功能: 中断效劳程序整点报时一分钟* 入口参数:* 出口参数:*****************************************************************************/ void Timer3_Service() interrupt 5{static uchar count;TF2 = 0; //软件清除中断标志count ++;if( in == 1 ){count = 0; //计算清0TR2 = 0; //关闭Timer2bell = 1; //关闭蜂鸣器}if( count == 120 ) // 一分钟后关闭报警{count = 0; //计算清0TR2 = 0; //关闭Timer2bell = 1; //关闭蜂鸣器}}/****************************************************************************** * 函数名称:main()* 功能:* 入口参数:* 出口参数:******************************************************************************* */void main( void ){uchar clock_time[7] = { 0x00, 0x17, 0x12, 0x14, 0x12, 0x08 }; //概念时刻变量秒分时日月年uchar alarm_time[2] = { 0, 0}; //闹钟设置alarm_time[0]: 分钟alarm_time[1] :小时uchar temperature[2]; //概念温度变量temperature[0] 低8位temperature[1] 高8位Lcd_Initial(); //LCD初始化Clock_Initial( clock_time ); //时钟初试化/***********************中断初始化***************************/EA = 1; //开总中断ET0 = 1; //Timer0 开中断ET2 = 1; //Timer2 开中断TMOD = 0x01 ; //Timer0 工作方式1RCAP2H = 0x3c;RCAP2L = 0xb0; //Timer2 延时50 mswhile( 1 ){switch( Key_Scan() ){case up_array: //{Key_Idle();}break;case down_array:{Key_Idle();}break;case clear_array:{Key_Idle();}break;case function_array:{Key_Function( clock_time, alarm_time );}case null:{Clock_Fresh( clock_time ); //时刻刷新Lcd_Clock( clock_time ); //时刻显示Sensor_Fresh( temperature ); //温度更新Lcd_Temperture( temperature ); //温度显示Calendar_Convert( 0 , clock_time );Week_Convert( 0, clock_time );//整点报时if( ( * clock_time == 0x59 ) && ( * ( clock_time + 1 ) == 0x59 ) ){bell = 0;TR2 = 1; //启动Timer2}//闹钟报警if( * alarm_time == * ( clock_time + 1 ) ) //分钟相吻合if( * ( alarm_time + 1 ) == *( clock_time + 2 ) ) //小时相吻合{bell = 0;TR2 = 1; //启动Timer2}}break;}}}#ifndef _SUN_MOON#define _SUN_MOON/*************************************************************************/#define uchar unsigned char#define uint unsigned int/****************************************************************************** *** 名称: get_moon_day(uchar month_p,uint table_addr)* 功能: 读取数据表中农历的大月或小月,若是大月返回1, 小月返回0* 入口参数:* 出口参数:******************************************************************************* **/bit get_moon_day( uchar month_p,uint calendar_address ){uchar temp;switch(month_p){case 1: { temp = year_code[calendar_address] & 0x08; if(temp==0) return(0); else return(1); }case 2: { temp = year_code[calendar_address] & 0x04; if(temp==0) return(0); else return(1); }case 3: { temp = year_code[calendar_address] & 0x02; if(temp==0) return(0); else return(1); }case 4: { temp = year_code[calendar_address] & 0x01; if(temp==0) return(0); else return(1); }case 5: { temp = year_code[calendar_address + 1] & 0x80; if(temp==0) return(0); else return(1); }case 6: { temp = year_code[calendar_address + 1] & 0x40; if(temp==0) return(0); else return(1); }case 7: { temp = year_code[calendar_address + 1] & 0x20; if(temp==0) return(0); else return(1); }case 8: { temp = year_code[calendar_address + 1] & 0x10; if(temp==0) return(0); else return(1); }case 9: { temp = year_code[calendar_address + 1] & 0x08; if(temp==0) return(0); else return(1); }case 10: { temp = year_code[calendar_address + 1] & 0x04; if(temp==0) return(0); else return(1); }case 11: { temp = year_code[calendar_address + 1] & 0x02; if(temp==0) return(0); else return(1); }case 12: { temp = year_code[calendar_address + 1] & 0x01; if(temp==0) return(0); else return(1); }case 13: { temp = year_code[calendar_address + 2] & 0x80; if(temp==0) return(0); else return(1); }}}/*************************************************************************** 名称: void Calendar_Convert( uchar * clock_time )* 功能: 输入BCD的阳历数据,输出BCD阴历数据( 1901 - 2099 )* 入口参数: c_flag:阳历的世纪标志clock_time: 时钟地址* 出口参数: 无* 说明: c_flag = 0 :21世纪c_flag = 1 :19世纪*****************************************************************************/ void Calendar_Convert( uchar c_flag, uchar * clock_time ){bit flag_month, flag_year;uchar year, month, day, month_point; //概念年月天uchar temp1, temp2, temp3;uint calendar_address; //概念农历地址uint day_number;uchar clock_moon[3]; //概念阴历clock_time += 3; //指向日day = ( * clock_time >> 4 ) * 10 + ( *clock_time & 0x0f ); //BCD转换十进制clock_time ++; //指向月month = ( * clock_time >> 4 ) * 10 + ( * clock_time & 0x0f ); //BCD转换十进制clock_time ++; //指向年year = ( * clock_time >> 4 ) * 10 + ( * clock_time & 0x0f ); //BCD转换十进制//定位日历地址if( c_flag == 0 )calendar_address = ( year + 99 ) * 3;elsecalendar_address = ( year - 1 ) * 3;//春节(正月初一)所在的阳历月份temp1 = year_code[ calendar_address + 2 ] & 0x60; //Bit6~~Bit5:春节所在的阳历月份temp1 >>= 5 ;//春节(正月初一)所在的阳历日期temp2 = year_code[ calendar_address + 2 ] & 0x1f; //Bit4~~Bit0:春节所在的阳历日期//计算春节(正月初一)离昔时元旦{ 1月1日(阳历) }的天数;春节只会在阳历的1月或2月if( temp1 == 1 )temp3 = temp2 - 1;elsetemp3 = temp2 + 31 - 1;//计算阳历月离昔时元旦{ 1月1日(阳历) }的天数if( month < 10 )day_number = day_code1[ month - 1 ] + day - 1;elseday_number = day_code2[ month - 10 ] + day - 1;//若是阳历的月大于2 且该年的2月为闰月,天数加1//闰年指的确实是阳历有闰日或阴历有闰月的一年;//阳历四年一闰,在二月加一天,这一天叫做闰日://农历三年一闰,五年两闰,十九年七闰,每逢闰年所加的一个月叫做闰月。

DS1302万年历芯片

DS1302万年历芯片

DS1302时钟时间芯片#include<reg52.h>#include<INTRINS.H>/************************************************************/#define uchar unsigned char#define uint unsigned int#define write_second 0x80 //秒开始数存储,修改用(下同)#define write_minute 0x82 //分开始数存储#define write_hour 0x84 //时开始数存储,12小时计时,从0开始要写入0x80(12小时要判断上下午)。

#define read_second 0x81 //秒,显示要读这个存储器#define read_minute 0x83 //分,显示要读这个存储器#define read_hour 0x85 //时,显示要读这个存储器#define write_day 0x86#define read_day 0x87#define write_month 0x88#define read_month 0x89#define write_week 0x8A#define read_week 0x8B#define write_year 0x8C#define read_year 0x8D#define write_protect 0x8E/************************************************************/ sbit ACC_7=ACC^7;sbit SCLK =P1^2;sbit DIO =P1^3;sbit CE =P1^4; //protus软件中的RES脚/********************************/uchar dd[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};void delay(char us){char m,n;while(us--){for(m=0;m<40;m++)for(n=0;n<50;n++);}}/**********/void write1302(unsigned char addr,dat){unsigned char i,temp; CE=0;SCLK=0;CE=1;for(i=0;i<8;i++){SCLK=0;temp=addr;if(temp&0x01==0x01) DIO=1;elseDIO=0;addr>>=1;SCLK=1;}for(i=0;i<8;i++){SCLK=0;temp=dat;if(temp&0x01==0x01) DIO=1;elsedat>>=1;SCLK=1;}}unsigned char read1302(unsigned char addr) {unsigned char i,temp,dat1,dat2;CE=0;SCLK=0;CE=1;for(i=8;i>0;i--)//дÈë¶ÁÊý¾ÝµØÖ·{SCLK =0;temp =addr;if(temp&0x01==0x01)DIO=1;elseDIO=0;addr>>=1;SCLK=1;for(i=8;i>0;i--)//¶ÁÊý¾Ý{ACC_7=DIO;SCLK=1;ACC>>=1;SCLK=0; //下降沿读出数据 }CE=0;dat1=ACC;dat2=dat1/16;dat1=dat1%16;dat1=dat1+dat2*10;return(ACC);}///////////////////////////////////// void Initial(void){write1302(write_protect,0x00); write1302(write_second,0x56); write1302(write_minute,0x34);write1302(write_hour,0x12);write1302(write_protect,0x80);}/////////////////////void main(void){unsigned char tt1,tt2,hour;Initial();write1302(write_second,0x55); //秒从55开始write1302(write_minute,0x59); //分从59开始write1302(write_hour,0x8B); //赋值0x80,为12小时计时,但低五位为计时为,所以,显示只显示低五位,小时从11开始write1302(write_year,0x0f); //15年write1302(write_week,0x03);//周三write1302(write_month,0x0a);//10月while(1){tt1=read1302(read_second);tt2=read1302(read_hour) & 0x1f; //取出低五位if(read1302(read_hour) & 0x20==0x20) //12小时计时判断上下午hour="pm "; // afternoonelsehour="am ";//morningP0=dd[tt1/10];P2=0xfe;delay(2);P2=0xff;P0=dd[tt1%10];P2=0xfd;delay(2);P2=0xff;P0=dd[tt2/10];P2=0xf7;delay(2);P2=0xff;P0=dd[tt2%10];P2=0xfb;delay(2);P2=0xff;}}。

基于PCF8563时钟芯片的万年历制作

基于PCF8563时钟芯片的万年历制作

万年历是一种能够显示日期、星期和时间的工具,它不仅能够告诉我们当天是几号,还能显示星期几和当前时间。

在这个项目中,我们将使用PCF8563时钟芯片来制作一个基于PCF8563的万年历。

PCF8563是一种CMOS实时时钟和日历芯片,它可以提供年、月、日、星期和小时、分钟、秒的数据。

它具有电源管理功能,可以通过一个电源低于2V脉冲输入来切换系统电源供电方式。

为了制作这个基于PCF8563的万年历,我们需要以下材料和工具:1. Arduino主控板2.PCF8563时钟芯片3.16x2液晶显示屏4.面包板5.杜邦线6.10k电阻接下来,我们将按照以下步骤来制作基于PCF8563的万年历:第一步:连接电路首先,将Arduino主控板插入面包板。

接着,连接PCF8563时钟芯片到Arduino主控板上的I2C总线。

将SDA引脚连接到A4引脚,将SCL引脚连接到A5引脚。

此外,还需要使用10k电阻将VCC引脚连接到VCC引脚上。

接下来,将16x2液晶显示屏连接到面包板。

连接液晶屏的RS引脚到Arduino主控板的D12引脚,RW引脚到GND引脚,和E引脚到D11引脚。

将液晶屏的D4到D7引脚连接到Arduino主控板的D5到D2引脚。

第二步:编写代码打开Arduino IDE并创建一个新的项目。

然后,编写以下代码:#include <Wire.h>#include <LiquidCrystal_I2C.h>//定义PCF8563的地址#define PCF8563_ADDR 0x51//定义显示屏的尺寸#define LCD_COLUMNS 16#define LCD_ROWS 2LiquidCrystal_I2C lcd(0x27, LCD_COLUMNS, LCD_ROWS);void setup//初始化I2C总线Wire.begin(;//设置时钟芯片为24小时模式Wire.beginTransmission(PCF8563_ADDR);Wire.write(0x02);Wire.write(0x00);Wire.endTransmission(;//初始化液晶显示屏lcd.begin(LCD_COLUMNS, LCD_ROWS);lcd.setCursor(0, 0);lcd.print("Date: ");lcd.setCursor(0, 1);lcd.print("Time: ");void loop//读取PCF8563的日期和时间Wire.beginTransmission(PCF8563_ADDR); Wire.write(0x02);Wire.endTransmission(;Wire.requestFrom(PCF8563_ADDR, 7);int second = bcdToDec(Wire.read( & 0x7F); int minute = bcdToDec(Wire.read();int hour = bcdToDec(Wire.read( & 0x3F); int dayOfWeek = bcdToDec(Wire.read();int dayOfMonth = bcdToDec(Wire.read();int month = bcdToDec(Wire.read( & 0x1F); int year = bcdToDec(Wire.read();//显示日期和时间lcd.setCursor(6, 0); printWithLeadingZero(dayOfMonth);lcd.print("/");printWithLeadingZero(month);lcd.print("/");lcd.print(2000 + year);lcd.setCursor(6, 1); printWithLeadingZero(hour);lcd.print(":");printWithLeadingZero(minute);lcd.print(":");printWithLeadingZero(second);delay(1000);//将BCD码转换为十进制int bcdToDec(int bcd)return (bcd / 16 * 10) + (bcd % 16);//打印带有前导零的数字void printWithLeadingZero(int number)if (number < 10)lcd.print('0');}lcd.print(number);第三步:上传代码将Arduino主控板连接到电脑,并根据需要选择正确的端口和板类型。

实时时钟,日历芯片-BM8563,兼容PCF8563,参考源代码

实时时钟,日历芯片-BM8563,兼容PCF8563,参考源代码

_nop_(); _nop_(); }
/******************************************************************** 函 数 名:Stop_I2C(void) 功 能:停止 I2C 总线的传输 说 明: 调 用: 入口参数:无 返 回 值:无 ***********************************************************************/ void Stop_I2C(void) { SCL=0; _nop_(); SCL=1; SomeNOP(); SDA=1; SomeNOP(); }
/******************************************************************** 函 数 名: GetBM8563(void) 功 能:从 BM8563 的内部寄存器(时间、状态、报警等寄存器)读取数据 说 明:该程序函数用来读取 BM8563 的内部寄存器,譬如时间,报警,状态等寄存器 采用页写的方式,设置数据的个数为 no,no 参数设置为 1 就是单字节方式 调 用:Start_I2C(),SendByte(),RcvByte(),Ack_I2C(),Stop_I2C() 入口参数:sla(BM8563 从地址) , suba(BM8563 内部寄存器地址) *s(设置读取数据存储的指针) , no(传输数据的个数) 返 回 值:有,返回布尔量(bit)用来鉴定传输成功否 ***********************************************************************/ bit GetBM8563(uchar sla,uchar suba,uchar *s,uchar no) { uchar i; Start_I2C(); SendByte(sla); if(ack==0)return(0); SendByte(suba); if(ack==0)return(0); Start_I2C(); SendByte(sla+1); if(ack==0)return(0); for (i=0;i<no-1;i++) { *s=RcvByte(); Ack_I2C(0); s++; } *s=RcvByte(); Ack_I2C(1); Stop_I2C();//除最后一个字节外,其他都要从 MASTER 发应答。 return(1); }

单片机万年历时钟

单片机万年历时钟

#include<reg52.h> //用定时器实现电子时钟#include<delay.h>#define uint unsigned int#define uchar unsigned charsbit wela = P2^7;sbit dula = P2^6;sbit lcdrs = P1^0;sbit lcdrw = P1^1;sbit lcden = P2^5;sbit beep = P2^3;uchar lcd1[] = "2014-07-22 TUE";uchar lcd2[] = "00-00-00";uchar num;uchar hour = 23,min = 59,sec = 50;uchar i;//循环时用到i计数uchar month = 7,day = 22;uint year = 2014, week = 3; //时间初始化,可自己定义void write_com(uchar com) //写命令{lcdrs = 0;lcden = 0;P0 = com;delayms(3);lcden = 1;delayms(3);lcden = 0;}void write_data(uchar dat) //写数据{lcdrs = 1;lcden = 0;P0 = dat;delayms(5);lcden = 1;delayms(5);lcden = 0;}void init()//液晶初始化,包括第一次的显示{dula = 0;wela = 0;lcden = 0;lcdrw = 0;write_com(0x38);//设置16*2显示,5*7点阵,8位数据口//delayms(5); //确保程序安全写入,程序小的情况下write_com(0x0c); //设置开显示,不显示光标//delayms(5);write_com(0x06);//写一个字符后地址指针加一//delayms(5);write_com(0x01);//显示清零,数据指针清零//delayms(5);write_com(0x80); //从第一行第一个光标开始//delayms(5);for(i=0;i<14;i++){write_data(lcd1[i]);delayms(1);}write_com(0x80+0x43); //从第二行第三个开始显示for(i=0;i<8;i++){write_data(lcd2[i]) ;delayms(1);}TMOD = 0x01; //定时器中断0初始化TH0 = (65536-45872)/256;TL0 = (65536-45872)%256;EA = 1;TR0 = 1;ET0 = 1;}void display_sfm(uchar add,uchar date){uchar shi,ge;shi = date/10;ge = date%10;write_com(0x80+0x40+add); //找到位write_data(0x30+shi);//写数据,0x30是16进制,在液晶中代表0,加几代表写几write_data(0x30+ge ) ;// 写数据依次来的}void display_week(uchar a )//显示星期几{switch(a){case 1: write_com(0x80+11);//星期一write_data(0x40);write_data(0x4f);write_data(0x4e);break;case 2: write_com(0x80+11);write_data(0x54);write_data(0x55);write_data(0x45);break;case 3: write_com(0x80+11);write_data(0x57);write_data(0x45);write_data(0x44);break;case 4: write_com(0x80+11);write_data(0x54);write_data(0x48);write_data(0x55);break;case 5: write_com(0x80+11);write_data(0x46);write_data(0x52);write_data(0x49);break;case 6: write_com(0x80+11);write_data(0x54);write_data(0x48);write_data(0x55);break;case 7: write_com(0x80+11);write_data(0x53);write_data(0x55);write_data(0x4e);break;}}void display_yue_ri(uchar add,uchar date) {uchar shi,ge;shi = date/10;ge = date%10;write_com(0x80+add); //找到位write_data(0x30+shi);//写数据,0x30是16进制,在液晶中代表0,加几代表写几write_data(0x30+ge);// 写数据依次来的}void display_year(uint year)//注意数据之间的传输不要出现错误{uchar a,b,c,d;a = year/1000;b = year/100%10;c = year/10%10;d = year%10;write_com(0x80);//控制指针write_data(0x30+a);//控制显示什么数字write_data(0x30+b);write_data(0x30+c);write_data(0x30+d);}void main()//主程序内越精简越好{init();while(1){if(num==20){num = 0;sec++;if(sec==60){sec = 0;min++;if(min==60){min = 0;hour++;if(hour==24){hour = 0;day++;display_week(week);//显示星期几week++;if(week==8)week = 0;if(((year/4==0&&year/100!=0)||(year/400==0)&&(month==2))&&(day==29))//闰年2月判断{day = 0;month++;}if(((month==1)||(month==3)||(month==5)||(month==7)||(month==8)||(month==10)||(month==12))&&(day==31))//1.3.5.7.8.10.12月份{day = 0;month++;}if(((month==4)||(month==6)||(month==9)||(month==11))&&(day==30))//4.6.9.11月份{day = 0;month++;}if((!(year/4==0&&year/100!=0)||(year/400==0))&&(month==2)&&(day==28))//非闰年2月判断{day = 0;month++;}if(month==12){month = 1;year++;}}}}display_sfm(9,sec);//显示display_sfm(6,min);display_sfm(3,hour);display_year(year);display_yue_ri(5,month);display_yue_ri(8,day);}}}void T0_timer() interrupt 1{TH0 = (65536-45872)/256;TL0 = (65536-45872)%256;num++;}。

单片机数字钟万年历(c语言)

单片机数字钟万年历(c语言)

#include <REGX51.H>#include <ABSACC.h>#define Font_code XBYTE[0xefff] //字符码写地址#define reg_code XBYTE[0xdfff] //字位码写地址#define s_1_con_key P3_2#define m_1_con_key P3_3#define h_1_con_key P3_4#define w_1_con_key P3_5#define p1 P1sbit BELL=P1^0;//sbit p10=P1^0;//sbit p20=P1^1;//sbit p30=P1^2;//sbit p40=P1^3;//sbit p50=P1^4;//sbit p60=P1^5;//sbit p70=P1^6;//sbit p80=P1^7;//字型码const unsigned char seg_design[11]={0x3F,/*0*/0x06,/*1*/0x5B,/*2*/0x4F,/*3*/0x66,/*4*/0x6D,/*5*/0x7D,/*6*/0x07,/*7*/0x7F,/*8*/0x6F,/*9*/0x40,/*-*/};//字位码const unsigned char bit_design[8]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};code unsigned char sszymmh[]={ 6,2,3, 5,2,1, 3,2,2, 5,2,2, 1,3,2, 6,2,1, 5,2,1,6,2,4, 3,2,2, 5,2,1, 6,2,1, 5,2,2, 3,2,2, 1,2,1,6,1,1, 5,2,1, 3,2,1, 2,2,4, 2,2,3, 3,2,1, 5,2,2,5,2,1, 6,2,1, 3,2,2, 2,2,2, 1,2,4, 5,2,3,3,2,1,2,2,1, 1,2,1, 6,1,1, 1,2,1, 5,1,6, 0,0,0} ;// 音阶频率表高八位code unsigned char FREQH[]={0xF2,0xF3,0xF5,0xF5,0xF6,0xF7,0xF8,0xF9,0xF9,0xFA,0xFA,0xFB,0xFB,0xFC,0xFC,//1,2,3,4,5,6,7,8,i0xFC,0xFD,0xFD,0xFD,0xFD,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFF,} ;// 音阶频率表低八位code unsigned char FREQL[]={0x42,0xC1,0x17,0xB6,0xD0,0xD1,0xB6,0x21,0xE1,0x8C,0xD8,0x68,0xE9,0x5B,0x8F,//1,2,3,4,5,6,7,8,i0xEE,0x44, 0x6B,0xB4,0xF4,0x2D,0x47,0x77,0xA2,0xB6,0xDA,0xFA,0x16,};unsigned char bit_con;unsigned int ms_1_con; //毫秒计数器unsigned char s_1_con; //秒计数器unsigned char m_1_con; //分计数器unsigned char h_1_con=12;//时计数器unsigned char w_1_con=6; //周计时器unsigned char d_1_con=1;unsigned char mon_1_con=1;unsigned int y_1_con=2011;unsigned char s1; //秒计数器unsigned char m1; //分计数器unsigned char h1; //时计数器unsigned char Display_Buffer[8]; //显示缓冲区unsigned int k1=0;unsigned int k2=0;unsigned char timer0h,timer0l,time,led=1,j=0;unsigned char flagd=0;void delay_nms(unsigned int n);void Calculation_display(void);void time_set(void);void time_set1(void);void time_set2(void);void InitTimer0(void){TMOD = 0x01; // 方式1,16位计数器方式TH0 = 0xFC; //定时初值=65536-n n=1000,定时周期是1ms TL0 = 0x18;EA = 1; //开总中断使能ET0 = 1; //允许定时器T0溢出中断TR0 = 1; //T0 运行}void delay(unsigned char t){unsigned char t1;unsigned long t2;for(t1=0;t1<t;t1++){for(t2=0;t2<4000;t2++){;}}TR0=0;}void song(){TH0=timer0h;TL0=timer0l;TR0=1;delay(time);}void sing(){unsigned char k,i=0;time=1;while(time){if(k1==0) break;InitTimer0();Calculation_display();if(k2==0)time_set();else if(k2==1)time_set1();elsetime_set2();p1=~seg_design[8];k=sszymmh[i]+7*sszymmh[i+1]-1;timer0h=FREQH[k];timer0l=FREQL[k];time=sszymmh[i+2];i=i+3;song();}}void main(void){InitTimer0();while(1){Calculation_display();delay_nms(100);if(k2==0)time_set();else if(k2==1)time_set1();elsetime_set2();sing();k1=0;InitTimer0();}}void Timer0Interrupt(void) interrupt 1 using 1 {TH0 = 0xFC;TL0 = 0x18;ms_1_con++;//采用定时扫描方式bit_con++;if(bit_con > 7) bit_con = 0;reg_code = 0x00; //先消隐显示Font_code = Display_Buffer[bit_con];reg_code = bit_design[bit_con];if(k1==1){TR0=0;BELL=!BELL;TH0=timer0h;TL0=timer0l;TR0=1;}}void delay_nms(unsigned int n) //延时N ms{unsigned char a,b;unsigned int c;for(c=n;c>0;c--)for(b=142;b>0;b--)for(a=2;a>0;a--);}void Calculation_display(void){unsigned char day;if(ms_1_con > 999) //1000ms定时到{ms_1_con = 0;s_1_con++;if(s_1_con > 59){s_1_con = 0;m_1_con++;if(m_1_con > 59){m_1_con = 0;h_1_con++;k1=1;if(h_1_con > 23){h_1_con = 0;w_1_con++;if(w_1_con>7)w_1_con=1;switch(mon_1_con){case 1:case 3:case 5:case 7:case 8:case 10:case 12:day=31;break;case 2:day=28;break;case 4:case 6:case 9:case 11:day=30;break;}d_1_con++;if(d_1_con>day){mon_1_con++;d_1_con=1;if(mon_1_con>12){y_1_con++;mon_1_con=1;}}}}}}p1=~seg_design[w_1_con];if(k2==0){if(ms_1_con<500){Display_Buffer[2] = seg_design[10];Display_Buffer[5] = seg_design[10];}else{Display_Buffer[2] = !seg_design[10];Display_Buffer[5] = !seg_design[10];}Display_Buffer[6] = seg_design[s_1_con/10];//秒十位Display_Buffer[7] = seg_design[s_1_con%10]; //秒个位Display_Buffer[3] = seg_design[m_1_con/10]; //分十位Display_Buffer[4] = seg_design[m_1_con%10]; //分个位Display_Buffer[0] = seg_design[h_1_con/10]; //时十位Display_Buffer[1] = seg_design[h_1_con%10]; //时个位}if(k2==1){Display_Buffer[3] = seg_design[y_1_con%10]; //年个位Display_Buffer[2] = seg_design[(y_1_con/10)%10]; //年十位Display_Buffer[1] = seg_design[((y_1_con/100)%10)]; //年百位Display_Buffer[0] = seg_design[y_1_con/1000]; //年千位Display_Buffer[6] = seg_design[d_1_con/10]; //日十位Display_Buffer[7] = seg_design[d_1_con%10]; //日个位Display_Buffer[4] = seg_design[mon_1_con/10]; //月十位Display_Buffer[5] = seg_design[mon_1_con%10]; //月个位}if(k2==2){Display_Buffer[2] = seg_design[10];Display_Buffer[5] = seg_design[10];Display_Buffer[6] = seg_design[s1/10]; //秒十位Display_Buffer[7] = seg_design[s1%10]; //秒个位Display_Buffer[3] = seg_design[m1/10]; //分十位Display_Buffer[4] = seg_design[m1%10]; //分个位Display_Buffer[0] = seg_design[h1/10]; //时十位Display_Buffer[1] = seg_design[h1%10]; //时个位}if(s1==s_1_con&&m1==m_1_con&&h1==h_1_con)k1=1;}void time_set(void){unsigned char day;if(!s_1_con_key){s_1_con++;if(s_1_con > 59){s_1_con = 0;m_1_con++;if(m_1_con > 59){m_1_con = 0;h_1_con++;if(h_1_con > 23){h_1_con = 0;w_1_con++;if(w_1_con>7)w_1_con=1;d_1_con++;switch(mon_1_con){case 1:case 3:case 5:case 7:case 8:case 10:case 12:day=31;break;case 2:day=28;break;case 4:case 6:case 9:case 11:day=30;break;}if(d_1_con>day){mon_1_con++;d_1_con=1;if(mon_1_con>12){y_1_con++;mon_1_con=1;}}}}}}if(!m_1_con_key){m_1_con++;if(m_1_con > 59){m_1_con = 0;h_1_con++;if(h_1_con > 23){h_1_con = 0;w_1_con++;if(w_1_con>7)w_1_con=1;d_1_con++;switch(mon_1_con){case 1:case 3:case 5:case 7:case 8:case 10:case 12:day=31;break;case 2:day=28;break;case 4:case 6:case 9:case 11:day=30;break;}if(d_1_con>day){mon_1_con++;d_1_con=1;if(mon_1_con>12){y_1_con++;mon_1_con=1;}}}}}if(!h_1_con_key){h_1_con++;if(h_1_con > 23){h_1_con = 0;w_1_con++;if(w_1_con>7)w_1_con=1;d_1_con++;switch(mon_1_con){case 1:case 3:case 5:case 7:case 8:case 10:case 12:day=31;break;case 2:day=28;break;case 4:case 6:case 9:case 11:day=30;break;}if(d_1_con>day){mon_1_con++;d_1_con=1;if(mon_1_con>12){y_1_con++;mon_1_con=1;}}}}if(!w_1_con_key){k2=1;}}void time_set1(void){unsigned char day;switch(mon_1_con){case 1:case 3:case 5:case 7:case 8:case 10:case 12:day=31;break;case 2:day=28;break;case 4:case 6:case 9:case 11:day=30;break;}if(!s_1_con_key){d_1_con++;w_1_con++;if(w_1_con>7)w_1_con=1;if(d_1_con>day){mon_1_con++;d_1_con=1;if(mon_1_con>12){y_1_con++;mon_1_con=1;}}}if(!m_1_con_key){mon_1_con++;w_1_con=(w_1_con+day%7)%7;if(mon_1_con>12){y_1_con++;mon_1_con=1;}}if(!h_1_con_key){y_1_con++;if(y_1_con>9999){w_1_con=(w_1_con+365%7)%7;y_1_con=0;}}if(!w_1_con_key){k2=2;}}void time_set2(void){if(!s_1_con_key){s1++;if(s1>59)s1=0;}if(!m_1_con_key){m1++;if(m1>59)m1=0;}if(!h_1_con_key){h1++;if(h1>23)h1=0;}if(!w_1_con_key){k2=0;}}。

51单片机 ds1302万年历 时钟显示

51单片机 ds1302万年历 时钟显示

//DS1302时钟芯片程序#include <reg52.h>#define uchar unsigned char#define uint unsigned intsbit CLK=P2^3; //定义口sbit IO=P2^4;sbit RST=P2^5;sbit ACC7=ACC^7;sbit ACC0=ACC^0;uchar a[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}, //定义数码管显示码b[8]={0x00,0x00,0x12,0x23,0x11,0x07,0x08,0xbe},//写入时钟数据,最后be突发访问c[7],s,s1,ml1,mh1,ml2,mh2,ml3,mh3; //c存放读.出时钟数据void delay(uint z) // 延时{uint i;uchar j;for(i=z;i>0;i--)for(j=200;j>0;j++);}// 显示子程序void display(uchar mh1,uchar ml1,uchar mh2,uchar ml2,uchar mh3,uchar ml3){uchar x,k,r;for(k=0;k<80;k++){for(r=0;r<8;r++){x=P2&0XF8;P2=x+r ;if(r==2||r==5){ P0=0XBF;delay(3);}//------秒-------if(r==0){P0=a[ml1] ;delay(3) ;}if(r==1){P0=a[mh1] ;delay(3) ;}//------fen---------if(r==3){P0=a[ml2] ;delay(3) ;}if(r==4){P0=a[mh2] ;delay(3) ;}//-----shi---------if(r==6){P0=a[ml3] ;delay(3) ;}if(r==7){P0=a[mh3] ;delay(3) ;}delay(3);}}}//********DS1302读写程序************void w(uchar u) //写入1位字节{uchar i;ACC = u;for(i=8; i>0; i--){IO = ACC0;CLK = 1;CLK = 0;ACC = ACC >> 1;}}uchar r(void) //读出1位字节{uchar i;for(i=8; i>0; i--){ACC = ACC >>1;ACC7 = IO;CLK = 1;CLK = 0;}return(ACC);}void W1302(uchar ucAddr, uchar ucDa){RST = 0;CLK = 0;RST = 1;w(ucAddr); // 地址,命令w(ucDa); //写1Byte数据CLK = 1;RST = 0;}void wclock(uchar *p) //写入时钟多字节数据{uchar i;// W1302(0x80,0x00); //停止时钟W1302(0x8e,0x00); // 允许写RST=0;CLK=0;RST=1;w(0xbe); //写多字节命令for(i=8;i>0;i--){w(*p); //按数组指针逐个写入,写入数据在主函数调用时指向b数组p++;}W1302(0x00,0x50); //启动定时器CLK=1;RST=0;}void rclock(uchar *p) //读出时钟多字节数据{uchar i;RST=0;CLK=0;RST=1;w(0xbf);for(i=7;i>0;i--){*p=r();p++;}CLK=1;RST=0;}void main(void){uchar mh,ml,fh,fl,sh,sl,z,v,q,e,y,t,k;wclock(b);while(1){rclock(c);mh=(c[0]&0xf0)>>4;ml=c[0]&0x0f;fh=(c[1]&0xf0)>>4;fl=c[1]&0x0f;sh=(c[2]&0xf0)>>4;sl=c[2]&0x0f;display(mh,ml,fh,fl,sh,sl);if(mh==3&&ml==0){ for(k=0;k<3;k++){z=(c[3]&0xf0)>>4;v=c[3]&0x0f;q=(c[4]&0xf0)>>4;e=c[4]&0x0f;y=(c[6]&0xf0)>>4;t=c[6]&0x0f;display(z,v,q,e,y,t);}}}}。

基于单片机的万年历源代码程序

基于单片机的万年历源代码程序

基于单片机的万年历源代码程序源程序代码如下:#include<reg52.h>#include<intrins.h>unsigned char code displaywelcome[]={" Welcome To My Lcd Timer"};//欢迎界面unsigned char code displaywish[]={" Happy Every Day ^_^"}; //欢迎界面unsigned char code overtemperature[]={"OVERTEMPERATURE!"};unsigned char code digit[]={"0123456789"}; //数字代码unsigned char mode,TH,TL,TN,TD,length,tempswitch,Maxtemp=40,amode,alarmmode,minutes,hours, minutea,seconds,houra=12;sbit SCLK=P1^0; //DS1302时钟输入sbit DATE=P1^1; //DS1302数据输入sbit REST=P1^2; //DS1302复位端口sbit SET=P1^4; //DS1302设置模式选择位sbit ADD=P1^5; //增加sbit RED=P1^6; //减小sbit CANL=P1^7;void delay1ms(int i)//1毫秒延时{int j,k;while(i--)for(j=76;j>1;j--);for(k=29;k>1;k--);}void delaynus(unsigned char n) //延时若干微秒{unsigned char i;for(i=0;i<n;i++);}/***********蜂鸣器模块************/sbit beep=P3^6; //位定义,定义P.6位fmpvoid dely500(void){unsigned char i;for(i=250;i>0;i--){_nop_();}}void baojing(unsigned char n){unsigned char x,i;while(n--){for(i=0;i<5;i++){for(x=0;x<200;x++){beep=~beep;dely500();}}for(i=0;i<3;i++){for(x=0;x<200;x++){beep=~beep;dely500();dely500();}}}}/*******DS1302模块*************/void Write1302(unsigned char date)//向1302写数据{unsigned char i;SCLK=0;delaynus(2);for(i=0;i<8;i++){DATE=date&0x01;SCLK=1;delaynus(2);SCLK=0;delaynus(2);date>>=1;}}void WriteSet1302(unsigned char cmd,unsigned char date) //根据相应的命令输入相应的数据{REST=0;SCLK=0;REST=1;Write1302(cmd);delaynus(5);Write1302(date);SCLK=1;REST=0;}unsigned char Read1302(void) //读取1302数据{unsigned char i,date;delaynus(2);for(i=0;i<8;i++){date>>=1;if(DATE==1)date|=0x80;SCLK=1;delaynus(2);SCLK=0;delaynus(2);}return date;}unsigned char ReadSet1302(unsigned char cmd)//根据命令读取1302相应的值{unsigned char date;REST=0;SCLK=0;REST=1;Write1302(cmd);delaynus(2);date=Read1302();SCLK=1;REST=0;return date;}void IntDS1302(void) //DS1302初始化{unsigned char flag;flag= ReadSet1302(0x81);if(flag&0x80) { //判断时钟芯片是否关闭WriteSet1302(0x8E,0x00); //根据写状态寄存器命令字,写入不保护指令WriteSet1302(0x80,((0/10)<<4|(0%10))); //根据写秒寄存器命令字,写入秒的初始值WriteSet1302(0x82,((0/10)<<4|(0%10))); //根据写分寄存器命令字,写入分的初始值WriteSet1302(0x84,((0/10)<<4|(0%10))); //根据写小时寄存器命令字,写入小时的初始值WriteSet1302(0x86,((0/10)<<4|(0%10))); //根据写日寄存器命令字,写入日的初始值WriteSet1302(0x88,((0/10)<<4|(0%10))); //根据写月寄存器命令字,写入月的初始值WriteSet1302(0x8c,((10/10)<<4|(10%10))); //根据写年寄存器命令字,写入年的初始值WriteSet1302(0x90,0xa5); //打开充电功能选择2K电阻充电方式WriteSet1302(0x8E,0x80); //根据写状态寄存器命令字,写入保护指令}}/***************液晶显示模块*****************/sbit RS=P2^5;sbit RW=P2^6;sbit E=P2^7;sbit BF=P0^7;/*液晶忙检测*/bit BusyTest(void){bit result;RS=0;RW=1;E=1;_nop_();_nop_();_nop_();result=BF;_nop_();_nop_();_nop_();E=0;return result;/*写指令*/void Write_com(unsigned char command) {while(BusyTest()!=0);RS=0;RW=0;E=0;_nop_();_nop_();_nop_();P0=command;_nop_();_nop_();_nop_();E=1;_nop_();_nop_();_nop_();E=0;}/*写地址*/void Write_Address(unsigned char address) {Write_com(address|0x80);delay1ms(1);}/*写数据*/void Write_Date(unsigned char date){RS=1;RW=0;E=0;_nop_();_nop_();_nop_();P0=date;_nop_();_nop_();_nop_();E=1;_nop_();_nop_();_nop_();E=0;delay1ms(1);}/*初始化*/void Lcd_Int(void){Write_com(0x38);delay1ms(1);Write_com(0x38);delay1ms(1);Write_com(0x06);delay1ms(1);Write_com(0x0c);delay1ms(1);Write_com(0x01);}void displaymainpart(void)//显示液晶主要部分(不变化部分){Write_Address(0x01);delay1ms(1);Write_Date('D');Write_Date('A');Write_Date('T');Write_Date('E');Write_Date(':');delay1ms(1);Write_Address(0x0A);delay1ms(1);Write_Date('-');Write_Address(0x0D);Write_Date('-');Write_Address(0x42);Write_Date('T');Write_Date('I');Write_Date('M');Write_Date('E');Write_Date(':');Write_Address(0x4A);Write_Date('-');Write_Address(0x4D);Write_Date('-');Write_Address(0x06);Write_Date('2');Write_Date('0');}void display_Second(unsigned char second) //在液晶上显示秒{unsigned char i,j;i=second/10;j=second%10;Write_Address(0x4E);Write_Date(digit[i]);Write_Date(digit[j]);delay1ms(1);}void display_Minute(unsigned char minute) //在液晶上显示分{unsigned char i,j;i=minute/10;j=minute%10;Write_Address(0x4B);Write_Date(digit[i]);Write_Date(digit[j]);delay1ms(1);}void display_Hour(unsigned char hour) //在液晶上显示时{unsigned char i,j;i=hour/10;j=hour%10;Write_Address(0x48);Write_Date(digit[i]);Write_Date(digit[j]);delay1ms(1);}void display_Day(unsigned char day) //在液晶上显示日{unsigned char i,j;i=day/10;j=day%10;Write_Address(0x0E);Write_Date(digit[i]);Write_Date(digit[j]);delay1ms(1);}void display_Month(unsigned char month) //在液晶上显示月{unsigned char i,j;i=month/10;j=month%10;Write_Address(0x0B);Write_Date(digit[i]);Write_Date(digit[j]);delay1ms(1);}void display_Year(unsigned char year) //在液晶上显示年{unsigned char i,j;i=year/10;j=year%10;Write_Address(0x08);Write_Date(digit[i]);Write_Date(digit[j]);delay1ms(1);}void display_houra(unsigned char x) //闹钟小时部分显示{unsigned char i,j;i=x/10;j=x%10;Write_Address(0x44);Write_Date(digit[i]);Write_Date(digit[j]);}void display_minutea(unsigned char x)//闹钟分钟部分显示{unsigned char i,j;i=x/10;j=x%10;Write_Address(0x47);Write_Date(digit[i]);Write_Date(digit[j]);}void display_Time(void) //显示实时时间{unsigned char value,day,month,year;Write_com(0x0c);value=ReadSet1302(0x81);seconds=(((value&0x70)>>4)*10+(value&0x0f));display_Second(seconds);value=ReadSet1302(0x83);minutes=(((value&0x70)>>4)*10+(value&0x0f));display_Minute(minutes);value=ReadSet1302(0x85);hours=(((value&0x70)>>4)*10+(value&0x0f));display_Hour(hours);value=ReadSet1302(0x87);day=(((value&0x70)>>4)*10+(value&0x0f));display_Day(day);value=ReadSet1302(0x89);month=(((value&0x70)>>4)*10+(value&0x0f));display_Month(month);value=ReadSet1302(0x8D);year=(((value&0xf0)>>4)*10+(value&0x0f));display_Year(year);}void displaystar(void) //显示欢迎界面{unsigned char i,j;Write_Address(0x0f);while(displaywelcome[i]!='\0'){Write_Date(displaywelcome[i]);i++;delay1ms(1);}i=0;Write_Address(0x4f);while(displaywish[i]!='\0'){Write_Date(displaywish[i]);i++;delay1ms(1);}j=40;while(j--){Write_com(0x18);//循环左移delay1ms(700);}Write_com(0x01);delay1ms(10);}void gbdisplay(unsigned char address) //时间调整时光标闪烁{Write_Address(address);delay1ms(5);Write_com(0x0f);delay1ms(5);}void displaymaxt(unsigned char x) //显示最大温度{unsigned char i,j,k;Write_com(0x0c);delay1ms(2);Write_Address(0x44);i=x/100;j=x/10;k=x%10;Write_Date(digit[i]);Write_Date(digit[j]);Write_Date(digit[k]);}/*****************时间调整部分*********************/void hourset(void) //调时{unsigned char timevalue,hour;delay1ms(500); //防止多次触发WriteSet1302(0x8e,0x00);//将写保护去掉,确保能正常将调整后的数值写入DS1302timevalue=ReadSet1302(0x85); //读取此时的数值hour=(((timevalue&0x70)>>4)*10+(timevalue&0x0f));while(1){if(ADD==0){delay1ms(50);if(ADD==0){hour++;delay1ms(300);while(ADD==0);}}if(RED==0){delay1ms(50);if(RED==0){hour--;delay1ms(300);if(hour==0) hour=23;while(RED==0);}}timevalue=(((hour)/10)<<4|(hour%10));WriteSet1302(0x84,timevalue);delay1ms(1);display_Hour(hour);Write_Address(0x49);delay1ms(5);if(hour>=24) hour=0;delay1ms(5);if(CANL==0){mode=0;Write_com(0x0c);break;}if(SET==0) break;}WriteSet1302(0x8e,0x80);}void minuteset(void) //调分{unsigned char timevalue,minute;delay1ms(500);WriteSet1302(0x8e,0x00);timevalue=ReadSet1302(0x83);minute=(((timevalue&0x70)>>4)*10+(timevalue&0x0f));while(1){if(ADD==0){delay1ms(10);if(ADD==0){minute++;if(minute>=60) timevalue=0;while(ADD==0);}}if(RED==0)delay1ms(10);if(RED==0){minute--;delay1ms(300);if(minute==0) minute=59;while(RED==0);}}timevalue=((minute/10)<<4|(minute%10));WriteSet1302(0x82,timevalue);delay1ms(1);display_Minute(minute);Write_Address(0x4c);delay1ms(5);if(minute>=60) minute=0;delay1ms(5);if(CANL==0){mode=0;Write_com(0x0c);break;}if(SET==0) break;}WriteSet1302(0x8e,0x80);}void secondset(void) //秒归零{unsigned char second;delay1ms(500);WriteSet1302(0x8e,0x00);while(1){if(ADD==0){delay1ms(10);if(ADD==0){second=0;WriteSet1302(0x80,0x00);while(ADD==0);}delay1ms(1);display_Second(second);Write_Address(0x4f);delay1ms(5);if(CANL==0){mode=0;Write_com(0x0c);break;}if(SET==0) break;}WriteSet1302(0x8e,0x80);}void yearset(void) //调年{unsigned char datevalue,year;delay1ms(500);WriteSet1302(0x8e,0x00);datevalue=ReadSet1302(0x8d);year=(((datevalue&0x70)>>4)*10+(datevalue&0x0f));while(1){if(ADD==0){delay1ms(10);if(ADD==0){year++;while(ADD==0);}}if(RED==0){delay1ms(10);if(RED==0){year--;delay1ms(300);while(RED==0);}}datevalue=((year/10)<<4|(year%10));WriteSet1302(0x8c,datevalue);delay1ms(5);display_Year(year);delay1ms(5);Write_Address(0x09);delay1ms(5);if(CANL==0){mode=0;Write_com(0x0c);break;}if(SET==0) break;}WriteSet1302(0x8e,0x80);}void monthset(void) //调月{unsigned char datevalue,month;delay1ms(500);WriteSet1302(0x8e,0x00);datevalue=ReadSet1302(0x89);month=(((datevalue&0x70)>>4)*10+(datevalue&0x0f));while(1){if(ADD==0){delay1ms(10);if(ADD==0){month++;if(month>12) month=1;while(ADD==0);}}if(RED==0){delay1ms(10);if(RED==0){month--;delay1ms(300);if(month==0) month=12;while(RED==0);}}datevalue=((month/10)<<4|(month%10));WriteSet1302(0x88,datevalue);delay1ms(1);display_Month(month);Write_Address(0x0c);delay1ms(5);if(CANL==0){mode=0;Write_com(0x0c);break;}if(SET==0) break;}WriteSet1302(0x8e,0x80);}void dayset(void) //调日{unsigned char datevalue,day;delay1ms(500);WriteSet1302(0x8e,0x00);datevalue=ReadSet1302(0x87);day=(((datevalue&0x70)>>4)*10+(datevalue&0x0f));while(1){if(ADD==0){delay1ms(10);if(ADD==0){day++;if(day>31) day=1;while(ADD==0);}}if(RED==0){delay1ms(10);if(RED==0){day--;delay1ms(300);if(day==0) day=31;while(RED==0);}}datevalue=((day/10)<<4|(day%10));WriteSet1302(0x86,datevalue);delay1ms(1);display_Day(day);Write_Address(0x0f);delay1ms(5);if(CANL==0){mode=0;Write_com(0x0c);break;}if(SET==0) break;}WriteSet1302(0x8e,0x80);}void alarmhourset(void) //闹钟小时调整{unsigned char value;value=houra;while(1){if(ADD==0){delay1ms(20);if(ADD==0){Write_com(0x0c);delay1ms(5);value++;if(value>23) value=0;while(ADD==0);}}if(RED==0){delay1ms(20);if(RED==0){value--;if(value==0) value=23;while(RED==0);}}houra=value;display_houra(houra);gbdisplay(0x45);if(CANL==0){delay1ms(500);break;}}}void alarmminuteset(void) //闹钟分钟调整{while(1){if(ADD==0){delay1ms(20);if(ADD==0){minutea++;if(minutea>59) minutea=0;while(ADD==0) ;}}if(RED==0){delay1ms(20);if(RED==0){minutea--;if(minutea==0) minutea=59;while(RED==0) ;}}display_minutea(minutea);gbdisplay(0x48);if(CANL==0){delay1ms(500);break;}}}void TimeSet(void) //时间调整函数{display_Time();if(SET==0){delay1ms(10);if(SET==0){mode++;delay1ms(20);switch(mode){case(1):{gbdisplay(0x48);hourset(); delay1ms(500);} break;case(2):{gbdisplay(0x4c);minuteset();delay1ms(500);} break;case(3):{gbdisplay(0x4f);secondset();delay1ms(500);} break;case(4):{gbdisplay(0x09);yearset();delay1ms(500);} break;case(5):{gbdisplay(0x0c);monthset();delay1ms(500);} break;case(6):{gbdisplay(0x0f);dayset();delay1ms(500);} break;}if(mode==7) mode=0;}}}/***************显示温度模块********************/unsigned char code displayexplain[]={"Digit thermometer"};unsigned char code displayerror[]={"DS18B20 ERROR"};unsigned char code displayerror1[]={"PLEASE CHECK "};unsigned char code displaypart1[]={"WenDu:"};unsigned char code displaypart2[]={"Cent"};unsigned char flag;/**********************操作DS18B20模块***************************/ sbit DQ=P3^3;unsigned char time;/**********************DS18B20初始化****************************/bit IntDS18B20(void){bit temp;DQ=1;for(time=0;time<2;time++);DQ=0;for(time=0;time<200;time++);DQ=1;for(time=0;time<10;time++);temp=DQ;for(time=0;time<200;time++);return temp;}/**************************读DS18B20**********************/unsigned char ReadDS18B20(void){unsigned char i;unsigned char dat;for(i=0;i<8;i++){DQ=1;_nop_();DQ=0;_nop_();DQ=1;for(time=0;time<2;time++);dat>>=1;if(DQ==1)dat=dat|0x80;elsedat=dat|0x00;for(time=0;time<10;time++);}return dat;}/*********************向DS18B20写数据**************************/ void WriteDS18B20(unsigned char date){unsigned char i;for(i=0;i<8;i++){DQ=1;_nop_();DQ=0;DQ=date&0x01;for(time=0;time<10;time++);DQ=1;for(time=0;time<1;time++);date>>=1;}for(time=0;time<4;time++);}/*******************为读取温度做好准备************************/ void ReadyreadDS18B20(void){IntDS18B20();WriteDS18B20(0XCC);WriteDS18B20(0X44);delay1ms(200);IntDS18B20();WriteDS18B20(0XCC);WriteDS18B20(0XBE);}/*************在1602液晶上显示相关信息模块**********************/ /****************当未检测到DS18B20时显示信息模块****************/ void Display_Error(void){unsigned char i=0;Write_Address(0x00);while(displayerror[i]!='\0'){Write_Date(displayerror[i]);i++;delay1ms(100);}delay1ms(5);i=0;Write_Address(0x40);while(displayerror1[i]!='\0'){Write_Date(displayerror1[i]);i++;delay1ms(100);}delay1ms(3000) ;}/*************温度显示模块****************/void Display_Explain(void){unsigned char i=0;Write_Address(0x00);delay1ms(5);while(displayexplain[i]!='\0'){Write_Date(displayexplain[i]);i++;delay1ms(5);}i=0;Write_Address(0x40);while(displaypart1[i]!='\0'){Write_Date(displaypart1[i]);i++;delay1ms(5);}i=0;Write_Address(0x4C);while(displaypart2[i]!='\0'){Write_Date(displaypart2[i]);i++;delay1ms(5);}Write_Address(0x49);Write_Date('.');delay1ms(5);}/*********************显示温度整数部分*************************/ void Display_Integer(unsigned char x){unsigned char i,j,k;i=x/100;j=x%100/10;k=x%10;Write_Address(0x46);if(flag==1) Write_Date('-');Write_Date(digit[i]);Write_Date(digit[j]);Write_Date(digit[k]);delay1ms(50) ;}/************显示温度小数部分*********************/ void Display_Decimal(unsigned char x){Write_Address(0x4A);delay1ms(5);Write_Date(digit[x]);delay1ms(50);}void displayovert(void){unsigned char i;Write_com(0x01);delay1ms(10);Write_Address(0x03);delay1ms(10);Write_Date('W');Write_Date('A');Write_Date('R');Write_Date('N');Write_Date('I');Write_Date('N');Write_Date('G');Write_Date('!');Write_Address(0x40);while(overtemperature[i]!='\0'){Write_Date(overtemperature[i]);i++;delay1ms(10);}}/*******************温度主函数********************/ void Temperature(void){unsigned char i;delay1ms(5);if(IntDS18B20()!=0) Display_Error();else{delay1ms(1);Write_com(0x01);delay1ms(5);Display_Explain();for(length=50;length>0;length--){for(i=0;i<6;i++){flag=0;ReadyreadDS18B20();TL=ReadDS18B20();TH=ReadDS18B20();if((TH&0XF8)!=0X00){flag=1;TL=~TL;TH=~TH;TL+=1;if(TL>255) TH+=1;TN=TH*16+TL/16;TD=(TL%16)*10/16;}TN=TH*16+TL/16;TD=(TL%16)*10/16;Display_Integer(TN);Display_Decimal(TD);delay1ms(10);}if(tempswitch==1){if(TN>=Maxtemp){Write_Address(0x03);delay1ms(5);displayovert();while(1){baojing(1);if(CANL==0){Write_com(0x01);delay1ms(5);break;}}}}if(CANL==0) break;}}}void tempset(void){if(ADD==0){delay1ms(10);if(ADD==0){Maxtemp++;while(ADD==0);}}if(RED==0){delay1ms(10);if(RED==0){Maxtemp--;while(RED==0);}}}void Maxtempset(void) //高温报警设置{Write_com(0x01);delay1ms(10);Write_Address(0x03);delay1ms(10);Write_Date('T');Write_Date('E');Write_Date('M');Write_Date('P');Write_Address(0x09);Write_Date('S');Write_Date('E');Write_Date('T');Write_Address(0x40);Write_Date('M');Write_Date('A');Write_Date('X');Write_Date(':');while(1){if(SET==0){delay1ms(20);if(SET==0){Write_Address(0x4e);Write_com(0x0f);while(1){if(ADD==0){delay1ms(20);if(ADD==0){Write_Address(0x4b);delay1ms(5);Write_Date('O');Write_Date('N');Write_Date(' ');tempswitch=1;}}if(RED==0){delay1ms(20);if(RED==0){Write_Address(0x4b);Write_Date('O');Write_Date('F');Write_Date('F');tempswitch=0;}}if(CANL==0){delay1ms(500);break;}}}}if(tempswitch==1){Write_Address(0x4b);Write_Date('O');Write_Date('N');Write_Date(' ');tempset();displaymaxt(Maxtemp);if(CANL==0){Write_com(0x01);displaymainpart();break;}}if(tempswitch==0){Write_com(0x0c);Write_Address(0x4b);Write_Date('O');Write_Date('F');Write_Date('F');}if(CANL==0){Write_com(0x01); displaymainpart();break;}}}void alarmswitchset(void){while(1){if(ADD==0){delay1ms(100);if(ADD==0){alarmmode=1;Write_Address(0x4c);Write_Date('O');Write_Date('N');Write_Date(' ');}}if(RED==0){alarmmode=0;Write_Address(0x4c);Write_Date('O');Write_Date('F');Write_Date('F');}if(CANL==0){delay1ms(500);break;}}}/**************** 设置模块 ******************/ void Set(void){if(SET==0){delay1ms(10);if(SET==0){Write_Address(0x40);Write_Date('T');Write_com(0x0f);delay1ms(1000);Write_com(0x0c);while(1){TimeSet();if(ADD==0){delay1ms(20);if(ADD==0){Write_com(0x01);Write_Address(0x00);delay1ms(5);Write_Date('S');delay1ms(10);Maxtempset();}}if(RED==0){delay1ms(20);if(RED==0){Write_com(0x01);delay1ms(5);Write_Address(0x02);Write_Date('A');Write_Date('L');Write_Date('A');Write_Date('R');Write_Date('M');Write_Address(0x09);Write_Date('S');Write_Date('E');Write_Date('T');Write_Address(0x46);Write_Date('-');display_houra(houra);display_minutea(minutea);if(alarmmode==1){Write_Address(0x4c);Write_Date('O');Write_Date('N');Write_Date(' ');}if(alarmmode==0){Write_Address(0x4c);Write_Date('O');Write_Date('F');Write_Date('F');}while(1){if(SET==0){delay1ms(100);if(SET==0){amode++;switch(amode){case(1):{gbdisplay(0x45);alarmhourset();Write_com(0x0c);delay1ms( 500);} break;case(2):{gbdisplay(0x48);alarmminuteset();Write_com(0x0c);delay1m s(500);} break;case(3):{gbdisplay(0x4c);alarmswitchset();Write_com(0x0c);delay1m s(500);} break;}if(amode==4) amode=0;}}if(CANL==0){Write_com(0x01);delay1ms(5);displaymainpart();break;}}}}if(CANL==0){Write_Address(0x40);Write_Date(' ');Write_com(0x0c);break;}}}}}/***************主函数**********************/void main(){IE=0X82; //打开定时中断TMOD=0X01; //选择定时器0工作在方式1TR0=0; //启动定时器0IntDS1302(); //初始化DS1302delay1ms(1);Lcd_Int(); //1602液晶初始化delay1ms(2);displaystar(); //显示欢迎界面displaymainpart(); //显示主要部分(不变化)while(1){display_Time( );Set( );if(ADD==0){Write_com(0x01);delay1ms(5);Temperature();Write_com(0x01);displaymainpart();}if((hours==houra)&&(minutes==minutea)&&(seconds==0)) {if(alarmmode==1){Write_com(0x01);delay1ms(5);Write_Address(0x03);Write_Date('T');Write_Date('I');Write_Date('M');Write_Date('E');Write_Address(0x08);Write_Date('U');Write_Date('P');Write_Date('!');delay1ms(5);while(1){baojing(1);if(CANL==0){Write_com(0x01);delay1ms(5);displaymainpart();break;}}}}}}。

万年历源代码

万年历源代码
LCD_Write(LCD_COMMAND, 0x04|InputMode); }
//初始化 LCD************************************************************
void LCD_Initial()
{
LcdEn=0; LCD_Write(LCD_COMMAND,0x38);
#define LCD_SHOW
0x04 //显示开
#define LCD_HIDE
0x00 //显示关
#define LCD_CURSOR #define LCD_NO_CURSOR
#define LCD_FLASH #define LCD_NO_FLASH
0x02 0x00
//显示光标 //无光标
{
Time->DateString[0] = '2';
Time->DateString[1] = '0';
Time->DateString[2] = Time->Year/10 + '0';
#include <REG52.H> #include <intrins.h> //#include "LCD1602.h" //#include "DS1302.h"
#define uint unsigned int #define uchar unsigned char sbit DS1302_CLK = P1^7; sbit DS1302_IO = P1^6; sbit DS1302_RST = P1^5;
0x01 0x00
//光标闪动 //光标不闪动

基于51与DS1302时钟芯片数码管显示万年历

基于51与DS1302时钟芯片数码管显示万年历
{
year=read_ds1302(0x8d);//年
mon=read_ds1302(0x89);//月
day=read_ds1302(0x87);//日
week=read_ds1302(0x8b);//星期
hour=read_ds1302(0x85);//时
min=read_ds1302(0x83);//分
void main()
{
TMOD=0x01;
TH0=0x3c;
TL0=0xb0;
EA=1;
ET0=1;
while (1)
{
set_rtc();//按键
read_rtc();//读取时间
display();//延时函数
dsbz();//判断函数
TR0=1;
}
}
/****************************************判断语句*******************************************************/
void dsbz();//判断语句定义
/**********************************DS1302单字节写入***********************************/
void write_ds1302_byte(uchar dat)
{
uchar i;
for (i=0;i<8;i++)
void set_rtc()
{
if (shi==0)
delay(100);
if (shi==0)
{
hour=(hour>>4)*10+(hour&0x0f);

数字万年历简易C语言程序源代码

数字万年历简易C语言程序源代码

数字万年历简易C语言程序源代码#include"reg52.h"#define uchar unsigned char#define uint unsigned intsbit rs=P2^0; // lcd 控制端sbit en=P2^2; // lcd 控制端sbit all=P2^1; // lcd 控制端sbit s0=P1^5; //时间调节sbit s1=P1^6;sbit s2=P1^7;sbit voice=P2^7;int nt;sbit DQ=P2^6;sbit DS1302_CLK = P2^3; //实时时钟时钟线引脚sbit DS1302_IO = P2^4; //实时时钟数据线引脚sbit DS1302_RST = P2^5; //实时时钟复位线引脚sbit ACC0 = ACC^0;sbit ACC7 = ACC^7;unsigned char time;#define ads_y 0#define ads_mo 3#define ads_d 6#define ads_w 9#define ads_h 65#define ads_m 68#define ads_s 71#define DS1302_SECOND 0x80 //写入ds地址宏定义#define DS1302_MINUTE 0x82#define DS1302_HOUR 0x84#define DS1302_WEEK 0x8A#define DS1302_DAY0x86#define DS1302_MONTH 0x88#define DS1302_YEAR 0x8Cvoid delay1(unsigned int i) //ds 延时函数放在前边是为了让EP 两次存储之间延时可以调用{while(i--);}void init_ds() //ds 初始化函数{unsigned char x=0;DQ=1; //DQ复位delay1(8); //稍做延时DQ=0; //单片机将DQ拉低delay1(80); //精确延时大于480usDQ=1; //拉高总线delay1(10);x=DQ; //稍做延时后如果x=0则初始化成功x=1则初始化失败delay1(5);}unsigned char read_ds() ///ds 读一个字节{unsigned char i=0;unsigned char dat=0;for(i=8;i>0;i--){DQ=0; // 给脉冲信号dat>>=1;DQ=1; // 给脉冲信号if(DQ)dat|=0x80;delay1(5);}return(dat);}void write_ds(unsigned char dat) ///写一个字节{unsigned char i=0;for(i=8;i>0;i--){DQ=0;DQ=dat&0x01;delay1(5);DQ=1;dat>>=1;}delay1(5);}void get_nt() //获取温度{unsigned char a=0;unsigned char b=0;init_ds();write_ds(0xCC); // 跳过读序号列号的操作write_ds(0x44); // 启动温度转换delay1(10);init_ds();write_ds(0xCC); //跳过读序号列号的操作write_ds(0xBE); //读取温度寄存器等(共可读9个寄存器)前两个就是温度a=read_ds();b=read_ds();nt=0;nt=nt+b;nt=nt<<8;nt=nt+a;nt=nt*0.625; //此ds18b20 最低位为0.5 扩大十倍}void delay_1302(uint n) //按键长延时{while(n--);}void delay(uchar n) //lcd 延时子程序{uchar i,j;for(i=0;i<n;i++)< bdsfid="161" p=""></n;i++)<>for(j=0;j<10;j++);}void write_com(char com) //lcd comond in LCD控制字写入函数{en=0;P3=com;rs=0;delay(1);en=1;delay(2);en=0;delay(2);}void write_byte(char byte) //lcd data in LCD数据写入函数{en=0;P3=byte;rs=1;delay(1);en=1;delay(2);en=0;delay(2);}void init_lcd_com() //lcd init LCD初始化{all=0;write_com(0x38);write_com(0x0c);write_com(0x06);}void DS1302InputByte(unsigned char d) //实时时钟写入一字节(内部函数){unsigned char i;ACC = d;for(i=8; i>0; i--){DS1302_IO = ACC0; //相当于汇编中的RRCDS1302_CLK = 1;DS1302_CLK = 0;ACC = ACC >> 1;}}unsigned char DS1302OutputByte(void) //实时时钟读取一字节(内部函数){unsigned char i;for(i=8; i>0; i--){ACC = ACC >>1; //相当于汇编中的RRCACC7 = DS1302_IO;DS1302_CLK = 1;DS1302_CLK = 0;}return(ACC);}void Write1302(unsigned char ucAddr, unsigned char ucDa) //ucAddr: DS1302地址, ucData: 要写的数据DS1302_RST = 0;DS1302_CLK = 0;DS1302_RST = 1;DS1302InputByte(ucAddr); // 地址,命令DS1302InputByte(ucDa); // 写1Byte数据DS1302_CLK = 1;DS1302_RST = 0;}unsigned char Read1302(unsigned char ucAddr) //读取DS1302某地址的数据{unsigned char ucData;DS1302_RST = 0;DS1302_CLK = 0;DS1302_RST = 1;DS1302InputByte(ucAddr|0x01); // 地址,命令ucData = DS1302OutputByte(); // 读1Byte数据DS1302_CLK = 1;DS1302_RST = 0;return(ucData);}void DS1302_SetProtect(bit flag) //是否写保护{if(flag)Write1302(0x8E,0x10);elseWrite1302(0x8E,0x00);}void DS1302_SetTime(unsigned char Address, unsigned char V alue) // 关键函数向内写入时间{DS1302_SetProtect(0);Write1302(Address, ((V alue/10)<<4 | (V alue%10)));}void DS1302_GetTime(unsigned char xy) //关键函数向外读出时间{unsigned char ReadV alue;ReadV alue = Read1302(xy);time=((ReadV alue&0x70)>>4)*10+(ReadV alue&0x0F);}void display_nt(char ads,uchar t) //将读出时间显示char ge,shi;write_com(0x80+ads);shi=t%100/10;ge=t%10;write_byte(shi+'0');write_byte(ge+'0');}void display_nt2(char ads,uchar t) //将读出星期显示{ write_com(0x80+ads);write_byte(t+'0');}void get_dis() //获得时间并显示{DS1302_GetTime(DS1302_YEAR);display_nt(ads_y,time);DS1302_GetTime(DS1302_MONTH);display_nt(ads_mo,time);DS1302_GetTime(DS1302_DAY);display_nt(ads_d,time);DS1302_GetTime(DS1302_WEEK);display_nt2(ads_w,time);DS1302_GetTime(DS1302_HOUR);display_nt(ads_h,time);DS1302_GetTime(DS1302_MINUTE);display_nt(ads_m,time);DS1302_GetTime(DS1302_SECOND);display_nt(ads_s,time);}void set_time() //三按键设置时间{if(s0==0){write_com(0x0f); //开闪烁write_com(0x80+ads_m+1);while(s0==0);delay_1302(30000);while(s0==1){if(s1==0){DS1302_GetTime(DS1302_MINUTE); time++;DS1302_SetTime(DS1302_MINUTE,time); display_nt(ads_m,time);write_com(0x80+ads_m+1);delay_1302(30000);}if(s2==0){DS1302_GetTime(DS1302_MINUTE); time--;DS1302_SetTime(DS1302_MINUTE,time); display_nt(ads_m,time);write_com(0x80+ads_m+1);delay_1302(30000);}}write_com(0x80+ads_h+1);while(s0==0);delay_1302(30000);while(s0==1){if(s1==0){DS1302_GetTime(DS1302_HOUR); time++;DS1302_SetTime(DS1302_HOUR,time); display_nt(ads_h,time);write_com(0x80+ads_h+1);delay_1302(30000);}if(s2==0){DS1302_GetTime(DS1302_HOUR); time--;DS1302_SetTime(DS1302_HOUR,time); display_nt(ads_h,time);write_com(0x80+ads_h+1);delay_1302(30000);}}write_com(0x80+ads_w);while(s0==0);delay_1302(30000);while(s0==1){if(s1==0){DS1302_GetTime(DS1302_WEEK); time++;DS1302_SetTime(DS1302_WEEK,time); display_nt2(ads_w,time);write_com(0x80+ads_w);delay_1302(30000);}if(s2==0){DS1302_GetTime(DS1302_WEEK); time--;DS1302_SetTime(DS1302_WEEK,time); display_nt2(ads_w,time);write_com(0x80+ads_w);delay_1302(30000);}}write_com(0x80+ads_d+1);while(s0==0);delay_1302(30000);while(s0==1){if(s1==0){DS1302_GetTime(DS1302_DAY);time++;DS1302_SetTime(DS1302_DAY,time); display_nt(ads_d,time);write_com(0x80+ads_d+1);delay_1302(30000);}if(s2==0){DS1302_GetTime(DS1302_DAY);time--;DS1302_SetTime(DS1302_DAY,time);display_nt(ads_d,time);write_com(0x80+ads_d+1);delay_1302(30000);}}write_com(0x80+ads_mo+1);while(s0==0);delay_1302(30000);while(s0==1){if(s1==0){DS1302_GetTime(DS1302_MONTH); time++;DS1302_SetTime(DS1302_MONTH,time); display_nt(ads_mo,time);write_com(0x80+ads_mo+1);delay_1302(30000);}if(s2==0){DS1302_GetTime(DS1302_MONTH); time--;DS1302_SetTime(DS1302_MONTH,time); display_nt(ads_mo,time);write_com(0x80+ads_mo+1);delay_1302(30000);}}write_com(0x80+ads_y+1);while(s0==0);delay_1302(30000);while(s0==1){if(s1==0){DS1302_GetTime(DS1302_YEAR); time++;DS1302_SetTime(DS1302_YEAR,time); display_nt(ads_y,time);write_com(0x80+ads_y+1);delay_1302(30000);}if(s2==0){DS1302_GetTime(DS1302_YEAR); time--;DS1302_SetTime(DS1302_YEAR,time); display_nt(ads_y,time);write_com(0x80+ads_y+1);delay_1302(30000);}}write_com(0x0c);while(s0==0);delay_1302(30000);}}void init_lcd_dis() //显示初始化{write_com(0x80+2);write_byte('*');write_com(0x80+5);write_byte('*');write_com(0x80+8);write_byte('-');write_com(0x80+67);write_byte(':');write_com(0x80+70);write_byte(':');}void my() //右下角显示函数{char *pp;char i;code char p[]=" hou fei see a girl and say I LOVE YOU replay I LOVE YOU too ";pp=p;if(time<=60){write_com(0x80+74);for(i=0;i<=5;i++){write_byte(*(pp+time));pp++;}}}void display_nntt(int t) //当前温度显示{char ge,shi,bai;if(t<0){write_com(0x80+11);write_byte('-');t=-t;}else{write_com(0x80+11);write_byte('+');}bai=t/100;shi=t%100/10;ge=t%10;write_byte(bai+'0');write_byte(shi+'0');write_byte('.');write_byte(ge+'0');}void main(){init_lcd_com();init_lcd_dis();DS1302_SetTime(DS1302_SECOND,00); while(1){get_dis();set_time();get_nt();display_nntt(nt); my();}}。

PIC单片机学习笔记之万年历

PIC单片机学习笔记之万年历

PIC单片机自学笔记之万年历实验环境:Proteus编程语言:汇编编程环境:MPLAB IDE单片机:PIC16F877晶振:20MHz实验目的用的定时器定时扫描的方式消除键盘抖动的影响,提高了程序的运行速率;可对分钟、小时、日期、月份和年份进行调节。

实验效果图如图1和图2.图1—系统开机效果图图2—调整时间后的显示状态PCF8563芯片概述:PCF8563 有16 个位寄存器:一个可自动增量的地址寄存器,一个内置32.768KHz的振荡器(带有一个内部集成的电容)一个分频器(用于给实时时钟RTC 提供源时钟)一个可编程时钟输出,一个定时器,一个报警器,一个掉电检测器和一个400KHz I2C 总线接口。

所有16 个寄存器设计成可寻址的8 位并行寄存器,但不是所有位都有用。

前两个寄存器(内存地址 00H,01H)用于控制寄存器和状态寄存器,内存地址 02H~08H 用于时钟计数器(秒~年计数器),地址09H~0CH 用于报警寄存器(定义报警条件),地址 0DH 控制CLKOUT 管脚的输出频率,地址0EH 和 0FH 分别用于定时器控制寄存器和定时器寄存器。

秒、分钟、小时、日、月、年、分钟报警、小时报警、日报警寄存器,编码格式为BCD,星期和星期报警寄存器不以 BCD 格式编码。

当一个RTC 寄存器被读时,所有计数器的内容被锁存,因此,在传送条件下,可以禁止对时钟日历芯片的错读。

MAX7219概述:MAX7219/MAX7221是一种集成化的串行输入/输出共阴极显示驱动器,它连接微处理器与8位数字的7段数字LED显示,也可以连接条线图显示器或者64个独立的LED。

其上包括一个片上的B型BCD编码器、多路扫描回路,段字驱动器,而且还有一个8*8的静态RAM用来存储每一个数据。

只有一个外部寄存器用来设置各个LED的段电流。

MAX7221与SPI™QSPI™以及MICROWIRE™相兼容,同时它有限制回转电流的段驱动来减少EMI(电磁干扰)。

万年历程序代码

万年历程序代码

/*****************************************************4字LED点阵屏+DS1302万年历电子钟C 程序*******************************************************DS1302 接线图Vcc2 CLK I/O /RST| | | |-------------------| 8 7 6 5 || DS1302 || || 1 2 3 4 |-------------------| | | |VCC1 GND1 脚接+5V 2,3脚32768HZ晶振4脚接地5脚接S51的P02 6脚接S51的P01 7接S51的P008脚接后备电源,可以接老计算机主板上的3.6V电池,也可以通过二级管隔离接一个大容量电解电容电压在2.5V以上即可维持595连级输出数据,138行驱动。

*///(本程序引用网上程序,有点BUG经过修改后可以使用,经过修改调整加上了温度显示功能,节日提醒功能和家人生日提醒功能。

//程序没有有效简化)07电气工程,付春平!//手动添加定时器2寄存器定义sfr T2CON = 0xC8;(special function register)sfr TL2 = 0xCC;sfr TH2 = 0xCD;sfr RCAP2L = 0xCA;sfr RCAP2H = 0xCB;sbit TF2 = T2CON^7;sbit EXF2 = T2CON^6;sbit RCLK = T2CON^5;sbit TCLK = T2CON^4;sbit EXEN2 = T2CON^3;sbit TR2 = T2CON^2;sbit C_T2 = T2CON^1;sbit CP_RL2= T2CON^0;//sbit ET2 =0xAD;#include<A T89x51.H>#include <intrins.h>#define uchar unsigned char#define uint unsigned intunsigned char irtime;//红外用全局变量bit irokk;unsigned char IRcord[2];unsigned char irdata[17];unsigned char data temp_data[2] = {0x00,0x00} ;void Ircordpro(void);uchar code hanzi[]; //汉字字模uchar code hanzi1[]; //汉字字模uchar code timer[18][16]; //0~9数字uchar code sw[]; //138驱动数据void Show_word(); //待机显示按三秒间隔分别显示年、月日、星期、时分秒。

万年历时钟芯片代码

万年历时钟芯片代码

万年历时钟芯片代码/******************************************************************** * 文件名: 时钟DS1302LCD.c* 描述: 该程序实现了用单片机来控制时钟芯片DS1302进行时钟的显示。

时钟会在1602上显示.* 创建人:东流,2012年2月7日* 版本号:1.0* 杜邦线接法:P3.5接J18的1端;J3.6接J18的2端;J3.7接J18的3端。

1602接到J17的排座上。

********************************************************************* **/#include&lt;reg52.h&gt;#include&lt;intrins.h&gt;#define uchar unsigned char#define uint unsigned intsbit ACC0 = ACC^0;sbit ACC7 = ACC^7;sbit T_CLK = P3^5; /*实时时钟时钟线引脚*/sbit T_IO = P3^6; /*实时时钟数据线引脚*/sbit T_RST = P3^7; /*实时时钟复位线引脚*///这三个引脚参考资料sbit E=P2^7;//1602使能引脚sbit RW=P2^6;//1602读写引脚sbit RS=P2^5;//1602数据/命令选择引脚/******************************************************************** * 名称: delay()* 功能: 延时,延时时间大概为5US。

* 输入: 无* 输出: 无********************************************************************* **/void delay(){_nop_();_nop_();_nop_();_nop_();}void Delay(uint i){uint x,j;for(j=0;j&lt;i;j++)for(x=0;x&lt;=148;x++);}/******************************************************************** * 名称: bit Busy(void)* 功能: 这个是一个读状态函数,读出函数是否处在忙状态* 输入: 输入的命令值* 输出: 无********************************************************************* **/bit Busy(void){bit busy_flag = 0;RS = 0;RW = 1;E = 1;delay();busy_flag = (bit)(P0 &amp; 0x80);E = 0;return busy_flag;}/******************************************************************** * 名称: wcmd(uchar del)* 功能: 1602命令函数* 输入: 输入的命令值* 输出: 无********************************************************************* **/void wcmd(uchar del){while(Busy());RS = 0;RW = 0;E = 0;delay();delay();E = 1;delay();E = 0;}/******************************************************************** * 名称: wdata(uchar del)* 功能: 1602写数据函数* 输入: 需要写入1602的数据* 输出: 无********************************************************************* **/void wdata(uchar del){while(Busy());RS = 1;RW = 0;E = 0;delay();P0 = del;delay();E = 1;delay();E = 0;}/******************************************************************** * 名称: L1602_init()* 功能: 1602初始化,请参考1602的资料* 输入: 无* 输出: 无********************************************************************* **/void L1602_init(void){wcmd(0x38);Delay(5);wcmd(0x38);Delay(5);wcmd(0x38);Delay(5);wcmd(0x38);wcmd(0x08);wcmd(0x0c);wcmd(0x04);wcmd(0x01);}/******************************************************************** * 名称: L1602_char(uchar hang,uchar lie,char sign)* 功能: 改变液晶中某位的值,如果要让第一行,第五个字符显示&quot;b&quot; ,调用该函数如下L1602_char(1,5,&#39;b&#39;)* 输入: 行,列,需要输入1602的数据* 输出: 无********************************************************************* **/void L1602_char(uchar hang,uchar lie,char sign){uchar a;if(hang == 1) a = 0x80;if(hang == 2) a = 0xc0;a = a + lie - 1;wcmd(a);wdata(sign);}/******************************************************************** * 名称: L1602_string(uchar hang,uchar lie,uchar *p)* 功能: 改变液晶中某位的值,如果要让第一行,第五个字符开始显示&quot;ab cd ef&quot; ,调用该函数如下L1602_string(1,5,&quot;ab cd ef;&quot;)* 输入: 行,列,需要输入1602的数据* 输出: 无********************************************************************* **/void L1602_string(uchar hang,uchar lie,uchar *p){uchar a,b=0;if(hang == 1) a = 0x80;if(hang == 2) a = 0xc0;a = a + lie - 1;while(1){wcmd(a++);if((*p == &#39;\0&#39;)||(b==16)) break;b++;wdata(*p);p++;}}/******************************************************************** * 名称: v_RTInputByte()* 功能: 往DS1302写入1Byte数据* 输入: ucDa 写入的数据* 输出: 无********************************************************************* **/void v_RTInputByte(uchar ucDa){uchar i;ACC = ucDa;T_RST = 1;for(i=8; i&gt;0; i--){T_IO = ACC0;T_CLK = 1;T_CLK = 0;ACC = ACC &gt;&gt; 1;}}/******************************************************************** * 名称: uc_RTOutputByte()* 功能: 从DS1302读取1Byte数据* 输入:无* 返回值: ACC********************************************************************* **/uchar uc_RTOutputByte(void){uchar i;T_RST = 1;for(i=8; i&gt;0; i--){ACC = ACC &gt;&gt;1;T_IO=1;ACC7 = T_IO;T_CLK = 1;T_CLK = 0;}return(ACC);}/******************************************************************** * 名称: v_W1302(uchar ucAddr, uchar ucDa)* 功能: 往DS1302写入数据* 输入: ucAddr: DS1302地址, ucDa: 要写的数据* 返回值: 无********************************************************************* **/void v_W1302(uchar ucAddr, uchar ucDa){T_RST = 0;T_CLK = 0;T_RST = 1;v_RTInputByte(ucAddr); // 写地址_nop_();_nop_();v_RTInputByte(ucDa); // 写1Byte数据T_CLK = 1;T_RST = 0;}/******************************************************************** * 名称: uc_R1302(uchar ucAddr)* 功能: 读取DS1302某地址的数据* 输入: ucAddr: DS1302地址* 返回值: ucDa :读取的数据********************************************************************* **/uchar uc_R1302(uchar ucAddr){uchar ucDa;T_RST = 0;T_CLK = 0;T_RST = 1;v_RTInputByte(ucAddr); //写地址,命令_nop_();_nop_();ucDa = uc_RTOutputByte(); //读1Byte数据T_CLK = 1;T_RST = 0;return(ucDa);}/******************************************************************** * 名称: v_BurstW1302T* 功能: 往DS1302写入时钟数据(多字节方式)* 输入: pSecDa: 时钟数据地址格式为: 秒分时日月星期年控制* 8Byte (BCD码) 1B 1B 1B 1B 1B 1B 1B 1B* 返回值: 无********************************************************************* **/void v_BurstW1302T(uchar *pSecDa){uchar i;v_W1302(0x8e, 0x00); //控制命令,WP=0,写操作T_RST = 0;T_CLK = 0;T_RST = 1;v_RTInputByte(0xbe); //0xbe:时钟多字节写命令for(i=8; i&gt;0; i--) //8Byte = 7Byte 时钟数据+ 1Byte 控制{v_RTInputByte(*pSecDa); //写1Byte数据pSecDa++;}T_CLK = 1;T_RST = 0;}/******************************************************************** * 名称: v_BurstR1302T(uchar *pSecDa)* 功能: 读取DS1302时钟数据* 输入: pSecDa: 时钟数据地址格式为: 秒分时日月星期年* 7Byte (BCD码) 1B 1B 1B 1B 1B 1B 1B* 返回值: ucDa :读取的数据***********************************************************************/void v_BurstR1302T(uchar *pSecDa){uchar i;T_RST = 0;T_CLK = 0;T_RST = 1;v_RTInputByte(0xbf); //0xbf:时钟多字节读命令for(i=8; i&gt;0; i--){*pSecDa = uc_RTOutputByte(); //读1Byte数据pSecDa++;}T_CLK = 1;T_RST = 0;}/******************************************************************** * 名称: v_BurstW1302R(uchar *pReDa)* 功能: 往DS1302寄存器数写入数据(多字节方式)* 输入: pReDa: 寄存器数据地址* 返回值: 无********************************************************************* **/void v_BurstW1302R(uchar *pReDa){uchar i;v_W1302(0x8e,0x00); //控制命令,WP=0,写操作T_RST = 0;T_CLK = 0;T_RST = 1;v_RTInputByte(0xfe); //0xbe:时钟多字节写命令for(i=31; i&gt;0; i--) //31Byte 寄存器数据{v_RTInputByte(*pReDa); //写1Byte数据pReDa++;}T_CLK = 1;T_RST = 0;}/******************************************************************** * 名称: v_BurstR1302R(uchar *pReDa)* 功能: 读取DS1302寄存器数据* 输入: pReDa: 寄存器数据地址* 返回值: 无********************************************************************* **/void v_BurstR1302R(uchar *pReDa){uchar i;T_RST = 0;T_CLK = 0;T_RST = 1;v_RTInputByte(0xff); //0xbf:时钟多字节读命令for(i=31; i&gt;0; i--) //31Byte 寄存器数据{*pReDa = uc_RTOutputByte(); //读1Byte数据pReDa++;}T_CLK = 1;T_RST = 0;}/********************************************************************* 名称: v_Set1302(uchar *pSecDa)* 功能: 设置初始时间* 输入: pSecDa: 初始时间地址。

单片机万年历程序代码

单片机万年历程序代码

单片机万年历程序代码以下是一个示例单片机万年历的程序代码:```c#include <reg51.h>typedef unsigned char uchar;typedef unsigned int uint;sbit K1 = P2^0; // 显示年份sbit K2 = P2^1; // 显示月份sbit K3 = P2^2; // 显示日期uchar code year_tab[] = {31,28,31,30,31,30,31,31,30,31,30,31}; uchar code week_tab[] = {0x06,0x07,0x01,0x02,0x03,0x04,0x05}; uchar year, month, day, week;void delay(uint ms){uint i, j;for(i=ms;i>0;i--)for(j=110;j>0;j--);}uchar getKey(){if(K1==0) {delay(5);if(K1==0)return 1;while(!K1);}if(K2==0) {delay(5);if(K2==0)return 2;while(!K2);}if(K3==0) {delay(5);if(K3==0)return 3;while(!K3);}return 0;}void display(uchar num) {P0 = num;delay(1);P0 = 0x00;}void init(){TMOD=0x01;TH0=0xFC;TL0=0x67;EA=1;ET0=1;TR0=1;}void main(){init();while(1) {uchar key = getKey();if(key == 1) {year++;if(year == 100)year = 0;}else if(key == 2) {month++;if(month == 13)month = 1;}else if(key == 3) {day++;if(day > year_tab[month-1]) { day = 1;}}display(year / 10);display(year % 10);display(month / 10);display(month % 10);display(day / 10);display(day % 10);display(week);}}void timer0() interrupt 1{TH0=0xFC;TL0=0x67;week++;if(week == 7)week = 0;}```该代码的主要思路是通过外部三个按键模拟年、月和日的调节,通过一个定时器不断更新星期的计数,然后将年、月、日和星期分别在数码管上显示出来。

单片机万年历

单片机万年历

关键词:时钟芯片DS12C887;温度采集DS18B20;单片机AT89S52;液晶显示1602摘要电子万年历是一种非常广泛日常计时工具,对现代社会越来越流行。

它可以对年、月、日、周日、时、分、秒进行计时,还具有闰年补偿等多种功能。

本系统选用DALLAS公司生产的日历时钟芯片DS12C887来作为实时时钟芯片,为本系统提供详细的年、月、日、星期和小时、分钟等时间信息。

数字万年历采用直观数字显示,可以同时显示年、月、日、周日、时、分、秒和温度等信息,还具有定时和时间校准等功能。

该电路采用AT89S52单片机作为核心,功耗小,能在3V的低压工作,电压可选用3~5V电压供电。

本系统硬件部分由AT89S52单片机、DS12C887时钟芯片、1062液晶显示器、DS18B20温度测量、键盘、蜂鸣器系统等部分构成。

软件部分在keil 环境下用C51语言编写,包括时间设置、时间显示、定时设置、定时闹钟、温度显示。

没有良好的基础知识和实践经验会受到很大限制,每项功能实现时需要那种硬件,程序该如何编写,算法如何实现等,没有一定的基础就不可能很好的实现。

在编写程序过程中发现以现有的相关知识要独自完成编写任务困难重重,在老师和同学的帮助下才完成了程序部分的编写。

文章后附有电路原理图、程序清单,以供读者参考。

因水平有限,难免有疏落不足之处,敬请老师和同学能给与批评指正。

目录第一章概述 (3)§1.1实时时钟研究的背景及意义 (3)§1.2论文主要研究内容 (3)1.2.1 系统设计实现的目标 (3)1.2.2 系统的总体设计 (3)第二章硬件电路设计 (5)§2.1单片机最小系统 (5)§2.2时钟芯片电路 (5)2.2.1 时钟芯片引脚介绍 (5)2.2.2时钟芯片DS12C887,其内存空间介绍 (7)2.2.3 4个控制寄存器介绍 (7)§2.4温度采集电路设计 (9)2.4.1 DS18B20的主要特性 (9)2.4.2 DS1820的基本操作指令 (9)2.4.3 温度测量的步骤 (10)2.4.4 DS18B20的操作时序 (10)§2.5 1602LCD液晶显示屏 (12)2.5.1 1602字符型LCD简介 (12)2.5.2 1602引脚功能说明 (12)2.5.3 1602LCD的指令说明及时序 (12)2.5.4 1602LCD的RAM地址映射及标准字库表 (14)2.5.5 1602LCD的一般初始化(复位)过程 (16)2.4.6 1602LCD的电路连接 (16)§2.6 蜂鸣器闹铃电路 (17)§2.7 按键调整电路 (17)§2.8 电源模块 (18)第三章软件部分设计 (19)§3.1 主程序流程 (19)§3.2 时间设置子程序流程 (19)§3.3 闹钟设置子程序流程 (20)§3.4 程序设计问题 (21)3.4.1 按键抖动问题 (21)3.4.2 蜂鸣器设置 (21)3.4.3 液晶显示的设置 (21)3.4.4 中断设置 (21)3.4.5 时钟芯片设置 (22)结束语 (25)致谢词 (26)参考文献 (27)附件1 (28)第一章概述§1.1实时时钟研究的背景及意义在现实我们生活中每个人都可能有自己的时钟,光阴在永不停息的流逝,有了时钟人们就能随着时间有计划的过着每一天。

c语言编的万年历

c语言编的万年历

万年历数字钟及可调时钟系统一、引言万年历数字钟是一种用万年历时钟芯片实现年、月、日、时、分、秒计时,并通过单片机处理后送给显示芯片显示的装置,与机械式时钟相比具有更高的准确性和直观性,且具有更长的使用寿命;本系统还可以扩展为可调的自动开关,对家电对用电设备进行控制,笔者在随后改制成为可调时的自动断电的供电系统.二、原理图设计1.单片机及其外围电路设计复位采用X25045芯片,复位电路如图1所示;图1 复位电路设计单片机采用贴片封装的AT89S51,晶振为;其中~为下载程序使用,电路如图2所示;图2 单片机89S51外围电路设计2.时钟芯片电路设计时钟芯片采用PCF8563,晶振采用,电容使用15pf;PCF8563 是PHILIPS 公司推出的一款工业级内含I2C 总线接口功能的具有极低功耗的多功能时钟/日历芯片;内部时钟电路、内部振荡电路、内部低电压检测电路以及两线制I2C 总线通讯方式,不但使外围电路及其简洁,而且也增加了芯片的可靠性;同时每次读写数据后,内嵌的字地址寄存器会自动产生增量;电路如图3所示;图3 时钟芯片电路设计3.显示芯片电路设计显示芯片采用ZLG7289,晶振为12MHz;ZLG7289A 是广州周立功单片机发展有限公司自行设计的,具有SPI 串行接口功能的可同时驱动8 位共阴式数码管或64 只独立LED 的智能显示驱动芯片,该芯片同时还可连接多达64 键的键盘矩阵,单片即可完成LED 显示﹑键盘接口的全部功能;电路如图4所示;图4 显示芯片电路设计4.双电源电路设计系统采用双电源,平时使用V1=10V的外接电源,停电时使用电池,由V2输入;电池有6节,其电压为9V;当电池电压低于6V时,LED亮,说明电池电量不足;电路如图5所示;图5 双电源电路设计三、程序设计程序开始时先对系统初始化,并设置好各种中断;下步操作主要是对时钟芯片进行操作,首先要给时钟芯片设置初值,时钟芯片便自行计数;此时检测是否有按键按下,按键是为了调整时钟;有按键按下则执行按键中断程序,没有按键按下则执行下一步的操作,即取时钟芯片中的时钟值,然后送显示;程序流程图如下;图6 总体流程图四、源程序include <>include <>include <>define uchar unsigned char /宏定义/define uint unsigned intuchar close_date,open_date;void RESWDIvoid;void WRENvoid;void WRDIvoid;void WRSRvoid;unsigned char RSDRvoid;void WIPCHKvoid;void OUTByteunsigned char Byte;unsigned char INPUTBytevoid;unsigned char ReadByteunsigned char ADD;void WriteByteunsigned char Byte,ADD;define _Nop _nop_ /定义空指令/sbit zlg7289_cs =P1^1;sbit zlg7289_clk =P2^6;sbit zlg7289_dio =P2^7;sbit zlg7289_key =P3^2;sbit p07=P0^7;sbit p06=P0^6;sbit CS=P2^4;sbit SCK=P2^2;sbit SO=P2^5;sbit SI=P2^3;sbit p10=P1^0;sbit SDA=P1^2; /模拟I2C数据传送位/sbit SCL=P1^3; /模拟I2C时钟控制位/uchar buf9={0x00,0x00,0x30,0x23,0x15,0x1,0x05,0x04,0x05}; uchar bufdata,bb,date;uchar SLA=0xA2,SUBA=0x00;uchar p; /接收指针/uchar keychange=0;uchar key=0; /键盘值/bit keyint=0; /按键中断标志/bit keyok=1; /数据是否修改好/uchar num=0; /移位键移到哪个LED//延时函数/void delayuchar i{whilei--;}// TIMER1 interrupt process //timer0 void interrupt 1 using 1{TH0=0x3c;TL0=0xb0;RESWDI;}void RESWDIvoid ////复位看门狗喂狗{zlg7289_cs=1;CS = 1;CS = 0;CS = 1;zlg7289_cs=1;}void WRENvoid //写使能复位使用{zlg7289_cs=1;SCK=0;CS=0;OUTByte0x06; //发送06H写使能命令字SCK=0;CS=1;zlg7289_cs=1;}void WRDIvoid //写使能复位禁止写{{zlg7289_cs=1;SCK=0;CS=0;OUTByte0x04; //发送04H写禁止命令字SCK=0; CS=1;zlg7289_cs=1;}void WRSRvoid //写状态寄存器{WREN;zlg7289_cs=1;SCK=0;CS=0;OUTByte0x01; //发送01H写寄存器命令字OUTByte0x00; //发送寄存器值BL0,BL1为0没写保护,WD0=0 W01=1 //WD1=0WD1=0看门狗复位时间SCK=0;CS=1;zlg7289_cs=1;WIPCHK; //判断是否写入}unsigned char RSDRvoid //读状态寄存器{unsigned char Temp;zlg7289_cs=1;SCK=0;CS=0;OUTByte0x05; //发送05H读状态寄存器命令字Temp = INPUTByte; //读状态寄存器值SCK=0;CS=1;return Temp;;//这一个调试时没有执行,Temp的值总是0xFF;zlg7289_cs=1;}void WIPCHKvoid //检查WIP位,判断是否写入完成{unsigned char Temp,TempCyc;forTempCyc=0;TempCyc<50;TempCyc++{Temp = RSDR; //读状态寄存器if Temp&0x01==0TempCyc = 50;}}//单字节指令或数据写入X25045//在SI线上输入的数据在SCK的上升沿被锁存;void OUTByteunsigned char Byte //输出一个定节{unsigned char TempCyc;zlg7289_cs=1;forTempCyc=0;TempCyc<8;TempCyc++{SCK = 0;ifByte&0x80SI = 1;elseSI = 0;SCK = 1;Byte = Byte<<1; //右移}SI=0; //使SI处于确定的状态zlg7289_cs=1;}//单字节数据从X25045读到单片机//数据由SCK的下降沿输出到SO线上;unsigned char INPUTBytevoid //输入一个字节{unsigned char Temp=0, TempCyc;zlg7289_cs=1;forTempCyc=0;TempCyc<8;TempCyc++{Temp = Temp<<1; //右移SCK = 1;SCK=0;if SOTemp = Temp|0x01; //SO为1,则最低位为1elseTemp&=0xFE;}return Temp;;//这一个调试时没有执行,Temp的值总是0zlg7289_cs=1;}unsigned char ReadByteunsigned char ADD //读地址中的数据这里不做先导字处理,只能读00-FFH{unsigned char Temp;zlg7289_cs=1;SCK=0;CS=0;SO=1;SI=1;OUTByte0x3; //发送读指令03H 如要支持000-FFF则要把高位地址左移3位再为03H相或OUTByteADD; //发送低位地址Temp = INPUTByte;SCK=0;CS=1;return Temp;//这一个调试时没有执行,Temp的zlg7289_cs=1;}void WriteByteunsigned char Byte,ADD //向地址写入数据这里同样不做先导字处理,只能写00-FFH{WREN;zlg7289_cs=1;SCK=0;CS=0;SO=1;SI=1;OUTByte0x2; //发送写指令02H 如要支持000-FFF则要把高位地址左移2位再为02H相或OUTByteADD; //发送低位地址OUTByteByte; //发送数据SCK=0;CS=1;zlg7289_cs=1;}/模拟I2C总线传输程序/bit ack; /应答标志位//起动总线函数/void Start_I2c{SDA=1; /发送起始条件的数据信号/_Nop;SCL=1;_Nop; /起始条件建立时间大于,延时/_Nop;_Nop;_Nop;_Nop;SDA=0; /发送起始信号/_Nop; / 起始条件锁定时间大于4μs/_Nop;_Nop;_Nop;_Nop;SCL=0; /钳住I2C总线,准备发送或接收数据 / _Nop;_Nop;}/结束总线函数/void Stop_I2c{SDA=0; /发送结束条件的数据信号/_Nop; /发送结束条件的时钟信号/SCL=1; /结束条件建立时间大于4μs/_Nop;_Nop;_Nop;_Nop;SDA=1; /发送I2C总线结束信号/_Nop;_Nop;_Nop;_Nop;}/字节数据传送函数/void SendByteuchar c{uchar BitCnt;forBitCnt=0;BitCnt<8;BitCnt++ /要传送的数据长度为8位/{ifc<<BitCnt&0x80SDA=1; /判断发送位/else SDA=0;_Nop;SCL=1; /置时钟线为高,通知被控器开始接收数据位/ _Nop;_Nop; /保证时钟高电平周期大于4μs/_Nop;_Nop;_Nop;SCL=0;}_Nop;_Nop;SDA=1; /8位发送完后释放数据线,准备接收应答位/_Nop;_Nop;SCL=1;_Nop;_Nop;_Nop;ifSDA==1ack=0;else ack=1; /判断是否接收到应答信号/_Nop;_Nop;}/字节数据接收函数/uchar RcvByte{uchar retc;uchar BitCnt;retc=0;SDA=1; /置数据线为输入方式/forBitCnt=0;BitCnt<8;BitCnt++{_Nop;SCL=0; /置时钟线为低,准备接收数据位/_Nop;_Nop; /时钟低电平周期大于/_Nop;_Nop;_Nop;SCL=1; /置时钟线为高使数据线上数据有效/_Nop;_Nop;retc=retc<<1;ifSDA==1retc=retc+1; /读数据位,接收的数据位放入retc中 / _Nop;_Nop;}SCL=0;_Nop;_Nop;returnretc;}/应答子函数/void Ack_I2cbit a{ifa==0SDA=0; /在此发出应答或非应答信号 /else SDA=1;_Nop;_Nop;_Nop;SCL=1;_Nop;_Nop; /时钟低电平周期大于4μs/_Nop;_Nop;_Nop;SCL=0; /清时钟线,钳住I2C总线以便继续接收/ _Nop;_Nop;}/向有子地址器件发送多字节数据函数/bit ISendStruchar sla,uchar suba,uchar s{uchar i;Start_I2c; /启动总线/SendBytesla; /发送器件地址/ifack==0return0;SendBytesuba; /发送器件子地址/ifack==0return0;fori=0;i<9;i++{SendBytes; /发送数据/ifack==0return0;s++;}Stop_I2c; /结束总线/return1;}/向有子地址器件读取多字节数据函数/bit IRcvStruchar sla,uchar suba,uchar suchar i;Start_I2c; /启动总线/SendBytesla; /发送器件地址/ifack==0return0;SendBytesuba; /发送器件子地址/ ifack==0return0;Start_I2c;SendBytesla+1;ifack==0return0;fori=0;i<8;i++{s=RcvByte; /发送数据/Ack_I2c0; /发送就答位/ s++;}s=RcvByte;Ack_I2c1; /发送非应位/ Stop_I2c; /结束总线/return1;}/模拟I2C程序结束//显示函数/void displayuint dis{uchar j;zlg7289_clk=0;delay20;zlg7289_cs=0;forj=0;j<16;j++{ifdis&0x8000==0x8000 zlg7289_dio=1;else zlg7289_dio=0;delay20;zlg7289_clk=1;delay10;zlg7289_clk=0;delay10;dis=dis<<1;}zlg7289_cs=1;delay20;}void dis_playuchar aa{uchar i;fori=0;i<8;i++{if_crol_aa,i&0x80zlg7289_dio = 1;elsezlg7289_dio = 0;zlg7289_clk = 1;delay10; /延时/zlg7289_clk = 0;}}void displaymonth{bufdata=buf5&0x0f;zlg7289_cs=0;delay10;dis_play0xc8;delay10;dis_playbufdata; /显示日个位/ zlg7289_cs=1;delay70;bufdata=buf5&0x30;bufdata=bufdata>>4;bufdata=bufdata&0x0f;zlg7289_cs=0;delay10;dis_play0xc9;delay10;dis_playbufdata; /显示日十位/ zlg7289_cs=1;delay70;bufdata=buf7&0x0f;zlg7289_cs=0;delay10;dis_play0xca;delay10;dis_playbufdata; /显示月个位/ zlg7289_cs=1;delay70;bufdata=buf7&0x10;bufdata=bufdata>>4;bufdata=bufdata&0x0f;zlg7289_cs=0;delay10;dis_play0xcf;delay10;dis_playbufdata; /显示月十位/ zlg7289_cs=1;delay70;}void displaytime{bufdata=buf3&0x0f;zlg7289_cs=0;delay10;dis_play0xce;delay10;dis_playbufdata; /显示分个位/ zlg7289_cs=1;delay70;bufdata=buf3&0x70;bufdata=bufdata>>4;bufdata=bufdata&0x0f;zlg7289_cs=0;delay10;dis_play0xcd;delay10;dis_playbufdata; /显示分十位/ zlg7289_cs=1;delay70;bufdata=buf4&0x0f;zlg7289_cs=0;delay10;dis_play0xcc;delay10;dis_playbufdata; /显示时个位/ zlg7289_cs=1;delay70;bufdata=buf4&0x30;bufdata=bufdata>>4;bufdata=bufdata&0x0f;zlg7289_cs=0;delay10;dis_play0xcb;delay10;dis_playbufdata; /显示时十位/ zlg7289_cs=1;delay70;}void display_x5045{date=ReadByte0x40;close_date=date;bufdata=date&0x0f;zlg7289_cs=0;delay10;dis_play0xce;delay10;dis_playbufdata; /显示分个位/ zlg7289_cs=1;delay70;bufdata=date&0x70;bufdata=bufdata>>4;bufdata=bufdata&0x0f;zlg7289_cs=0;delay10;dis_play0xcd;delay10;dis_playbufdata; /显示分十位/ zlg7289_cs=1;delay70;date=ReadByte0x42;bufdata=date&0x0f;zlg7289_cs=0;open_date=ReadByte0x42;delay10;dis_play0xcc;delay10;dis_playbufdata; /显示时个位/zlg7289_cs=1;delay70;bufdata=date&0x30;bufdata=bufdata>>4;bufdata=bufdata&0x0f;zlg7289_cs=0;delay10;dis_play0xcb;delay10;dis_playbufdata; /显示时十位/zlg7289_cs=1;delay70;}/按键处理程序///key=47: 闪烁移位键shift//key=39: +//key=39: -//key=31: 确认键okvoid key_int interrupt 0 /键盘中断程序/{keyint=1;}void keyexe{uchar i;uchar temp=0;uchar aa;p06=1;EX0=1;zlg7289_cs = 0;delay10;dis_play0x15; /写入读键盘数据指令/delay10;fori=0;i<8;i++{temp=temp<<1;aa=zlg7289_dio; // 按位或ifaa==1 // 读数据位,接收的数据位放入retc中temp=temp+1;zlg7289_clk=1;delay10; // 延时zlg7289_clk=0;}zlg7289_cs=1;key=temp;ifkey==47 //闪烁移位键{key=0;keyok=0;EX0=0;ifnum==8{num=1;}elsenum++;switchnum{ case 1: {display0x88fe;}break;case 2: {display0x88fd;}break;case 3: {display0x88fb;}break;case 4: {display0x88f7;}break;case 5: {display0x88ef;}break;case 6: {display0x88df;}break;case 7: {display0x88bf;}break;case 8: {display0x887f;}break;default: ;}EX0=1;}else ifkey==39 //+{EX0=0;key=0;RESWDI;ifnum=0{keyok=0;keychange=1;RESWDI;}ifnum==7 //在分个位上{ifbuf3&0x0f==0x09 buf3&=0xf0;else ++buf3;EX0=1;bufdata=buf3&0x0f;zlg7289_cs=0;delay10;dis_play0xce;delay10;dis_playbufdata; /显示分个位/zlg7289_cs=1;delay70;RESWDI;}else ifnum==6 //在分十位上{ifbuf3&0xf0==0x50 buf3&=0x0f;else buf3+=0x10;EX0=1;bufdata=buf3&0x70;bufdata=bufdata>>4;bufdata=bufdata&0x0f;zlg7289_cs=0;delay10;dis_play0xcd;delay10;dis_playbufdata; /显示分十位/zlg7289_cs=1;delay70;RESWDI;}else ifnum==5 //在小时个位上{ifbuf4&0xf0==0x20{ifbuf4&0x0f>0x02 buf4&=0xf0;else ++buf4;}else ifbuf4&0x0f==0x09 buf4&=0xf0;else ++buf4;EX0=1;bufdata=buf4&0x0f;zlg7289_cs=0;delay10;delay10;dis_playbufdata; /显示时个位/zlg7289_cs=1;delay70;RESWDI;}else ifnum==4 //在小时十位上{ifbuf4&0x0f>0x03{ifbuf4&0xf0>0x00 buf4&=0x0f;else buf4+=0x10;}else ifbuf4&0xf0==0x20 buf4&=0x0f;else buf4+=0x10;EX0=1;bufdata=buf4&0x30;bufdata=bufdata>>4;bufdata&=0x0f;zlg7289_cs=0;RESWDI;delay10;dis_play0xcb;delay10;dis_playbufdata; /显示时十位/zlg7289_cs=1;delay70;RESWDI;}else ifnum==1 //在日的个位上{ifbuf5&0xf0==0x30{ifbuf5&0x0f>0x00 buf5&=0xf0;else ++buf5;}else ifbuf5&0x0f==0x09 buf5&=0xf0;else ++buf5;EX0=1;bufdata=buf5&0x0f;RESWDI;zlg7289_cs=0;delay10;delay10;dis_playbufdata; /显示日个位/zlg7289_cs=1;delay70;RESWDI;}else ifnum==2 //在日的十位上{ifbuf5&0x0f>0x01{ifbuf5&0xf0>0x10 buf5&=0x0f;else buf5+=0x10;}else ifbuf5&0xf0==0x30 buf5&=0x0f;else buf5+=0x10;EX0=1;bufdata=buf5&0x30;RESWDI;bufdata=bufdata>>4;bufdata&=0x0f;zlg7289_cs=0;delay10;dis_play0xc9;delay10;dis_playbufdata; /显示日十位/zlg7289_cs=1;delay70;RESWDI;}else ifnum==4 //在月个位上{ifbuf7&0xf0==0x10{ifbuf7&0x0f>0x01 buf7&=0x0f;else ++buf7;}else ifbuf7&0x0f==0x09 buf7&=0xf0;else ++buf7;EX0=1;bufdata=buf7&0x0f;RESWDI;zlg7289_cs=0;delay10;dis_play0xca;delay10;dis_playbufdata; /显示月个位/zlg7289_cs=1;delay70;RESWDI;}else ifnum==8 //在月十位上{ifbuf7&0x0f>0x02{buf7&=0x0f;}else ifbuf7&0xf0==0x10 buf7&=0x0f;else buf7+=0x10;EX0=1;bufdata=buf7&0x10;bufdata=bufdata>>4;bufdata&=0x0f;RESWDI;zlg7289_cs=0;delay10;dis_play0xcf;delay10;dis_playbufdata; /显示月十位/zlg7289_cs=1;delay70;RESWDI;}else ;}else ifkey==15 //存放断电时间,数据存放于5045中,每按键数据减少一{display_x5045;EX0=1;key=0;ifnum=0{keyok=0;keychange=1;}ifnum==7 //在分个位上{date=ReadByte0x40;ifdate&0x0f==0x00 date|=0x09;else --date;EX0=1;bufdata=date&0x0f;zlg7289_cs=0;delay10;dis_play0xce;delay10;dis_playbufdata; /显示分个位/zlg7289_cs=1;delay70;WriteBytedate,0x40;}else ifnum==6 //在分十位上{date=ReadByte0x40;ifdate&0xf0==0x00 date|=0x50;else date-=0x10;EX0=1;bufdata=date&0x70;bufdata=bufdata>>4;bufdata&=0x0f;zlg7289_cs=0;delay10;dis_play0xcd;delay10;dis_playbufdata; /显示分十位/zlg7289_cs=1;delay70;WriteBytedate,0x40;}else ifnum==5 //在小时个位上{date=ReadByte0x42;ifdate&0xf0==0x20{ifdate&0x0f==0x00||date&0x0f>0x03 date|=0x03;else --date;}else ifdate&0x0f==0x00 date|=0x09;else --date;EX0=1;bufdata=date&0x0f;zlg7289_cs=0;delay10;dis_play0xcc;delay10;dis_playbufdata; /显示时个位/zlg7289_cs=1;delay70;WriteBytedate,0x42;}else ifnum==4 //在小时十位上{date=ReadByte0x42;ifdate&0x0f>0x03{ifdate&0xf0==0x00 date|=0x10;else date-=0x10;}else ifdate&0xf0==0x00 date|=0x20;else date-=0x10;EX0=1;bufdata=date&0x30;bufdata=bufdata>>4;bufdata&=0x0f;zlg7289_cs=0;delay10;dis_play0xcb;delay10;dis_playbufdata; /显示时十位/zlg7289_cs=1;delay70;WriteBytedate,0x42;}else ifnum==1 //在日的个位上{ifbuf5&0xf0==0x30{ifbuf5&0x0f==0x00||buf5&0x0f>0x01 buf5|=0x01;else --buf5;}else ifbuf5&0x0f==0x00 buf5|=0x09;else --buf5;bufdata=buf5&0x0f;zlg7289_cs=0;delay10;dis_play0xc8;delay10;dis_playbufdata; /显示日个位/zlg7289_cs=1;delay70;}else ifnum==2 //在日的十位上{ifbuf5&0x0f>0x01{ifbuf5&0xf0==0x00 buf5|=0x20;else buf5-=0x10;}else ifbuf5&0xf0==0x00 buf5|=0x30;else buf5-=0x10;bufdata=buf5&0x30;bufdata=bufdata>>4;bufdata&=0x0f;zlg7289_cs=0;delay10;dis_play0xc9;delay10;dis_playbufdata; /显示日十位/zlg7289_cs=1;delay70;}else ifnum==3 //在月个位上{ifbuf7&0xf0==0x10{ifbuf7&0x0f==0x00||buf7&0x0f>0x01 buf7|=0x01;else --buf7;}else ifbuf7&0x0f==0x00 buf7|=0x09;else --buf7;bufdata=buf7&0x0f;zlg7289_cs=0;delay10;dis_play0xca;delay10;dis_playbufdata; /显示月个位/zlg7289_cs=1;delay70;}else ifnum==8 //在月十位上{ifbuf7&0x0f>0x02 buf7&=0x0f;else ifbuf7&0xf0==0x00 buf7|=0x10;else buf7-=0x10;bufdata=buf7&0x10;bufdata=bufdata>>4;bufdata&=0x0f;zlg7289_cs=0;delay10;dis_play0xcf;delay10;dis_playbufdata; /显示月十位/zlg7289_cs=1;delay70;EX0=1;}else ;}else ifkey==31 //ok{EX0=0;key=0;keyok=1;num=0;ifkeychange==1{keychange=0;p=buf;SUBA=0x00;buf0=0x00;buf1=0x00;buf2=0x00;ISendStrSLA,SUBA,p;for i=0;i<250;i++delay250;}else ;zlg7289_cs=0;delay10;dis_play0x88;delay10;dis_play0xff; /清LED闪烁/zlg7289_cs=1;delay70;}EX0=1;}/主函数//void main{unsigned char i,j,word2;/程序的初始化/TMOD=0x09;TH0=0x3c;TL0=0xb0;TR0=1;ET0=1;IP=0x02; //中断优先级敲定IT0=1;EX0=1;IE0=1;EA=1; /打开全部中断/p10=1;p06=1;p07=1;WREN;WRSR;WRDI;WriteByte0x07,0x40;//在0x20中写入0x10, 为了验证WriteByte0x0a,0x42;WRDI;word2=ReadByte0x22;/初始化结束//清LED显示/zlg7289_cs=0;delay10;dis_play0xA4; //复位zlg7289_cs=1;delay70;/给时钟芯片附初值/Stop_I2c;EX0=0;p=buf;SUBA=0x00;buf0=0x00;buf1=0x00;forj=0;j<8;j++{fori=0;i<250;i++delay250;}ISendStrSLA,SUBA,p;delay100;EX0=1;while1{ifkeyint==1{EX0=1;ET0=1;keyexe;ifkeychange==0{keyint=0;ET0=1;}for i=0;i<250;i++delay250;EX0=1;}ifkeyok==1&&keychange==0&&keyint==0 {EX0=0;p=buf;SUBA=0x00;IRcvStrSLA,SUBA,p;for i=0;i<250;i++delay25;buf3&=0x7f;buf4&=0x3f;buf5&=0x3f;buf7&=0x1f;displaymonth;displaytime;EX0=1;}ifbuf4>=close_date||buf4<=open_date p10=0;for i=0;i<250;i++delay25;}}。

单片机万年历 代码

单片机万年历 代码

void DS1302_limit(void) //初始化{DS1302_WriteEnable();DS1302_OscEnable();for(ds1302_b=0;ds1302_b<7;ds1302_b++)DS1302_SendByte(ds_sec+2*ds1302_b,d1302[ds1302_b]); //赋值初始化}uchar DS1302_Read(uchar address) //读时钟{uchar dat;DS1302_WriteEnable();switch(address){case 0:dat=DS1302_ReceiveByte(ds_sec+1);break;case 1:dat=DS1302_ReceiveByte(ds_min+1);break;case 2:dat=DS1302_ReceiveByte(ds_hour+1);break;case 3:dat=DS1302_ReceiveByte(ds_day+1);break;case 4:dat=DS1302_ReceiveByte(ds_week+1);break;case 5:dat=DS1302_ReceiveByte(ds_month+1);break;case 6:dat=DS1302_ReceiveByte(ds_year+1);break;}DS1302_WriteDisable();return(dat);}void DS1302_Write(uchar address,uchar dat){DS1302_WriteEnable();switch(address){case 0:DS1302_SendByte(ds_sec,dat);break;case 1:DS1302_SendByte(ds_min,dat);break;case 2:DS1302_SendByte(ds_hour,dat);break;case 3:DS1302_SendByte(ds_day,dat);break;case 4:DS1302_SendByte(ds_week,dat);break;case 5:DS1302_SendByte(ds_month,dat);break;case 6:DS1302_SendByte(ds_year,dat);break;}DS1302_WriteDisable();}ds1302pro() //读出数据{nian01=DS1302_ReceiveByte(ds_year+1);yue01=DS1302_ReceiveByte(ds_month+1);ri01=DS1302_ReceiveByte(ds_day+1);xiaoshi01=DS1302_ReceiveByte(ds_hour+1);sec01=DS1302_ReceiveByte(ds_sec+1); //读秒信息min01=DS1302_ReceiveByte(ds_min+1); //读分信息zhouxingqi=DS1302_ReceiveByte(ds_week+1);d1302_transfer(); //数值处理提取出待显示的值}void DS1302_SendByte(uchar Command,uchar XmtDat) // 发送数据程序,发送1个字节给被控器DS1302{uchar i;RST=0;_nop_();SCLK=0;_nop_();RST=1;for(i=0;i<8;i++){IO_DATA= (bit)(Command&0x01);Command = Command >> 1;SCLK=1;_nop_();SCLK=0;}for(i=0;i<8;i++){IO_DATA= (bit)(XmtDat&0x01);XmtDat = XmtDat >> 1;SCLK=1;_nop_();SCLK=0;}RST=0;}uchar DS1302_ReceiveByte(uchar Command) // 接收数据程序;从被控器DS1302 接收1个字节数据{uchar i, RcvDat=0;RST=0;_nop_();SCLK=0;_nop_();RST=1;for(i=0;i<8;i++){IO_DATA= (bit)(Command&0x01);Command = Command >> 1;SCLK=1;_nop_();SCLK=0;}for(i=0;i<7;i++){if(IO_DATA)RcvDat|=0x80;RcvDat= RcvDat >> 1;SCLK=1;_nop_();SCLK=0;}if(IO_DATA)RcvDat|=0x80;RST=0;return RcvDat;}void DS1302_WriteEnable(void) //允许数据写入寄存器{DS1302_SendByte(ds_com,00);}void DS1302_WriteDisable(void) //禁止数据写入寄存器{DS1302_SendByte(ds_com,0x80);}void DS1302_OscEnable(void) //起动时钟操作{DS1302_SendByte(ds_sec,0x00);}void DS1302_OscDisable(void) //停止时钟操作{DS1302_SendByte(ds_sec,0x80);}void d1302_transfer(void) //数据转换函数{nian02=nian01&0x0f;nian01=nian01>>4;yue02=yue01&0x0f;yue01=yue01>>4;ri02=ri01&0x0f;ri01=ri01>>4;xiaoshi02=xiaoshi01&0x0f;xiaoshi01=xiaoshi01>>4;min02=min01&0x0f;min01=min01>>4;sec02=sec01&0x0f; //取miao信号的低四位 sec01=sec01>>4; //取高四位}void delay1302(int i) //延时函数{uchar x,j;for(x=0;x<i;x++){for(j=0;j<125;j++){;} }}。

基于PIC16F887和1307的数字万年历c程序代码

基于PIC16F887和1307的数字万年历c程序代码

//温度在 R1
//========主程序 void main() { CSH(); READ_DS1307(0,7);//读 DS1307 if(A[0]&0x80) DS1307_CSH();//判断是否初始化 while(1) { clock(); set_time();//按键检测 delaynms(50); if(flag==0) { READ_DS1307(0,7);//读 DS1307
MENU_DS1307();//显示 DS1307 T=READ_T();//读温度 DISP_T(T);//显示温度 } } }
//========初始化端口 void CSH(void) { TRISD=0b00000000; RD7=1; TRISB=0x0FF; RBPU=0; WPUB=0x0FF; ANSELH=0; PORTB=0x00;
//控制 LCD1604,全为输出 //背光
//===PWM 设置 TRISC1=0; //RC1 为输出 RC1=0; PR2=124; //周期为 1ms CCPR2L=0x32; CCP2CON=0b00000000;//关闭 PWM T2CON=0b00000110; //TMR2 预分频 1:16,开始工 IIC_CSH(); LCD_CSH(); } //LCD 模块初始化 void LCD_CSH(void) { DELAY(20); //延时 20ms LCD_WRITE_4(0b0011,COM); //发送控制序列 DELAY_US(10); //延时 100us LCD_WRITE_4(0b0011,COM); //发送控制序列 DELAY_US(10); //延时 100us LCD_WRITE_4(0b0011,COM); //发送控制序列 DELAY_US(10); //延时 100us LCD_WRITE_4(0b0010,COM); //4 位数据格式 LCD_BUSY(); //LCD 忙检测 LCD_WRITE(0b00101000,COM); //4 位数据格式,2 行,5×7 点阵

单片机代码-DS1302万年历

单片机代码-DS1302万年历

#include<reg52.h>#include<intrins.h> //为了使用这个头文件中的_nop_()延时函数sbitsda=P2^0; //定义1302的数据线sbitscl=P2^1; //定义1302的时钟线sbitrst=P2^4; //定义1302的复位控制端,高电平时启动1302,低电平时关闭1302 sbit hc573_sg_le=P2^6; //对用于锁存段数据的573锁存LE端进行定义sbit hc573_bit_le=P2^7; //对用于锁存位选通数据的573锁存LE端进行定义sbitlcd_rs=P1^0; //1602数据/命令选择端,高电平执行数据操作,低电平执行命令操作sbitlcd_rw=P1^1; //1602读/写控制端高电平读,低电平写sbitlcd_en=P2^5; //1602读写控制使能信号,它为高脉冲信号才可执行读写操作sbit sta7=P0^7; //1602忙信号检测位,为1则忙,需等待,为0表示空闲unsigned char write_dat[8]={0x12,0x36,0x17,0x23,0x8,0x5,0x13,0x80}; //秒分时日月星期年和保护寄存器的初值unsigned char read_dat[8]; //用于接收从1302读到的寄存器当前值unsigned char code lcd_line1[]={" 20 - -"}; //定义第一行液晶显示的格式字符数组unsigned char code lcd_line2[]={"Week: : :"}; //定义第二行液晶显示的格式字符数组void lcd_busy_check(void) //1602忙信号检测,忙则等待{P0=0xff;do{lcd_rs=0; //读状态操作,为0lcd_rw=1; //读操作为1lcd_en=0;lcd_en=1; //读状态,需为高电平}while (sta7==1); //如果为1则忙,等待...直到为0lcd_en=0;}void lcd_write_cmd(unsigned char cmd) //液晶写命令函数{lcd_busy_check(); //每次操作之前都要进行忙信号检测lcd_rs=0; //执行命令操作,为0lcd_rw=0; //写操作,为0P0=cmd; //送指令到液晶数据端口P0,准备执行命令_nop_(); //这是一个延时函数,可延时一个机器周期,它在“intrins.h”中lcd_en=1; //高电平,指令送入液晶控制器_nop_(); //保持一会儿,使指令可靠地送入液晶控制器lcd_en=0; //低电平,执行命令}void lcd_write_data(unsigned char dat) //液晶写数据函数{lcd_busy_check(); //每次操作之前都要进行忙信号检测lcd_rs=1; //执行数据操作,为1lcd_rw=0; //写操作,为0P0=dat; //送数据到液晶数据端口P0,准备执行数据操作_nop_();lcd_en=1; //高电平,数据送入液晶液晶数据RAM_nop_(); //保持一会儿,使显示数据可靠地送入液晶数据RAM lcd_en=0; //低电平,显示数据}void lcd1602_init() //液晶显示初始化操作{P0=0x00;hc573_bit_le=0;hc573_sg_le=0; //关闭HC573使数码管不显示lcd_en=0; //为0,为实现高脉冲作准备lcd_write_cmd(0x38); //设置为5x7显示lcd_write_cmd(0x0c); // 打开显示-显示光标-光标闪烁lcd_write_cmd(0x6); //地址加一,光标右移,整屏显示不移动lcd_write_cmd(0x01); //清屏}/*--对1302进行写一个字节的函数--*/voidwrite_byte(unsigned char dat){unsigned char i;for(i=8;i>0;i--){sda=(bit)(dat&0x01);scl=0;scl=1;dat=dat>>1;}}/*--对1302进行读一个字节的函数--*/unsigned char read_byte(){unsigned char dat,i;for(i=8;i>0;i--){dat=dat>>1;scl=1;scl=0;if(sda==1)dat=(dat|0x80);}returndat;}/*--1302的初始化函数。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

/********************************************************************
* 名称 : delay()
* 功能 : 延时,延时时间大概为5US。
* 输入 : 无
* 输出 : 无
***********************************************************************/
* 功能 : 往DS1302写入1Byte数据
* 输入 : ucDa 写入的数据
* 输出 : 无
***********************************************************************/
void v_RTInputByte(uchar ucDa)
}
/********************************************************************
* 名称 : v_W1302(uchar ucAddr, uchar ucDa)
* 功能 : 往DS1302写入数据
* 输入 : ucAddr: DS1302地址, ucDa: 要写的数据
void L1602_string(uchar hang,uchar lie,uchar *p)
{
uchar a,b=0;
if(hang == 1) a = 0x80;
if(hang == 2) a = 0xc0;
a = a + lie - 1;
while(1)
{
wcmd(a++);
{
while(Busy());
RS = 0;
RW = 0;
E = 0;
delay();
P0 = del;
delay();
E = 1;
delay();
E = 0;
}
/********************************************************************
* 名称 : uc_R1302(uchar ucAddr)
* 功能 : 读取DS1302某地址的数据
* 输入 : ucAddr: DS1302地址
* 返回值 : ucDa :读取的数据
***********************************************************************/
* 名称 : wcmd(uchar del)
* 功能 : 1602命令函数
* 输入 : 输入的命令值
* 输出 : 无
***********************************************************************/
void wcmd(uchar del)
* 名称 : wdata(uchar del)
* 功能 : 1602写数据函数
* 输入 : 需要写入1602的数据
* 输出 : 无
***********************************************************************/
void wdata(uchar del)
if(hang == 2) a = 0xc0;
a = a + lie - 1;
wcmd(a);
wdata(sign);
}
/********************************************************************
* 名称 : L1602_string(uchar hang,uchar lie,uchar *p)
T_RST = 1;
v_RTInputByte(ucAddr); // 写地址
_nop_();
_nop_();
v_RTInputByte(ucDa); // 写1Byte数据
T_CLK = 1;
T_RST = 0;
}
/********************************************************************
***********************************************************************/
void L1602_char(uchar hang,uchar lie,char sign)
{
uchar a;
if(hang == 1) a = 0x80;
* 名称 : bit数,读出函数是否处在忙状态
* 输入 : 输入的命令值
* 输出 : 无
***********************************************************************/
bit Busy(void)
uchar uc_RTOutputByte(void)
{
uchar i;
T_RST = 1;
for(i=8; i>0; i--)
{
ACC = ACC >>1;
T_IO=1;
ACC7 = T_IO;
T_CLK = 1;
T_CLK = 0;
}
return(ACC);
/********************************************************************
* 文件名 : 时钟DS1302LCD.c
* 描述 : 该程序实现了用单片机来控制时钟芯片DS1302进行时钟的显示。
时钟会在1602上显示.
#include<reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit ACC0 = ACC^0;
sbit ACC7 = ACC^7;
sbit T_CLK = P3^5; /*实时时钟时钟线引脚 */
{
uchar i;
ACC = ucDa;
T_RST = 1;
for(i=8; i>0; i--)
{
T_IO = ACC0;
T_CLK = 1;
T_CLK = 0;
ACC = ACC >> 1;
}
}
/********************************************************************
* 名称 : L1602_char(uchar hang,uchar lie,char sign)
* 功能 : 改变液晶中某位的值,如果要让第一行,第五个字符显示"b" ,调用该函数如下
L1602_char(1,5,'b')
* 输入 : 行,列,需要输入1602的数据
* 输出 : 无
{
wcmd(0x38);
Delay(5);
wcmd(0x38);
Delay(5);
wcmd(0x38);
Delay(5);
wcmd(0x38);
wcmd(0x08);
wcmd(0x0c);
wcmd(0x04);
wcmd(0x01);
}
/********************************************************************
* 返回值 : 无
***********************************************************************/
void v_W1302(uchar ucAddr, uchar ucDa)
{
T_RST = 0;
T_CLK = 0;
* 创建人 : 东流,2012年2月7日
* 版本号 : 1.0
* 杜邦线接法:P3.5接J18的1端;J3.6接J18的2端;J3.7接J18的3端。
1602接到J17的排座上。
***********************************************************************/
void delay()
{
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
}
void Delay(uint i)
{
uint x,j;
for(j=0;j<i;j++)
for(x=0;x<=148;x++);
}
/********************************************************************
* 功能 : 改变液晶中某位的值,如果要让第一行,第五个字符开始显示"ab cd ef" ,调用该函数如下
L1602_string(1,5,"ab cd ef;")
* 输入 : 行,列,需要输入1602的数据
* 输出 : 无
***********************************************************************/
相关文档
最新文档