壓縮文件中包含程序及protues仿真
0.png (21.13 KB, 下載次數: 92)
下載附件
2017-10-21 22:57 上傳
0.png (43.25 KB, 下載次數: 70)
下載附件
2017-10-21 22:57 上傳
單片機源程序如下:
- #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)
2017-10-21 13:29 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|