《2022年PICFA万历程序2.docx》由会员分享,可在线阅读,更多相关《2022年PICFA万历程序2.docx(54页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、PIC16F877A万年历程序时间:2021-03-05来源:作者:Wujieflash点击: 1581字体大小 :【大中小 】为了把 KS0108 系列的液晶吃透 , 特殊制作了这款万年历 , 感觉成效仍是不错的 .期望大家共享我的欢乐,究竟有了更多志同道合的伴侣支持, 我才能更进一步提高 .一, 原理介绍说明 :1. 单片机仍是采纳 PIC 中最经典的 PIC16F877A, 端口多 ,功能全 , 特殊是他有 8K 的 ROM,这是我挑选的主要缘由 ,由于储存液晶的字库需要很大的空间.2. 液晶显示仍是用的KS0108 系列,主要是他性价比高 ,指令简洁 ,特殊是公司也在用.3. 时钟 /
2、日历芯片用的 DALLOS 的 DS1302 芯片 , 他可以储存从2000-2099年的日历 , 及实时时钟 ,可以便利的读写 .4. 温度测量仍是用的DS18B20, 这在我上一实例中已经用过, 有爱好可以查阅 .5. 本万年历可以显示实时时钟,精确到秒 ,年, 月,日, 星期 ,阴历 ,温度, 生肖等 , 显示的信息量大 . 6, 可以通过按键自由设定时钟及日历, 按设置 键可以在秒 ,分, 时,日, 月,星期 ,年之间来回切换, 要设置的单元以闪耀提示. 通过 +.-按键可以把要设置的单元设定到预想状态.54 / 29二, 程序说明 :本程序有很多小的模块,现分列如下 :1. 主程序/
3、* 标题:万年历* 作者: Wujieflash* 日期: 2021 年 1 月 13 日* 说明:包含文件*/ #include#include ziku.h #include lcd_init.h #include ds1302.h #include ds18b20.h #include keyscan.h #include yinli.h/ 子程序/LCD 显示空白边框子程序void LCDShowTableuch i ;SlectScreen1;/写左半屏SetLine0 ;/起使页SetColumn0;/起使列fori=0;i/ 显示固定字符子程序void LCDShowGuding
4、WordShow8X16_20,24,s0;Show8X16_20,32,s0;Show8X162,1,s0;Show8X162,9,s0;Show16X16_36,40,ri ;Show16X322,24,ss0 ;Show16X322,40,ss0 ;Show8X16_20,64,s0 ;Show8X16_20,72,s0 ;Show8X16_20,80,maohao;Show8X16_20,88,s0;Show8X16_20,96,s0;Show8X16_20,104,maohao;Show8X16_20,112,s0;Show8X16_20,119,s0;Show8X162,80,s0
5、;Show8X162,88,s0;Show16X16_24,64,shiyi;Show16X16_24,80,yue;Show16X16_24,95,chu;Show16X16_24,111,yi;Show16X16_36,72,sheng;Show16X16_36,88,xiao;Show16X16_36,104,shu;Show16X16_20,40,nian;Show16X164,2,yue;Show16X16_36,8,xing;Show16X16_36,24,qi;Show16X162,96,danwei1;Show8X16_20,8,s2;Show8X16_20,16,s0;/*-
6、*/TRM1 初始化子程序void TMR1init/TRM1 INITIALT1CON=0X30;/8分频TMR1IF=0;/清中断标志TMR1IE=1;/使能定时器1 中断TMR1L=0XDB ;/初始值(定时 0.5S ) TMR1H=0X0B ;TMR1ON=1 ;/开定时器 1/ 冒号闪耀子程序void FlashMaohaostatic uch timecount=0;ifTMR1IF=1TMR1ON=0 ;TMR1IF=0 ;TMR1L=0XDB ;/重新付初值TMR1H=0X0B;flag+;flag=flag%2;/ 闪耀标志在 0-1 间翻转TMR1ON=1;timecou
7、nt+;iftimecount=120/1分钟采样一次温度timecount=0;get_temp; / 温度转换子程序ifflag=0Show8X16_20,80,maohao;Show8X16_20,104,maohao;ifflag=1Show8X16_20,80,noshu;/ 清除Show8X16_20,104,noshu;/ 主程序void mainTMR1init ;/定时器 1 初始化keyinit ;/键盘初始化LCDinit ;/LCD操作初始化LCDShowTable ;/显示空白表格LCDShowGudingWord; / 显示固定字符/Set1302DisCash;/
8、 设置初始时间(默认写入我写程序的时间)get_temp;/读取温度while1v_Get1302clock; / 读取时间、日历display ;YangToYinclock6/16*10+clock6&0x0f,clock4/16*10+clock4&0x0f,clock3/16*1 0+clock3&0x0f;FlashMaohao;/冒号闪耀KeyScan ;/键盘扫描2. 测温程序 :/* 标题: DS18B20 测温* 作者: Wujieflash* 日期: 2021 年 1 月 13 日* 说明:使用 DS18B20 芯片测温*/# define DQ RC3/定义 18B20
9、数据端口# define DQ_DIR TRISC3/定义 18B20D 口方向寄存器# define DQ_HIGH DQ_DIR =1/设置数据口为输入# define DQ_LOW DQ = 0; DQ_DIR = 0/设置数据口为输出unsigned char TLV=0;/采集到的温度高 8 位unsigned char THV=0;/采集到的温度低 8 位unsigned char TZ=0;/转换后的温度值整数部分/-/ 延时函数/ 系统初始化函数void initADCON1=0X07 ;/设置 A 口为一般数字口TRISA=0X00;/设置 A 口方向为输出/TRISC3=0
10、;/设置 D 口方向为输出/-/ 复位 DS18B20 函数resetvoidchar presence=1;whilepresenceDQ_LOW;/主机拉至低电平delay2,90;/延时 503usDQ_HIGH;delay2,8;/释放总线等电阻拉高总线,并保持 1560us延时 70usifDQ=1 presence=1;/没有接收到应答信号,连续复位else presence=0;/接收到应答信号delay2,70;/延时 430us/-/ 写 18b20 写字节函数void write_byteuch valuch i ;uch temp ;fori=8;i0 ;i-temp=v
11、al&0x01;DQ_LOW ;/最低位移出NOP ;NOP ;NOP ;NOP ;NOP ;/从高拉至低电平 , 产生写时间隙iftemp=1 DQ_HIGH;/假如写 1, 拉高电平delay2,7;/延时 63usDQ_HIGH;NOP ;NOP ;val=val1;/右移一位/-/18b20读字节函数uch read_bytevoiduch i ;uch value=0;/读出温度static bit j;fori=8;i0 ;i-value=1 ;DQ_LOW ;NOP ;NOP ;NOP ;NOP ;/6usDQ_HIGH;/拉至高电平NOP ;NOP ;NOP ;/4usj=DQ
12、 ;ifj value|=0x80;delay2,7;/63usreturnvalue;/-/ 启动温度转换函数void get_tempint i ;DQ_HIGH ;reset ;/复位等待从机应答write_byte0XCC;/忽视 ROM 匹配write_byte0X44;/发送温度转化命令fori=10 ; i0 ;i-delay201,132;/调用多次推迟函数,确保温度转换完成所需要的时间reset ;/再次复位,等待从机应答write_byte0XCC;/忽视 ROM 匹配write_byte0XBE;/发送读温度命令TLV=read_byte;/读出温度低 8THV=read
13、_byte;/读出温度高 8 位DQ_HIGH ;/释放总线TZ=TLV4|THV0 ; i-IO = d&0x01;/取最低位SCLK = 1;/上升沿发送SCLK = 0;/复原d = d 1;/从 1302 读取 1Byte 数据 / uch RTOutputBytevoiduch i,val=0;TRISC2=1;/设置为输入fori=8; i0 ; i-val = val 1;ifIOval=val|0x80;/ 从最低位开头接收SCLK = 1;/下降沿接收SCLK = 0;returnval;/先写地址,后写命令 / 数据/ void W1302uch ucAddr, uch u
14、cDaRST = 0;SCLK = 0 ;RST = 1;/打开 DS1302 RTInputByteucAddr;/ /*地址,命令 */ RTInputByteucDa;/ /*写 1Byte 数据 */ SCLK = 1 ;RST = 0;/关闭 DS1302/先写地址,后读命令 / 数据/ uch R1302uch ucAddruch ucData;RST = 0;SCLK = 0 ;RST = 1;RTInputByteucAddr;/ /*地址,命令 */ucData = RTOutputByte;/ /*读 1Byte 数据 */ SCLK = 1 ;RST = 0;return
15、ucData;/向 1302 写入 秒 分 时 日 月 星期 年 */ void Set1302uch *pClockuch i ;uch ucAddr = 0x80;/起使地址W13020x8e,0x00;/*掌握命令 ,WP=0, 答应写操作 */ fori =7; i0 ; i-W1302ucAddr,*pClock; /*秒 分 时 日 月 星期 年 */ pClock+;ucAddr +=2;/写地址加 2W13020x8e,0x80;/ /*掌握命令 ,WP=1, 写爱护 */从 1302 读出 秒 分 时 日 月 星期 年 */ void v_Get1302unsigned ch
16、ar ucCurtimeunsigned char i;unsigned char ucAddr = 0x81;fori=0 ;i/与 LCD 的显示接口 / void displayuch i ;fori=0;i4. 按键扫描与服务程序/* 标题:按键扫描和服务* 作者: Wujieflash* 日期: 2021 年 1 月 17 日* 说明:当按键按下,选中的单元就会闪耀*/ uch k=0 ;/ 键盘初始化子程序void keyinitTRISD0=1 ;TRISD0=1 ;TRISD0=1 ;/*-*/ 键盘扫描子程序void KeyScanint d ;ifRD0=0 /设置键按下k
17、+ ; / 选定入口值k=k%8;while1ifRD0=1break;/ 等待按键松开switchk/键盘服务入口case 1:/设置秒d=R13020x81;/ 读取秒d=d/16*10+d%16;/ 转换为 16 进制second=flag; / 设置秒的闪耀标志minute=1;/其余变量不闪耀hour=1;year=1;month=1;date=1;day=1 ;ifsecond=0 /闪耀Show8X16_20,111,noshu;Show8X16_20,119,noshu;ifRD1=0/秒数值加 1d+;ifd0x3bd=0;/ 大于 59 就为 0 d=d/10*16+d%1
18、0;W13020x80,d;/ 写入 DS1302while1ifRD1=1break;/ 等待键松开ifRD2=0/数值减 1d- ;ifd0x3bd=0;d=d/10*16+d%10;W13020x82,d;while1ifRD1=1break; ifRD2=0d- ;ifd0x17d=0;d=d/10*16+d%10;W13020x84,d;while1ifRD1=1break;ifRD2=0d- ;ifd0x1fd=1;d=d/10*16+d%10;W13020x86,d;while1ifRD1=1break; ifRD2=0d- ;ifd0x0cd=1;d=d/10*16+d%10;
19、W13020x88,d;while1ifRD1=1break; ifRD2=0d- ;ifd0x07d=1;d=d/10*16+d%10;W13020x8a,d;while1ifRD1=1break; ifRD2=0d- ;ifd0x63d=0;d=d/10*16+d%10;W13020x8c,d;while1ifRD1=1break; ifRD2=05. 液晶显示程序/* 标题: LCD 操作* 作者: Wujieflash* 日期: 2021 年 1 月 12 日* 说明: KS0108 系列液晶不带字库*/ #include#define ERA0/液晶使能端#define RWRA1/
20、读写掌握端#define DIRA2/数据 / 指令通道#define CSA RA5/片选 #define CSB RA3/片选#define nop asmnop/基本子函数 / 延时void delaychar x,char ychar z ;doz=y;do;while-z;while-x;/ 其指令时间为: 7+ ( 3* ( Y-1 ) +7 ) * ( X-1 )假如再加上函数调用的call 指令、页面设定、传递参数花掉的7 个指令;/ 就是: 14+ (3* ( Y-1 )+7 )* ( X-1);/-void LCDdelayunsigned int i=500;whilei
21、- ;/*-*/ 状态检查void CheckStateunsigned int dat;RW=1 ;DI=0 ;TRISB=0xff;/读状态设置口为输入while1E=1 ;/高电平读数据dat=PORTB&0x90 E=0 ;ifdat=0x00break;/当 4、7 位为 0 时为正常状态TRISB=0x00 ;/复原口为输出/*-*/ 写显示数据/dat: 显示数据void WriteDataunsigned char datCheckState ;DI=1 ;/写数据RW=0 ;PORTB=dat ;E=1 ;E=0 ;/*-*/ 写指令/command:操作 LCD 的指令vo
22、id WriteCommandunsigned char datCheckState ;RW=0 ;/写指令PORTB=dat ;E=1 ;E=0 ;/*-*/ 设定页地址0-7void SetLineunsigned char lineline=line&0x07;/0/ 设定列地址 -Y:0 63void SetColumnunsigned char columncolumn=column&0x3f;/0/ 设定开头行void SetStartLineunsigned char startlinestartline=startline&0x3f; /0/ 开关显示/1: 开显示 0: 关显
23、示void SetOnOffunsigned char statestate=state|0x3e;WriteCommandstate;/*-*/ 挑选屏幕/screen: 1:左屏 2: 右屏void SlectScreenunsigned char screenswitchscreencase 1: CSA=0 ;CSB=1 ;/ 左屏break ;case 2: CSA=1 ;CSB=0 ;/ 右屏break ;/*-*/ 清屏/screen: 1:左屏 2: 右屏void ClearScreenunsigned char screenunsigned char i,j;SlectScr
24、eenscreen;fori=0;i/ 显示一个 16X16 的汉字void Show16X16unsigned char line,unsigned char column,const unsigned char *ptunsigned char i,column_temp;column_temp=column;SlectScreen1;/选通左屏SetColumncolumn;/设置起始列SetLineline;/设置行fori=0;i=64/假如列 =64 ,就选通右屏SlectScreen2;column=column%64;/设置右屏起始列SetColumncolumn;SetLin
25、eline;WriteData*pt;/写数据*pt+;/column+;SlectScreen1;SetLineline+1;/设置汉字下半部分显示页column=column_temp;SetColumncolumn;fori=0;i=64SlectScreen2;column=column%64;SetColumncolumn;SetLineline+1;WriteData*pt;*pt+;column+;/*-*/ 显示一个 16X16 的汉字带上划线void Show16X16_2unsigned char line,unsigned char column,const unsign
26、ed char *ptunsigned char i,column_temp;column_temp=column;SlectScreen1;/选通左屏SetColumncolumn;/设置起始列SetLineline;/设置行fori=0;i=64/假如列 =64 ,就选通右屏SlectScreen2;column=column%64;/设置右屏起始列SetColumncolumn;SetLineline;WriteData*pt|0x01;/写数据*pt+;column+;SlectScreen1;SetLineline+1;/设置汉字下半部分显示页column=column_temp;S
27、etColumncolumn;fori=0;i=64SlectScreen2;column=column%64;SetColumncolumn;SetLineline+1;WriteData*pt;*pt+;column+;/*-*/ 显示一个 16X16 的汉字带下划线void Show16X16_3unsigned char line,unsigned char column,const unsigned char *ptunsigned char i,column_temp;column_temp=column;SlectScreen1;/选通左屏SetColumncolumn;/设置起
28、始列SetLineline;/设置行fori=0;i=64/假如列 =64 ,就选通右屏SlectScreen2;column=column%64;/设置右屏起始列SetColumncolumn;SetLineline;WriteData*pt;/写数据*pt+;column+;SlectScreen1;SetLineline+1;/设置汉字下半部分显示页column=column_temp;SetColumncolumn;fori=0;i=64SlectScreen2;column=column%64;SetColumncolumn;SetLineline+1;WriteData*pt|0x
29、80;*pt+;column+;/*-*/ 显示一个 8X16 的字符void Show8X16unsigned char line,unsigned char column,const unsigned char *ptunsigned char i,column_temp;column_temp=column;SlectScreen1;/选通左屏SetColumncolumn;/设置起始列SetLineline;/设置行fori=0;i=64/假如列 =64 ,就选通右屏SlectScreen2;column=column%64;/设置右屏起始列SetColumncolumn;SetLin
30、eline;WriteData*pt;/写数据*pt+;column+;SlectScreen1;SetLineline+1;/设置汉字下半部分显示页column=column_temp;SetColumncolumn;fori=0;i=64SlectScreen2;column=column%64;SetColumncolumn;SetLineline+1;WriteData*pt;*pt+;column+;/*-*/ 显示一个 8X16 的字符带上划线void Show8X16_2unsigned char line,unsigned char column,const unsigned
31、char *ptunsigned char i,column_temp;column_temp=column;SlectScreen1;/选通左屏SetColumncolumn;/设置起始列SetLineline;/设置行fori=0;i=64/假如列 =64 ,就选通右屏SlectScreen2;column=column%64 SetColumncolumn SetLineline ;/设置右屏起始列WriteData*pt|0x01*pt+;column+;/写数据SlectScreen1;SetLineline+1;/设置汉字下半部分显示页colu mn=column_temp;SetColumncolumn;fori=0;i=64SlectScreen2;column=column%64;SetColumncolumn;SetLineline+1;WriteData*pt;*pt+;column+;/*-*/ 显示一个 16X32 的字符void Show16X32unsigne