基于pic16f877a单片机的秒表计时器
- 格式:doc
- 大小:66.50 KB
- 文档页数:9
基于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中显示。
目录第一章引言 (3)选题背景及其意义 (3)877A单片机的介绍 (3)设计要求及其功能 (4)本设计实现的功能 (4)第二章系统整体方案 (5)系统整体方案框图 (5)设计要求 (5)按照设计要求画出系统框图 (5)控制系统时刻分析表 (6)处置器的选择 (6)时钟芯片的选择 (7)液晶显示器的选择 (7)第三章硬件部份的设计 (7)系统部份 (7)键盘接口电路 (8)显示部份 (9)第四章控制系统软件部份 (10)软件介绍 (10)程序流程图 (11)按键的扫描子程序 (12)铃声控制程序 (12)仿真电路 (13)第五章总结 (15)参考文献 (16)致谢 (16)基于单片机的可编程作息时刻控制器的设计何欢(伊犁师范学院电子与信息工程学院电子信息科学与技术09-2班,新疆伊宁市 835000)摘要:本设计是作息时刻控制器,由单片机最小系统、按键模块、数码管显示模块、铃声模块组成。
采用PIC16F877A单片机、主频4MHZ晶振,通过按键STATE、TEN、UNIT控制时刻的校正时刻和铃声设定;数码管显示模块用来显示时刻,显示格式为“时分”,并能够按照需要显示年、月、日,由数码管小数点闪动作为秒计数;铃声模块进行到时提示并出相应动作:发光二极管闪亮,同时播放音乐。
时钟芯片采用的是DS1302,此芯片是DALLAS 公司推出的涓流充电时钟芯片,其内含有一个实不时钟/日历和31 字节静态RAM,并通过简单的串行接口与单片机进行通信。
实不时钟/日历电路提供秒、分、时、日、日期、月、年的信息,每一个月的天数和闰年的天数可自动调整,时钟操作可通过AM/PM 指示决定采用24 或12 小时格式。
DS1302 工作时功耗很低,维持数据和时钟信息时功率小于1mW。
该设计采用C语言编写程序,由于汇编语言的移植性比较差,而C语言则比较灵活,许多子函数都能够直接移植过去。
关键词:PIC16F877A单片机;晶振;液晶显示器;源程序Based on single chip microcomputer controller design ofprogrammable calendarHehuan(ili normal college of electronic and information engineering college of electronic information science and technology 09-2 class, xinjiang yining city, 835000 )Abstract:This is the time schedule controller designed by single chip microcomputer minimum system module, buttons, digital tube display module, alarm module. Using PIC16F877A MCU, 4 MHZ crystal vibration main frequency, through the button STATE, TEN, UNIT control time correction time and set ring; Digital tube display module is used to display time, display format of"time", and can according to need to display year, month, day, by the digital tube decimal counting flashing as seconds; Bell module to remind and make the corresponding action: light-emitting diodes, play music at the same time.Used clock chip DS1302, this chip is DALLAS company to launch a trickle charging the clock chip, containing a real-time clock/calendar and 31 bytes static RAM, and communicate with single chip microcomputer with simple serial interface. Real-time clock/calendar circuit provides seconds, minutes, and information day, date, month, year, number of days per month and leap year the number of days can be automatically adjusted, clock operation by an AM/PM indicator decided to adopt 12 or 24 hour format. DS1302 power consumption is low, while working to keep data and clock information when the power is less than 1 mw.This design USES the C language program, due to the portability of assembly language, but C is more flexible, Many functions can be directly transplanted in the past.Keywords: PIC16F877A MCU;crystals and liquid crystal display; the source program第一章引言选题背景和意义自从人类学会计时开始,计时方式由在木棍和骨头上刻标记,随着人类的智慧的进展,到后面利用计时工具不断的改良,由最开始的圭表、日晷、漏壶、漏箭、机械闹钟、秒表、沙漏、怀表、自摆钟、石英钟等。
20XX年小学期单片机设计实验报告题目:基于PIC16F877单片机的LED旋转时钟班级:学号:班内序号:实验组号:学生姓名:指导教师:基于PIC16F877单片机的LED旋转时钟――班实验摘要本次我们制作的基于PIC16F877单片机的LED旋转时钟是能够输入、显示时间的时钟。
结构新颖,效果奇特。
加入了现代科技的元素,利用人眼的视觉暂留特性,解决了传统时钟结构单一,显示效果固定的缺陷,更好了满足了人们对美的追求。
整个系统中,微控制器采用了Microchip公司的PIC16F877,软件设计中涉及PORTA用作普通数字I/O脚控制按键输入,PORTB、PORTC控制灯的亮灭,PORTD向时钟芯片DS1302写入和读出时间。
概括来说,本实验就是用人眼的视觉暂留特性,用PIC16F877单片机作为主控芯片,采用电机带动发光二极管高速旋转,利用频闪显示原理呈现时钟画面。
A b s t r a c tIn this experiment, we made a LED rotating clock base on PIC16F877 MCU. It can input and show time. Its structure is novel and its effect is amazing. It’s full of modern technology element. With human eyes’ persistence of vision, it solves traditional clock’s structure and effect’s disadvantage, fits human pursue for beauty better.The system uses the production of the Microchip cord--PIC16F877. The design includes the drive of PORTA as general digital ports to input time, the drive of PORTB and PORTC to control the LED’s on, the drive of PORTD to write and read time on DS1302.In conclusion, with human eyes’ persistence of v ision, this experiment uses PIC16F877 MCU as master chip, uses motor to drive LED rotate at high speed, uses strobe display principle to show the clock.关键字单片机——microcontroller 芯片——CMOS chipLED旋转时钟-- LED rotating clock一.实验论证与比较1.LED显示模块LED的特点非常明显,寿命长、光效高、无辐射与低功耗。
基于PIC16F877A单片机的温度,时间显示以及闹钟设置,硬件和软件配备一,硬件图#include<pic.h>__CONFIG(0x3B31);#define rs RD0#define rw RD1#define en RD2#define BEEP RD3 #define s1 RA0#define s2 RA1#define s3 RA2#define s4 RA3#define uint unsigned int#define uchar unsigned charsigned char set_time[7]={0,58,23,6,1,5,12};//秒分时星期日月年signed char read_time[7]={0,0,0,0,0,0,0};signed char shi=7,fen=15,alarm_time=1,reapeat_fen=2,cent;//闹钟时,闹钟分,闹铃响分钟,闹铃响间隔uchar s1_num,s2_num;const uchar alarm[]={"ALARM TIME:"};const uchar mode[]={"MODE:"};const uchar rpt[]={"RPT:"};const uchar min[]={"min"};void PORT_INIT(){TRISA=0xff;//A口设置为输入ADCON1=0x06;//RA口上电复位为模拟输入口TRISC3=1;//SCL和SDA设置为输入TRISC4=1;TRISD=0x00;//D口设置为输出}void IIC_INIT(){SSPCON=0x28;STAT_SMP=0;SSPADD=4;}void delayms(uint z)//延时函数{uint x,y;for(x=z;x>0;x--)for(y=110;y>0;y--);}void delayus(uint k){while(k--);}void write_byte_low(uchar R1,uchar flag0)//写一个字节的低4位,flag0为指令/数据选择位{ //,0为写指令,1为写数据uchar low;rs=flag0;low=R1&0x0f;low=low<<4;PORTD&=0x0f;NOP();PORTD|=low;NOP();//写指令的低4位en=1;delayus(20);en=0;}void lcd_write(uchar dat,uchar flag1)//写指令/数据到1602{uchar dat_high,dat_low;dat_high=dat>>4;write_byte_low(dat_high,flag1);dat_low=dat&0x0f;write_byte_low(dat_low,flag1);NOP();}void write_string(uchar address,uchar const *str)//往指定的地址写字符串{uchar i=0;lcd_write(address,0);while(str[i]!='\0'){lcd_write(str[i],1);delayus(5);i++;}}void LCD_INIT()//初始化函数{rw=0;en=0;delayms(20);write_byte_low(0b0011,0);delayms(1);write_byte_low(0b0011,0);delayus(10);write_byte_low(0b0011,0);delayus(10);write_byte_low(0b0010,0);delayms(1);lcd_write(0x28,0);delayms(5);lcd_write(0x0c,0);delayms(5);lcd_write(0x01,0);delayms(5);lcd_write(0x06,0);delayms(5);}void naoling(){uchar i;for(i=0;i<20;i++){BEEP=1;delayus(5);BEEP=0;delayus(5);}}void IIC_SEND(uchar num){SSPBUF=num;while(STAT_RW==1);//等待发送结束while(SSPIF==0);while(ACKSTAT==1);//等待应答}signed char read_temp()//读温度{signed char temp;SEN=1;while(SEN==1);IIC_SEND(0b10011010);IIC_SEND(0);RSEN=1;while(RSEN==1);IIC_SEND(0b10011011);RCEN=1;while(RCEN==1);// SSPIF=0;// while(SSPIF==0);//等待接收结束temp=SSPBUF;PEN=1;while(PEN==1);return temp;}void dispose()//BCD数据处理{uchar i,temp1,temp2;for(i=0;i<7;i++){temp1=set_time[i]/10;temp2=set_time[i]%10;set_time[i]=temp1*16+temp2;}}void time_csh()//时间初始化{uchar i;dispose();for(i=0;i<7;i++){SEN=1;//起始信号while(SEN==1);//检测起始信号是否已完成IIC_SEND(0xd0);IIC_SEND(i);IIC_SEND(set_time[i]);PEN=1;//停止信号while(PEN==1);}}void read_ds1307()//读时间{uchar k;for(k=0;k<8;k++){SEN=1;//起始信号while(SEN==1);IIC_SEND(0xd0);IIC_SEND(k);PEN=1;//停止信号while(PEN==1);RSEN=1;//重新启动while(RSEN==1);IIC_SEND(0xd1);SSPIF=0;RCEN=1;while(SSPIF==0);//等待接收结束read_time[k-1]=SSPBUF;NOP();NOP();PEN=1;//停止信号while(PEN==1);}}void display_time(){lcd_write(0x80,0);lcd_write(0x32,1);lcd_write(0x30,1);lcd_write(0x30+read_time[6]/16,1);//年lcd_write(0x30+read_time[6]%16,1);lcd_write('-',1);lcd_write(0x30+read_time[5]/16,1);//月lcd_write(0x30+read_time[5]%16,1);lcd_write('-',1);lcd_write(0x30+read_time[4]/16,1);//日lcd_write(0x30+read_time[4]%16,1);lcd_write(0x80+0x0d,0);switch(read_time[3]){case 1:lcd_write('M',1);lcd_write('O',1);lcd_write('N',1);break;case 2:lcd_write('T',1);lcd_write('U',1);lcd_write('E',1);break;case 3:lcd_write('W',1);lcd_write('E',1);lcd_write('D',1);break;case 4:lcd_write('T',1);lcd_write('H',1);lcd_write('U',1);break;case 5:lcd_write('F',1);lcd_write('R',1);lcd_write('I',1);break;case 6:lcd_write('S',1);lcd_write('A',1);lcd_write('T',1);break;case 7:lcd_write('S',1);lcd_write('U',1);lcd_write('N',1);break;lcd_write(0x80+0x40,0);lcd_write(0x30+read_time[2]/16,1);//时lcd_write(0x30+read_time[2]%16,1);lcd_write(':',1);lcd_write(0x30+read_time[1]/16,1); //分lcd_write(0x30+read_time[1]%16,1);lcd_write(':',1);lcd_write(0x30+read_time[0]/16,1); //秒lcd_write(0x30+read_time[0]%16,1);NOP();NOP();cent=read_temp();lcd_write(0x80+0x4b,0);lcd_write(0x30+cent/10,1);lcd_write(0x30+cent%10,1);lcd_write(0xdf,1);lcd_write('C',1);if((shi==(read_time[2]/16*10+read_time[2]%16))&&(fen<=(read_ti me[1]/16*10+read_time[1]%16))&&((read_time[1]/16*10+read_time[1] %16)<(fen+alarm_time)))naoling();}if((shi==(read_time[2]/16*10+read_time[2]%16))&&(fen+reapeat_fe n<=(read_time[1]/16*10+read_time[1]%16))&&((read_time[1]/16*10+re ad_time[1]%16)<(fen+alarm_time+reapeat_fen))){naoling();}if((shi==(read_time[2]/16*10+read_time[2]%16))&&(fen+2*reapeat _fen<=(read_time[1]/16*10+read_time[1]%16))&&((read_time[1]/16*10 +read_time[1]%16)<(fen+alarm_time+2*reapeat_fen))){naoling();}if((shi==(read_time[2]/16*10+read_time[2]%16))&&(fen+3*reapeat _fen<=(read_time[1]/16*10+read_time[1]%16))&&((read_time[1]/16*10 +read_time[1]%16)<(fen+alarm_time+3*reapeat_fen))){naoling();}if((shi==(read_time[2]/16*10+read_time[2]%16))&&(fen+4*reapeat_fen<=(read_time[1]/16*10+read_time[1]%16))&&((read_time[1]/16*10 +read_time[1]%16)<(fen+alarm_time+4*reapeat_fen))){naoling();}}void setting_time(){uchar l,s2_value,setting_flag;if(s2==0){delayms(10);if(s2==0){s2_value++;setting_flag = 1;while(s2==0);//松手检测for(l=0;l<7;l++)//存储当前时间数据//年星期月日时分秒{set_time[l]=read_time[l]/16*10+read_time[l]%16;}while(setting_flag){if(s2==0){delayms(5);if(s2==0){s2_value++;while(s2==0);//松手检测}}if(s2_value==1){lcd_write(0x83,0);//指向年份lcd_write(0x0f,0);//显示游标并闪烁if(s3==0){delayms(5);if(s3==0){set_time[6]++;if(set_time[6]==100){set_time[6]=0;}lcd_write(0x82,0);lcd_write(0x30+set_time[6]/10,1);lcd_write(0x30+set_time[6]%10,1);lcd_write(0x83,0);//指向年份while(s3==0);}}if(s4==0){delayms(5);{set_time[6]--;if(set_time[6]==-1){set_time[6]=99;}lcd_write(0x82,0);lcd_write(0x30+set_time[6]/10,1);lcd_write(0x30+set_time[6]%10,1);lcd_write(0x83,0);//指向年份while(s4==0);}}}if(s2_value==2){lcd_write(0x86,0);//指向月份if(s3==0){delayms(5);{set_time[5]++;if(set_time[5]==13){set_time[5]=1;}lcd_write(0x85,0);lcd_write(0x30+set_time[5]/10,1);lcd_write(0x30+set_time[5]%10,1);lcd_write(0x86,0);//指向月份while(s3==0);}}if(s4==0){delayms(5);if(s4==0){set_time[5]--;{set_time[5]=12;}lcd_write(0x85,0);lcd_write(0x30+set_time[5]/10,1);lcd_write(0x30+set_time[5]%10,1);lcd_write(0x86,0);//指向月份while(s4==0);}}}if(s2_value==3){lcd_write(0x89,0);//指向日if(s3==0){delayms(5);if(s3==0){set_time[4]++;{set_time[4]=1;}lcd_write(0x88,0);lcd_write(0x30+set_time[4]/10,1);lcd_write(0x30+set_time[4]%10,1);lcd_write(0x89,0);//指向日while(s3==0);}}if(s4==0){delayms(5);if(s4==0){set_time[4]--;if(set_time[4]==0){set_time[4]=31;lcd_write(0x88,0);lcd_write(0x30+set_time[4]/10,1);lcd_write(0x30+set_time[4]%10,1);lcd_write(0x89,0);//指向日while(s4==0);}}}if(s2_value==4){lcd_write(0x8f,0);//指向星期if(s3==0){delayms(5);if(s3==0){set_time[3]++;if(set_time[3]==8)set_time[3]=1;}switch(set_time[3]){case1:lcd_write(0x8d,0);lcd_write('M',1);lcd_write('O',1);lcd_write('N',1);bre ak;case2:lcd_write(0x8d,0);lcd_write('T',1);lcd_write('U',1);lcd_write('E',1);brea k;case3:lcd_write(0x8d,0);lcd_write('W',1);lcd_write('E',1);lcd_write('D',1);bre ak;case4:lcd_write(0x8d,0);lcd_write('T',1);lcd_write('H',1);lcd_write('U',1);brea k;case5:lcd_write(0x8d,0);lcd_write('F',1);lcd_write('R',1);lcd_write('I',1);break ;case6:lcd_write(0x8d,0);lcd_write('S',1);lcd_write('A',1);lcd_write('T',1);break;case7:lcd_write(0x8d,0);lcd_write('S',1);lcd_write('U',1);lcd_write('N',1);brea k;}lcd_write(0x8f,0);//指向星期while(s3==0);}}if(s4==0){delayms(5);if(s4==0){set_time[3]--;if(set_time[3]==0){set_time[3]=7;}switch(set_time[3])case1:lcd_write(0x8d,0);lcd_write('M',1);lcd_write('O',1);lcd_write('N',1);bre ak;case2:lcd_write(0x8d,0);lcd_write('T',1);lcd_write('U',1);lcd_write('E',1);brea k;case3:lcd_write(0x8d,0);lcd_write('W',1);lcd_write('E',1);lcd_write('D',1);bre ak;case4:lcd_write(0x8d,0);lcd_write('T',1);lcd_write('H',1);lcd_write('U',1);brea k;case5:lcd_write(0x8d,0);lcd_write('F',1);lcd_write('R',1);lcd_write('I',1);break ;case6:lcd_write(0x8d,0);lcd_write('S',1);lcd_write('A',1);lcd_write('T',1);brea k;case7:lcd_write(0x8d,0);lcd_write('S',1);lcd_write('U',1);lcd_write('N',1);brea k;lcd_write(0x8f,0);//指向星期while(s4==0);}}}if(s2_value==5){lcd_write(0x80+0x41,0);//指向小时if(s3==0){delayms(5);if(s3==0){set_time[2]++;if(set_time[2]==24){set_time[2]=0;}lcd_write(0x80+0x40,0);lcd_write(0x30+set_time[2]/10,1);lcd_write(0x30+set_time[2]%10,1);lcd_write(0x80+0x41,0);//指向小时while(s3==0);}}if(s4==0){delayms(5);if(s4==0){set_time[2]--;if(set_time[2]==-1){set_time[2]=23;}lcd_write(0x80+0x40,0);lcd_write(0x30+set_time[2]/10,1);lcd_write(0x30+set_time[2]%10,1);lcd_write(0x80+0x41,0);//指向小时while(s4==0);}}}if(s2_value==6){lcd_write(0x80+0x44,0);//指向分钟if(s3==0){delayms(5);if(s3==0){set_time[1]++;if(set_time[1]==60){set_time[1]=0;}lcd_write(0x80+0x43,0);lcd_write(0x30+set_time[1]/10,1);lcd_write(0x30+set_time[1]%10,1);lcd_write(0x80+0x44,0);//指向分钟while(s3==0);}}if(s4==0){delayms(5);if(s4==0){set_time[1]--;if(set_time[1]==-1){set_time[1]=59;}lcd_write(0x80+0x43,0);lcd_write(0x30+set_time[1]/10,1);lcd_write(0x30+set_time[1]%10,1);lcd_write(0x80+0x44,0);//指向分钟while(s4==0);}}}if(s2_value==7){lcd_write(0x80+0x47,0);//指向秒if(s3==0){delayms(5);if(s3==0){set_time[0]++;if(set_time[0]==60){set_time[0]=0;}lcd_write(0x80+0x46,0);lcd_write(0x30+set_time[0]/10,1);lcd_write(0x30+set_time[0]%10,1);lcd_write(0x80+0x47,0);//指向分钟while(s3==0);}}if(s4==0){delayms(5);if(s4==0){set_time[0]--;if(set_time[0]==-1){set_time[0]=59;}lcd_write(0x80+0x46,0);lcd_write(0x30+set_time[0]/10,1);lcd_write(0x30+set_time[0]%10,1);lcd_write(0x80+0x47,0);//指向分钟while(s4==0);}}}if(s2_value==8)//这里注意?{s2_value=0;lcd_write(0x0c,0);setting_flag=0;time_csh();}}}}}void naozhong(){write_string(0x80,alarm);lcd_write(0x30+shi/10,1);lcd_write(0x30+shi%10,1);lcd_write('-',1);lcd_write(0x30+fen/10,1);lcd_write(0x30+fen%10,1);write_string(0x80+0x40,mode);lcd_write(0x30+alarm_time,1);write_string(0x80+0x47,rpt);lcd_write(0x30+reapeat_fen/10,1);lcd_write(0x30+reapeat_fen%10,1);write_string(0x80+0x4d,min);}uchar s1_scan(){if(s1==0){delayms(5);if(s1==0){s1_num++;if(s1_num==2){s1_num=0;s2_num=0;lcd_write(0x0c,0);}while(s1==0);lcd_write(0x01,0);if(s1_num==1){naozhong();lcd_write(0x0f,0);}}}return s1_num;}void setting_naozhong(){if(s2==0){delayms(5);if(s2==0){s2_num++;if(s2_num==4){s2_num=0;}while(s2==0);}}switch(s2_num){case 0:{lcd_write(0x8c,0);if(s3==0){delayms(5);if(s3==0){shi++;if(shi==24){shi=0;}lcd_write(0x8b,0);lcd_write(0x30+shi/10,1);lcd_write(0x30+shi%10,1);lcd_write(0x8c,0);//指向小时while(s3==0);}}if(s4==0){delayms(5);if(s4==0){shi--;if(shi==-1){shi=23;}lcd_write(0x8b,0);lcd_write(0x30+shi/10,1);lcd_write(0x30+shi%10,1);lcd_write(0x8c,0);//指向小时while(s4==0);}}break;}case 1:{lcd_write(0x8f,0);if(s3==0){delayms(5);if(s3==0){fen++;if(fen==60){fen=0;}lcd_write(0x8e,0);lcd_write(0x30+fen/10,1);lcd_write(0x30+fen%10,1);lcd_write(0x8f,0);//指向小时while(s3==0);}}if(s4==0){delayms(5);if(s4==0){fen--;if(fen==-1){fen=59;}lcd_write(0x8e,0);lcd_write(0x30+fen/10,1);lcd_write(0x30+fen%10,1);lcd_write(0x8f,0);//指向小时while(s4==0);}}break;}case 2:{lcd_write(0x80+0x45,0);if(s3==0){delayms(5);if(s3==0){alarm_time++;if(alarm_time==10){alarm_time=1;}lcd_write(0x30+alarm_time,1);lcd_write(0x80+0x45,0);//指向小时while(s3==0);}}if(s4==0){delayms(5);if(s4==0){alarm_time--;if(alarm_time==0){alarm_time=9;}lcd_write(0x30+alarm_time,1);lcd_write(0x80+0x45,0);//指向小时while(s4==0);}}break;}case 3:{lcd_write(0x80+0x4c,0);if(s3==0){delayms(5);if(s3==0){reapeat_fen++;if(reapeat_fen==60){reapeat_fen=0;}lcd_write(0x80+0x4b,0);lcd_write(0x30+reapeat_fen/10,1);lcd_write(0x30+reapeat_fen%10,1);lcd_write(0x80+0x4c,0);//指向小时while(s3==0);}}if(s4==0){delayms(5);if(s4==0){reapeat_fen--;if(reapeat_fen==-1){reapeat_fen=59;}lcd_write(0x80+0x4b,0);lcd_write(0x30+reapeat_fen/10,1);lcd_write(0x30+reapeat_fen%10,1);lcd_write(0x80+0x4c,0);//指向小时while(s4==0);}}break;}default:break;}}void main(){PORT_INIT();LCD_INIT();IIC_INIT();time_csh();while(1){switch(s1_scan()){case 0:read_ds1307();display_time();setting_time();break;case 1:setting_naozhong();break;default:break;}} }。
PIC16F877A定时器的学习由于实时数据的仿真需要用到定时器产生数据,今天晚上完成PIC16F877A 产生正弦波形,并将波形数据发送到上位机!这是一个三角波的仿真程序,并通过串口发送到上位机#include #include #include#include “main.h”#include“t232.h”#include“lcd.h”#include“timer.h”//define global variablebank1 uchar flag =0 ;//利用flag 判断中断时间是否到了!bank1 char dat[6] ;bank2 char str[]=“shan dong qing gong ye xue yuan”;bank2 char str1[]=“Starting........”;bank2 char str2[]=“Capturing.......”;bank2 char str3[]=“Stop..........” ;//bank2 float test = 0;//bank2 float t1 ;bank2 uchar t1 =0 ;bank2 uchar t2=0 ;bank1 uchar state = READY ;//当前状态bank1 uchar frame[3] ;//帧缓冲bank1 uchar temp ;//ms 级延时程序void DelayMS(uint ms){ uint i; while(ms--){ for(i=0;i//10us 级延时程序void Delay10US(uint us){ uchar i; for(i=0;iwhile(1) {while((t1>=-20)&&(state==CAPTURE)){t1++ ;sprintf(dat,”(%d)”,t1) ;send_str(dat);if(t1==20)break ;}while((t1}tips:感谢大家的阅读,本文由我司收集整编。
贵港职业学院毕业设计(论文)姓名:覃正杨学号: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)引言现在是一个知识爆炸的新时代。
基于PIC16F877单片机的简易测速计设计方案
0 引言
随着微电子技术的迅猛发展,单片机在汽车、通信、办公自动化、工业控制、高级玩具、家用电器等方面都得到了广泛的应用。
如果将Proteus
作为单片机系统仿真工具,则不用制作电路板,而可以使用Proteus 进行系统虚拟实现,这样不仅能完成所需功能设计验证,还能降低硬件成本的耗用,从而缩短整个设计周期,从根本上提高了电子产品的开发效率。
测速是工农业生产中经常遇到的问题,基于单片机的各种优势,将单片机应用于测速系统,具有很重要的意义。
而对于测速技术,首先要解决的就是采样问题。
在使用模拟技术制作测速设备时,常用测速发电机的方法,即将测速发电机的转轴与待测轴相连,测速发电机的电压高低反映了转速的高低;而使用单片机进行测速,则可以使用简单的脉冲计数法。
只要转轴每旋转一周,产生一个或固定的多个脉冲,并将脉冲送入单片机中进行计数,最终计算出单位时间内的脉冲个数,即可获得转速的相关信息。
本文将基于PIC16F877 单片机的捕捉功能来完成脉冲计数,利用软件编程实现相关物理关系的转换,最终得出齿轮线速度,并显示在数码管上。
#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);//读DS1307 if(A[0]&0x80)DS1307_CSH();//判断是否初始化while(1){clock();set_time();//按键检测delaynms(50);if(flag==0){ READ_DS1307(0,7);//读DS1307 MENU_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模式}}}。
基于pic16f877a单片机的秒表计时器
内蒙古民族大学
草原神鹰工作组
电路组王恒舜2012/12/12
键盘从左至右依次为:开启计时器,一次计时、二次计时,三次计时。
按下左一键开始计时: D 714D 613D 512D 411D 310D 29D 18D 07E 6R W 5R S 4V S S 1V D D 2V E E 3LCD1
LM032L D 714D 613D 512D 411D 310D 29D 18D 07E 6R W 5R S 4V S S 1V D D 2V E E 3LCD1LM032L
D 7
14D 613D 512D 411D 310D 29D 18D 07E
6R W 5R S 4V S S 1V D D 2V E E 3LCD1
LM032L
D 7
14D 613D 512D 411D 310D 29D 18D 07E
6R W 5R S 4V S S 1V D D 2V E E 3LCD1
LM032L
#define RS RC0
#define RW RC1
#define E RC2
uchar const table[]={'0','1','2','3','4','5','6','7','8','9'}; int num,s1,s2,s3,s4,s5,s6,a,b,c,n,i;
void LCD_write_command(uchar dat);
void LCD_write_data(uchar dat);
void LCD_disp_char(uchar x,uchar y,uchar dat); void delay(uint x);
void init();
void main()
{
TRISB=0;
PORTB=0X07;
i=0;
if(RB0==0)
{
init();
delay(10);
while(RB0)
{
if(num>=58)
{
num=0;
n++;
c=n/3600;
s5=c/10;
s6=c%10;
a=n%3600/60;
s1=a/10;
s2=a%10;
b=n%60;
s3=b/10;
s4=b%10;
LCD_disp_char(0,1,'3');
LCD_disp_char(2,1,table[s1]);
LCD_disp_char(3,1,table[s2]);
LCD_disp_char(4,1,':');
LCD_disp_char(5,1,table[s3]);
LCD_disp_char(6,1,table[s4]);
LCD_disp_char(7,1,'s');
}
if(RB1==0&&i==0)
{
i=1;
LCD_disp_char(0,0,'1');
LCD_disp_char(2,0,table[s1]);
LCD_disp_char(3,0,table[s2]);
LCD_disp_char(4,0,':');
LCD_disp_char(5,0,table[s3]);
LCD_disp_char(6,0,table[s4]);
LCD_disp_char(7,0,'s');
}
if(RB1==0&&i==1)
{
i=1;
LCD_disp_char(10,0,'2');
LCD_disp_char(12,0,table[s1]);
LCD_disp_char(13,0,table[s2]);
LCD_disp_char(14,0,':');
LCD_disp_char(15,0,table[s3]);
LCD_disp_char(16,0,table[s4]);
LCD_disp_char(17,0,'s');
}
if(RB2==0) while(RB0);
}
}
}
void init()
{
TRISC=0;
TRISD=0;
PORTD=0;
LCD_write_command(0x38);//设置格式
LCD_write_command(0x0c);//整体显示关光标不闪烁?
LCD_write_command(0x06);//设置输入方式,增量不够移位?
LCD_write_command(0x01);//清屏?
OPTION_REG=0X07;//设置预分为1:256
INTCON=0Xa0;//开启TMR0中断
TMR0=57;//TMR0寄存器预存57
}
void interrupt time0()//中断
{
T0IF=0;
TMR0=57;
num++;
}
void LCD_write_data(uchar dat)
{
RS=1;
RW=0;
PORTD=dat;
E=1;
E=0;
delay(10);
}
void LCD_write_command(uchar dat)
{
RS=0;
RW=0;
PORTD=dat;
E=1;
E=0;
delay(10);
}
void LCD_disp_char(uchar x,uchar y,uchar dat) {
uchar address;
if(y==1)
address=0x80+x;
else
address=0xc0+x;
LCD_write_command(address);
LCD_write_data(dat);
}
void delay(uint x)
{
int a,b;
for(a=x;a>0;a--)
for(b=110;b>0;b--);
}。