压缩文件中包含程序及protues仿真
单片机源程序如下:
- #include <REG52.H>
- #include <intrins.H>
- #include <math.h>
- /* 液晶引脚定义 */
- #define LCD_DB P0
- sbit LCD_RS=P2^0;
- sbit LCD_RW=P2^1;
- sbit LCD_E=P2^2;
- /* 温度传感器引脚定义 */
- sbit DSA=P1^3;
- /* 时钟芯片引脚定义 */
- sbit IO=P1^0;
- sbit SCLK=P1^1;
- sbit RST=P1^2;
- /* 独立按键引脚定义 */
- sbit KeyOne = P3^2;
- sbit KeyThree = P3^3;
- sbit KeyTwo = P3^4;
- sbit KeyFour = P3^5;
- /* 第0位 第八位 位操作 */
- sbit ACC0=ACC^0;
- sbit ACC7=ACC^7;
- /* 报警指示引脚定义 */
- sbit Red = P3^6;
- sbit Green = P3^7;
- sbit Beep = P1^4;
- /* 时钟芯片寄存器定义 */
- #define write_second 0x80
- #define write_minute 0x82
- #define write_hour 0x84
- #define write_day 0x86
- #define write_month 0x88
- #define write_week 0x8a
- #define write_year 0x8c
- /* 按键状态 */
- enum KEYSTART
- {
- KEYDOWN,
- KEYUP,
- };
- /* 按键键值 */
- enum KEYCONFIG
- {
- KEYINIT,
- KEYYEAR,
- KEYMONTH,
- KEYDAY,
- KEYWEEK,
- KEYHOUR,
- KEYMINTH,
- KEYALARH,
- KEYALARM,
- };
- /* 逻辑变量定义 */
- unsigned char miao=0,shi=0,fen=0,ri=0,yue=0,nian=0,week=0;
- extern unsigned char miao,shi,fen,ri,yue,nian,week;
- unsigned int TempVal=0,AlarmFlag=0;
- unsigned char YearData=0,MonthData=0,DayData=0,WeekData=0,HourData=0,
- MinuteData=0,AlarmH=0,AlarmM=0;
- /* n*10微妙延时 */
- void delay_n10us(unsigned int n)
- {
- unsigned int i=0;
- for(i=n;i>0;i--)
- {
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- }
- }
- /* 写命令函数 */
- void LCD_write_command(unsigned char dat)
- {
- delay_n10us(10);
- LCD_RS=0;
- LCD_RW=0;
- LCD_E=1;
- LCD_DB=dat;
- delay_n10us(10);
- LCD_E=0;
- delay_n10us(10);
- }
- /* 写数据函数 */
- void LCD_write_data(unsigned char dat)
- {
- delay_n10us(10);
- LCD_RS=1;
- LCD_RW=0;
- LCD_E=1;
- LCD_DB=dat;
- delay_n10us(10);
- LCD_E=0;
- delay_n10us(10);
- }
- /* 写字符函数 X:0~15 Y:1,2 */
- void LCD_disp_char(unsigned char x,unsigned char y,unsigned char dat)
- {
- unsigned char address=0;
- if(y==1)
- address=0x80+x;//第一行第一个字符地址
- else
- address=0xc0+x; //第二行第一个字符地址
- LCD_write_command(address);
- LCD_write_data(dat);
- }
- /* 写一串字符 X:0~15 Y:1,2 */
- void LCD_disp_str(unsigned char x,unsigned char y,unsigned char *str)
- {
- unsigned char address=0;
- if(y==1)
- address=0x80+x;
- else
- address=0xc0+x;
- LCD_write_command(address);
- while(*str!='\0')
- {
- LCD_write_data(*str);
- str++;
- }
- }
- /* 液晶初始化 */
- void LCD_init(void)
- {
- delay_n10us(10);
- LCD_write_command(0x38);//显示模式设置
- delay_n10us(10);
- LCD_write_command(0x0c);//开显示
- delay_n10us(10);
- LCD_write_command(0x06); //光标移动指令
- delay_n10us(10);
- LCD_write_command(0x01);//显示清屏
- delay_n10us(100);
- }
- /* 温度传感器最小单位延时 */
- void delayA(unsigned int Delay)
- {
- unsigned int i=0,j=0;
- for(i=Delay;i>0;i--)
- for(j=120;j>0;j--);
- }
- /* 温度传感器复位操作,初始化DS18B20
- 让DS18B20一段相对长时间低电平, 然后一段相对非常短时间高电平, 即可启动
- 使用unsigned int型, 一个i++指令的时间, 作为与DS18B20通信的小时间间隔 */
- void dsresetA(void)
- {
- unsigned int i=0;
- DSA=0;
- i=103;
- while(i>0)
- i--;
- DSA=1;
- i=4;
- while(i>0)
- i--;
- }
- /* 读温度传感器一位数据信息,向DS18B20读取一位数据
- 读一位, 让DS18B20一小周期低电平, 然后两小周期高电平,
- 之后DS18B20则会输出持续一段时间的一位数据 */
- bit tmpreadbitA(void)
- {
- unsigned int i=0;
- bit dat=0;
- DSA=0;
- i++;
- DSA=1;
- i++;
- i++;
- dat=DSA;
- i=8;
- while(i>0)
- i--;
- return (dat);
- }
- /* 读温度传感器八位数据信息 */
- unsigned char tmpreadA(void)
- {
- unsigned char i=0,j=0,dat=0;
- for(i=1;i<=8;i++)
- {
- j=tmpreadbitA();//先读最低位
- dat=(j<<7)|(dat>>1);//得八位数据信息
- }
- return(dat);
- }
- /* 写温度传感器八位数据信息 */
- void tmpwritebyteA(unsigned char dat)
- {
- unsigned int i=0;
- unsigned char j=0;
- bit testb=0;
- for(j=1;j<=8;j++)
- {
- testb=dat&0x01;
- dat=dat>>1;
- if(testb) //write 1 让低电平持续2个小延时, 高电平持续8个小延时
- {
-
- DSA=0;
- i++;
- i++;
- DSA=1;
- i=8;
- while(i>0)
- i--;
- }
- else
- {
- DSA=0; //write 0 让低电平持续8个小延时, 高电平持续2个小延时
- i=8;
- while(i>0)
- i--;
- DSA=1;
- i++;
- i++;
- }
- }
- }
- /* 温度转换 */
- void tmpchangeA(void)
- {
- dsresetA();
- delayA(1);
- tmpwritebyteA(0xcc); //跳过ROM
- tmpwritebyteA(0x44); //转换
- }
- /* 读取温度寄存器转换数据 */
- unsigned int gettmpA(void)
- {
- float tt=0;
- unsigned char a=0,b=0;
- unsigned int tempA=0;
- dsresetA();
- delayA(1);
- tmpwritebyteA(0xcc);
- tmpwritebyteA(0xbe);//读取数据命令
- a=tmpreadA();//读低8位
- b=tmpreadA();//读高8位
- tempA=b;
- tempA<<=8;
- tempA=tempA|a; //合并高八位和低八位
- tt=tempA*0.0625;//精确度为0.0625度
- tempA=tt*10+0.5; //乘以10,表示小数点后只取一位, 0.5是进行4舍5入
- return tempA;
- }
- /* 写时钟芯片八位数据信息 */
- void write_byte(unsigned char dat)
- {
- unsigned char a=0;
- ACC=dat;
- RST=1; // RST:输入信号,在读、写数据期间,必须为高。
- for(a=8;a>0;a--)
- {
- IO=ACC0;
- SCLK=0;
- SCLK=1;//上升沿写入,下降沿读出
- ACC=ACC>>1;
- }
- }
- /* 读时钟芯片八位数据信息 */
- unsigned char read_byte()
- {
- unsigned char a=0;
- RST=1;
- for(a=8;a>0;a--)
- {
- ACC7=IO;
- SCLK=1;
- SCLK=0;
- ACC=ACC>>1;
- }
- return (ACC);
- }
- /* 在时钟芯片指定位置写指定数据 */
- void write_1302(unsigned char add,unsigned char dat)
- {
- RST=0;//初始RST线置为0
- SCLK=0;//初始时钟线置为0
- RST=1;//初始RST置为1,传输开始
- write_byte(add);
- write_byte(dat);
- SCLK=1;//时钟线拉高
- RST=0; //读取结束,RST置为0,结束数据的传输
- }
- /* 读取时钟芯片指定地址的数据信息 */
- unsigned char read_1302(unsigned char add)
- {
- unsigned char temp;
- RST=0;
- SCLK=0;
- RST=1;
- write_byte(add);
- temp=read_byte();
- SCLK=1;
- RST=0;
- return(temp);
- }
- /* 时钟芯片数据转换 */
- unsigned char BCD_Decimal(unsigned char bcd)
- {
- unsigned char Decimal;
- Decimal=bcd>>4; //先取bcd码的高位,因为整个BCD码表示数不会超过99,所以定义成uchar
- return(Decimal=Decimal*10+(bcd&=0x0F));//高位乘10加上原来数的低位,这就转成10进制数
- }
- /* 时钟芯片初始化操作 控制寄存器(8Fh、8Eh)的位7是写保护位(WP)
- 其它7位均置为0。在任何的对时钟和RAM的写操作之前
- WP位必须为0。当WP位为1时,写保护位
- 防止对任一寄存器的写操作 */
- void ds1302_init()
- {
- RST=0;
- SCLK=0;
- write_1302(0x8e,0x00);//写保护关 将控制寄存器值设为0,wp=0允许写
- write_1302(0x8e,0x80);//写保护开,防止影响时间值
- }
- /* 设置时钟芯片参数信息 */
- void Set_RTC(unsigned char address,unsigned char temp)
- {
- unsigned char tmp=0;
- tmp=temp/10;
- temp=temp%10;
- temp=temp+tmp*16;
- write_1302(0x8E,0X00);
- write_1302(address,temp&0x7f);
- write_1302(0x8E,0x80);
- }
- /* 提取时钟芯片时间信息 */
- void GetTime(void)
- {
- miao = BCD_Decimal(read_1302(0x81));
- fen = BCD_Decimal(read_1302(0x83));
- shi = BCD_Decimal(read_1302(0x85));
- ri = BCD_Decimal(read_1302(0x87));
- yue = BCD_Decimal(read_1302(0x89));
- nian=BCD_Decimal(read_1302(0x8d));
- week=BCD_Decimal(read_1302(0x8b));
- }
- /* 按键小抖动操作 */
- void DelayKey(void)
- {
- unsigned char i=0,j=0,k=0;
- for(i=15;i>0;i--)
- for(k=81;k>0;k--);
- }
- /* 读取按键键值 */
- unsigned char KeyProcess(void)
- {
- static unsigned char KeyVal=KEYINIT;
- if(KeyOne==KEYDOWN)
- {
- DelayKey();
- if(KeyOne==KEYDOWN)
- {
- while(KeyOne==KEYDOWN);
- LCD_disp_str(0,1," ");
- LCD_disp_str(0,2," ");
- KeyVal++;
- if(KeyVal>KEYALARM)
- KeyVal=KEYINIT;
- }
- }
- return KeyVal;
- }
- /* 定时器配置 */
- void init() //定时器、计数器设置函数
- {
- TMOD=0x11; //指定定时/计数器的工作方式为3
- TH0=0x3c; //定时器T0的高四位=0
- TL0=0xb0; //定时器T0的低四位=0
- EA=1; //系统允许有开放的中断
- ET0=1; //允许T0中断
- TR0=1; //开启中断,启动定时器
- }
- /* 外围硬件初始化 */
- void HandInit(void)
- {
- LCD_init();
- ds1302_init();
- init();
- Red = 1;
- Green = 0;
- }
- /* 年月日信息显示 */
- void show_Data(void)
- {
- unsigned char dis_Data[16]={0};
- dis_Data[0]='2';
- dis_Data[1]='0';
- dis_Data[2]=(nian/10)+0x30;
- dis_Data[3]=(nian%10)+0x30;
- dis_Data[4]='-';
- dis_Data[5]=(yue/10)+0x30;
- dis_Data[6]=(yue%10)+0x30;
- dis_Data[7]='-';
- dis_Data[8]=(ri/10)+0x30;
- dis_Data[9]=(ri%10)+0x30;
- dis_Data[10]=' ';
- dis_Data[11]='W';
- dis_Data[12]=126;
- dis_Data[13]='<';
- dis_Data[14]=(week%10)+0x30;
- dis_Data[15]='>';
- LCD_disp_str(0,1,dis_Data);
- }
- /* 时分秒温度信息显示 */
- void Show_Time(void)
- {
- unsigned char dis_Time[16]={0};
- dis_Time[0]=' ';
- dis_Time[1]=(shi/10)+0x30;
- dis_Time[2]=(shi%10)+0x30;
- dis_Time[3]=':';
- dis_Time[4]=(fen/10)+0x30;
- dis_Time[5]=(fen%10)+0x30;
- dis_Time[6]=':';
- dis_Time[7]=(miao/10)+0x30;
- dis_Time[8]=(miao%10)+0x30;
- dis_Time[9]=' ';
- dis_Time[10]=TempVal/100+'0';
- dis_Time[11]=TempVal%100/10+'0';
- dis_Time[12]='.';
- dis_Time[13]=TempVal%10+'0';
- dis_Time[14]=223;
- dis_Time[15]='C';
- LCD_disp_str(0,2,dis_Time);
- }
- /* 设置年参数 */
- void Set_Year(void)
- {
- YearData=read_1302(0x8D);
- YearData=(YearData>>4)*10+(YearData&0x0f);
- if(KeyTwo==KEYDOWN)
- {
- DelayKey();
- if(KeyTwo==KEYDOWN)
- {
- while(KeyTwo==KEYDOWN);
- if(YearData<=0)
- YearData=1;
- YearData-=1;
- Set_RTC(write_year,YearData);
- }
- }
- if(KeyThree==KEYDOWN)
- {
- DelayKey();
- if(KeyThree==KEYDOWN)
- {
- while(KeyThree==KEYDOWN);
- if(YearData>=99)
- YearData=98;
- YearData+=1;
- Set_RTC(write_year,YearData);
- }
- }
- LCD_disp_str(0,1," SET YEAR ");
- LCD_disp_char(4,2,'2');
- LCD_disp_char(5,2,'0');
- LCD_disp_char(6,2,YearData/10+0x30);
- LCD_disp_char(7,2,YearData%10+0x30);
- }
- /* 设置月参数 */
- void SetMonth(void)
- {
- MonthData=read_1302(0x89);
- MonthData=(MonthData>>4)*10+(MonthData&0x0f);
- if(KeyTwo==KEYDOWN)
- {
- DelayKey();
- if(KeyTwo==KEYDOWN)
- {
- while(KeyTwo==KEYDOWN);
- if(MonthData<=1)
- MonthData=2;
- MonthData-=1;
- Set_RTC(write_month,MonthData);
- }
- }
- if(KeyThree==KEYDOWN)
- {
- DelayKey();
- if(KeyThree==KEYDOWN)
- {
- while(KeyThree==KEYDOWN);
- if(MonthData>=12)
- MonthData=11;
- MonthData+=1;
- Set_RTC(write_month,MonthData);
- }
- }
- LCD_disp_str(0,1," SET MONTH ");
- LCD_disp_char(6,2,MonthData/10+0x30);
- LCD_disp_char(7,2,MonthData%10+0x30);
- }
- /* 设置日参数 */
- void SetDay(void)
- {
- DayData=read_1302(0x87);
- DayData=(DayData>>4)*10+(DayData&0x0f);
- if(KeyTwo==KEYDOWN)
- {
- DelayKey();
- if(KeyTwo==KEYDOWN)
- {
- while(KeyTwo==KEYDOWN);
- if(DayData<=1)
- DayData=2;
- DayData-=1;
- Set_RTC(write_day,DayData);
- }
- }
- if(KeyThree==KEYDOWN)
- {
- DelayKey();
- if(KeyThree==KEYDOWN)
- {
- while(KeyThree==KEYDOWN);
- if(DayData>=30)
- DayData=29;
- DayData+=1;
- Set_RTC(write_day,DayData);
- }
- }
- LCD_disp_str(0,1," SET DAY ");
- LCD_disp_char(6,2,DayData/10+0x30);
- LCD_disp_char(7,2,DayData%10+0x30);
- }
- /* 设置周期参数 */
- void SetWeek(void)
- {
- WeekData=read_1302(0x8b);
- WeekData=(WeekData>>4)*10+(WeekData&0x0f);
- if(KeyTwo==KEYDOWN)
- {
- DelayKey();
- if(KeyTwo==KEYDOWN)
- {
- while(KeyTwo==KEYDOWN);
- if(WeekData<=1)
- WeekData=2;
- WeekData-=1;
- Set_RTC(write_week,WeekData);
- }
- }
- if(KeyThree==KEYDOWN)
- {
- DelayKey();
- if(KeyThree==KEYDOWN)
- {
- while(KeyThree==KEYDOWN);
- if(WeekData>=7)
- WeekData=6;
- WeekData+=1;
- Set_RTC(write_week,WeekData);
- }
- }
- LCD_disp_str(0,1," SET WEEK ");
- LCD_disp_char(6,2,WeekData/10+0x30);
- LCD_disp_char(7,2,WeekData%10+0x30);
- }
- /* 设置小时参数 */
- void SetHour(void)
- {
- HourData=read_1302(0x85);
- HourData=(HourData>>4)*10+(HourData&0x0f);
- if(KeyTwo==KEYDOWN)
- {
- DelayKey();
- if(KeyTwo==KEYDOWN)
- {
- while(KeyTwo==KEYDOWN);
- if(HourData<=0)
- HourData=1;
- HourData-=1;
- Set_RTC(write_hour,HourData);
- }
- }
- if(KeyThree==KEYDOWN)
- {
- DelayKey();
- if(KeyThree==KEYDOWN)
- {
- while(KeyThree==KEYDOWN);
- if(HourData>=23)
- HourData=22;
- HourData+=1;
- Set_RTC(write_hour,HourData);
- }
- }
- LCD_disp_str(0,1," SET HOUR ");
- LCD_disp_char(6,2,HourData/10+0x30);
- LCD_disp_char(7,2,HourData%10+0x30);
- }
- /* 设置分钟参数 */
- void SetMinute(void)
- {
- MinuteData=read_1302(0x83);
- MinuteData=(MinuteData>>4)*10+(MinuteData&0x0f);
- if(KeyTwo==KEYDOWN)
- {
- DelayKey();
- if(KeyTwo==KEYDOWN)
- {
- while(KeyTwo==KEYDOWN);
- if(MinuteData<=0)
- MinuteData=1;
- MinuteData-=1;
- Set_RTC(write_minute,MinuteData);
- }
- }
- if(KeyThree==KEYDOWN)
- {
- DelayKey();
- if(KeyThree==KEYDOWN)
- {
- while(KeyThree==KEYDOWN);
- if(MinuteData>=59)
- MinuteData=58;
- MinuteData+=1;
- Set_RTC(write_minute,MinuteData);
- }
- }
- LCD_disp_str(0,1," SET MINUTE ");
- LCD_disp_char(6,2,MinuteData/10+0x30);
- LCD_disp_char(7,2,MinuteData%10+0x30);
- }
- /* 设置闹钟小时参数 */
- void SetAlarH(void)
- {
- if(KeyTwo==KEYDOWN)
- {
- DelayKey();
- if(KeyTwo==KEYDOWN)
- {
- while(KeyTwo==KEYDOWN);
- if(AlarmH<=0)
- AlarmH=1;
- AlarmH-=1;
- }
- }
- if(KeyThree==KEYDOWN)
- {
- DelayKey();
- if(KeyThree==KEYDOWN)
- {
- while(KeyThree==KEYDOWN);
- if(AlarmH>=23)
- AlarmH=22;
- AlarmH+=1;
- }
- }
- LCD_disp_str(0,1," SET ALARMH ");
- LCD_disp_char(6,2,AlarmH/10+0x30);
- LCD_disp_char(7,2,AlarmH%10+0x30);
- }
- /* 设置闹钟分钟参数 */
- void SetAlarM(void)
- {
- if(KeyTwo==KEYDOWN)
- {
- DelayKey();
- if(KeyTwo==KEYDOWN)
- {
- while(KeyTwo==KEYDOWN);
- if(AlarmM<=0)
- AlarmM=1;
- AlarmM-=1;
- }
- }
- if(KeyThree==KEYDOWN)
- {
- DelayKey();
- if(KeyThree==KEYDOWN)
- {
- while(KeyThree==KEYDOWN);
- if(AlarmM>=59)
- AlarmM=58;
- AlarmM+=1;
- }
- }
- LCD_disp_str(0,1," SET ALARMM ");
- LCD_disp_char(6,2,AlarmM/10+0x30);
- LCD_disp_char(7,2,AlarmM%10+0x30);
- }
- /* 逻辑信息处理 */
- void Process(void)
- {
- unsigned char StartChange=KEYINIT;
- StartChange=KeyProcess();
- if(KeyFour==KEYDOWN)
- {
- DelayKey();
- if(KeyFour==KEYDOWN)
- ……………………
- …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
所有资料51hei提供下载:
程序.rar
(87.86 KB, 下载次数: 209)
|