基于PIC16F887单片机的数字钟完整c程序代码

合集下载

PIC16F887时钟课设

PIC16F887时钟课设

《PIC单片机》课程设计学生姓名:学生学号:指导教师:鲍光海二○一三年5月16 日目录1. 课程设计目的 (2)2. 课程设计题目和要求 (2)3. 课程设计报告内容 (3)3.1 硬件原理图 (3)3.2 软件原理框图 (6)3.3 功能实现 (7)4. 课设中存在的问题以及解决方法 (8)5 设计体会 ........................................................................................ 错误!未定义书签。

6 参考文献 (8)7 附录 (9)7.1 仿真原理图 (9)7.2 部分程序 (9)7.2.1 秒表程序 (9)7.2.2 闹钟程序 (12)1.课程设计目的《PIC单片机课程设计》是电气工程及其自动化专业及相近专业的一门重要的专业实践课,本课程设计是在《PIC 单片机》课程的基础上,通过硬件设计与软件编程与调试的实践,进一步掌握PIC单片机的应用方法,熟练PIC单片机的C程序的编写与调试,是毕业设计前的一次重要实践,为今后走上工作岗位打下坚实的单片机应用基础。

通过本次课程设计:熟悉PCB板的焊接流程,熟练运用Proteus进行原理图设计与仿真,熟练运用MPLAB和ICD2进行软件编程与调试熟练掌握PIC16F887 TC74模块(IIC接口的温度传感器)、实时时钟芯片DS1307、定时器、中断的编程方法;熟练掌握LCD YB1602A、按键模块的应用与编程设计掌握单片机应用的一般设计方法,熟悉开发一单片机应用系统的全过程,为今后从事相应的工作打下基础。

学会用C语言编写一个完整的程序,掌握程序的设计方法,拓展编程思维。

2. 课程设计题目和要求本次课程设计我的设计题目为《多功能数字钟》,通过在PROTEUS仿真及在开发板上调试,功能实现。

设计内容:采用DS1307芯片和单片机进行IIC通信,将时钟芯片中的数据读出来,然后送到LCD1602中去显示,然后设置秒表功能,闹钟功能,还有温度显示功能,通过按键的切换来实现各个功能。

单片机数码时钟设计C语言程序

单片机数码时钟设计C语言程序

//实例66:#include<reg51.h> // 包含51单片机寄存器定义的头文件unsigned char Tab[ ]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //control shape unsigned char port[8]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};unsigned char int_time ; //中断次数计数变量unsigned char second; //秒计数变量unsigned char minute; //分钟计数变量unsigned char hour; //小时计数变量/////////////////////////////////////////////////////void delay(void) //延时函数,延时约0.6ms{unsigned char j;for(j=0;j<200;j++);}/******************************************************************函数功能:显示秒的子程序入口参数:s********************************************************************/void DisplaySecond(unsigned char s){P2=0xbf; //P2.6引脚输出低电平,DS6点亮P0=Tab[s/10]; //显示十位delay();P2=0x7f; //P2.7引脚输出低电平,DS7点亮P0=Tab[s%10]; //显示个位delay();P2=0xff; //关闭所有数码管}/******************************************************************函数功能:显示分钟的子程序入口参数:m********************************************************************/void DisplayMinute(unsigned char m){P2=0xf7; // P2.3引脚输出低电平,DS3点亮P0=Tab[m/10];//显示个位delay();P2=0xef; // P2.4引脚输出低电平,DS4点亮P0=Tab[m%10];delay();P2=0xdf; //P2.5引脚输出低电平,DS5点亮P0=0xbf; //分隔符“-”的段码delay();P2=0xff; //关闭所有数码管}/****************************************************************** 函数功能:显示小时的子程序入口参数:h********************************************************************/ void DisplayHour(unsigned char h){P2=0xfe; //P2.0引脚输出低电平,DS0点亮P0=Tab[h/10]; //显示十位delay();P2=0xfd; //P2.1引脚输出低电平,DS1点亮P0=Tab[h%10]; //显示个位delay();P2=0xfb; //P2.2引脚输出低电平,DS2点亮P0=0xbf; //分隔符“-”的段码delay();P2=0xff; //关闭所有数码管}/****************************************************************** 函数功能:主函数********************************************************************/void main(void){TMOD=0x01; //使用定时器T0EA=1; //开中断总允许ET0=1; //允许T0中断TH0=(65536-46083)/256; //定时器高八位赋初值TL0=(65536-46083)%256; //定时器低八位赋初值TR0=1;int_time=0; //中断计数变量初始化second=0; //秒计数变量初始化minute=0; //分钟计数变量初始化hour=0; //小时计数变量初始化while(1){DisplaySecond(second); //调用秒显示子程序delay();DisplayMinute(minute); //调用分钟显示子程序delay();DisplayHour(hour);delay();}}/******************************************************************函数功能:定时器T0的中断服务子程序********************************************************************/void interserve(void ) interrupt 1 using 1 //using Time0{int_time++;if(int_time==20){int_time=0; //中断计数变量清0second++; //秒计数变量加1}if(second==60){second=0; //如果秒计满60,将秒计数变量清0minute++; //分钟计数变量加1}if(minute==60){minute=0; //如果分钟计满60,将分钟计数变量清0hour++; //小时计数变量加1}if(hour==24){hour=0; //如果小时计满24,将小时计数变量清0}TH0=(65536-46083)/256; //定时器重新赋初值TL0=(65536-46083)%256;}。

基于单片机的数字钟毕业设计(附程序全)

基于单片机的数字钟毕业设计(附程序全)

基于单片机的数字钟毕业设计(附程序全) 电子时钟设计随着现代人类生活节奏的加快,人们越来越重视起了时间观念,可以说是时间和金钱划上了等号。

对于那些对时间把握非常严格和准确的人或事来说,时间的不准确会带来非常大的麻烦,所以以数码管为显示器的时钟比指针式的时钟表现出了很大的优势。

数码管显示的时间简单明了而且读数快、时间准确性更高~数字钟是采用数字电路实现对“时”、“分”、“秒”数字显示的计时装置。

数字钟的精度、稳定度远远超过老式机械钟。

在这次设计中,我们采用LED数码管显示时、分、秒,以24小时计时方式,根据数码管动态显示原理来进行显示,用12MHz的晶振产生振荡脉冲,并且由单片机的定时器计数。

在此次设计中,电路具有显示时间的其本功能,还可以实现对时间的调整。

数字钟是其小巧,价格低廉,走时精度高,使用方便,功能多,便于集成化而受广大消费的喜爱,因此得到了广泛的使用。

关键词:数字钟;单片机;数码管;时间;准确性1目录第一章绪论1. 数字电子钟的意义和应用…………………………………………………………………… 3 第二章整体设计方案2.1 单片机的选择…………………………………………………………………………… 3 2.2 单片机的基本结构……………………………………………………………………… 5 第三章数字钟的硬件设计3.1 最小系统设计…………………………………………………………………………… 9 3.2 LED显示电路…………………………………………………………………………… 12 3.3 键盘控制电路…………………………………………………………………………… 14 第四章数字钟的软件设计4.1 系统软件设计流程图…………………………………………………………………… 15 4.2 数字电子钟的原理图…………………………………………………………………… 18 4.3 主程序…………………………………………………………………………………… 19 4.4 时钟设置子程序………………………………………………………………………… 20 4.5 定时器中断子程序……………………………………………………………………… 20 4.6 LED显示子程序………………………………………………………………………… 21 4.7 按键控制子程序………………………………………………………………………… 23 第五章系统仿真5.1 PROTUES软件介绍................................................................................. 24 5.2 电子钟系统PROTUES仿真........................................................................ 24 结束语. (2)5 参考文献 (26)2第一章绪论1.数字电子钟的意义和应用数字钟是采用数字电路实现对时、分、秒数字显示的计时装置,广泛用于个人家庭、车站、码头、办公室等公共场所,成为人们日常生活中不可少的必需品,由于数字集成电路的发展和石英晶体振荡器的广泛应用,使得数字钟的精度,远远超过老式钟表, 钟表的数字化给人们生产生活带来了极大的方便,而且大大地扩展了钟表原先的报时功能。

用C语言写的一个PIC16F877的时闹钟程序

用C语言写的一个PIC16F877的时闹钟程序

用C语言写的一个PIC16F877的时闹钟程序单片机用16F877,主时钟用20MHz,用32768作定时时间。

可以实现2路定闹,每一路都可分别设置和开关,采用4x4键盘,16x2的字符型LCD显示。

连线在程序开头有说明。

程序的功能:(1)上电后LCD背光打开,并显示倒计时5秒,然后时钟开始工作。

(2)用模式键(*)切换模式,如显示时间、日期、闹钟1、闹钟2等,并且可以用上、下键控制加1、减1或是闹钟的On、Off。

(3)原程序有16个键,包括0~9数字键,可以直接输入要设置的时间值,但后来将数字键取消了,你仍然可以通过修改程序的部分注释恢复此功能。

(4)闹钟有2路,时间到后闹2分钟,可按任意键取消本次闹钟。

闹钟响时有2种音调,是用PIC的PWM实现的。

(5)按任意键可打开背光,1分钟后自动关闭背光。

(6)RA0~RA3为按键扫描输入,应接下拉电阻。

主程序// FileName: Main.c// MCU: Microchip PIC16F877// Tool: CCS-C compiler// Author: KingEDA, MSN:kingeda@, skype:kingeda, E-mail:kingeda@// Website: // Description:// A timer program// Ver 0.1: 2003-03-31, all clock function with date display, 2 way alarm.// Ver 0.2: 2003-05-05, (1) Alarm default is on,modify alarm1 time to 7:00:00,// and alarm2 to 13:30:00.// (2) Backlight will be enabled when alarming.// (3) Automatic adjust day(28,30,31).// (4) Automatic move cursor to next location when set item.// PIN Connection:// RC0~1 : 32768Hz crystal// RC2 : Buzzer// RC3 : LCD Back Light,drive a PNP BJT// RD0~RD7 : to LCD DB0~DB7// RA0~RA3 : keypad col in// RC4~RC7 : keypad line out// 7 8 9 #// 4 5 6 ↑// 1 2 3 ↓// 0 ←→*// RE0 : LCD RS// RE1 : LCD RW// RE2 : LCD E#include "my16f877.h"#device ICD=true//#fuses HS,NOWDT,NOPROTECT,PUT,BROWNOUT #use delay(clock = 24000000)//#use fast_io(C)#use fast_io(E)#define lcd_busy (lcd_read_addr()&0x80) == 0x80#define time_start_addr 0x80+0x04#define time_hourh_addr time_start_addr#define time_hourl_addr time_start_addr+1#define time_minuteh_addr time_start_addr+3#define time_minutel_addr time_start_addr+4#define time_secondh_addr time_start_addr+6#define time_secondl_addr time_start_addr+7#define key_0 0x11#define key_1 0x21#define key_2 0x22#define key_3 0x24#define key_4 0x41#define key_5 0x42#define key_6 0x44#define key_7 0x81#define key_8 0x82#define key_9 0x84#define key_left 0x12#define key_right 0x14#define key_up 0x48#define key_down 0x28#define key_mode 0x18#define key_cancel 0x88char StrPower1[] = " * Power on * ";char StrSetTime[] = " * Adjust time* ";char StrSetDate[] = " * Adjust date* ";char StrAlarm1[] = " * Set alarm 1* ";char StrAlarm2[] = " * Set alarm 2* ";unsigned char PORTC_MAP;#bit BackLightEn = PORTC_MAP.3unsigned char BackLightTimer;int1 led;#bit lcd_rs = PORTE.0#bit lcd_rw = PORTE.1#bit lcd_e = PORTE.2#byte lcd_bus = PORTD#byte lcd_dir = TRISD#define PWM_on 0x0c#define PWM_off 0x00#define PWM_period 200#define PWM_DC 100unsigned char lcd_addr;unsigned char KeyLine;unsigned char KeyOld;unsigned char KeyNew;struct mTime {unsigned char hourh; // hour,0~23unsigned char hourl;unsigned char minuteh; // minute,0~59unsigned char minutel;unsigned char secondh; // second,0~59unsigned char secondl;};struct mTime CurrentTime = {1,2,0,0,0,0};struct mTime AlarmTime1 = {0,7,0,0,0,0}; // 07:00:00 struct mTime AlarmTime2 = {1,3,3,0,0,0}; // 13:30:00 unsigned char AlarmStatus;#bit Alarm1Enable = AlarmStatus.0#bit Alarm2Enable = AlarmStatus.1#bit Alarm1Alarm = AlarmStatus.2#bit Alarm2Alarm = AlarmStatus.3unsigned char Alarm1Cnt; // alarm1 second count unsigned char Alarm2Cnt;unsigned char CurrentMode;#define mode_time 0#define mode_set_time 1#define mode_set_date 2#define mode_set_alarm1 3#define mode_set_alarm2 4unsigned char adjust_item;struct mDate {unsigned char year1; //unsigned char year2;unsigned char year3;unsigned char year4;unsigned char monthh;unsigned char monthl;unsigned char dayh;unsigned char dayl;};struct mDate CurrentDate = {2,0,0,3,0,1,0,1}; unsigned char *pStr;// ------------------------------------------------------- unsigned char lcd_read_addr(){unsigned char ch;lcd_dir = 0xff; // read from lcdlcd_rs = 0;lcd_rw = 1; // instlcd_e = 1;#asmnopnopnop#endasmch = lcd_bus;lcd_e = 0;lcd_dir = 0x00; // set write to lcdreturn ch;}// ------------------------------------------------------- unsigned char lcd_write_data(unsigned char ch) {while (lcd_busy){ restart_wdt(); }lcd_rs = 1; // datalcd_rw = 0; // writelcd_bus = ch; // write outlcd_e = 1;#asmnopnopnop#endasmlcd_e = 0;return 'Y';}// ------------------------------------------------------- unsigned char lcd_write_inst(unsigned char ch) {while (lcd_busy){ restart_wdt(); }lcd_rs = 0; // instlcd_rw = 0; // writelcd_bus = ch;lcd_e = 1;#asmnopnopnop#endasmlcd_e = 0;return 'Y';}// ------------------------------------------------------- unsigned char lcd_read_data(){unsigned char ch;while (lcd_busy){ restart_wdt(); }lcd_dir = 0xff; // read from lcdlcd_rs = 1; // datalcd_rw = 1; // readlcd_e = 1;#asmnopnopnop#endasmch = lcd_bus; // read inlcd_e = 0;lcd_dir = 0x00; // set write to lcdreturn ch;}// ------------------------------------------------------- void lcd_init(){unsigned char Tempch;lcd_addr = 0;delay_ms(100);Tempch = 0x38; // 1-line mode,5x8 dotslcd_write_inst(Tempch); // Function setTempch = 0x0f; // lcd on,cursor on,blink onlcd_write_inst(Tempch); // Display on/offTempch = 0x06; // Increment mode,Entire shift offlcd_write_inst(Tempch);Tempch = 0x01; // clear displaylcd_write_inst(Tempch);delay_ms(3);}// -------------------------------------------------------//#int_timer1//void timer1_interrupt(void)#int_ccp2void ccp2_interrupt(void){//TMR1H = 0x80;if (CurrentTime.secondl==9){CurrentTime.secondl=0;if (CurrentTime.secondh==5){CurrentTime.secondh=0;if (CurrentTime.minutel==9){CurrentTime.minutel=0;if (CurrentTime.minuteh==5){CurrentTime.minuteh=0;if (CurrentTime.hourl==9){CurrentTime.hourl=0;CurrentTime.hourh++;}else if((CurrentTime.hourl==3) && (CurrentTime.hourh==2)){CurrentTime.hourl=0;CurrentTime.hourh=0;if ((((CurrentDate.dayl == 8) || (CurrentDate.dayl == 9)) && (CurrentDate.dayh == 2) && (CurrentDate.monthl == 2) && (CurrentDate.monthh == 0)) ||((CurrentDate.dayl == 0) && (CurrentDate.dayh == 3) && ((((CurrentDate.monthl == 4) || (CurrentDate.monthl == 6)|| (CurrentDate.monthl == 9)) && (CurrentDate.monthh == 0)) || ((CurrentDate.monthl == 1) && (CurrentDate.monthh == 1)))) ||((CurrentDate.dayl == 1) && (CurrentDate.dayh == 3))){CurrentDate.dayl=1;CurrentDate.dayh=0;if ((CurrentDate.monthl == 2) && (CurrentDate.monthh == 1)){CurrentDate.monthl = 1;CurrentDate.monthh = 0;if (CurrentDate.year4 == 9){CurrentDate.year4 = 0;if (CurrentDate.year3 == 9){CurrentDate.year3 = 0;if (CurrentDate.year2 == 9){CurrentDate.year2 = 0;CurrentDate.year1++;}elseCurrentDate.year2++;}elseCurrentDate.year3++;}elseCurrentDate.year4++;}else if(CurrentDate.monthl == 9){CurrentDate.monthl = 0;CurrentDate.monthh++;}elseCurrentDate.monthl++;}else if(CurrentDate.dayl == 9){CurrentDate.dayl=0;CurrentDate.dayh++;}elseCurrentDate.dayl++;}elseCurrentTime.hourl++;}elseCurrentTime.minuteh++;}elseCurrentTime.minutel++;}elseCurrentTime.secondh++;}elseCurrentTime.secondl++;if ((Alarm1Alarm == false) & (Alarm2Alarm == false)){led = 0;CCP1CON = PWM_off;}else{if (led == 1){led = 0;PR2 = PWM_period; // set pwm periodCCPR1L = PWM_DC; // set pwm duty cycle//CCP1CON = PWM_on;}else{led = 1;PR2 = PWM_period/2; // set pwm periodCCPR1L = PWM_DC/2; // set pwm duty cycle//CCP1CON = PWM_off;}}Alarm1Cnt++;Alarm2Cnt++;if (BackLightEn == 0)if (((BackLightTimer++)>=60) & (Alarm1Alarm == false) & (Alarm1Alarm == false))BackLightEn = 1; // disable backlight PORTC = PORTC_MAP;//TMR1IF = 0;//PIR1 = PIR2 = 0x00;CCP2IF = 0;}// ------------------------------------------------------- unsigned char get_key(void){unsigned char key_in,tmp;TRISC = 0x03;KeyLine = 0xf0;PORTC = KeyLine | PORTC_MAP;#asmnopnopnop#endasmif ((PORTA & 0x0f) != 0){tmp = 0x10;for (KeyLine = tmp;KeyLine!=0;KeyLine = tmp){PORTC = KeyLine | PORTC_MAP;tmp = KeyLine <<1;#asmnopnopnop#endasmkey_in = PORTA & 0x0f;if (key_in != 0){return (key_in | KeyLine);}}return 0;}elsereturn 0;}// -------------------------------------------------------void set_mode(void){if (CurrentMode == mode_set_alarm2)CurrentMode = mode_time;else{CurrentMode++;adjust_item = 0;}lcd_write_inst(0x01); // clear LCD displaylcd_write_inst(time_start_addr); // set LCD line1 if (CurrentMode == mode_set_time){lcd_write_data(CurrentTime.hourh + '0');lcd_write_data(CurrentTime.hourl + '0');lcd_write_data(':');lcd_write_data(CurrentTime.minuteh + '0');lcd_write_data(CurrentTime.minutel + '0');lcd_write_data(':');lcd_write_data(CurrentTime.secondh + '0');lcd_write_data(CurrentTime.secondl + '0');pStr = StrSetTime;}else if(CurrentMode == mode_set_date){lcd_write_data(CurrentDate.year1 + '0');lcd_write_data(CurrentDate.year2 + '0');lcd_write_data(CurrentDate.year3 + '0');lcd_write_data(CurrentDate.year4 + '0');lcd_write_data('/');lcd_write_data(CurrentDate.monthh + '0');lcd_write_data(CurrentDate.monthl + '0');lcd_write_data('/');lcd_write_data(CurrentDate.dayh + '0');lcd_write_data(CurrentDate.dayl + '0');pStr = StrSetDate;}else if(CurrentMode == mode_set_alarm1){lcd_write_data(AlarmTime1.hourh + '0');lcd_write_data(AlarmTime1.hourl + '0');lcd_write_data(':');lcd_write_data(AlarmTime1.minuteh + '0');lcd_write_data(AlarmTime1.minutel + '0');lcd_write_data(':');lcd_write_data(AlarmTime1.secondh + '0');lcd_write_data(AlarmTime1.secondl + '0');lcd_write_data(' ');lcd_write_data('O');if (Alarm1Enable){lcd_write_data('n');}else{lcd_write_data('f');lcd_write_data('f');}pStr = StrAlarm1;Alarm1Cnt =0;}else if(CurrentMode == mode_set_alarm2) {lcd_write_data(AlarmTime2.hourh + '0');lcd_write_data(AlarmTime2.hourl + '0');lcd_write_data(':');lcd_write_data(AlarmTime2.minuteh + '0');lcd_write_data(AlarmTime2.minutel + '0');lcd_write_data(':');lcd_write_data(AlarmTime2.secondh + '0');lcd_write_data(AlarmTime2.secondl + '0');lcd_write_data(' ');lcd_write_data('O');if (Alarm2Enable){lcd_write_data('n');}else{lcd_write_data('f');lcd_write_data('f');}pStr = StrAlarm2;Alarm2Cnt = 0;}lcd_write_inst(0xc0); // set LCD line2 if (CurrentMode != mode_time){for (;*pStr!=0;pStr++){ // write hint messagelcd_write_data(*pStr);}lcd_write_inst(0x0f); // LCD cursor onlcd_write_inst(time_start_addr); // move cursor to start }else // time mode,write date to second line{lcd_write_inst(0x0c); // LCD sursor off/* lcd_write_inst(0xc0 + 3); // set date start address lcd_write_data(CurrentDate.year1 + '0');lcd_write_data(CurrentDate.year2 + '0');lcd_write_data(CurrentDate.year3 + '0');lcd_write_data(CurrentDate.year4 + '0');lcd_write_data('/');lcd_write_data(CurrentDate.monthh + '0');lcd_write_data(CurrentDate.monthl + '0');lcd_write_data('/');lcd_write_data(CurrentDate.dayh + '0');lcd_write_data(CurrentDate.dayl + '0');*/ }if (CurrentMode == mode_set_time){lcd_write_inst(time_start_addr); // move cursor to start }else if (CurrentMode == mode_set_date){lcd_write_inst(time_start_addr); // move cursor to start }else if (CurrentMode == mode_set_alarm1){lcd_write_inst(time_secondl_addr+3);adjust_item = 6;}else if (CurrentMode == mode_set_alarm2){lcd_write_inst(time_secondl_addr+3);adjust_item = 6;}else{lcd_write_inst(0x0c); // LCD cursor off}}// ------------------------------------------------------- void set_date(void){if (adjust_item == 0) // adjust year{if ((KeyNew >=0) & (KeyNew <= 9)){CurrentDate.year1 = KeyNew;lcd_write_data(CurrentDate.year1 + '0');//lcd_write_inst(time_start_addr);adjust_item ++;}else if (KeyNew == key_left){adjust_item = 7;lcd_write_inst(time_start_addr + 9);}else if(KeyNew == key_right){adjust_item ++;lcd_write_inst(time_start_addr + 1);}}else if(adjust_item == 1){if ((KeyNew >=0) & (KeyNew <= 9)){CurrentDate.year2 = KeyNew;lcd_write_data(CurrentDate.year2 + '0');//lcd_write_inst(time_start_addr + 1);adjust_item ++;}else if (KeyNew == key_left){adjust_item --;lcd_write_inst(time_start_addr + 0);}else if(KeyNew == key_right){adjust_item ++;lcd_write_inst(time_start_addr + 2);}}else if(adjust_item == 2){if ((KeyNew >=0) & (KeyNew <= 9)){CurrentDate.year3 = KeyNew;lcd_write_data(CurrentDate.year3 + '0');//lcd_write_inst(time_start_addr + 2);adjust_item ++;}else if (KeyNew == key_left){adjust_item --;lcd_write_inst(time_start_addr + 1);}else if(KeyNew == key_right){adjust_item ++;lcd_write_inst(time_start_addr + 3);}}else if(adjust_item == 3){if ((KeyNew >=0) & (KeyNew <= 9)){CurrentDate.year4 = KeyNew;lcd_write_data(CurrentDate.year4 + '0');//lcd_write_inst(time_start_addr + 3);adjust_item ++;lcd_write_inst(time_start_addr + 5);}else if (KeyNew == key_left){adjust_item --;lcd_write_inst(time_start_addr + 2);}else if(KeyNew == key_right){adjust_item ++;lcd_write_inst(time_start_addr + 5);}}else if(adjust_item == 4)if (((CurrentDate.monthl>2) & (KeyNew == 0)) | ((CurrentDate.monthl == 0) & (KeyNew == 1))| (((CurrentDate.monthl == 1) | (CurrentDate.monthl == 2)) & (KeyNew <2))) {CurrentDate.monthh = KeyNew;lcd_write_data(CurrentDate.monthh + '0');//lcd_write_inst(time_start_addr + 5);adjust_item ++;}else if (KeyNew == key_left){adjust_item --;lcd_write_inst(time_start_addr + 3);}else if (KeyNew == key_right){adjust_item ++;lcd_write_inst(time_start_addr + 6);}}else if(adjust_item == 5){if (((CurrentDate.monthh == 3) & (KeyNew <2)) | ((CurrentDate.monthh != 3) & (KeyNew >=0) & (KeyNew <=9))){CurrentDate.monthl = KeyNew;lcd_write_data(CurrentDate.monthl + '0');//lcd_write_inst(time_start_addr + 6);adjust_item ++;lcd_write_inst(time_start_addr + 8);}else if (KeyNew == key_left){adjust_item --;lcd_write_inst(time_start_addr + 5);}else if (KeyNew == key_right){adjust_item ++;lcd_write_inst(time_start_addr + 8);}}else if(adjust_item == 6)if (((CurrentDate.dayl>1) & ((KeyNew == 1) | (KeyNew == 2))) | ((CurrentDate.dayl == 0) & (KeyNew >0) & (KeyNew<4))| ((CurrentDate.dayl == 1) & (KeyNew <4))){CurrentDate.dayh = KeyNew;lcd_write_data(CurrentDate.dayh + '0');//lcd_write_inst(time_start_addr + 8);adjust_item ++;}else if (KeyNew == key_left){adjust_item --;lcd_write_inst(time_start_addr + 6);}else if (KeyNew == key_right){adjust_item ++;lcd_write_inst(time_start_addr + 9);}}else if(adjust_item == 7){if (((CurrentDate.dayh == 3) & (KeyNew <2)) | ((CurrentDate.dayh != 3) & (KeyNew >=0) & (KeyNew <=9))){CurrentDate.dayl = KeyNew;lcd_write_data(CurrentDate.dayl + '0');//lcd_write_inst(time_start_addr + 9);adjust_item ++;lcd_write_inst(time_start_addr + 0);}else if (KeyNew == key_left){adjust_item --;lcd_write_inst(time_start_addr + 8);}else if (KeyNew == key_right){adjust_item = 0;lcd_write_inst(time_start_addr + 0);}}}// -------------------------------------------------------void set_time(void){if (adjust_item == 0) // set hourh{if (((CurrentTime.hourl <4) & (KeyNew < 3)) | ((CurrentTime.hourl >3) & (KeyNew <2))){CurrentTime.hourh = KeyNew;lcd_write_data(CurrentTime.hourh + '0'); // refresh hourh//lcd_write_inst(0x10); // move cursor backadjust_item ++;}else if(KeyNew == key_left){adjust_item = 5;lcd_write_inst(time_secondl_addr);}else if(KeyNew == key_right){adjust_item ++;lcd_write_inst(time_hourl_addr);}}else if (adjust_item == 1) // set hourl{if (((CurrentTime.hourh == 2) & (KeyNew < 4)) | ((CurrentTime.hourh < 2) & (KeyNew <=9))){CurrentTime.hourl = KeyNew;lcd_write_data(CurrentTime.hourl + '0'); // refresh hourl//lcd_write_inst(0x10); // move cursor backadjust_item ++;lcd_write_inst(time_minuteh_addr);}else if(KeyNew == key_left){adjust_item --;lcd_write_inst(time_hourh_addr);}else if(KeyNew == key_right){adjust_item ++;lcd_write_inst(time_minuteh_addr);}}else if (adjust_item == 2) // set minuteh{if (KeyNew <6){CurrentTime.minuteh = KeyNew;lcd_write_data(CurrentTime.minuteh + '0');//lcd_write_inst(0x10); // move cursor backadjust_item ++;}else if(KeyNew == key_left){adjust_item --;lcd_write_inst(time_hourl_addr);}else if(KeyNew == key_right){adjust_item ++;lcd_write_inst(time_minutel_addr);}}else if (adjust_item == 3) // set minutel{if ((KeyNew >=0) & (KeyNew <=9)){CurrentTime.minutel = KeyNew;lcd_write_data(CurrentTime.minutel + '0');//lcd_write_inst(0x10); // move cursor backadjust_item ++;lcd_write_inst(time_secondh_addr);}else if(KeyNew == key_left){adjust_item --;lcd_write_inst(time_minuteh_addr);}else if(KeyNew == key_right){adjust_item ++;lcd_write_inst(time_secondh_addr);}}else if (adjust_item == 4) // set secondh{if (KeyNew <6){CurrentTime.secondh = KeyNew;lcd_write_data(CurrentTime.secondh + '0');//lcd_write_inst(0x10); // move cursor backadjust_item ++;}else if(KeyNew == key_left){adjust_item --;&nb, sp; lcd_write_inst(time_minutel_addr);}else if(KeyNew == key_right){adjust_item ++;lcd_write_inst(time_secondl_addr);}}else if (adjust_item == 5) // set secondl{if ((KeyNew >=0) & (KeyNew <=9)){CurrentTime.secondl = KeyNew;lcd_write_data(CurrentTime.secondl + '0');//lcd_write_inst(0x10); // move cursor backadjust_item = 0;lcd_write_inst(time_hourh_addr);}else if(KeyNew == key_left){adjust_item --;lcd_write_inst(time_secondh_addr);}else if(KeyNew == key_right){adjust_item = 0;lcd_write_inst(time_hourh_addr);}}}// -------------------------------------------------------void set_alarm1(void){if (adjust_item == 0) // set hourh{if (((AlarmTime1.hourl <4) & (KeyNew < 3)) | ((AlarmTime1.hourl >3) & (KeyNew <2))){AlarmTime1.hourh = KeyNew;lcd_write_data(AlarmTime1.hourh + '0'); // refresh hourh//lcd_write_inst(0x10); // move cursor backadjust_item ++;}else if(KeyNew == key_left){adjust_item = 6;lcd_write_inst(time_secondl_addr + 3);}else if(KeyNew == key_right){adjust_item ++;lcd_write_inst(time_hourl_addr);}}else if (adjust_item == 1) // set hourl{if (((AlarmTime1.hourh == 2) & (KeyNew < 4)) | ((AlarmTime1.hourh < 2) & (KeyNew <=9))){AlarmTime1.hourl = KeyNew;lcd_write_data(AlarmTime1.hourl + '0'); // refresh hourl//lcd_write_inst(0x10); // move cursor backadjust_item ++;lcd_write_inst(time_minuteh_addr);}else if(KeyNew == key_left){adjust_item --;lcd_write_inst(time_hourh_addr);}else if(KeyNew == key_right){adjust_item ++;lcd_write_inst(time_minuteh_addr);}}else if (adjust_item == 2) // set minuteh{if (KeyNew <6){AlarmTime1.minuteh = KeyNew;lcd_write_data(AlarmTime1.minuteh + '0');//lcd_write_inst(0x10); // move cursor backadjust_item ++;}else if(KeyNew == key_left){adjust_item --;lcd_write_inst(time_hourl_addr);}else if(KeyNew == key_right){adjust_item ++;lcd_write_inst(time_minutel_addr);}}else if (adjust_item == 3) // set minutel{if ((KeyNew >=0) & (KeyNew <=9)){AlarmTime1.minutel = KeyNew;lcd_write_data(AlarmTime1.minutel + '0');//lcd_write_inst(0x10); // move cursor backadjust_item ++;lcd_write_inst(time_secondh_addr);}else if(KeyNew == key_left){adjust_item --;lcd_write_inst(time_minuteh_addr);}else if(KeyNew == key_right){adjust_item ++;lcd_write_inst(time_secondh_addr);}}else if (adjust_item == 4) // set secondh{if (KeyNew <6){AlarmTime1.secondh = KeyNew;lcd_write_data(AlarmTime1.secondh + '0');//lcd_write_inst(0x10); // move cursor backadjust_item ++;}else if(KeyNew == key_left){adjust_item --;lcd_write_inst(time_minutel_addr);}else if(KeyNew == key_right){adjust_item ++;lcd_write_inst(time_secondl_addr);}}else if (adjust_item == 5) // set secondl{if ((KeyNew >=0) & (KeyNew <=9)){AlarmTime1.secondl = KeyNew;lcd_write_data(AlarmTime1.secondl + '0');//lcd_write_inst(0x10); // move cursor backadjust_item ++;lcd_write_inst(time_secondl_addr+3);}else if(KeyNew == key_left){adjust_item --;lcd_write_inst(time_secondh_addr);}else if(KeyNew == key_right){adjust_item ++;lcd_write_inst(time_secondl_addr+3);}}else if (adjust_item == 6) // set on/off{if ((KeyNew == key_up) | (KeyNew == key_down)){if (Alarm1Enable){Alarm1Enable =false; // disable alarm1lcd_write_data('f');lcd_write_data('f');}else{Alarm1Enable =true; // enable alarm1lcd_write_data('n');lcd_write_data(' ');}//lcd_write_inst(time_secondl_addr+3);adjust_item = 0;lcd_write_inst(time_hourh_addr);Alarm1Cnt = 0;}else if(KeyNew == key_left){adjust_item --;lcd_write_inst(time_secondl_addr);}else if(KeyNew == key_right){adjust_item = 0;lcd_write_inst(time_hourh_addr);}}}// -------------------------------------------------------void set_alarm2(void){if (adjust_item == 0) // set hourh{if (((AlarmTime2.hourl <4) & (KeyNew < 3)) | ((AlarmTime2.hourl >3) & (KeyNew <2))){AlarmTime2.hourh = KeyNew;lcd_write_data(AlarmTime2.hourh + '0'); // refresh hourh//lcd_write_inst(0x10); // move cursor backadjust_item ++;}else if(KeyNew == key_left){adjust_item = 6;lcd_write_inst(time_secondl_addr+3);}else if(KeyNew == key_right){adjust_item ++;lcd_write_inst(time_hourl_addr);}}else if (adjust_item == 1) // set hourl{if (((AlarmTime2.hourh == 2) & (KeyNew < 4)) | ((AlarmTime2.hourh < 2) & (KeyNew <=9))){AlarmTime2.hourl = KeyNew;lcd_write_data(AlarmTime2.hourl + '0'); // refresh hourl//lcd_write_inst(0x10); // move cursor backadjust_item ++;lcd_write_inst(time_minuteh_addr);}else if(KeyNew == key_left){adjust_item --;lcd_write_inst(time_hourh_addr);}else if(KeyNew == key_right){adjust_item ++;lcd_write_inst(time_minuteh_addr);}}else if (adjust_item == 2) // set minuteh{if (KeyNew <6){AlarmTime2.minuteh = KeyNew;lcd_write_data(AlarmTime2.minuteh + '0');//lcd_write_inst(0x10); // move cursor backadjust_item ++;}else if(KeyNew == key_left){adjust_item --;lcd_write_inst(time_hourl_addr);}else if(KeyNew == key_right){adjust_item ++;lcd_write_inst(time_minutel_addr);}}else if (adjust_item == 3) // set minutel{if ((KeyNew >=0) & (KeyNew <=9)){AlarmTime2.minutel = KeyNew;lcd_write_data(AlarmTime2.minutel + '0');//lcd_write_inst(0x10); // move cursor backadjust_item ++;lcd_write_inst(time_secondh_addr);}else if(KeyNew == key_left){adjust_item --;lcd_write_inst(time_minuteh_addr);}else if(KeyNew == key_right){adjust_item ++;lcd_write_inst(time_secondh_addr);}}else if (adjust_item == 4) // set secondh{if (KeyNew <6){AlarmTime2.secondh = KeyNew;lcd_write_data(AlarmTime2.secondh + '0');//lcd_write_inst(0x10); // move cursor backadjust_item ++;}else if(KeyNew == key_left){adjust_item --;lcd_write_inst(time_minutel_addr);}else if(KeyNew == key_right){adjust_item ++;lcd_write_inst(time_secondl_addr);}}else if (adjust_item == 5) // set secondl{if ((KeyNew >=0) & (KeyNew <=9)){AlarmTime2.secondl = KeyNew;lcd_write_data(AlarmTime2.secondl + '0');//lcd_write_inst(0x10); // move cursor backadjust_item ++;lcd_write_inst(time_secondl_addr+3);}else if(KeyNew == key_left){adjust_item --;lcd_write_inst(time_secondh_addr);}else if(KeyNew == key_right){adjust_item ++;lcd_write_inst(time_secondl_addr+3);}}else if (adjust_item == 6) // set on/off{if ((KeyNew == key_up) | (KeyNew == key_down)){if (Alarm2Enable){Alarm2Enable =false; // disable alarm2lcd_write_data('f');lcd_write_data('f');}else{Alarm2Enable =true; // enable alarm2lcd_write_data('n');lcd_write_data(' ');}//lcd_write_inst(time_secondl_addr+3);adjust_item = 0;lcd_write_inst(time_hourh_addr);Alarm2Cnt = 0;}else if(KeyNew == key_left){adjust_item --;lcd_write_inst(time_secondl_addr);}else if(KeyNew == key_right){adjust_item = 0;lcd_write_inst(time_hourh_addr);}}}// -------------------------------------------------------void main(void){unsigned char cnt;TRISC = 0x03; // PORTC.3 drive led,low activePORTC_MAP = 0x00;led = 0;BackLightEn = 0;BackLightTimer = 0;PORTC = PORTC_MAP;TRISA = 0xff; // low half byte as keyscan inTRISE = 0x00;ADCON0 = 0x00;ADCON1 = 0x06; // all digital I/Oslcd_init();INTCON = 0x00;lcd_write_inst(0x80); // set lcd ddram addressfor (pStr = StrPower1;*pStr!=0;pStr++){lcd_write_data(*pStr);}lcd_write_inst(0x0c); // LCD cursor offPIR1 = PIR2 = 0x00;T1CON = 0x0f; // T1CON: -- T1CKPS1 T1CPS0 T1OSCEN /T1SYNC TMR1CS TMR1ONTMR1H = 0x80;TMR1L = 0x00;。

基于PIC16F887单片机的温度、时钟显示以及闹钟功能

基于PIC16F887单片机的温度、时钟显示以及闹钟功能

基于PIC16F887单片机的温度、时钟显示以及闹钟功能基于PIC16F887单片机的温度、时钟显示以及闹钟功能一、课程设计的目的《PIC 单片机课程设计》是电气工程及其自动化专业及相近专业的一门重要的专业实践课,本课程在《PIC 单片机》课程的基础上,通过硬件设计与软件编程与调试的实践,进一步掌握PIC 单片机的应用方法,熟练PIC 单片机的C 程序的编写与调试,是毕业设计前的一次重要的实践,为今后走上工作岗位打下坚实的单片机应用基础。

二、设计内容1 Proteus 线路图绘制根据所设计的线路图,绘制与之一致的,能用于仿真的Proteus 线路图。

一致。

要求所绘的线路图美观、紧凑,参数要与课设2、软件编制与调试根据所设计的线路图制相应的单片机C 程序,要求所制的程序符合C 语言译,有错及时修改,并先在Proteus 上仿真,格式并加上注解。

每编一段即进行基本正确后再用PICkit3 在线调试,最后应脱机运行。

三、设计目标1该设计包括数字钟及数字温度计:按键的使用.LCD.蜂鸣器时钟芯片DS1307和温度传感器TC74。

2功能;此设计可以感测环境的温度,显示当前的时间,及闹钟。

温度与时间都显示在LCD显示屏上,以及如何调整闹钟界面四硬件设计及说明1 复位按键2时钟芯片DS1307及附属接线时钟芯片DS1307用于产生时间,它提供了秒、分、时、日、年、和星期等数据,能算只瑞年2100年,时钟的晶振是典型的32.768Hz。

(1)其引脚作用如下:2 (2)DS1307的读写如下;1写DS1307 的步骤如下:a) 发送启始位;b) 发送DS1307 的7位地址+0 (写),即0b11010000;c) 发送要写入DS1307 的地址,地址见图16,如要修改分,此值为1;d) 发送要写入DS1307 的数,如要把分修改为十进制数37,则此数为0x37;e) 发送停止位;2读DS1307 的步骤如下:a) 发送启始位;b) 发送DS1307 的7位地址+0 (写),即0b11010000;c) 发送要读的DS1307 的起始地址,如要从秒读起,为0;d) 发送停止位;e) 发送重新开始位;f) 发送DS1307 的7位地址+1 (读),即0b11010001;g) 发送读使能位,接收一个数据,单片机发送应答位;h) 发送读使能,接收下一个数据(地址会自动+1),单片机发送应答位,直到读数完成,接收最后一个数时单片机不发送应答位;i) 发送停止位;注意在DS1307仿真的时候七位地址为0b1001101 而实际为0b1001000 ; (3)功能是;提供时间通过pic16F877送入LCD中显示。

毕业设计-基于PIC16F877A单片机字符液晶显示数字时钟设计

毕业设计-基于PIC16F877A单片机字符液晶显示数字时钟设计

贵港职业学院毕业设计(论文)姓名:覃正杨学号:200930112126专业班级:电机系09级应用电子技术班论文题目:基于PIC16F877A字符液晶数字时钟指导教师:------二零一一年六月基于PIC16F877A单片机字符液晶显示数字时钟摘要近年来,随着电子产品的发展,人们对数字钟的要求越来越高,针对人们的这一需求设计了一种有单片机控制的智能化数字时钟,功能强大,界面友好,更好的满足了人们对它的智能化要求。

本文设计并实现了一款基于字符液晶显示的单片机数字钟,详细叙述了系统硬件、软件的具体实现过程。

论文重点阐述了数字钟硬件模块、时钟模块和相关控制模块等的模块化设计与制作;软件同样采用模块化的设计,包括读取模块、显示模块、时间调整模块设计,并采用汇编言语编写实现。

本设计实现了年、月、日和时间的显示功能、日期和时间修改功能。

设计方案已通过仿真软件验证,证明了设计的合理性。

关键词:单片机;数字钟;液晶显示;仿真目录目录 (3)引言 (4)第一章方案对比与选择 (5)方案1 (5)方案2 (5)方案选择 (5)第二章16F877A单片机概述 (6)2.1 单片机的用途与发展 (6)2.2 PIC16F877A单片机的结构与特点 (6)2.2.1 PIC16F877A单片机引脚结构 (6)2.2.2 PIC16F877A的内部结构 (7)2.2.3单片机的特点 (7)本章小结 (8)第三章LCD 1602A字符液晶显示说明 (9)3.1 LCD 1602A字符液晶显示的优势 (9)3.2 LCD 1602A字符液晶引脚说明 (9)本章小结 (9)第四章整体设计方案 (10)4.1 硬件选择 (10)4.3 PIC16F877A单片机电路 (10)4.4 LCD 1602A字符液晶显电路 (11)4.5 电源电路 (11)4.6 轻触按键电路 (11)4.7 整体电路图 (12)4.8 程序主流程图 (12)4.9 LCD 1602A字符液晶程序流程图 (13)本章小结 (13)第五章在线调式 (14)5.1 MPLAB ICD 2 在线调试器 (14)5.2 使用ICD 2 进行调试 (14)5.4 ICD2在线调式结果 (15)本章小结 (15)第六章结束语 (16)参考文献 (17)致谢 (17)附录字符液晶数字时钟程序 (18)引言现在是一个知识爆炸的新时代。

第三章 PIC16F887功能及编程

第三章 PIC16F887功能及编程

0:计时
01-1:4
… 1111-1:16
1X-1:16
福州大学电气工程与自动化学院
• TMR0是个8位计数/定时器,有可编程预分频率 器,可对外部脉冲计数或对内部指令脉冲计数的 功能。
• 当对外部脉冲计数时,符合一定要求的外部脉冲 送到RA4/T0CKI,且OPTION_REG(<T0CS>)要 置1,且该口(RA4)要设置为输入。
• TMR0寄存器的地址在01H、101H。 • TMR0有溢出中断功能。
中断 信接收 信发送 行通信 模块 溢出 溢出 使能 中断 中断 中断 中断 中断 中断
使能 使能 使能 使能 使能 使能
福州大学电气工程与自动化学院
bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0
- ADIF RCIF TXTF SSPIF CCP1IF TMR2IF TMR1IF - AD转换 串行通 串行通 同步串 CCP1 TMR2 TMR1
• 恢复被保护的相关寄存器 • 程序执行到”RETFIE”时后入先出的原则,从堆栈
中弹出地址给PC,GIE=1,程序返回到中断前 要执行的程序,程序恢复中断前程序的运行状 态。
福州大学电气工程与自动化学院
PIC16F887有17个中断源,每个中断源都有自 己的使能控制位(IE)和中断标志位(IF)。包括:
• 假设当前TRM1H、TMR1L=0x01FF,则在读取TMR1时 就可能发生错误:
• 如先读低字节,得到0xFF,假设此时发生进位,则再读 高字节时得到0x02,总的结果是0x2FF,显然是错误的。
• 如先读高字节,得到0x01,假设此时发生进位,则再读低 字节得到0x00,总的结果是0x100,也是错误的。

(完整word版)基于PIC16F877A的数字钟设计

(完整word版)基于PIC16F877A的数字钟设计

电子工程系项目考核(报告)项目名称:数字时钟项目姓名班级学号课程名称一、项目要求:数码管默认显示00:00。

数码管1,2 表示小时,数码管3,4 表示分钟。

如此,实现时钟功能.要求能够整点报时、闹钟提示;并附带有秒表功能。

按键可以调整时钟时间、切换显示页面和设定闹钟时间等。

二、项目原理分析在项目用的单片机开发板上单片机的IO 口接四位数码管的各段。

同时开发板共阴数码管的阴极由138 译码器的输出端控制。

在该项目中我采用了数码管的动态显示,即每位数码管点亮2ms 时间左右,由于人的视觉暂留现象及发光二极管的余辉效应,只要扫描的速度足够快,给人的印象就是一组稳定的显示数据,不会有闪烁感,动态显示的效果和静态显示是一样的,能够节省大量的I/O 端口,而且功耗更低。

在实现了数码管的动态显示的基础上在主程序中通过计算定时器1的中断次数,从而得到计时时间和秒表时间的基准时间。

同时在主程序中添加按键处理程序,实现时钟的开始、中断和校时,同时实现闹钟定时和切换显示等功能,还有秒表计时功能。

三、硬件电路图以及原理3。

1 硬件电路图如下:3。

2硬件原理:该项目中,主要的功能模块有:数码管显示模块;按键模块;蜂鸣器模块。

数码管显示模块主要是由芯片PIC16F877A内部的定时器1的定时中断实现数码管的动态显示.按键模块主要利用矩阵式按键实现多按键功能,矩阵式按键原理是在一端加高电平,然后检测另一端是否为高电平来判断按键是否按下,通过不同的定义可以让按键实现不同的功能。

蜂鸣器模块通过三极管的开关作用和驱动作用由芯片控鸣叫与否。

四、程序说明以及程序流程图该时钟默认显示页面为时钟计时页面,按键SW1 控制时钟、秒表的开始和中断,按按键SW1一次,如果数码管在显示秒表,则开始计秒功能;否则,开始正常计时;再按一次SW1则实现中断功能.按键SW2实现是数码管的选位,从第一个数码管开始,按一次就选中下一位数码管,循环选择。

SW3实现的是加1功能,每按一次就在SW2选中的位上加1。

毕业设计——基于PIC16F877的智能电子钟设计

毕业设计——基于PIC16F877的智能电子钟设计

基于PIC16F877的智能电子钟设计1 引言随着电子技术产业结构调整,生产工艺的飞速发展,人们生活水平的不断提高,家用电器逐渐普及,而随着人们对周围环境便利程度的要求,市场对于智能时钟控制系统的需求也越来越大。

智能钟应实现的主要功能为:能实现二十四小时制的时分秒显示,具有快速手动校时电路,具有整点报时功能,具有闹钟表功能(可设置时分),具有倒计时功能。

2 设计原理及方案2.1 设计原理单片机是一门技术性、应用性很强的学科,实践教学是它的一个极为重要的环节。

不论是硬件扩展、接口应用还是编程方法、程序调试,都离不开实践。

本次设计的目的是通过完成一个涉及PIC单片机都种资源应用并具有综合功能的小系统目标板的设计与编程应用,能够对电子电路、电子元器件、印制电路板等方面的知识进一步加深认识,同时在软件编程、排版调试、焊接技术、相关仪器设备的使用技能等方面得到较全面的锻炼和提高,为今后能够独立进行某些单片机应用系统的开发设计工作打下一定的基础。

该电子时钟不但具有显示时、分、秒的作用,而且用按键还可以实现时间的调整和闹铃的设定。

本次综合实践完成了在单片机数据采集与定时系统的硬件电路设计后的基础上,焊接制作电路板,完成该系统的软件设计与调试。

待仿真成功后,再将程序烧写入单片机中。

2.2 设计方案系统结构整个电子时钟系统电路可分为五大部分:中央处理单元(CPU)、电源电路部分、显示部分、键盘输入部分。

系统由PIC16F877、LED 数码管、按键、发光二极管等部分构成,能实现时间的调整、定时时间的设定,输出等功能。

系统的功能选择由SB0、SB1、SB2、SB3、SB4 完成。

其中SB0 为时间校对,定时器调整功能键,按SB 0 进入调整状态。

SB1 为功能切换键。

第一轮按动 SB1 依次进入一路、二路、三路定时时间设置提示程序,按SB3 进入各路定时调整状态。

定时时间到,二极管发亮。

到了关断时间后灭掉。

如果不进入继续按SB1 键,依次进入时间年位校对、月位校对、日位校对、时位校对、分位校对、秒位校对状态。

基于PIC16F887单片机的数字钟课程设计报告

基于PIC16F887单片机的数字钟课程设计报告

==《PIC单片机》课程设计学生姓名:学号: 010900616专业班级: 2009级6班指导教师:二○一二年 5 月 4日目录1.课程设计题目和要求 (3)2.设计方案 (3)3.硬件设计及说明 (3)4.软件设计及说明 (5)5.实验验证 (8)6.实验小结 (9)1.课程设计题目和要求1.1课程设计的性质和目的《PIC单片机课程设计》是电气工程及其自动化专业及相近专业的一门重要的专业实践课,本课程在《PIC 单片机》课程的基础上,通过硬件设计与软件编程与调试的实践,进一步掌握PIC单片机的应用方法,熟练PIC 单片机的C程序的编写与调试,是毕业设计前的一次重要的实践,为今后走上工作岗位打下坚实的单片机应用基础。

1.2课程设计内容和要求设计一个具有完整功能、有一定工作量与一定难度的单片机应用线路,并绘制能用于仿真的proteus 线路图,编制相应的单片机c 语言,分别在proteus仿真界面和实物板上调试运行正确。

最后用实物进行运行演示,并写出符合规范的课程设计报告。

2.设计方案利用PIC16F887单片机设计一个万年历,通过IIC通信将DS1307时钟芯片中的时间用LCD液晶屏显示。

同时,该设计还兼具闹钟功能和温度显示功能,可以通过键盘设置当前时间、日期、闹钟。

3.硬件设计及说明3.1硬件设计思路根据所要实现的预期功能,硬件必须要有最小系统模块、LCD显示模块、时钟模块、闹铃模块、温度模块、按键模块等。

根据所提供的实验板资料,可以设计如下电路(proteus图):3.2 最小系统最小系统包括16F887单片机、复位模块、4M外部晶振、排针等部件组成如下最基本电路,其中芯片供电的引脚略去。

本课设板所用的单片机为PIC16F887,是877A的升级,其主要参数与887A类似,但使用更为灵活、有的参数更为细化(如异步通信的波特率为双字节),而价格比887A更低,887引脚与877A兼容.3.3 LCD显示模块如图所示,为了节省I/O口,采用4位接线法,RD口的低四位和LCD的高4位连接,RD7用于背光显示(RD7=1),RD4、RD5、RD6用于读写和使能控制.上电后要延时15ms 后,才能进行初始。

基于PIC16F887单片机的温度、时钟显示以及闹钟功能

基于PIC16F887单片机的温度、时钟显示以及闹钟功能

基于PIC16F887单片机的温度、时钟显示以及闹钟功能基于PIC16F887单片机的温度、时钟显示以及闹钟功能一、课程设计的目的《PIC 单片机课程设计》是电气工程及其自动化专业及相近专业的一门重要的专业实践课,本课程在《PIC 单片机》课程的基础上,通过硬件设计与软件编程与调试的实践,进一步掌握PIC 单片机的应用方法,熟练PIC 单片机的C 程序的编写与调试,是毕业设计前的一次重要的实践,为今后走上工作岗位打下坚实的单片机应用基础。

二、设计内容1 Proteus 线路图绘制根据所设计的线路图,绘制与之一致的,能用于仿真的Proteus 线路图。

一致。

要求所绘的线路图美观、紧凑,参数要与课设2、软件编制与调试根据所设计的线路图制相应的单片机C 程序,要求所制的程序符合C 语言译,有错及时修改,并先在Proteus 上仿真,格式并加上注解。

每编一段即进行基本正确后再用PICkit3 在线调试,最后应脱机运行。

三、设计目标1该设计包括数字钟及数字温度计:按键的使用.LCD.蜂鸣器时钟芯片DS1307和温度传感器TC74。

2功能;此设计可以感测环境的温度,显示当前的时间,及闹钟。

温度与时间都显示在LCD显示屏上,以及如何调整闹钟界面四硬件设计及说明1 复位按键2时钟芯片DS1307及附属接线时钟芯片DS1307用于产生时间,它提供了秒、分、时、日、年、和星期等数据,能算只瑞年2100年,时钟的晶振是典型的32.768Hz。

(1)其引脚作用如下:2 (2)DS1307的读写如下;1写DS1307 的步骤如下:a) 发送启始位;b) 发送DS1307 的7位地址+0 (写),即0b11010000;c) 发送要写入DS1307 的地址,地址见图16,如要修改分,此值为1;d) 发送要写入DS1307 的数,如要把分修改为十进制数37,则此数为0x37;e) 发送停止位;2读DS1307 的步骤如下:a) 发送启始位;b) 发送DS1307 的7位地址+0 (写),即0b11010000;c) 发送要读的DS1307 的起始地址,如要从秒读起,为0;d) 发送停止位;e) 发送重新开始位;f) 发送DS1307 的7位地址+1 (读),即0b11010001;g) 发送读使能位,接收一个数据,单片机发送应答位;h) 发送读使能,接收下一个数据(地址会自动+1),单片机发送应答位,直到读数完成,接收最后一个数时单片机不发送应答位;i) 发送停止位;注意在DS1307仿真的时候七位地址为0b1001101 而实际为0b1001000 ; (3)功能是;提供时间通过pic16F877送入LCD中显示。

PIC16F877A数字时钟时钟程序(优推内容)

PIC16F877A数字时钟时钟程序(优推内容)

;Digit clock;-----------------------------------------------;DA TE :20101205;Author:Tang HS;M C U :PIC16F877A;FileName : ClockPIC.ASM;-----------------------------------------------------------;Date: {2010/12/07.14:35}-V er01--CS-ICD:0xAFCE---ISP:0xb7ce----;功能: 1.LED显示:时分秒;格式:[ hh mm ss ] 备注:按键未定义;------------------------------------------------------------;-----------------------------------------------------------;Date: {2010/12/07.22:15}-V er01--CS-ICD:0xAFCE---ISP:0xb7ce----;功能: 1.LED显示:时分秒;格式:[ hh mm ss ] 备注:按键未定义; 2.RB0-SET_KEY;RB1-ADD_KEY;RB2-SUB_KEY;RB3-EXIT_KEY;------------------------------------------------------------;Date: {2010/12/09.18:06}-V er02--CS-ICD:0xAFCE---ISP:0xef0e----;************************************************************;Date: {2010/12/10.00:47}-V er03--CS-ICD:0xb08d---ISP:0xfaa7----;功能: 1.LED显示:时分秒;格式:[ hh mm ss ] 备注:按键未定义; 2.RB0-SET_KEY;RB1-ADD_KEY;RB2-SUB_KEY;RB3-EXIT_KEY 都OK ; 3.MOVLW 纠正MOVV REG,1 引起的SUB_不良;;--------------------------------------------------------------;Date: {2010/12/10.13:10}-V er03.1--CS-ICD:0xb08b---ISP:0xfaa4----; 4.时差。

基于单片机C语言电子时钟完整版(闹钟,整点报时)

基于单片机C语言电子时钟完整版(闹钟,整点报时)

《单片机技术》课程设计说明书数字电子钟系、部:电气与信息工程学院学生姓名:指导教师:职称专业:班级:完成时间:2013-06-07摘要电子钟在生活中应用非常广泛,而一种简单方便的数字电子钟则更能受到人们的欢迎。

所以设计一个简易数字电子钟很有必要。

本电子钟采用ATMEL公司的AT89S52单片机为核心,使用12MHz 晶振与单片机AT89S52 相连接,通过软件编程的方法实现以24小时为一个周期,同时8位7段LED数码管(两个四位一体数码管)显示小时、分钟和秒的要求,并在计时过程中具有定时功能,当时间到达提前定好的时间进行蜂鸣报时。

该电子钟设有四个按键KEY1、KEY2、KEY3、KEY4和KEU5键,进行相应的操作就可实现校时、定时、复位功能。

具有时间显示、整点报时、校正等功能。

走时准确、显示直观、运行稳定等优点。

具有极高的推广应用价值。

关键词电子钟;AT89S52;硬件设计;软件设计ABSTRACTClock is widely used in life, and a simple digital clock is more welcomed by people. So to design a simple digital electronic clock is necessary.The system use a single chip AT89S52 of ATMEL’s as its core to control The crystal oscillator clock,using of E-12MHZ is connected with the microcontroller AT89S52, through the software programming method to achieve a 24-hour cycle, and eight 7-segment LED digital tube (two four in one digital tube) displays hours, minutes and seconds requirements, and in the time course of a timing function, when the time arrived ahead of scheduled time to buzz a good timekeeping. The clock has four buttons KEY1, KEY2, KEY3,KEY4 and KEY5 key, and make the appropriate action can be achieved when the school, timing, reset. With a time display, alarm clock settings, timer function, corrective action. Accurate travel time, display and intuitive, precision, stability, and so on. With a high application value.Key words Electronic clock;;AT89S52;Hardware Design;Software Design目录1设计课题任务、功能要求说明及方案介绍 (1)1.1设计课题任务 (1)1.2功能要求说明 (1)1.3设计总体方案介绍及原理说明 (1)2设计课题硬件系统的设计 (2)2.1设计课题硬件系统各模块功能简要介绍 (2)2.2设计课题电路原理图、PCB图、元器件布局图 (2)2.3设计课题元器件清单 (5)3设计课题软件系统的设计 (6)3.1设计课题使用单片机资源的情况 (6)3.2设计课题软件系统各模块功能简要介绍 (6)3.3设计课题软件系统程序流程框图 (6)3.4设计课题软件系统程序清单 (10)4设计结论、仿真结果、误差分析、教学建议 (21)4.1设计课题的设计结论及使用说明 (21)4.2设计课题的仿真结果 (21)4.3设计课题的误差分析 (22)4.4设计体会 (22)4.5教学建议 (22)结束语 (23)参考文献 (24)致谢 (25)附录 (26)1 设计课题任务、功能要求说明及方案介绍1.1 设计课题任务设计一个具有特定功能的电子钟。

基于PIC16F877A时钟程序实验C程序

基于PIC16F877A时钟程序实验C程序
PORTB=0x00;
TMR1CS=0;
T1CKPS1=1;
T1CKPS0=1;
TMR1H=0x0B;
TMR1L=0xE9;
T1SYNC=0Βιβλιοθήκη TMR1ON=1; TMR1IF=0;
TMR1IE=1;
PEIE=1;
GIE=1;
while(1)
U5C=0; //U5A=1,U5B=1,U5C=0,选通数码管的个位进行显示
PORTD=LED[j%10];
}
}
}
》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》
《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《
{
U5A=0; //U5A=0,U5B=1,U5C=0,选通数码管的十位进行显示
U5B=1; //U5A=0,U5B=1,U5C=0,选通数码管的十位进行显示
U5C=0; //U5A=0,U5B=1,U5C=0,选通数码管的十位进行显示
PORTD=0x00;
PORTB=0x00;
TMR1CS=0;
T1CKPS1=1;
T1CKPS0=1;
TMR1H=0x0B;
TMR1L=0xE9;
T1SYNC=0;
TMR1ON=1;
TMR1IF=0;
TMR1IE=1;
PEIE=1;
GIE=1;
while(1)
{
PORTD=0x00; //关一次显示,以免显示出鬼影
if(j>59)j=0;
if(++d>3) d=1;
if(d==2) //如果d=2,显示十位

PIC16F877A数字时钟时钟程序

PIC16F877A数字时钟时钟程序

;Digit clock;-----------------------------------------------;DA TE :20101205;Author:Tang HS;M C U :PIC16F877A;FileName : ClockPIC.ASM;-----------------------------------------------------------;Date: {2010/12/07.14:35}-V er01--CS-ICD:0xAFCE---ISP:0xb7ce----;功能: 1.LED显示:时分秒;格式:[ hh mm ss ] 备注:按键未定义;------------------------------------------------------------;-----------------------------------------------------------;Date: {2010/12/07.22:15}-V er01--CS-ICD:0xAFCE---ISP:0xb7ce----;功能: 1.LED显示:时分秒;格式:[ hh mm ss ] 备注:按键未定义; 2.RB0-SET_KEY;RB1-ADD_KEY;RB2-SUB_KEY;RB3-EXIT_KEY;------------------------------------------------------------;Date: {2010/12/09.18:06}-V er02--CS-ICD:0xAFCE---ISP:0xef0e----;************************************************************;Date: {2010/12/10.00:47}-V er03--CS-ICD:0xb08d---ISP:0xfaa7----;功能: 1.LED显示:时分秒;格式:[ hh mm ss ] 备注:按键未定义; 2.RB0-SET_KEY;RB1-ADD_KEY;RB2-SUB_KEY;RB3-EXIT_KEY 都OK ; 3.MOVLW 纠正MOVV REG,1 引起的SUB_不良;;--------------------------------------------------------------;Date: {2010/12/10.13:10}-V er03.1--CS-ICD:0xb08b---ISP:0xfaa4----; 4.时差。

基于16F887单片机数字钟课设设计报告

基于16F887单片机数字钟课设设计报告

基于16F887单片机数字钟课设设计报告第44页共44页xxxxxx《基于PIC16F887单片机的数字钟》课程设计报告学生姓名:_学号:_____专业班级:____________指导教师:___________*年*月*日目录1.功能介绍31.1PIC16F887介绍31.2DS1307介绍31.3TC74介绍31.4LM1602L介绍31.5蜂鸣器介绍32.硬原理框图43.模块介绍43.1单片机最小系统模块43.2时间和温度通讯模块5 3.3按键模块53.4蜂鸣器和液晶显示器模块5 4.软框图75.软功能介绍75.1端口﹑LCD和IIC初始化及端口若上拉75.2显示预显示的数字和字母85.3根据闹钟按键判断95.4写入初值到时钟芯片95.5时间加减设置105.6显示时间﹑读和显示温度﹑显示字母星期11 6.个人心得体会126.1关于PIC课设126.2课设过程遇到的问题及解决措施126.3我的建议14附录1:数字钟的全部C程序15附录2:Proteus完整仿真图441.功能介绍1.1PIC16F887介绍PIC16F887单片机共有40个引脚,其中有33个端口引脚,7个电源﹑地和复位引脚。

外部晶振设为4MHz,引脚1接复位按键。

此数字钟用到单片机的B端口中断功能,端口若上拉,电平变化下降沿中断。

1.2DS1307介绍DS1307时钟芯片是实时时钟芯片,它提供秒﹑分﹑时﹑日﹑月﹑年和星期等数据,有备用电源,主电源掉电备用,时钟晶振是32.768kHz。

其控制寄存器的地址为07,其值0b10000,代表允许其7脚输出每秒1Hz的方波。

其秒﹑分﹑时﹑日﹑月﹑年和星期分别存在地址为00﹑01﹑02﹑04﹑05﹑06﹑03中。

其与单片机的通讯为IIC通讯。

1.3TC74介绍温度传感器TC74是感测周围温度值。

TC74芯片的默认值为0b1001(实验板上芯片调试时的地址为0b1001000,此为仿真时用的地址)。

PIC16F887单片机LED数字钟程序

PIC16F887单片机LED数字钟程序

PIC16F887单⽚机LED数字钟程序1.硬件原理图2.印制板PCB图3.硬件测试程序⽤PIC16F887实验板,通过PIC3连接,进⾏在线调试和脱机运⾏,调试中遇到很多问题;经过我们的努⼒和⽼师的讲解我们成功攻克所有难题。

程序如下:#include__CONFIG(0X03E4);__CONFIG(0X0700);#define uint unsigned int#define uchar unsigned charuchartab[]={0x3F,0x06,0x5b,0x4f,0x66,0x6d,0x7c,0x07,0x7f,0x67};//七段数码管段码uchar table1[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd, 0x87,0xff,0xef};init();disp(uint num1,uint num2,uint num3,uint num4,uint num5,uint num6);disp1(uint num7,uint num8,uint num9,uint num10,uint num11,uint num12);//闹钟delay(uint x);uint i=0;int q=0,m=0,p=0;void KeyProcess();#define K0 RB0#define K1 RB2#define K2 RB1#define K3 RB3#define BEEP RE0uchar K1_FLAG=0;uint miao=0,mig=0,mis=0;uint fen=0,fe=0,fn=0;uint shi=0,sh=0,si=0;uint shia=0,shb=0,sic=0; uchar a1,a2,a3,a4,a5,a6; main(){init();TMR0=6;while(1){if((q==0)||(q==1)){mig=miao/10; //⼗位mis=miao%10; //个位fe=fen/10; //⼗位fn=fen%10; //个位sh=shi/10; //⼗位si=shi%10; //个位disp(sh,si,fe,fn,mig,mis); }if(K3==0){delay(10);if(K3==0){q++;K1_FLAG=1;if(q==3){TMR1ON=1;q=0;p==0;K1_FLAG=0;}while(!K3);if(K1_FLAG==1) KeyProcess(); }}void interrupt t0() {uint k=0,m=0;T0IF=0;i++;if(i==3670){miao++;if(miao>59){miao=0;k=1;}if(fen==59)if(miao>53){BEEP=1;//蜂鸣器delay(50); BEEP=0;delay(50); BEEP=1;//蜂鸣器delay(50); BEEP=0;delay(50);}if(shi==shia)if(fen==(fena-1)) if(miao>53){BEEP=1;//蜂鸣器delay(50);BEEP=0;delay(50);}i=0;}TMR0=6;if(k==1){fen++;if(fen>59){fen=0;m=3;}}if(m==3){shi++;if(shi>23)shi=0;}}init(){TRISE=0x00;OPTION=0x18;//B端⼝弱电上位(使⽤B端⼝内部上啦电阻) INTCON=0XA0; TRISD=0;TRISB=0XFF;ANS8=0;ANSEL=0;BEEP=0;}disp(uint num1,uint num2,uint num3,uint num4,uint num5,uint num6) { PORTD=tab[num1];PORTC=0XFE;delay(1);PORTD=table1[num2];PORTC=0XFD;delay(1);PORTD=0X40;PORTC=0XFB;delay(1);PORTD=tab[num3];PORTC=0XF7;delay(1);PORTD=table1[num4];PORTC=0XEF;delay(1);PORTD=0X40;PORTC=0Xdf;;delay(1);PORTD=tab[num5];PORTC=0XBF;delay(1);PORTD=tab[num6];PORTC=0X7F;delay(1);}delay(uint x)//延时{for(b=110;b>0;b--); }//******按键处理****//// void KeyProcess() {TMR1ON=0;if(q==1){if(K1==0){delay(10);if(K1==0){shi++;if(shi==24)shi=0;while(!K1);}}if(K2==0){delay(10);if(K2==0){while(!K2);fen++;if(fen==60)fen=0;}}}if(q==2){delay(10);if(K1==0){shia++;if(shia==24)shia=0;while(!K1);}}if(K2==0){delay(10);if(K2==0){while(!K2);fena++;if(fena==60)fena=0;}}migb=miaoa/10; //⼗位misc=miaoa%10; //个位feb=fena/10; //⼗位fnc=fena%10; //个位shb=shia/10; //⼗位sic=shia%10; //个位disp(shb,sic,feb,fnc,migb,misc);}}disp1(uint num7,uint num8,uint num9,uint num10,uint num11,uint num12) {PORTD=tab[num7];PORTC=0XFE;PORTC=0XFD;delay(5000);PORTD=0X40; PORTC=0XFB;delay(5000);PORTD=tab[num9]; PORTC=0XF7;delay(5000);PORTD=table1[num10]; PORTC=0XEF;delay(5000);PORTD=0X40; PORTC=0Xdf;;delay(5000);PORTD=tab[num11]; PORTC=0XBF;delay(5000);PORTD=tab[num12]; PORTC=0X7F;delay(500);}最终成品:。

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

#include <pic.h>__CONFIG (0x20F1);__CONFIG (0x3FFF); //调试用#define LCD_E RD6 //LCD E 读写使能控制#define LCD_RW RD5 //LCD 读(1)/写(0)控制线#define LCD_RS RD4 //LCD 寄存器选择数据(1)指令(0)//RD4-RD7分别接DB4-DB7,RD7为忙标志#define COM 0 //在LCD_WRITE()中的第2参数为0表示写命令#define DAT 1 //在LCD_WRITE()中的第2参数为1表示写数据#define mod RB3//模式选择(时间、闹钟、温度、秒表)#define set RB0//选择按键#define add RB1//加按键#define miu RB2//减按键#define RTR 0b00000000 //TC74的读温度命令#define TC74_ADD 0b1001101 //TC74的7位地址#define LINE1 0b10000000#define LINE2 0b11000000signed char hourt,mint,sect;//闹钟设置位int f;//闹钟显示清零判断char flag=0;//按键标志位char WW,QW,BW,SW,GW,M;char table[]="Mon Tue Wed Thu Fri Sat Sun ";//星期signed char year,month,day,week,hour,min,sec,a,T;bank1 char DD[16]; //一行LCD显示数据暂存char A[7];//DS1307读数//====LCD程序void CSH(void); //初始化void LCD_CSH(void); //LCD初始化void LCD_BUSY(void); //检测LCD是否忙char LCD_READ(void); //读LCD,忙检测用void LCD_WRITE(char,char); //LCD写1字节,命令或数据void LCD_WRITE_4(char,char); //LCD写半字节void DISP_C(char); //在指定行中显示字符,字符在数组DD中void DISP_MENU(const char *); //由常数数组显示整屏字符void DELAY_US(char);void DELAY(unsigned int);void delaynms(unsigned int);//===DS1307void IIC_SEND(char);void IIC_CSH(void);void READ_DS1307(char addr,char n);void write_DS1307(char addr,char data);void DS1307_CSH(void);//DS1307初始化void MENU_DS1307(void);//==温度void DISP_T(signed char R1); //温度在R1 signed char READ_T(void);void clock();//闹钟void set_time(void);//按键void bcd_dec(char adr,char R);char dec_bcd(char dec);void BCD(unsigned int R1);void guangbiao(void);//光标//========主程序void main(){CSH();READ_DS1307(0,7);//读DS1307if(A[0]&0x80)DS1307_CSH();//判断是否初始化while(1){clock();set_time();//按键检测delaynms(50);if(flag==0){ READ_DS1307(0,7);//读DS1307MENU_DS1307();//显示DS1307T=READ_T();//读温度DISP_T(T);//显示温度}}}//========初始化端口void CSH(void){TRISD=0b00000000; //控制LCD1604,全为输出RD7=1; //背光TRISB=0x0FF;RBPU=0;WPUB=0x0FF;ANSELH=0;PORTB=0x00;//===PWM设置TRISC1=0; //RC1为输出RC1=0;PR2=124; //周期为1msCCPR2L=0x32;CCP2CON=0b00000000;//关闭PWMT2CON=0b00000110; //TMR2预分频1:16,开始工IIC_CSH();LCD_CSH();}//LCD模块初始化void LCD_CSH(void){ DELAY(20); //延时20msLCD_WRITE_4(0b0011,COM); //发送控制序列DELAY_US(10); //延时100usLCD_WRITE_4(0b0011,COM); //发送控制序列DELAY_US(10); //延时100usLCD_WRITE_4(0b0011,COM); //发送控制序列DELAY_US(10); //延时100usLCD_WRITE_4(0b0010,COM); //4位数据格式LCD_BUSY(); //LCD忙检测LCD_WRITE(0b00101000,COM); //4位数据格式,2行,5×7点阵LCD_WRITE(0b00001100,COM); //D(d2)=1:打开显示,C(d1)=1:光标打开,B(d0)=1:光标不闪烁LCD_WRITE(0b00000001,COM); //清除显示DELAY(2); //延时2msLCD_WRITE(0b00000110,COM); //输入模式,I/D(d1)=1:地址加1,S(d0)=1:显示移位关闭}//========读LCD状态char LCD_READ(void){ unsigned char R1;TRISD|=0X0F; //LCD数据线为输入LCD_RS=0; //寄存器选择LCD_RW=1;NOP(); //读为1LCD_E=1;NOP(); //使能R1=0; //短延时R1=(PORTD<<4 )& 0xF0; //读数据的高4位给R1高四位LCD_E=0;NOP(); //读数据结束LCD_E=1;NOP(); //使能R1 |= (PORTD & 0x0F); //读PORTD的低4位,R1的高4位不变!LCD_E=0;NOP(); //读数据结束LCD_RW=0;return (R1);}//写一字节数R1,FLAG为写命令或数据选择,0为写命令,1为写数据//写之前先检查是否忙,写完后延时100us,分二次写4位数据/命令void LCD_WRITE(char R1,char FLAG){ char R2;TRISD&=0XF0;LCD_BUSY();R2=R1 & 0xF0; //低4位清0R2=R2>>4; //取高4位LCD_WRITE_4(R2,FLAG); //先写高4位R2=(R1 & 0x0F); //高4位清0,取低4位LCD_WRITE_4(R2,FLAG); //再送低4位DELAY_US(10); //延时100us}//写R1的低4位,FLAG为寄存器选择,1为命令,0为数据void LCD_WRITE_4(char R1,char FLAG){ TRISD&=0XF0;LCD_RW=0;NOP(); //写模式LCD_RS=FLAG;NOP(); //寄存器选择PORTD &= 0xF0;NOP(); //RD低4位先清0LCD_E=1;NOP(); //使能R1=(R1&0x0F); //R1低4位送至低4位PORTD |=R1;NOP(); //送4位LCD_E=0;NOP(); //数据送入有效,下降沿送入LCD_RS=0;NOP();PORTD &= 0xF0; //RD低4位清0}//========检测LCD是否忙void LCD_BUSY(void){ unsigned char R1;while(1){ R1=LCD_READ(); //读寄存器if ((R1 & 0x80)==0x00) //最高位为忙标志位break;};}//======延时(n)msvoid DELAY(unsigned int n){unsigned int j;char k;for (j=0;j<n;j++)for (k=246;k>0;k--) NOP();}//======延时(n)msvoid delaynms(unsigned int n){unsigned int j;char k;for (j=0;j<n;j++)for (k=246;k>0;k--) NOP();}//======延时(n×10)usvoid DELAY_US(char n){ char j;for (j=0;j<n;j++){NOP();NOP();}}//=======DS1307有关子程序//===DS1307初始化void DS1307_CSH(){write_DS1307(0x00,0X00);//秒钟设置write_DS1307(0x01,0x01);//分钟设置write_DS1307(0x02,0x01);//小时设置write_DS1307(0x03,0X01);//星期天设置write_DS1307(0x04,0x01);//日月设置write_DS1307(0x05,0x05);//月设置write_DS1307(0x06,0x12);//年设置write_DS1307(0x07,0x70);//7脚方波允许,输出1HZ}//==IIC初始化void IIC_CSH(){ TRISC =0b00011000; //SDA,SCL设置为输入SSPCON=0b00101000; //同步串口使能(SSPEN),主控方式SMP=0; //使能高速模式(400 kHz) 的压摆率控制SSPADD=4; //主控模式为波特率值,每位时间T=(SSPADD+1)/Tcy=5us }//发送数R并等待发送完成,收到从机的应答信号void IIC_SEND(char R){ SSPBUF=R; //发送while (RW==1); //在主动模式下,判断发送是否完成while (SSPIF==0); //等待发送完成while (ACKSTA T==1); //等待从机发送应答信号NOP();}//====读写DS1307程序void write_DS1307(char addr,char data){SEN=1; //发送起始位while(SEN==1); //检测起始位完成IIC_SEND(0b11010000); //送DS1307的七位地址和写功能IIC_SEND(addr); //发送要写入的地址IIC_SEND(data); //发送要写入的数PEN=1; //发送停止位while (PEN==1); //检查停止位结束}//===读DS1307void READ_DS1307(char addr,char n){char i;SEN=1; //产生起始位while (SEN==1); //检测起始位完成IIC_SEND(0b11010000); //送DS1307的7位地址IIC_SEND(addr); //此值为DS1307要读的地址PEN=1; //发送停止位while (PEN==1);//检查停止位结束NOP();RSEN=1; //发送重新启始位while(RSEN==1); //检测重新起始位完成IIC_SEND(0b11010001); //读数据for (i=0;i<n;i++) //读字节个数{ RCEN=1;while (RCEN==1);A[i]=SSPBUF; //读1字节if (i<n-1){ ACKDT=0;ACKEN=1;while (ACKEN==1);}else{ ACKDT=1;ACKEN=1;while (ACKEN==1);} //最后一字节不应答}PEN=1;while (PEN==1);}//=====显示DS1307void MENU_DS1307(void){ LCD_WRITE(0b00001100,COM); //D(d2)=1:打开显示,C(d1)=1:光标打开,B(d0)=1:光标不闪烁char i;LCD_WRITE(LINE1,COM); //DDRAM地址,第1行的第1个字符LCD_WRITE(' ',DAT);LCD_WRITE('2',DAT);LCD_WRITE('0',DAT);LCD_WRITE((A[6]>>4)+0x30,DA T);LCD_WRITE((A[6]&0x0F)+0x30,DA T);LCD_WRITE('-',DAT);LCD_WRITE((A[5]>>4)+'0',DA T);LCD_WRITE((A[5]&0x0F)+'0',DAT);LCD_WRITE('-',DAT);LCD_WRITE((A[4]>>4)+'0',DA T);LCD_WRITE((A[4]&0x0F)+'0',DAT);LCD_WRITE(' ',DAT);i=A[3]&0x07;LCD_WRITE(table[(i-1)*4],DA T);LCD_WRITE(table[(i-1)*4+1],DAT);LCD_WRITE(table[(i-1)*4+2],DAT);LCD_WRITE(table[(i-1)*4+3],DAT);//LCD_WRITE(' ',DAT);LCD_WRITE(LINE2,COM); //DDRAM地址,第2行的第1个字符LCD_WRITE(' ',DAT);LCD_WRITE((A[2]>>4)+'0',DA T);LCD_WRITE((A[2]&0x0F)+'0',DAT);LCD_WRITE(0x3A,DA T);LCD_WRITE((A[1]>>4)+'0',DA T);LCD_WRITE((A[1]&0x0F)+'0',DAT);LCD_WRITE(0x3A,DA T);LCD_WRITE((A[0]>>4)+'0',DA T);LCD_WRITE((A[0]&0x0F)+'0',DAT);LCD_WRITE(' ',DAT);}char dec_bcd(char dec){char bcd;bcd= 0;while(dec >= 10){dec -= 10;bcd++;}bcd <<= 4;bcd |= dec;return (bcd);}void bcd_dec(char adr,char R) {SW=A[adr]>>4;GW=A[adr]&0x0F;while(SW>0){R=R+10;SW--;}R+=GW;}//====按键程序void set_time(){if(mod==0){delaynms(30);if(mod==0){while(!mod);//等待M++;if(M==3){ M=0;flag=0;f=0;a=0;}}}if(M==1)//设置时间{if(set==0){delaynms(30);if(set==0){while(!set);a++;if(a==8)a=0;}}guangbiao();//光标定位,闪烁if(a==1){if(add==0){delaynms(30);if(add==0){while(!add);bcd_dec(0,sec);sec++;if(sec==60)sec=0;write_DS1307(0,dec_bcd(sec));}}if(miu==0){delaynms(30);if(miu==0){while(!miu);bcd_dec(0,sec);sec--;if(sec==-1)sec=59;write_DS1307(0,dec_bcd(sec));}}}if(a==2){if(add==0){delaynms(30);if(add==0){while(!add);bcd_dec(1,min);min++;if(min==60)min=0;write_DS1307(1,dec_bcd(min));}}if(miu==0){delaynms(30);if(miu==0){while(!miu);bcd_dec(1,min);min--;if(min==-1)min=59;write_DS1307(1,dec_bcd(min));}}}if(a==3){if(add==0){delaynms(30);if(add==0){while(!add);bcd_dec(2,hour);hour++;if(hour==24)hour=0;write_DS1307(2,dec_bcd(hour));}}if(miu==0){delaynms(30);if(miu==0){while(!miu);bcd_dec(2,hour);hour--;if(hour==-1)hour=23;write_DS1307(2,dec_bcd(hour));}}}if(a==4){if(add==0){delaynms(30);if(add==0){while(!add);bcd_dec(3,week);week++;if(week==8)week=1;write_DS1307(3,dec_bcd(week));}}if(miu==0){delaynms(30);if(miu==0){while(!miu);bcd_dec(3,week);week--;if(week==0)week=7;write_DS1307(3,dec_bcd(week));}}}if(a==5){if(add==0){delaynms(30);if(add==0){while(!add);bcd_dec(4,day);day++;if(day==32)day=1;write_DS1307(4,dec_bcd(day));}}if(miu==0){delaynms(30);if(miu==0){while(!miu);bcd_dec(4,day);day--;if(day==0)day=31;write_DS1307(4,dec_bcd(day));}}}if(a==6){if(add==0){delaynms(30);if(add==0){while(!add);bcd_dec(5,month);month++;if(month==13)month=1;write_DS1307(5,dec_bcd(month));}}if(miu==0){delaynms(30);if(miu==0){while(!miu);bcd_dec(5,month);month--;if(month==0)month=12;write_DS1307(5,dec_bcd(month));}}}if(a==7){if(add==0){delaynms(30);if(add==0){while(!add);bcd_dec(6,year);year++;if(year==99)year=0;write_DS1307(6,dec_bcd(year));}}if(miu==0){delaynms(30);if(miu==0){while(!miu);year--;if(year==-1)year=99;bcd_dec(6,year);write_DS1307(6,dec_bcd(year));}}}READ_DS1307(0,7);//读DS1307}//====闹钟按键设置else if(M==2){f++;flag=1;if(f==1){a=0;LCD_WRITE(LINE2+1,COM);//显示上次闹铃时间BCD(hourt);LCD_WRITE(SW+'0',DAT);LCD_WRITE(GW+'0',DAT);LCD_WRITE(LINE2+4,COM);BCD(mint);LCD_WRITE(SW+'0',DAT);LCD_WRITE(GW+'0',DAT);LCD_WRITE(LINE2+7,COM);BCD(sect);LCD_WRITE(SW+'0',DAT);LCD_WRITE(GW+'0',DAT);}if(set==0) //设置时间{delaynms(30);if(set==0){while(!set);a++;if(a==4)a=0;}}guangbiao();//光标定位,闪烁if(a==1){if(add==0){delaynms(30);if(add==0){while(!add);sect++;if(sect==60)sect=0;BCD(sect);LCD_WRITE(LINE2+7,COM);LCD_WRITE(SW+0x30,DAT); //显示十位LCD_WRITE(GW+0x30,DAT); //显示个位}}if(miu==0){delaynms(30);if(miu==0){while(!miu);sect--;if(sect==-1)sect=59;BCD(sect);LCD_WRITE(LINE2+7,COM);LCD_WRITE(SW+0x30,DAT); //显示十位LCD_WRITE(GW+0x30,DAT); //显示个位}}}if(a==2){if(add==0){delaynms(30);if(add==0){while(!add);mint++;if(mint==60)mint=0;BCD(mint);LCD_WRITE(LINE2+4,COM);LCD_WRITE(SW+0x30,DAT); //显示十位LCD_WRITE(GW+0x30,DAT); //显示个位}}if(miu==0){delaynms(30);if(miu==0){while(!miu);mint--;if(mint==-1)mint=59;BCD(mint);LCD_WRITE(LINE2+4,COM);LCD_WRITE(SW+0x30,DAT); //显示十位LCD_WRITE(GW+0x30,DAT); //显示个位}}}if(a==3){if(add==0){delaynms(30);if(add==0){while(!add);hourt++;if(hourt==24)hour=0;BCD(hourt);LCD_WRITE(LINE2+1,COM);LCD_WRITE(SW+0x30,DAT); //显示十位LCD_WRITE(GW+0x30,DAT); //显示个位}}if(miu==0){delaynms(30);if(miu==0){while(!miu);hourt--;if(hourt==-1)hourt=23;BCD(hourt);LCD_WRITE(LINE2+1,COM);LCD_WRITE(SW+0x30,DAT); //显示十位LCD_WRITE(GW+0x30,DAT); //显示个位}}}}}//====光标定位void guangbiao(void){switch(a){case(1):LCD_WRITE(0b11001000,COM);LCD_WRITE(0b00001111,COM);break;//定位秒,光标打开,B(d0)=1:光标闪烁case(2):LCD_WRITE(0b11000101,COM);LCD_WRITE(0b00001111,COM);break;//定位分,光标打开,B(d0)=1:光标闪烁case(3):LCD_WRITE(0b11000010,COM);LCD_WRITE(0b00001111,COM);break;//定位时,光标打开,B(d0)=1:光标闪烁case(4):LCD_WRITE(0b10001110,COM);LCD_WRITE(0b00001111,COM);break;//定位星期,光标打开,B(d0)=1:光标闪烁case(5):LCD_WRITE(0b10001010,COM);LCD_WRITE(0b00001111,COM);break;//定位日,光标打开,B(d0)=1:光标闪烁case(6):LCD_WRITE(0b10000111,COM);LCD_WRITE(0b00001111,COM);break;//定位月,光标打开,B(d0)=1:光标闪烁case(7):LCD_WRITE(0b10000100,COM);LCD_WRITE(0b00001111,COM);break;//定位秒,光标打开,B(d0)=1:光标闪烁case(8):LCD_WRITE(0b10000010,COM);LCD_WRITE(0b00001111,COM);break;//定位秒,光标打开,B(d0)=1:光标闪烁}}//=====读TC74的温度值signed char READ_T(void){ signed char R1;SEN=1; //开始条件while (SEN==1); //检测开始条件是否完成?IIC_SEND(TC74_ADD<<1); //送TC74地址(写)IIC_SEND(RTR); //写RTR命令(写)RSEN=1; //重新开始条件while (RSEN==1); //等待重新开始条件结束IIC_SEND((TC74_ADD<<1)+1);//发送TC74地址(读)RCEN=1; //接收使能while (RCEN==1); //等待接收完成R1=SSPBUF; //接收数据存入R1PEN=1; //停止位while(PEN==0);return(R1);}//从R1双字节数转换为十进制数万位-个位:WW,QW,BW,SW,GW void BCD(unsigned int R1){ WW=0;QW=0;BW=0;SW=0;GW=0;while(R1>=10000){R1-=10000;WW++;}while(R1>=1000){R1-=1000;QW++;}while(R1>=100){R1-=100;BW++;}while(R1>=10){R1-=10; SW++;}GW=R1;}//===温度显示void DISP_T(signed char R1) //温度在R1{ char R2;if (R1>=0)BCD(R1);else{ R2=~(R1)+1;BCD(R2);}if (R1<0){LCD_WRITE(LINE2+10,COM); //DDRAM地址,第1行的第5个字符LCD_WRITE('-',DAT);}if (R1>=0) //只在温度为正时才显示百位LCD_WRITE(BW+0x30,DAT); //显示百位,数字加上0x30即为相应的ASCII码,下同LCD_WRITE(SW+0x30,DAT); //显示十位LCD_WRITE(GW+0x30,DAT); //显示个位LCD_WRITE(0xDF,DA T); //°LCD_WRITE('C',DAT);LCD_WRITE(' ',DAT);}//====闹钟void clock(){ if(!mod||!set||!add||!miu){delaynms(30);if(!mod||!set||!add||!miu);CCP2CON=0b00000000; //关PWM模式}BCD(sect);if(SW==(A[0]>>4)&&GW==(A[0]&0x0F)){BCD(mint);if(SW==(A[1]>>4)&&GW==(A[1]&0x0F)){BCD(hourt);if(SW==(A[2]>>4)&&GW==(A[2]&0x0F))CCP2CON=0b00001100; //开PWM模式}}}。

相关文档
最新文档