带字库12864 串口 时钟显示

合集下载

51单片机+带字库液晶12864+DS1302数字时钟C源程序(无按键修改功能)

51单片机+带字库液晶12864+DS1302数字时钟C源程序(无按键修改功能)

51单片机+带字库液晶12864+DS1302数字时钟C源程序(无按键修改功能)2009-10-19 16:47经过两天的搜索与调试,在别人程序的基础上,不断修改,终于调试成功了这个程序。

目前还不能修改时间与日期,只是以预定时间以始。

适用于开发板:51单片机(AT89S52)+带字库液晶12864(ST7920)+DS1302(实时时钟)实现功能:简单,数字时钟+日期(以后会不断完美)。

C语言源程序如下:#include <reg52.h>#include <intrins.h>#define uchar unsigned char#define uint unsigned int/*DS1302 端口设置 */sbit SCK=P3^6; //DS1302时钟sbit SDA=P3^4; //DS1302 IOsbit RST = P3^5; // DS1302复位bit ReadRTC_Flag; //读DS1302全局变量/* 12864端口定义*/#define LCD_data P0 //带字库液晶12864数据口sbit LCD_RS = P2^4; //寄存器选择输入sbit LCD_RW = P2^5; //液晶读/写控制sbit LCD_EN = P2^6; //液晶使能控制sbit PSB=P2^1; //并口控制sbit RES=P2^3;uchar code dis1[] = {" 电子设计天地"}; //液晶显示的汉字uchar code dis2[] = {"有志者,事竟成!"};uchar code dis4[] = {'0','1','2','3','4','5','6','7','8','9'}; unsigned char temp;#define delayNOP(); {_nop_();_nop_();_nop_();_nop_();};void lcd_pos(uchar X,uchar Y); //确定显示位置unsigned char l_tmpdate[7]={0,7,16,19,10,1,9};//秒分时日月周年09-10-19 16:07:00code unsigned charwrite_rtc_address[7]={0x80,0x82,0x84,0x86,0x88,0x8a,0x8c}; //秒分时日月周年最低位读写位code unsigned charread_rtc_address[7]={0x81,0x83,0x85,0x87,0x89,0x8b,0x8d};void Write_Ds1302_byte(unsigned char temp);void Write_Ds1302( unsigned char address,unsigned char dat ); unsigned char Read_Ds1302 ( unsigned char address );void Read_RTC(void);//read RTCvoid Set_RTC(void); //set RTCvoid InitTIMER0(void);//inital timer0/*******************************************************************/ /* */ /* 延时函数 */ /* */ /*******************************************************************/void delay(unsigned int m) //延时程序{unsigned int i,j;for(i=0;i<m;i++)for(j=0;j<10;j++);}/*******************************************************************/ /* */ /*检查LCD忙状态 *//*lcd_busy为1时,忙,等待。

12864zk红外遥控数字时钟

12864zk红外遥控数字时钟

/*---------------------------------------------------------------------------红外遥控多功能数字时钟程序单片机:STC89C52RC晶振:12MHz时钟芯片:DS1302液晶屏:LCM-12864-ST7920功能描述: 大数字显示时间;能显示农历、温度和设置闹铃;有整点报时功能红外遥控和按键都能设置时间和闹铃说明:LCM12864使用并口连接方式,PSB、RST接高电平------------------------------------------------------------------------------*//*-------------------------------头文件---------------------------------------*/#include <reg52.h>#include <intrins.h>#include "LCD12864.h"#include "DS1302.h"#include "DS18B20.h"#include "nongli.h"#include "displaytime.h"#include "zk.h"#include "bell.h"#include "HW.H"#include "delay.h"#define uint unsigned int#define uchar unsigned char/*--------------------定义按键-----------------------------------------------*/sbit K1 = P1^0; //K1-设置sbit K2 = P1^1; //K2-确认、返回sbit K3 = P1^2; //K3-加sbit K4 = P1^3; //K4-减//K5=P1^4,K5-控制闹钟的打开与关闭,在"hw.h"中定义/*---------------------函数声明------------------------------*/void ds_w0(void);void ds_w(void);void Conver_week(bit c,uchar year,uchar month,uchar day);/*-----------------------------定义全局变量------------------------------*/bit w=0; //调时标志位unsigned char yy,mo,dd,xq,hh,mm,ss,month_moon,day_moon,week,tiangan,dizhi,moontemp1,moontemp2;//定义时间映射全局变量(专用寄存器)signed char address,item,item0,max,mini;unsigned char clk_ala[2]={0x00,0x00};//闹钟数据存放初,始值为00:00unsigned char hour,minute,time;//用于闹铃的设置/*-----------------------------日期、时间设置函数-----------------------------*/void tiaozheng(void){yy = read_clock(0x8d);//调用1302时钟数据中的年数据,从地址0x8d中mo = read_clock(0x89);//调用1302时钟数据中的月数据,从地址0x89中dd = read_clock(0x87);//从1302芯片中读取日数据,从地址0x87中week = read_clock(0x8b);//从1302芯片中读取星期数据,从地址0x8b中//----------------------------------lcm_w_test(0,0x80);lcm_w_word("20");//显示内容字符20lcm_w_test(1,(yy/16)+0x30);//函数参数1,代表本行写数据,YY/16+0X30得出年十位数字的显示码地址,送显示lcm_w_test(1,yy%16+0x30);//函数lcm_w_word("年");//----------------------------------lcm_w_test(1,(mo/16)+0x30);lcm_w_test(1,mo%16+0x30);//与16取余数,得到月份的个位数,加0x30得到该数字的液晶内定显示码送显示lcm_w_word("月");//调用字符显示函数,显示文字月//----------------------------------/*lcm_w_test(0,0x88);//第一个参数0,表示本行写入LCM的是指令,指定显示位置88H (第三行左端)lcm_w_word("星期");//调用字符显示函数,显示文字星期lcm_w_test(1,mo%16+0x30);//与16取余数,得到月份的个位数,加0x30得到该数字的液晶内定显示码送显示*///----------------------------------lcm_w_test(1,(dd/16)+0x30);lcm_w_test(1,dd%16+0x30);//第一个1参数,表示本行写数据,日数据与16取余得个位数,加0x30得到显示码lcm_w_word("日");//显示字符日//----------------------------------if(read_clock(0x85) != hh){//如果程序中的小时与1302芯片中的不同,hh = read_clock(0x85);//刷新程序中的小时数据}lcm_w_test(0,0x91);//第一个参数0,表示本行写入LCM的是指令,指定显示位置88H (第三行左端)lcm_w_test(1,(hh/16)+0x30);//显示十位lcm_w_test(1,hh%16+0x30);//显示个位lcm_w_word("时");//----------------------------------if(read_clock(0x83) != mm){//如果1302芯片中的分钟数据与程序中的分钟变量不相等mm = read_clock(0x83);//刷新程序中的分钟数据}lcm_w_test(1,(mm/16)+0x30);//向液晶写数据,显示分钟的十位数lcm_w_test(1,mm%16+0x30);//向液晶写数据,显示分钟的个位数lcm_w_word("分");//----------------------------------if(read_clock(0x81) != ss){//如果1302芯片中的分钟数据与程序中的秒钟变量不相等(0x81为读秒数据0x80为写秒数据)ss = read_clock(0x81);//刷新程序中的秒钟数据}lcm_w_test(1,(ss/16)+0x30);//向液晶写数据,显示分钟的十位数lcm_w_test(1,ss%16+0x30);//向液晶写数据,显示分钟的个位数lcm_w_word("秒");////////////////////////////////////////////////////////////////////////=========显示闹钟的设置时间===================hour=clk_ala[0]; //取出上一次的闹钟小时值minute=clk_ala[1]; //取出上一次的闹钟分钟值lcm_w_test(0,0x88);lcm_w_word("闹钟---");//----------------------------lcm_w_test(1,(hour/10)+0x30);//显示小时十位lcm_w_test(1,(hour%10)+0x30);//显示小时个位//----------------------------lcm_w_word(":");//----------------------------lcm_w_test(1,(minute/10)+0x30);//显示分钟的十位lcm_w_test(1,(minute%10)+0x30);//显示分钟的个位//----------------------------lcm_w_word("----");}/*****************************************************************************/ //被调数据加一或减一,并检查数据范围,写入1302指定地址保存void ds_w(void){item0=time;item=((read_clock(address+1))/16)*10 + (read_clock(address+1))%16;//时间的调整if(K3 == 0||key_add==1){//如果按动上调键item++;//数加1}if(K4 == 0||key_minish==1){//如果按动下调键item--;//数减1}if(item>max) item=mini;//查看数值是否在有效范围之内if(item<mini) item=max;//如果数值小于最小值,则自动等于最大值write_clock(0x8e,0x00);//允许写1302芯片操作write_clock(address,(item/10)*16+item%10);//转换成16进制写入1302write_clock(0x8e,0x80);//写保护,禁止写操作}/********************************************************************///===============闹钟时间的加减设置======================void ds_w0(void){item0=time;if(K3 == 0||key_add==1){//如果按动上调键item0++;//数加1}if(K4 == 0||key_minish==1){//如果按动下调键item0--;//数减1}if(item0>max) item0=mini;//查看数值是否在有效范围之内if(item0<mini)item0=max;//如果数值小于最小值,则自动等于最大值time=item0;//调整后的时间重新赋值给time(time为hour或minute),这步很重要,没有将无法更新闹钟数据}/****************************************************************************** ****************************///调整时间子函数,设置键、数据范围、上调加一,下调减一功能。

12864点阵LCD液晶屏带中文字库

12864点阵LCD液晶屏带中文字库

功能
令 RS R/W D7 D6 D5 D4 D3 D2 D1 D0
待命
进入待命模式,执行其他指令都棵终止
0 0 0 0000001
模式
待命模式
卷动地 SR=1:允许输入垂直卷动地址
址开关 0 0 0 0 0 0 0 0 1 SR SR=0:允许输入 IRAM 和 CGRAM 地址
开启
反白
选择 2 行中的任一行作反白显示,并可决定反白与否。初始值 R1R
0 0 0 0 0 0 0 1 R1 R0
选择
0=00,第一次设定为反白显示,再次设定变回正常
睡眠
SL=0:进入睡眠模式
0 0 0 0 0 0 1 SL X X
模式
SL=1:脱离睡眠模式
CL=0/1:4/8 位数据 扩充
RE=1: 扩充指令操作 功能 0 0 0 0 1 CL X RE G 0
RE=0: 基本指令操作 设定
示移位控 0 0 0 0 0 1 S/C R/L X X RAM 的内容

DL=0/1:4/8 位数据 功能
0 0 0 0 1 DL X RE X X RE=1: 扩充指令操作 设定
RE=0: 基本指令操作
设定 CG
RAM
0 0 0 1 AC5 AC4 AC3 AC2 AC1 AC0 设定 CGRAM 地址
G=1/0:绘图开关
设定
设定绘图 RAM
绘图 RA
0 0 0 AC3 AC2 AC1 AC0 先设定垂直(列)地址 AC6AC5…AC0
001
M
AC6 AC5 AC4 AC3 AC2 AC1 AC0 再设定水平(行)地址 AC3AC2AC1AC0
地址
将以上 16 位地址连续写入即可

带中文字库的12864lcd显示程序

带中文字库的12864lcd显示程序
uint i, j; for(i = a; i > 0; i--)
for(j = 100; j > 0; j--); }
// 检测 LCD是否处于忙状态 , 若忙返回 1, 空闲返回 0 bit checkBusy() { bit busy;
RS = 0; RW = 1; E = 1; delayUs(); busy = (bit)(LCD_DATA&0x80); E = 0; return busy; }
1
文档来源为 :从网络收集整理 .word 版本可编辑 .欢迎下载支持 .
// 等待 LCD到空闲 void wait() {
while(checkBusy()); }
// 写命令 void writeCmd(uchar cmd) {
wait(); RS = 0; RW = 0; E = 0; delayUs(); LCD_DATA = cmd; delayUs(); E = 1; delayUs(); E = 0; }3ຫໍສະໝຸດ delayMs(10); }
void setPosition(uchar x, uchar y) { uchar p;
switch(x%4) {
case 0: p = 0x80; break; // case 1: p = 0x90; break; // case 2: p = 0x88; break; // case 3: p = 0x98; break; // } p += y; writeCmd(p); }
PSB = 1; // 并口方式 writeCmd(0x30); // 基本指令 , 扩充指令为 34H delayMs(10); writeCmd(0x0c); // 显示开 , 关光标 delayMs(10); writeCmd(0x01); // 清屏

12864时钟显示程序

12864时钟显示程序

/************12864时钟显示函数*************//******实现时间走动、按键控制、蜂鸣器闹铃******/#include<reg52.h>#define uchar unsigned char //宏定义#define uint unsigned int //宏定义sbit rs=P0^7;sbit rw=P0^6;sbit en=P0^5;sbit beet=P0^4; //蜂鸣器定义sbit key1=P3^5; //功能选择sbit key2=P3^4; //至加sbit key3=P3^3; //至减char hour=23;char minute=59;char second=46;int years=2012;char month=12;char day=30;uchar count=0;char mm;char cc;uchar code table1[]={"创新工作室"};uchar code table2[]={" 应用电子"};/*************************延时函数****************************/ void delay(uint z){uint x,y;for(x=z;x>0;x--)for(y=110;y>0;y--);}/*********地址初始化*************/void xieling_shu(uchar aa,uchar bb){if(aa==1){rs=0;}if(aa==0){rs=1;}rw=0;P2=bb;delay(1);en=1;delay(1);en=0;delay(1);}/***********************液晶12864写入地址*********************/ void xieludizhi(uchar x, uchar y){switch(x){case 1:xieling_shu(1,0x80 + y ); return;//return 返回的意思case 2:xieling_shu(1,0x90 + y ); return;case 3:xieling_shu(1,0x88 + y ); return;case 4:xieling_shu(1,0x98 + y ); return;}}/**********************液晶12864写入字符串********************/ void xiezifuchuan(uchar *dd){while(*dd != '\0'){xieling_shu(0,*dd++ );}}/********************** 液晶12864清屏函数*********************/ void qingping(){xieling_shu(1,0x01); //清屏xieling_shu(1,0x01); //清屏xieling_shu(1,0x01); //清屏delay(20);}/********************液晶12864初始化显示函数******************/ void init_12864(){ mm=0;cc=7; //选择星期初始化xieling_shu(1,0x30); //基本指令操作xieling_shu(1,0x30); //基本指令操作xieling_shu(1,0x0C); //0x0c: 无光标,OXOF: 光标反白显示xieling_shu(1,0x01); //清屏xieling_shu(1,0x06);}/******************* 液晶12864初始化字串显示******************/ void init_zifu(){//qingping();xieludizhi(1,0);xiezifuchuan(table1); //delay(1);xieludizhi(4,0);xiezifuchuan(table2); //delay(1);xieludizhi(3,0);xieling_shu(0,0x30+hour/10);xieling_shu(0,0x30+hour%10);xieling_shu(0,':');xieling_shu(0,0x30+minute/10);xieling_shu(0,0x30+minute%10);xieling_shu(0,':');xieling_shu(0,0x30+second/10);xieling_shu(0,0x30+second%10);xieludizhi(3,5);xiezifuchuan("星期");xieludizhi(2,0);xieling_shu(0,0x30+years/1000);xieling_shu(0,0x30+years%1000/100);xieling_shu(0,0x30+years%100/10);xieling_shu(0,0x30+years%10);xiezifuchuan("年");xieling_shu(0,0x30+month/10);xieling_shu(0,0x30+month%10);xiezifuchuan("月");xieling_shu(0,0x30+day/10);xieling_shu(0,0x30+day%10);xiezifuchuan("日");}/***************星期函数***************/void xingqi(){switch(cc){case 1: xieludizhi(3,7); xiezifuchuan("一"); return;case 2: xieludizhi(3,7); xiezifuchuan("二"); return;case 3: xieludizhi(3,7); xiezifuchuan("叁"); return;case 4: xieludizhi(3,7); xiezifuchuan("四"); return;case 5: xieludizhi(3,7); xiezifuchuan("五"); return;case 6: xieludizhi(3,7); xiezifuchuan("六"); return;case 7: xieludizhi(3,7); xiezifuchuan("日"); return;}}/***************按键程序***************/void anjian(){if(key1==0) //key1按键选择功能{ mm++;delay(1);if(mm==1){xieludizhi(3,3);xieling_shu(0,0x5f);}if(mm==2){TR0=1;xieludizhi(3,2);xieling_shu(0,0x5f);}if(mm==3){xieludizhi(3,0);xieling_shu(0,0x5f);}if(mm==4){xieludizhi(2,5);xieling_shu(0,0x5f);}if(mm==5){xieludizhi(2,3);xieling_shu(0,0x5f);}if(mm==6){xieludizhi(2,1);xieling_shu(0,0x5f);}if(mm==7){xieludizhi(3,5);xieling_shu(0,0x5f);}if(mm==8){xieludizhi(2,7);xieling_shu(0,0x02);}if(mm==9){xieludizhi(2,7);xieling_shu(1,0x01);mm=0;}} //key2按键控制if(mm==1&&key2==0) //秒加1{TR0=0;delay(1);if(key2==0){second++;if(second==60){second=0;}}}if(mm==1&&key3==0) //秒减1{TR0=0;delay(1);if(key3==0){second--;if(second==-1){second=59;}}}if(mm==2&&key2==0) //分加1 { delay(1);if(key2==0){minute++;if(minute==60){minute=0;}}}if(mm==2&&key3==0) //分减1 { delay(1);if(key3==0){minute--;if(minute==-1){minute=59;}}}if(mm==3&&key2==0) //时加1 { delay(1);if(key2==0){hour++;if(hour==24){hour=0;}}}if(mm==3&&key3==0) //时减1 { delay(1);if(key3==0){hour--;if(hour==-1){hour=23;}}}if(mm==4&&key2==0) //日加1 { delay(1);if(key2==0){day++;if(day==31){day=1;}}}if(mm==4&&key3==0) //日减1 { delay(1);if(key3==0){day--;if(day==0){day=30;}}}if(mm==5&&key2==0) //月加1 { delay(1);if(key2==0){month++;if(month==13){month=1;}}}if(mm==5&&key3==0) //月减1 { delay(1);if(key3==0){month--;if(month==0){month=12;}}}if(mm==6&&key2==0) //年加1 { delay(1);if(key2==0){years++;}}if(mm==6&&key3==0) //年减1 { delay(1);if(key3==0){years--;}}if(mm==7&&key2==0) //星期加1 { delay(1);if(key2==0){cc++;if(cc==8){cc=1;}}}if(mm==7&&key3==0) //星期减1 { delay(1);if(key3==0){cc--;if(cc==0){cc=7;}}}}/***************************定时器函数************************/void init_t0_t1() //定时器t0,t1初始化函数{TMOD=0x11;EA=1;ET0=1;TR0=1; //开启中断TH0=(65536-50000)/256;TL0=(65536-50000)%256;}/**************主函数**************/void main(){init_12864();init_t0_t1();while(1){init_zifu();anjian();xingqi();}}/***************中断函数***************/void time() interrupt 1{TH0=(65536-50000)/256;TL0=(65536-50000)%256;if(hour==0&minute==0&second==0||hour==0&minute==1&second==0||hour==0&minute==1&s econd==5)//采用与或逻辑设定闹铃{beet=0;delay(5);beet=1;}count++;if(count==20){count=0;second++;}if(second==60){second=0;minute++;}if(minute==60){minute=0;hour++;}if(hour==24){hour=0;day++;cc++;if(cc==8){cc=1;}}if(day==31){day=1;month++;}if(month==13){month=1;years++;}}。

51单片机带字库12864液晶动态汉字显示C语言源程序

51单片机带字库12864液晶动态汉字显示C语言源程序

51单片机带字库12864液晶动态汉字显示C语言源程序2009-10-17 19:36实验芯片为:AT89S52,带字库液晶屏:12864,实现的目的:动态一个汉字一个汉字显示。

其实和显示汉字的程序一样,只是稍做一下修改即可。

C语言源程序如下:#include <stdio.h>#include <math.h>#include <reg52.h>#include <string.h>sbit RS=P2^4;sbit WRD=P2^5;sbit E=P2^6;sbit PSB=P2^1;sbit RES=P2^3;void TransferData(char data1,bit DI);void delayms(unsigned int n);void delay(unsigned int m);void lcd_mesg003(unsigned char code *addr1);unsigned char code IC_DAT[]={"我是一个中国人啊"};void initinal(void){delay(40);PSB=1; //并口工作模式delay(1);RES=0; //复位delay(1);RES=1; //复位置高delay(10);TransferData(0x30,0);delay(100);TransferData(0x30,0);delay(37);TransferData(0x08,0);delay(100);TransferData(0x10,0);delay(100);TransferData(0x0C,0);delay(100);TransferData(0x01,0);delay(10);TransferData(0x06,0);delay(100);}void main(void){while(1){initinal();//调用LCD字库初始化程序delay(100);lcd_mesg003(IC_DAT);}}void lcd_mesg003(unsigned char code *addr1){unsigned char i;//第一行TransferData(0x80,0);delay(100);for(i=0;i<16;i++){TransferData(*addr1,1);addr1++;delayms(50);}}void TransferData(char data1,bit DI) //传送数据或是命令,当DI=0时,传送命令,当DI=1时,传送数据{WRD=0;RS=DI;delay(1);P0=data1;E=1;delay(1);E=0;}void delayms(unsigned int n){unsigned int i,j;for(i=0;i<n;i++)for(j=0;j<2000;j++);}void delay(unsigned int m){unsigned int i,j;for(i=0;i<m;i++)for(j=0;j<10;j++);}原理就是在显示每个汉字的时候加了一个延时程序,当然可以用定时器来实现,这样的话,不占用CPU处理时间。

SG12864-12带汉字库LCD显示器

SG12864-12带汉字库LCD显示器

72us
DDRAM 的地址计数器(AC)到“00H”
卷动地址或
00 0
0
0
0
0
0
1 SR SR=1:允许输入垂直卷动地址
72us
IRAM 地址
选择
反白选择 0 0
睡眠模式 0 0
扩充功能设
00

设定 IRAM 地址或卷动 0 0
地址 设定绘图
00
RAM 地址
深圳市显能实业有限公司 SHENZHNE SHINE INDUSTRY CO;LTD SG12864 中文字库
7、设定 CGRAM 位址
CODE: RW RS DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
L
L
L
H AC5 AC4 AC3 AC2 AC1 AC0
功能:设定 CGRAM 位址到位址计数器(AC)
8、设定 DDRAM 位址
CODE: RW RS
L
L
深圳市显能实业有限公司 SHENZHNE SHINE INDUSTRY CO;LTD SG12864 中文字库
X
深圳市显能实业有限公司 SHENZHNE SHINE INDUSTRY CO;LTD SG12864 中文字库
0
0
0
1
D
C
B C=1:游标 ON
开/关
B=1:游标位置 ON
游标或显示移
位控制
00 0
0
功能设定 0 0 0 0
0
1 S/C R/L X
0
1 DL X
X
RE
设定游标的移动与显示的移位控制位
X
元;这个指令并不改变 DDRAM 的内容

毕业设计—基于单片机的12864时钟显示

毕业设计—基于单片机的12864时钟显示

学士学位毕业论文(设计)题目:基于单片机的12864时钟显示摘要电子时钟是一种非常广泛日常计时工具,给人们的带来了很大的方便,在社会上越来越流行。

它可以对年、月、日、星期、时、分、秒进行计时,采用直观的数字显示,可以同时显示年月日时分秒等信息,还有时间校准等功能。

该电子时钟主要采用STC89C52单片机作为主控核心,用DS1302时钟芯片作为时钟、液晶12864显示屏显示。

STC89C52单片机是由深圳宏晶科技公司推出的,功耗小,电压可选用4~6V电压供电;DS1302时钟芯片是美国DALLAS公司推出的具有细电流充电功能的低功耗实时时钟芯片,它可以对年、月、日、星期、时、分、秒进行计时,还具有闰年补偿等多种功能,而且DS1302的使用寿命长,误差小;数字显示是采用的12864液晶显示屏来显示,可以同时显示年、月、日、星期、时、分、秒等信息。

此外,该电子时钟还具有时间校准等功能。

关键词:STC89C51单片机,DS1302时钟芯片,液晶12864AbstractElectronic clock is a very extensive daily timing tool, to the people has brought great convenience, more and more popular in the community. It can be the year, month, date, day, hour, minute, second for a time, using intuitive digital display, can display information such as year, month, day, hour, and time alignment functions. The electronic clock is used mainly as a master STC89C52 microcontroller core, with theDS1302 clock chip as a clock, LCD display12864. STC89C52 SCM is a Shenzhen Hong Crystal Technology has introduced, power consumption, voltage can be selected 4 ~ 6V voltage power supply; DS1302 clock chip is American DALLAS company launched with a fine current charging low-power real-time clock chip, it can year, month, date, day, hour, minute, second for a time, also has a leap year compensation and other functions, DS1302 and long life, small error; 12864 LCD digital display isused to display that can display year, month, date, day, hour, minute, second and so on. In addition, the electronic clock also has a time calibration function.Key Words:STC89C51 microcontroller, DS1302 clock chip, LCD 12864目录1绪论 (3)1.1时钟发展史 (3)1.2 目前的研究现状 (4)1.3研究目的及意义 (4)2 总体方案设计 (5)2.1 方案的选择 (5)2.1.1设计要求 (5)2.1.2方案的选择 (5)2.2总体方案组成框图 (6)3系统硬件设计 (6)3. 1主芯片模块 (6)3.1.1 中断系统 (8)3.1.2常用寄存器 (8)3.2晶振和复位电路 (10)3.2.1晶振电路 (10)3.2.2复位电路 (11)3.3 DS1302时钟芯片电路 (11)3.3.1 DS1302引脚图 (11)3.3.2 DS1302寄存器 (12)3.3.3 DS1302外围电路 (13)3.4 LCD12864显示模块 (13)3.4.1 LCD12864引脚功能 (13)3.4.2 LCD12864指令说明 (14)3.4.3 LCD12864电路接线 (15)3.5 红外遥控模块 (16)4 系统软件设计 (17)4.1 主程序设计 (17)4.2 LCD12864驱动程序 (19)4.3 DS1302驱动程序 (21)4.4 红外遥控程序 (24)5 调试结果 (25)5.1 正常显示日期时间画面 (26)5.2 进入调整时间日期画面 (26)5.3图片显示画面 (26)6总结 (27)致谢 (28)参考文献 (29)附录一 (31)附录二 (32)1绪论1.1时钟发展史很早以前,人类主要是利用天文现象和流动物质的连续运动来计时。

51单片机带字库液晶12864ds1302数字时钟c源程序(无按键修改功能)

51单片机带字库液晶12864ds1302数字时钟c源程序(无按键修改功能)

51单片机+带字库液晶12864+DS1302数字时钟C 源程序(无按键修改功 能)过两天的搜索与调试,在别人程序的基础上,不断修改,终于调试成功了 这个程序。

目前还不能修改时间与日期,只是以预定时间以始。

适用于开发板:51单片机(AT89S52 +带字库液晶12864(ST7920)+DS1302实时时钟)实现功能:简单,数字时钟 +日期(以后会不断完美)。

C 语言源程序如下:#include <reg52.h>#include <intrins.h> #define uchar unsigned char #define uint unsigned int /*DS1302 端 口设置 */sbit SCK=P3A 6;sbit SDA=P3A4;sbit RST = P3A5;bitReadRTC_Flag;/* 12864 端口定义 */ #define LCD_data P0 sbit LCD_RS = P2A4;sbit LCD_RW = P2A5; sbit LCD_EN = P2A 6;//液晶使能控制sbit PSB 二卩2八1; //并口控制 //DS1302 时钟 //DS1302 IO // DS1302 复位 //读DS1302全局变量//带字库液晶 12864数据口// 寄存器选择输入// 液晶读/写控制sbit RES=P2A3;uchar code dis1[] = {"电子设计天地"};// 液晶显示的汉字uchar code dis2[] = {"有志者,事竟成!"};uchar code dis4[] = {'0','1','2','3','4','5','6','7','8','9'};unsigned char temp;#define delayNOP(); {_nop_();_nop_();_nop_();_nop_();};void lcd_pos(uchar X,uchar Y); //确定显示位置unsigned char l_tmpdate[7]={0,7,16,19,10,1,9};〃秒分时日月周年09-10-19 16:07:00code unsigned charwrite_rtc_address[7]={0x80,0x82,0x84,0x86,0x88,0x8a,0x8c}; //秒分时日月周年最低位读写位code unsigned charread_rtc_address[7]={0x81,0x83,0x85,0x87,0x89,0x8b,0x8d};void Write_Ds1302_byte(unsigned char temp);void Write_Ds1302( unsigned char address,unsigned char dat );unsigned char Read_Ds1302 ( unsigned char address );void Read_RTC(void);//read RTCvoid Set_RTC(void); //set RTCvoid InitTIMER0(void);//inital timer0/*******************************************************************//**//* 延时函数 *//* *//******************************************************************* /void delay(unsigned int m) // 延时程序 {unsigned int i,j;for(i=0;i<m;i++)**************************************************//*检查LCD 忙状态*//*lcd_busy 为1时,忙,等待。

带字符的12864驱动及12887显示时间

带字符的12864驱动及12887显示时间

一、硬件电路图二、程序部分#include "reg52.h"#include "intrins.h"sbit io_LCD12864_RS = P1^2 ;sbit io_LCD12864_RW = P1^3 ;sbit io_LCD12864_EN = P1^4;sbit G=P2^0; //锁存器控制端sbit dscs=P2^3; // 时钟芯片片选sbit dsas=P2^4; //时钟芯片的地址信号sbit dsrw=P2^5; //时钟芯片的读写信号控制sbit dsds=P2^6; //时钟芯片的数据信号*/sbit dsirq=P2^7; //时钟芯片的中断允许请求#define uchar unsigned char#define uint unsigned int#define io_LCD12864_DATAPORT P0 //P0为数据口#define SET_DATA io_LCD12864_RS = 1 ;#define SET_INC io_LCD12864_RS = 0 ;#define SET_READ io_LCD12864_RW = 1 ;#define SET_WRITE io_LCD12864_RW = 0 ;#define SET_EN io_LCD12864_EN = 1 ;#define CLR_EN io_LCD12864_EN = 0 ;uchar miao,shi,fen,yue,ri,nian,xq,flag,s1num,flag1,x1,x2,x3; //定义时,分,秒,年。

月,日等变量uchar code num[]="0123456789"; //定义字符串数组void v_Lcd12864CheckBusy_f( void ) //忙检测函数{unsigned int nTimeOut = 0 ;SET_INCSET_READCLR_ENSET_ENwhile( ( io_LCD12864_DA TAPORT & 0x80 ) && ( ++nTimeOut != 0 ) ) ;CLR_ENSET_INCSET_READ}void v_Lcd12864SendCmd_f( unsigned char byCmd ) //发送命令{v_Lcd12864CheckBusy_f() ;SET_INCSET_WRITECLR_ENio_LCD12864_DATAPORT = byCmd ;_nop_();_nop_();SET_EN_nop_();_nop_();CLR_ENSET_READSET_INC}void v_Lcd12864SendData_f( unsigned char byData ) //发送数据{v_Lcd12864CheckBusy_f() ;SET_DATASET_WRITECLR_ENio_LCD12864_DATAPORT = byData ;_nop_();_nop_();SET_EN_nop_();_nop_();CLR_ENSET_READSET_INC}void v_DelayMs_f( unsigned int nDelay ) //延时{unsigned int i ;for( ; nDelay > 0 ; nDelay-- ){for( i = 125 ; i > 0 ; i-- ) ;}}void v_Lcd12864Init_f( void ) //初始化{v_Lcd12864SendCmd_f( 0x30 ) ; //基本指令集v_DelayMs_f( 50 ) ;v_Lcd12864SendCmd_f( 0x01 ) ; //清屏v_DelayMs_f( 50 ) ;v_Lcd12864SendCmd_f( 0x06 ) ; //光标右移v_DelayMs_f( 50 ) ;v_Lcd12864SendCmd_f( 0x0c ) ; //开显示}void v_Lcd12864SetAddress_f( unsigned char x, y ) //地址转换{unsigned char byAddress ;switch( y ) //由y来控制数据在行的位置{case 0 : byAddress = 0x80 + x ;break;case 1 : byAddress = 0x90 + x ;break ;case 2 : byAddress = 0x88 + x ;break ;case 3 : byAddress = 0x98 + x ;break ;default :break ;}v_Lcd12864SendCmd_f( byAddress ) ;}void v_Lcd12864PutString_f( unsigned char x, unsigned char y, unsigned char pData ){v_Lcd12864SetAddress_f( x, y ) ;if( pData != '\0' ){v_Lcd12864SendData_f( pData ) ;} //发送数组中一个元素}void v_Lcd12864PutString_f2( unsigned char x, unsigned char y, unsigned char *pData1 ){v_Lcd12864SetAddress_f( x, y ) ;while( *pData1 != '\0' ){v_Lcd12864SendData_f( *pData1++ ) ;}} //利用指针发送整个数组的元素void write_ds(uchar add,uchar date) //时钟芯片写子函数{dscs=0;dsas=1;dsds=1;dsrw=1;P0=add;dsas=0;dsrw=0;P0=date;dsrw=1;dsas=1;dscs=1;}uchar read_ds(uchar add) //时钟芯片读子函数{uchar ds_date;// P0=0xff;dscs=0;dsas=1;dsds=1;dsrw=1;P0=add;dsas=0;dsds=0;P0=0xff;ds_date=P0;dsds=1;dsas=1;dscs=1;return ds_date;}void init() //初始化函数{//set_time();EA=1; //开总中断EX0=1; //开外部中断0IT0=1; //设置为电平触发方式//set_alarm(0xc0,0xc0,0); //定时为下午六点write_ds(0x0a,0x20); //启动DS12887write_ds(0x0b,0x86); //禁止更新,接下来初始化数据,即写入时间,日期等write_ds(0x0B,0x26); //写定时器B寄存器write_ds(0x0b,0x06); //正常更新,二进制格式,24进制小时read_ds(0x0c); //读定时器C寄存器v_DelayMs_f( 50 ); //延时}void main( void ){ G=0;init(); //12887初始化v_Lcd12864Init_f() ; //液晶初始化while(1){{ //read_ds(0x0c) ;miao=read_ds(0); //读取时钟芯片内的数据fen=read_ds(2);shi=read_ds(4);xq=read_ds(0x06);ri=read_ds(0x07);yue=read_ds(0x08);nian=read_ds(0x09);}v_Lcd12864PutString_f(0,0,num[2]);v_Lcd12864SendData_f( num[0] );v_Lcd12864SendData_f( num[nian/10] );v_Lcd12864SendData_f( num[nian] );v_Lcd12864PutString_f2(2,0,"年");v_Lcd12864SendData_f( num[yue/10] );v_Lcd12864SendData_f( num[yue] );v_Lcd12864PutString_f2(4,0,"月");v_Lcd12864SendData_f( num[ri/10] );v_Lcd12864SendData_f( num[ri] );v_Lcd12864PutString_f2(6,0,"日");v_Lcd12864PutString_f(0,1,num[shi/10]);v_Lcd12864SendData_f( num[shi] );v_Lcd12864PutString_f2(1,1,"点");v_Lcd12864SendData_f( num[fen/10] );v_Lcd12864SendData_f( num[fen] );v_Lcd12864PutString_f2(3,1,"分");v_Lcd12864SendData_f( num[miao/10] );v_Lcd12864SendData_f( num[miao] );v_Lcd12864PutString_f2(5,1,"秒");v_Lcd12864PutString_f2(6,1,"周");v_Lcd12864SendData_f( num[xq] ); //在液晶上将得到的数据显示}}。

12864液晶电子时钟+温度显示

12864液晶电子时钟+温度显示

12864液晶电子时钟+温度显示上午花了一上午时间,用12864 液晶写了一个电子时钟加温度传感器程序,先说一下程序的功能,可以实现显示年月日时间和温度,年月日和时间是可通过按键调节的,调节相应的选项时,该选项会闪烁,并停止走时,当调节完毕后时钟恢复走时。

现在将程序和思路写下来,以便日后查看和与大家探讨改进,欢迎高手提出宝贵意见。

我使用的是HJ12864M-1 带字库液晶,所以在显示上稍微方便一点。

下面先来说一下我的编程思路。

时间更新用的是单片机自带的定时器,液晶要显示数字必需将它转换成ASCii 码的形式,数字0-9 的ASCii 码与数字之间有一个定量的关系,当数字加上0x30 之后便得到该数字的ASCii 码,这样以来液晶更新数据就变得简单了。

调节时间时对应选项闪烁,是通过不断的交替写入数据和空格实现的。

温度显示用的是DS18B20,,将测得的当前温度不断更新显示在液晶上。

调节时间用的是三个独立按键。

由于这个程序我使用模块化来写的,就只能将每个模块分别给出来,大家只要组装一下便可以使用。

如果需要完整程序的可以给我留言我发给你们。

下面是12864 液晶的初始化,读写命令,及读忙操作#include “lcd12864.h”#include reg52.hsbit RS=P2 ; //控制端口位定义sbitRW=P2;s b it EN=P2;vo id init_12864(){delay(40);write_com(0x30);//8 位数据格式,基本指令显示delay(10); //延时时间write_com(0x30);//8 位数据格式,基本指令显示delay(37);write_com(0x0C);//开显示、关闭光标delay(10);write_com(0x01);//清屏指令delay(10); //延时write_com(0x06);//设置显示点:指针自加1}tips:感谢大家的阅读,本文由我司收集整编。

vhdl-12864-cpld 时钟.doc

vhdl-12864-cpld 时钟.doc

--vhdl 12864显示时分秒,小时是12进制-- 输入时钟是50MHZ-- 所有12864液晶使用st7920控制器(带字库)采用并口工作方式,需自己将psb置高电平--此程序本人编译下载成功,能显示--青农611实验室library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_arith.all;use ieee.std_logic_unsigned.all;entity vhdl1 isport(clk,reset: in std_logic;en,rw,rs: OUT std_logic;data: out std_logic_vector(7 downto 0));end entity vhdl1;architecture behav of vhdl1 istype states is(st0,st1,st2,st3,st4,st5,st6);type ram1 is array(0 to 9) of std_logic_vector(7 downto 0);constant cgram1 : ram1 :=(x"30",x"31",x"32",x"33",x"34",x"35",x"36",x"37",x"38",x"39"); --0123456789的ASCII码signal current_state: states;signal lcd_clk,clk_out:std_logic;signal shi_clk,yifen_clk,shifen_clk,yimiao_clk,shimiao_clk:std_logic;signal miaoge,miaoshi,fenge,fenshi,shi1,shi2:integer range 0 to 9;beginprocess(CLK)variable n1:integer range 0 to 100000; --将输入时钟分频为250hz,4msbeginif rising_edge(Clk) thenif n1<100000 then n1:=n1+1;else n1:=0; Clk_Out<=not Clk_Out;end if;end if;end process;en<=clk_out;lcd_clk<=clk_out;RW <= '0' ;process(CLK_out) --再分频为1hz,即一秒的时钟信号variable n2:integer range 0 to 125;--1hzbeginif rising_edge(Clk_out) thenif n2<125 then n2:=n2+1;else n2:=0; yimiao_clk<=not yimiao_clk;end if;end if;end process;process(yimiao_clk) --秒个位variable cq1:integer range 0 to 9;beginif rising_edge(yimiao_Clk) thenif cq1<9 then cq1:=cq1+1;shimiao_clk<='0';else cq1:=0;shimiao_clk<='1';end if;end if;miaoge<=cq1;end process;process(shimiao_clk) --秒十位variable cq2:integer range 0 to 5;beginif rising_edge(shimiao_Clk) thenif cq2<5 then cq2:=cq2+1;yifen_clk<='0';else cq2:=0;yifen_clk<='1';end if;end if;miaoshi<=cq2;end process;process(yifen_clk) --分个位variable cq3:integer range 0 to 9;beginif rising_edge(yifen_Clk) thenif cq3<9 then cq3:=cq3+1;shifen_clk<='0';else cq3:=0;shifen_clk<='1';end if;end if;fenge<=cq3;end process;process(shifen_clk) --分十位variable cq4:integer range 0 to 5;beginif rising_edge(shifen_Clk) thenif cq4<5 then cq4:=cq4+1;shi_clk<='0';else cq4:=0;shi_clk<='1';end if;end if;fenshi<=cq4;end process;process(shi_clk)--小时,十二进制计数器variable cq5:integer range 0 to 11;beginif rising_edge(shi_Clk) thenif cq5<11 then cq5:=cq5+1;else cq5:=0;end if;end if;shi1<= cq5 rem 10; --对十取余shi2<= cq5 / 10; --对十取整end process;process(LCD_Clk,Reset,Current_State)variable cn2: integer range 0 to 4 ;beginif Reset='0' then Current_State<=st0; RS<='0';elsif rising_edge(LCD_Clk) then Current_State <= Current_State ; RS <= '0';case Current_State iswhen st0=> --基本指令集动作Data<="00110000";Current_State<=st1;when st1=> -- 整体显示设置:光标off 反光off:0x0cData<="00001100";Current_State<=st2;--end if;when st2=> --清除显示,并且认定地址指针为00h:0x01Data<="00000001";Current_State<=st3;when st3=> --指定游标的移动方向及指定显示的移位:06Data<="00000110";Current_State<=st4;when st4=> --地址设定从第一行的第一个字开始显示到第五个字地址设定if cn2<5 then cn2:=cn2+1;else cn2:=0;end if;if cn2=0 then data<="10000000";--0x80elsif cn2=1 then data<="10000001";--0x81elsif cn2=2 then data<="10000010";--0x82elsif cn2=3 then data<="10000011";--0x83else data<="10000100";--0x84end if;current_state<=st5;when st5=> --送数据1 一个字地址可以放两个数字,所以一个地址送两次数据rs<='1';if cn2=0 then data<=cgram1(conv_integer(shi2));--送时显示的十位elsif cn2=1 then data<="00100000";--空格elsif cn2=2 then data<=cgram1(conv_integer(fenshi));--送分显示的十位elsif cn2=3 then data<="00100000";--空格else data<=cgram1(conv_integer(miaoshi));--送个显示的十位end if;current_state<=st6;when st6=> --送数据2rs<='1';if cn2=0 then data<=cgram1(conv_integer(shi1));--送时显示的个位elsif cn2=1 then data<="00111010";--冒号elsif cn2=2 then data<=cgram1(conv_integer(fenge));--送分个位elsif cn2=3 then data<="00111010";--冒号else data<=cgram1(conv_integer(miaoge));--送秒个位end if;current_state<=st4;when others => rs<='Z';data<=(others=>'Z');end case;end if;end process;end behav;。

LCD12864(串口)显示程序

LCD12864(串口)显示程序

LCD12864(串口)显示程序#ifndef jh_f330#define jh_f330#include#endiftypedef unsigned char uint8;typedef unsigned int uint16;/*************端口配置**************/sbit LCD_CS = P0^4; //片选信号,低电平有效sbit LCD_RST = P0^3; //复位信号,低电平有效sbit LCD_A0 = P0^2; //数据、指令选择,H:数据、L:指令sbit LCD_DAT = P1^0; //串行输入数据引脚sbit LCD_CLK = P1^1; //串行时钟输入引脚uint8 code word1[]={0x04,0x44,0x84,0x04,0xE4,0x1F,0x84,0x44,0xA4,0x3F,0xA4,0x A4,0x64,0x06,0x04,0x00,0x20,0x10,0x09,0x04,0xFF,0x04,0x04,0x14,0x26,0x05,0x84,0xFF,0x04,0x06,0x04,0x00 };/**********预定义数据*********/#define LCD_X 128-1 //屏幕的X轴的物理宽度#define LCD_Y 64-1 //屏幕的Y轴的物理宽度/***********LCD指令集***************///LCD开关命令#define LCD_ON() Wr_Com(0xaf)#define LCD_OFF() Wr_Com(0xae)//设置显示起始行#define LCD_START_LINE 0x40 //起始行地址为,0x40+(0-63)//页地址设置#define LCD_Page 0xb0 //页地址为:0xb0+(0-8)//列地址设置#define LCD_Ad_H 0x10 //列高四位地址:0x10+()#define LCD_Ad_L 0x00 //列低四位地址:0x00+()//行列地址方向设置#define ADC_Norm() Wr_Com(0xa0);#define ADC_Reve() Wr_Com(0xa1);#define Com_Norm() Wr_Com(0xc0);#define Com_Reve() Wr_Com(0xc8);void Init_f330(){/*****内部振荡器配置******/OSCICL=OSCICL+4; //设置系统时钟为24MHZ,ΔT=(0.005*ΔOSCICL)/fbase // OSCICL=OSCICL+22; //设置系统时钟为22.1184MHZ// OSCICL=OSCICL+45; //设置系统时钟为20MHZ //15MHZ--24.5MHZ/********设置分频*********/// OSCICN|=0x00; //设置时钟为八分频,OSCIN复位值为1100000//00:8分频,01:4分频,10:2分频,11:不分频// OSCICN|=0x01; //设置系统时钟4分频// OSCICN|=0x02; //设置系统时钟2分频OSCICN|=0x03; //设置系统时钟不分频// RSTSRC=0x04;// OSCLCN = 0x82; // 设置内部L-F振荡器为40kHZ// CLKSEL = 0x02; // 内部低频振荡器while(OSCLCN&0x40 == 0); // 等待振荡器频率稳定/*****设置看门狗*****/PCA0MD &=~0x40; // 禁止看门狗定时器EA=1;/*****端口初始化******/P0MDIN = 0xff; //复位值为11111111P1MDIN = 0xff; //1为数字输入,0为模拟输入P0MDOUT = 0xff; //复位值为11111111P1MDOUT = 0xff; //1为推挽输出,0为漏极输出XBR0 = 0x00; // 交叉开关使能XBR1 = 0x40; //交叉开关允许,T0接到引脚//XBR1 = 0x48; // ECI连到端口引脚//XBR1 |= 0x08; // PCA0 外部计数输入使能}/***************************************功能:LCD串行写入数据程序**输入:8位数据**输出:无************************************/ void Wr_Dat(uint8 dat) {uint8 Num;LCD_CS = 0; //选通芯片LCD_A0 = 1; //写数据for(Num=0;Num<8;Num++){if((dat&0x80) == 0) LCD_DAT = 0;else LCD_DAT = 1;dat = dat << 1;LCD_CLK = 0;LCD_CLK = 1;}LCD_CS = 1;}/***************************************函数名称:Wr_Com()**功能:LCD串行写入命令程序**输入:8位数据**输出:无************************************/ void Wr_Com(uint8 com) {uint8 Num;LCD_CS = 0; //选通芯片LCD_A0 = 0; //写入命令for(Num=0;Num<8;Num++){if((com&0x80) == 0) LCD_DAT = 0;else LCD_DAT = 1;com = com << 1;LCD_CLK = 0;LCD_CLK = 1;}LCD_CS = 1;}/***************************************功能:LCD全屏显示数据程序**输入:8位数据**输出:无************************************/void LCD_Fill(uint8 dat){uint8 page;uint8 colume;for(page=0;page<8;page++)Wr_Com(LCD_Page+page);Wr_Com(LCD_Ad_H);Wr_Com(LCD_Ad_L);for(colume=0;colume<lcd_x;colume++)< p="">Wr_Dat(dat);}}/***************************************函数名称:LCD_Clear()**功能:LCD清屏程序(全屏填充0x00)**输入:8位数据**输出:无************************************/void LCD_Clear(){LCD_Fill(0x00);}/******************************************************* ** 函数名称: LCD12864_Init** 功能: LCD1286初始化程序** 输入: 无TimeDelay ** 输出: 无********************************************************/ void TimeDelay(int Time){int i;while(Time > 0){for(i = 0;i < 8000;i++){Time --;}}void LCD_Init(void){LCD_RST=0;TimeDelay(200);LCD_RST=1;TimeDelay(200);ADC_Norm();Com_Reve();Wr_Com(0xa2);Wr_Com(0x2c); //vc onTimeDelay(200);Wr_Com(0x2e); //vr onTimeDelay(200);Wr_Com(0x2f); //internal booster,follower,divided onWr_Com(0x24); //set rb/ra=5.29Wr_Com(0x81); //set reference voltage selectWr_Com(0x1d);LCD_ON();Wr_Com(LCD_START_LINE);}/************************************************************** *********函数名称:LCD_Word()**功能:输入单个汉字(16x16符号)**输入:页地址,列地址、字符数组**输出:无*************************************************************** ********/ void LCD_Word(unsigned char row,unsigned char colume,unsigned char *pword){unsigned char page= row;unsigned char col_high=colume>>4;unsigned char col_low =colume&0x0f;unsigned char i;Wr_Com(LCD_Page+page);Wr_Com(LCD_Ad_H+col_high);Wr_Com(LCD_Ad_L+col_low);for(i=0;i<16;i++){Wr_Dat(*(pword+i));}Wr_Com(LCD_Page+page+1);Wr_Com(LCD_Ad_H+col_high);Wr_Com(LCD_Ad_L+col_low);for(i=0;i<16;i++){Wr_Dat(*(pword+16+i));}main(){Init_f330();LCD_Init();LCD_Clear();LCD_Word(1,1,word1);while(1);}</lcd_x;colume++)<>。

吴鉴鹰单片机项目之12864实现圆形模拟时钟显示

吴鉴鹰单片机项目之12864实现圆形模拟时钟显示

吴鉴鹰单片机项目之 12864 实现圆形动态模拟时钟显示 4
这就涉及到文字的字模,字模虽然也是一组数字,但它的意义却与数字的意义有 了根本的变化,它是用数字的各位信息来记载英文或汉字的形状,如英文的'A' 在字模的记载方式如图 1 所示:
图 1 “A”字模图 而中文的“你”在字模中的记载却如图 2 所示:
sbit LCD_CS1_OUT=P2^4;
//端口定义
sbit WJY_K1_IN=P3^5;
//按键
sbit WJY_K2_IN=P3^3;
sbit WJY_K3_IN=P3^1;
吴鉴鹰单片机项目之 12864 实现圆形动态模拟时钟显示 10
sbit WJY_K4_IN=P3^4;
char datastring[13]; ////存放时间的数组
传动系
传动系是将原动系的能量传至擒纵调速器的一组传动齿轮,它是由二轮(中心轮)、三轮 (过轮)、四轮(秒轮)和擒纵轮齿轴组成,其中 轮片是主动齿轮,齿轴是从动齿轮。钟表传动 系的齿形绝大部分是根据理论摆线的原理,经过修正而制作的修正摆线齿形。
擒纵调速器
擒纵调速器是由擒纵机构和振动系统两部分组成,它依靠振动系统的周期性震动,使擒 纵机构保持精确和规律性的间歇运动,从而取得调速作用。叉瓦式擒纵机构是应用最广的一 种擒纵机构。它由擒纵轮、擒纵叉、双圆盘和限位钉等组成。它的作用是把原动系的能量传 递给振动系统,以便维持振动系统作等幅振动,并把振动系统的振动次数传递给指示机构, 达到计量时间的目的。
振动系统主要由摆轮、摆轴、游丝、活动外桩环、快慢针等组成。游丝的内外端分别固 定在摆轴和摆
夹板上;摆轮受外力偏离其平衡位置开始摆动时,游丝便被扭转而产生位能,称为恢复 力矩。擒纵机构完成前述两动作的过程 ,振动系在游丝位能作用下,进行反方向摆动而完 成另半个振动周期,这就是机械钟表在运转时擒纵调速器不断和重复循环工作的原理。

用51单片机控制12864显示数字时钟

用51单片机控制12864显示数字时钟

用51单片机控制12864显示数字时钟用51单片机控制12864显示数字时钟里面有128564显示汉字的程序,自己研究下,不过是用msp430控制的,你改改端口i就可以了。

#include "msp430x26x.h"#define uchar unsigned char#define uint unsigned int#define iDat 1 //数据标志#define iCmd 0 //指令标志#define LCDb_RS 0x20 //定义四个控制引脚#define LCDb_RW 0x40#define LCDb_E 0x80#define LCDb_RST 0x04#define LCDb_L1 0x80 //第一行的地址#define LCDb_L2 0x90 //第二行的地址#define LCDb_L3 0x88 //第三行的地址#define LCDb_L4 0x98 //第四行的地址#define LCDb_SET_RS P1OUT|=LCDb_RS //四个控制管脚的控制操作#define LCDb_SET_RW P1OUT|=LCDb_RW#define LCDb_SET_E P1OUT|=LCDb_E#define LCDb_SET_RST P8OUT|=LCDb_RST#define LCDb_CLR_RS P1OUT&=~LCDb_RS#define LCDb_CLR_RW P1OUT&=~LCDb_RW#define LCDb_CLR_E P1OUT&=~LCDb_E#define LCDb_CLR_RST P8OUT&=~LCDb_RST#define LCDb_DO P4OUT //输出数据总线端口定义#define LCDb_FUNCTION 0x38 // 液晶模式为8位,2行,5*8字符#define LCDb_BASCMD 0x30 // 基本指令集#define LCDb_CLS 0x01 // 清屏#define LCDb_HOME 0x02 // 地址返回原点,不改变DDRAM 内容#define LCDb_ENTRY 0x06 // 设定输入模式,光标加,屏幕不移动#define LCDb_C2L 0x10 // 光标左移#define LCDb_C2R 0x14 // 光标右移#define LCDb_D2L 0x18 // 屏幕左移#define LCDb_D2R 0x1C // 屏幕又移#define LCDb_ON 0x0C // 打开显示#define LCDb_OFF 0x08 // 关闭显示unsigned char RXData;unsigned char Seg_Data[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x 6f} ; //数码管编码unsigned char Result[5]; //整数转化成字符串,给LCD显示void Delayms(uint MS){uint i,j;for( i=0;i<ms;i++)< bdsfid="104" p=""></ms;i++)<>for(j=0;j<1141;j++);}void Delayus(uint US){uint i;US=US*5/4;for( i=0;i<us;i++);< bdsfid="112" p=""></us;i++);<>}void LCD12864_portini()P1DIR=0xFF;P4DIR=0xFF;P5DIR=0xFF;P8DIR=0xFF;P8OUT |=LCDb_RST;// P1OUT=0xFF;}/*函数名称: LCD12864_sendbyte功能: 向12864液晶写入一个字节数据或者指令*/void LCD12864_sendbyte(uchar DatCmd, uchar dByte) {if (DatCmd == iCmd) //指令操作LCDb_CLR_RS;elseLCDb_SET_RS;LCDb_CLR_RW; //写操作LCDb_SET_E;LCDb_DO = dByte; //写入数据//Delayus(500);Delayms(1);LCDb_CLR_E;}/*函数名称: LCD12864_sendstr功能: 向12864液晶写入一个字符串参数: ptString--字符串指针返回值 : 无*/void LCD12864_sendstr(uchar *ptString)while((*ptString)!='\0') //字符串未结束一直写{LCD12864_sendbyte(iDat, *ptString++);}}/*函数名称: LCD12864_clear功能: 12864液晶清屏参数: 无返回值 : 无*/void LCD12864_clear(void){LCD12864_sendbyte(iCmd,LCDb_CLS);Delayms(2);// 清屏指令写入后,2ms 的延时是很必要的}/*函数名称: LCD12864_gotoXY功能: 移动到指定位置参数: Row--指定的行Col--指定的列返回值 : 无*/void LCD12864_gotoXY(uchar Row, uchar Col){switch (Row) //选择行{case 2:LCD12864_sendbyte(iCmd, LCDb_L2 + Col); break; //写入第2行的指定列case 3:LCD12864_sendbyte(iCmd, LCDb_L3 + Col); break; //写入第3行的指定列case 4:LCD12864_sendbyte(iCmd, LCDb_L4 + Col); break; //写入第4行的指定列default:LCD12864_sendbyte(iCmd, LCDb_L1 + Col); break; //写入第1行的指定列}}/*函数名称: LCD12864_initial功能: 12864液晶初始化*/void LCD12864_initial(void){Delayms(100); // 等待内部复位LCD12864_portini(); //端口初始化LCD12864_sendbyte(iCmd, LCDb_FUNCTION); //功能、模式设定LCD12864_sendbyte(iCmd, LCDb_ON); //打开显示LCD12864_clear(); //清屏LCD12864_sendbyte(iCmd, LCDb_ENTRY); // 输入模式设定}void Int_char(int data){if(data/1000){Result[0]=data/1000+'0';Result[1]=data/100%10+'0';Result[2]=data/10%10+'0';Result[3]=data%10+'0';Result[4]=0;}else if(data/100){Result[0]=data/100+'0';Result[1]=data/10%10+'0';Result[2]=data%10+'0';Result[3]=0;}else if(data/10){Result[0]=data/10%10+'0';Result[1]=data%10+'0';Result[2]=0;}else{Result[0]=data%10+'0';Result[1]=0;}}unsigned char Key_Press(void){P7OUT=0xF0;if((P7IN&0x10)&&(P7IN&0x20)&&(P7IN&0x40)&&(P7IN&0 x80)) return 0x00; else return 0xFF;}unsigned char Get_Keycode(void){while(1)P7OUT=0xFE; //扫描第一列if((P7IN&0x10)==0) return 0;else if((P7IN&0x20)==0) return 4;else if((P7IN&0x40)==0) return 8;else if((P7IN&0x80)==0) return 12;P7OUT=0xFD; //扫描第二列if((P7IN&0x10)==0) return 1;else if((P7IN&0x20)==0) return 5;else if((P7IN&0x40)==0) return 9;else if((P7IN&0x80)==0) return 13;P7OUT=0xFB; //扫描第三列if((P7IN&0x10)==0) return 2;else if((P7IN&0x20)==0) return 6;else if((P7IN&0x40)==0) return 10;else if((P7IN&0x80)==0) return 14;P7OUT=0xF7; //扫描第四列if((P7IN&0x10)==0) return 3;else if((P7IN&0x20)==0) return 7;else if((P7IN&0x40)==0) return 11;else if((P7IN&0x80)==0) return 15;}}void Init_compa(){CACTL1 = CAON+CAREF_2+CARSEL; // Enable Comp, ref = 0.5*Vcc = Vin- CACTL2 = P2CA0; // Pin to CA0P1DIR |= 0x01; // P1.0 = o/p direction(CAOUT - LED) P1SEL |= 0x01; // P1.0 - CAOUT, option select}** 函数名称:初始化函数*/void Init_IIC(void){P3SEL |= 0x06; // Assign I2C pins to USCI_B0UCB0CTL1 |= UCSWRST; // Enable SW resetUCB0CTL0 = UCMST + UCMODE_3 + UCSYNC; // I2C Master, synchronous modeUCB0CTL1 = UCSSEL_2 + UCSWRST; // Use SMCLK, keep SW resetUCB0BR0 = 12; // fSCL = SMCLK/12 = ~100kHzUCB0BR1 = 0;UCB0I2CSA = 0x50; // Slave Address is 048hUCB0CTL1 &= ~UCSWRST; // Clear SW reset, resume operation IE2 |= UCB0RXIE; // Enable RX interrupt_BIS_SR(GIE);// RXCompare = 0x0; // Used to check incoming data }/** 函数名称:字节写函数*/void EEPROM_Write(unsigned char high_Address,unsigned char low_Address,unsigned char Word){while (UCB0CTL1 & UCTXSTP); // 确定总线空闲UCB0CTL1 |= UCTXSTT + UCTR; // 发送起始位,确定为发送模式UCB0TXBUF = high_Address; // 发送高位地址while((IFG2 & UCB0TXIFG)==0); // 判断是否发送完毕UCB0TXBUF = low_Address; // 发送低位地址while((IFG2 & UCB0TXIFG)==0); // 判断是否发送完毕UCB0TXBUF = Word; // 发送数据while((IFG2 & UCB0TXIFG)==0); // 判断是否发送完毕UCB0CTL1 |= UCTXSTP; // 发送停止位while((UCB0CTL1 & UCTXSTP)==1); // 判断停止位是否发送完毕}/**** 函数名称:字节读函数*/void EEPROM_readmore(){UCB0CTL1 &= ~UCTR; // 确定为读while (UCB0CTL1 & UCTXSTP); // 总线是否空闲UCB0CTL1 |= UCTXSTT; // 发送开始位}/*** 函数名称:字节写函数**/void EEPROM_read(unsigned char high_Address,unsigned char low_Address){while (UCB0CTL1 & UCTXSTP); // Ensure stop condition got sent UCB0CTL1 |= UCTXSTT + UCTR; // 发送起始位,确定为写UCB0TXBUF = high_Address; // 发送地址位高位while((IFG2 & UCB0TXIFG)==0); // 判断是否发送完毕UCB0TXBUF = low_Address; // 发送地址位低位while((IFG2 & UCB0TXIFG)==0); // 判断是否发送完毕UCB0CTL1 &= ~UCTR; // 确定为接收while (UCB0CTL1 & UCTXSTP); //UCB0CTL1 |=UCTXSTT ;while((UCB0CTL1 & UCTXSTT)==1);for(unsigned char i=0x0;i<0x2f;i++); // 延时确定数据已经被发送出去UCB0CTL1 |=UCTXSTP + UCTXNACK; // 发送停止位和NACK 位}/*** 函数名称:接收中断函数**/// USCI_B0 Data ISR#pragma vector = USCIAB0TX_VECTOR__interrupt void USCIAB0TX_ISR(void){RXData = UCB0RXBUF; // Get RX dataInt_char(RXData);LCD12864_gotoXY(2,0); //第2行,第1列显示LCD12864_sendstr(Result);/*key_code[0]=RXData%10+'0';key_code[1]=0;LCD12864_gotoXY(1,0); //第1行,第1列显示LCD12864_sendstr(key_code);*/// __bic_SR_register_on_exit(CPUOFF); // Exit LPM0}void Init_UART(){P3OUT &= ~(BIT4+BIT5+BIT6+BIT7);P3SEL = 0xF0; // P3.4,5,6,7 = USCI_A0 TXD/RXD USCI_A1 TXD/RXDUCA0CTL1 |= UCSSEL_1; // CLK = ACLKUCA0BR0 = 0x03; // 32kHz/9600 = 3.41UCA0BR1 = 0x00; //UCA0MCTL = UCBRS1 + UCBRS0; // Modulation UCBRSx = 3UCA0CTL1 &= ~UCSWRST; // **Initialize USCI state machine** IE2 |= UCA0RXIE; // Enable USCI_A0 RX interrupt UCA1CTL1 |= UCSSEL_1; // CLK = ACLKUCA1BR0 = 0x03; // 32kHz/9600 = 3.41UCA1BR1 = 0x00; //UCA1MCTL = UCBRS1 + UCBRS0; // Modulation UCBRSx = 3UCA1CTL1 &= ~UCSWRST; // **Initialize USCI state machine** UC1IE |= UCA1RXIE; // Enable USCI_A0 RX interrupt _BIS_SR(GIE); //使能中断}void Init_ADC(){ADC12CTL0 = SHT0_2 + ADC12ON; // Set sampling time, turn on ADC12 ADC12CTL1 = SHP; // Use sampling timer ADC12IE = 0x01; // Enable interruptADC12CTL0 |= ENC; // Conversion enabledP6DIR &= 0x01; // P6.0, i/pP6SEL |= 0x01; // P6.0-ADC option select_BIS_SR(GIE); //使能中断}void Start_ADC(){ADC12CTL0 |= ADC12SC; // Start convn, software controlled }#pragma vector=USCIAB0RX_VECTOR__interrupt void USCI0RX_ISR(void){while (!(IFG2&UCA0TXIFG)); // USCI_A0 TX buffer ready? UCA0TXBUF = UCA0RXBUF; // TX -> RXed characterLCD12864_sendbyte(iDat,UCA0RXBUF);}#pragma vector=USCIAB1RX_VECTOR__interrupt void USCI1RX_ISR(void){while (!(UC1IFG&UCA1TXIFG)); // USCI_A0 TX buffer ready? UCA1TXBUF = UCA1RXBUF; // TX -> RXed characterLCD12864_sendbyte(iDat,UCA0RXBUF);//UCA1TXBUF = 'z';}// ADC12 interrupt service routine#pragma vector=ADC12_VECTOR__interrupt void ADC12_ISR (void){int i=ADC12MEM0;Int_char(i);LCD12864_gotoXY(2,0); //第1行,第1列显示LCD12864_sendstr(Result);/*key_code[0] =i/1000+'0';key_code[1] =i/100%10+'0';key_code[2] =i/10%10+'0';key_code[3] =i%10+'0';key_code[4] =0;LCD12864_gotoXY(1,0); //第1行,第1列显示LCD12864_sendstr(key_code);*/}void Init_all(){LCD12864_initial(); //LCD初始化,包含了数码管和LED灯初始化P7DIR=0x0F; //键盘扫描初始化P7REN=0xF0; //输入上下拉电阻使能,输出上下拉不使能P7OUT=0xF0; //输入上拉Init_UART(); //串口初始化Init_compa(); //比较器初始化Init_ADC(); //ADC初始化Init_IIC(); //IIC初始化}void Test_Led(){unsigned char i=0;LCD12864_gotoXY(1,0); //第1行,第1列显示LCD12864_sendstr("1.Test_LED");for(;i<16;i++){P8OUT=0xF0|i;Delayms(50);}}void Test_Seg(){int i;LCD12864_gotoXY(1,0); //第1行,第1列显示LCD12864_sendstr("2.Test_SEG");for(i=0;i<500;i++){//4,3,2,1P1OUT&=~0x02;P1OUT|=0x10|0x08|0x04;P5OUT=Seg_Data[9]; //清楚数码管显示Delayms(1); P1OUT&=~0x04;P1OUT|=0x10|0x08|0x02;P5OUT=Seg_Data[8]; //清楚数码管显示Delayms(1); P1OUT&=~0x08;P1OUT|=0x10|0x04|0x02;P5OUT=Seg_Data[7]; //清楚数码管显示Delayms(1); P1OUT&=~0x10;P1OUT|=0x08|0x04|0x02;P5OUT=Seg_Data[6]; //清楚数码管显示Delayms(1); }P5OUT=0x00; //熄灭所有数码管}void Test_Key(){unsigned char i=0;LCD12864_gotoXY(1,0); //第1行,第1列显示LCD12864_sendstr("3.Test_KEY");LCD12864_gotoXY(2,0); //第2行,第1列显示LCD12864_sendstr("按键:");for(;i<16;i++){Int_char(Get_Keycode());LCD12864_gotoXY(2,3);LCD12864_sendstr(" ");LCD12864_gotoXY(2,3);LCD12864_sendstr(Result);Delayms(100); //防抖}}void Test_Uart(){LCD12864_gotoXY(1,0); //第1行,第1列显示LCD12864_sendstr("4.Test_UART");LCD12864_gotoXY(2,0); //第2行,第1列显示}void Test_Compa(){LCD12864_gotoXY(1,0); //第1行,第1列显示LCD12864_sendstr("5.Test_COMPA");}void Test_ADC(){int i=0;LCD12864_gotoXY(1,0); //第1行,第1列显示LCD12864_sendstr("6.Test_ADC");for(;i<200;i++){Start_ADC();Delayms(10);}}void Test_IIC(){LCD12864_gotoXY(1,0); //第1行,第1列显示LCD12864_sendstr("7.Test_IIC");EEPROM_Write(0x00,0x40,7); // 字节写Delayms(10);EEPROM_read(0x00,0x40);}void main( void ){// Stop watchdog timer to prevent time out resetWDTCTL = WDTPW + WDTHOLD;//关闭看门狗Init_all();while(1){Test_Led(); //1.测试LEDLCD12864_gotoXY(2,0); //第1行,第1列显示LCD12864_sendstr("请按16键!");while(!(Get_Keycode()==15)); //按下最后一键测试下一个例子LCD12864_clear();Test_Seg(); //2.测试数码管LCD12864_gotoXY(2,0); //第1行,第1列显示LCD12864_sendstr("请按16键!");while(!(Get_Keycode()==15)); //按下最后一键测试下一个例子LCD12864_clear();Test_Key(); //3.测试按键扫描LCD12864_gotoXY(2,0); //第1行,第1列显示LCD12864_sendstr("请按16键!");while(!(Get_Keycode()==15)); //按下最后一键测试下一个例子LCD12864_clear();LCD12864_gotoXY(3,0); //第3行,第1列显示LCD12864_sendstr("请按16键!");Test_Uart(); //4.测试串口while(!(Get_Keycode()==15)); //按下最后一键测试下一个例子LCD12864_clear();Test_Compa(); //5.测试比较器LCD12864_gotoXY(2,0); //第2行,第1列显示LCD12864_sendstr("请按16键!");while(!(Get_Keycode()==15)); //按下最后一键测试下一个例子LCD12864_clear();Test_ADC(); //6.测试ADCLCD12864_gotoXY(3,0); //第3行,第1列显示LCD12864_sendstr("请按16键!");while(!(Get_Keycode()==15)); //按下最后一键测试下一个例子LCD12864_clear();Test_IIC(); //7.测试IICDelayms(100);LCD12864_gotoXY(3,0); //第3行,第1列显示LCD12864_sendstr("测试完成");while(!(Get_Keycode()==15)); //按下最后一键测试下一个例子LCD12864_clear();}}。

12864液晶屏(带字库)51单片机3线串口驱动程序

12864液晶屏(带字库)51单片机3线串口驱动程序

#include<reg51.h>typedef unsigned char uint8; typedef unsigned int uint16; typedef unsigned long uitn32;sbit CS = P1^0;//片选信号引脚sbit SDA = P1^1;//数据线sbit SCK = P1^2;//串行时钟线//sbit RST = P1^3;//复位引脚//sbit PSB = P1^4;//串并控制引脚code uint8 strint1[] = "I Love You !";/*void delay5ms(void) //误差0us {unsigned char a,b;for(b=185;b>0;b--)for(a=12;a>0;a--);}*///发送一个字节void Send_Byte(uint8 dat){uint8 i;SCK = 0;for(i=0;i<8;i++){SDA = dat&0x80;SCK = 1;dat <<= 1;SCK = 0;}}//读取一个字节数据uint8 Read_Byte(void){uint8 i;uint16 byte = 0;SCK = 0;for(i=0;i<16;i++){byte <<= 1;SCK = 1;if(SDA)byte |= 0x0001;SCK = 0;}byte = ((byte>>4)|(byte>>8))&0x00ff;return ((uint8)(byte));}//读忙标志void Read_Busy(void){uint8 temp;CS = 1;do{Send_Byte(0xfc);//发送读命令temp = Read_Byte();//读取数据}while(temp&0x80);CS = 0;}//发送命令void Write_Cmd(uint8 cmd){uint8 temph = 0;uint8 templ = 0;//制作发送命令格式temph = cmd & 0xf0;templ = (cmd & 0x0f) << 4;Read_Busy();CS = 1;Send_Byte(0XF8);//发送命令命令//发送命令Send_Byte(temph);Send_Byte(templ);CS = 0;}//发送数据void Write_Dat(uint8 dat){uint8 temph = 0;uint8 templ = 0;//制作发送数据格式temph = dat & 0xf0;templ = (dat & 0x0f) << 4;Read_Busy();CS = 1;Send_Byte(0XFA);//发送数据命令Send_Byte(temph);//发送数据Send_Byte(templ);CS = 0;}//在指定位置显示半字宽字符void Dis_HCGROM(uint8 x,uint8 y,uint8 dat) {uint8 addr;switch(y){case 0:addr = 0x80 + x;break;case 1:addr = 0x90 + x;break;case 2:addr = 0x88 + x;break;case 3:addr = 0x98 + x;break;default:break;}Write_Cmd(addr);Write_Dat(dat);}//指定位置显示字符串void Dis_String(uint8 x, uint8 y, uint8 len, uint8 *dat) {uint8 addr,i;switch(y){case 0:addr = 0x80 + x;break;case 1:addr = 0x90 + x;break;case 2:addr = 0x88 + x;break;case 3:addr = 0x98 + x;break;default:break;}Write_Cmd(addr);for(i = 0;i < len;i++){Write_Dat(*dat++);}}//制定位置显示8位无符号数字void Dis_UNum8(uint8 x,uint8 y,uint8 dat){uint8 addr;switch(y){case 0:addr = 0x80 + x;break;case 1:addr = 0x90 + x;break;case 2:addr = 0x88 + x;break;case 3:addr = 0x98 + x;break;default:break;}Write_Cmd(addr);Write_Dat(dat/100%10+'0');Write_Dat(dat/10%10+'0');Write_Dat(dat/1%10+'0');}//制定位置显示16位无符号数字void Dis_UNum16(uint8 x,uint8 y,uint8 dat) {uint8 addr;switch(y){case 0:addr = 0x80 + x;break;case 1:addr = 0x90 + x;break;case 2:addr = 0x88 + x;break;case 3:addr = 0x98 + x;break;default:break;}Write_Cmd(addr);Write_Dat(dat/10000%10+'0');Write_Dat(dat/1000%10+'0');Write_Dat(dat/100%10+'0');Write_Dat(dat/10%10+'0');Write_Dat(dat/1%10+'0');}//在指定位置显示汉字//x范围:0-7,y范围:0-3//dat:汉字字形码void Dis_GB(uint8 x,uint8 y,uint16 dat) {uint8 addr;switch(y){case 0:addr = 0x80 + x;break;case 1:addr = 0x90 + x;break;case 2:addr = 0x88 + x;break;case 3:addr = 0x98 + x;break;default:break;}Write_Cmd(addr);Write_Dat((uint8)(dat >> 8));Write_Dat((uint8)(dat));}//LCD初始化void LCD_Init(void){/*RST = 0;delay5ms();delay5ms();RST = 1;PSB = 0;*/Write_Cmd(0X30);Write_Cmd(0X01);Write_Cmd(0X02);Write_Cmd(0X0C);}void main(void){LCD_Init();while(1){Dis_GB(0,0,0xc9b5);Dis_HCGROM(1,0,0x03);Dis_String(0,1,13,strint1);Dis_UNum8(0,2,250);} }。

毕业设计—基于单片机的12864时钟显示

毕业设计—基于单片机的12864时钟显示

学士学位毕业论文(设计)题目:基于单片机的12864时钟显示摘要电子时钟是一种非常广泛日常计时工具,给人们的带来了很大的方便,在社会上越来越流行。

它可以对年、月、日、星期、时、分、秒进行计时,采用直观的数字显示,可以同时显示年月日时分秒等信息,还有时间校准等功能。

该电子时钟主要采用STC89C52单片机作为主控核心,用DS1302时钟芯片作为时钟、液晶12864显示屏显示。

STC89C52单片机是由深圳宏晶科技公司推出的,功耗小,电压可选用4~6V电压供电;DS1302时钟芯片是美国DALLAS公司推出的具有细电流充电功能的低功耗实时时钟芯片,它可以对年、月、日、星期、时、分、秒进行计时,还具有闰年补偿等多种功能,而且DS1302的使用寿命长,误差小;数字显示是采用的12864液晶显示屏来显示,可以同时显示年、月、日、星期、时、分、秒等信息。

此外,该电子时钟还具有时间校准等功能。

关键词:STC89C51单片机,DS1302时钟芯片,液晶12864AbstractElectronic clock is a very extensive daily timing tool, to the people has brought great convenience, more and more popular in the community. It can be the year, month, date, day, hour, minute, second for a time, using intuitive digital display, can display information such as year, month, day, hour, and time alignment functions. The electronic clock is used mainly as a master STC89C52 microcontroller core, with theDS1302 clock chip as a clock, LCD display12864. STC89C52 SCM is a Shenzhen Hong Crystal Technology has introduced, power consumption, voltage can be selected 4 ~ 6V voltage power supply; DS1302 clock chip is American DALLAS company launched with a fine current charging low-power real-time clock chip, it can year, month, date, day, hour, minute, second for a time, also has a leap year compensation and other functions, DS1302 and long life, small error; 12864 LCD digital display isused to display that can display year, month, date, day, hour, minute, second and so on. In addition, the electronic clock also has a time calibration function.Key Words:STC89C51 microcontroller, DS1302 clock chip, LCD 12864目录1绪论 (3)1.1时钟发展史 (3)1.2 目前的研究现状 (4)1.3研究目的及意义 (4)2 总体方案设计 (5)2.1 方案的选择 (5)2.1.1设计要求 (5)2.1.2方案的选择 (5)2.2总体方案组成框图 (6)3系统硬件设计 (6)3. 1主芯片模块 (6)3.1.1 中断系统 (8)3.1.2常用寄存器 (8)3.2晶振和复位电路 (10)3.2.1晶振电路 (10)3.2.2复位电路 (11)3.3 DS1302时钟芯片电路 (11)3.3.1 DS1302引脚图 (11)3.3.2 DS1302寄存器 (12)3.3.3 DS1302外围电路 (13)3.4 LCD12864显示模块 (13)3.4.1 LCD12864引脚功能 (13)3.4.2 LCD12864指令说明 (14)3.4.3 LCD12864电路接线 (15)3.5 红外遥控模块 (16)4 系统软件设计 (17)4.1 主程序设计 (17)4.2 LCD12864驱动程序 (19)4.3 DS1302驱动程序 (21)4.4 红外遥控程序 (24)5 调试结果 (25)5.1 正常显示日期时间画面 (26)5.2 进入调整时间日期画面 (26)5.3图片显示画面 (26)6总结 (27)致谢 (28)参考文献 (29)附录一 (31)附录二 (32)1绪论1.1时钟发展史很早以前,人类主要是利用天文现象和流动物质的连续运动来计时。

12864串口液晶显示程序

12864串口液晶显示程序

#include <reg52.h>#include <intrins.h>#define SENDCOMM 0XF8 //0XF1000#define READCOMM 0XFC //0XF1100#define SENDDATA 0XFA //0XF1010#define READDATA 0XFE //0XF1110void LCD_send_byte(unsigned char a);unsigned char LCD_read_byte(void);void LCD_comm(unsigned char comm);void LCD_setxy(unsigned char x,unsigned char y);void LCD_WriteStr(unsigned char dis_addr_x,unsigned char dis_addr_y,char* str); sbit E_CLK =P2^2; //clock inputsbit RW_SID=P2^1; //data input/outputsbit RS_CS =P2^0; //chip selectvoid delay(unsigned int n){unsigned int i;for(i=0; i<n; i++) {;}}void LCD_send_byte(unsigned char a){unsigned char i;for(i=8;i>0;i--){if(a&(0x01<<(i-1)))RW_SID=1;elseRW_SID=0;delay(100);E_CLK=1;delay(100);E_CLK=0;delay(100);}}unsigned char LCD_read_byte(void){unsigned char i,dat=0;for(i=8;i>0;i--){E_CLK=1;delay(100);if(RW_SID==1)dat|=(0x01<<(i-1));E_CLK=0;delay(100);}return dat;}unsigned char LCD_bf(void){unsigned char readh,readl;RS_CS=1;delay(100);LCD_send_byte(READCOMM);readh=LCD_read_byte();readl=LCD_read_byte();delay(100);RS_CS=0;}void LCD_comm(unsigned char comm) {unsigned char temp;RS_CS=1;delay(100);LCD_send_byte(SENDCOMM);temp=comm&0XF0;LCD_send_byte(temp);temp=((comm&0X0F)<<4)&0XF0; LCD_send_byte(temp);delay(100);RS_CS=0;}void LCD_data(unsigned char lcd_data)unsigned char temp;RS_CS=1;delay(100);LCD_send_byte(SENDDA TA);temp=lcd_data&0xf0;LCD_send_byte(temp);temp=(lcd_data&0X0F)<<4;LCD_send_byte(temp);delay(100);RS_CS=0;}void LCD_setxy(unsigned char x,unsigned char y) //设置显示位置X(1~16),Y(1~4){switch(y){case 1:LCD_comm(0X7F+x);break;case 2:LCD_comm(0X8F+x);break;case 3:LCD_comm(0X87+x);break;case 4:LCD_comm(0X97+x);break;default:break;}}void LCD_WriteStr(unsigned char dis_addr_x,unsigned char dis_addr_y,char* str)// 在指定位置显示字符串{unsigned char LCD_temp;LCD_setxy(dis_addr_x,dis_addr_y);LCD_temp=*str;while(LCD_temp != 0x00){LCD_data(LCD_temp);LCD_temp=*(++str);}}void LCD_init(void){unsigned char i;while(i==0x80)RS_CS=0;delay(500);LCD_comm(0x30);//一次送8位数据LCD_comm(0x0C);//整体显示,游标off,游标位置offLCD_comm(0x01);//清DDRAMLCD_comm(0x02);//DDRAM地址归位LCD_comm(0x80);//设定DDRAM 7位地址000,0000到地址计数器AC }void main(){LCD_init();LCD_WriteStr(3,1,"热烈欢迎");LCD_WriteStr(2,2,"宝鸡文理学院");LCD_WriteStr(1,3,"物理与信息技术系");LCD_WriteStr(2,4,"09测控测控班");while(1);}。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
delaynms(1); //延时是必须的
sendbyte(Ldata);//发送低四位
delaynms(1); //延时是必须的
}
void sendbyte(unsigned char bbyte) //发送一个字节
{
unsigned char i;
for(i=0;i<8;i++)
{
SID=bbyte&0x80; //取出最高位
k=n%1000%100/10; //取余取整运算,求得十位数字
l=n%1000%100%10; //取余取整运算,求得个位数字
write(0,0x80); //写显示地址
write(1,ma4[i]); //将千位数字的字符常量写入LCD
write(1,ma4[j]); //将百位数字的字符常量写入LCD
write(1,ma4[i]); //将十位数字的字符常量写入LCD
write(1,ma4[j]); //将个位数字的字符常量写入LCD
}
/*********************************************************************
main function
write(0,0x01); //清屏,将DDRAM的地址计数器归零
}
void write(bit start, unsigned char ddata) //写指令或数据bit start;定义一个位的变量,他是1或0
{
unsigned char start_data,Hdata,Ldata;
if(start==0) start_data=0xf8;//写指令
write(1,ma4[i]); //将十位数字的字符常量写入LCD
write(1,ma4[j]); //将个位数字的字符常量写入LCD
}
/******************************************************************************
函数功能:显示日
******************************************************************************/
void DisplaySecond()
{
unsigned char i,j;
i=s/10;
j=s%10;
write(0,0x8d); //写显示地址,将十位数字显示在第2行第11列
/*12864LCD(ST7920)驱动程序
可显示年月日时分秒及加减时钟切换*/
#include <REGx51.H>
/*引脚定义*/
#define CS P2_0//片选高电平有效单片LCD使用时可固定高电平
#define SID P2_1//串数究谳
#define SCLK P2_2//串同步时钟信号
******************************************************************************/
void miao()
{
unsigned char i,j;
i=ss/10;
j=ss%10;
write(0,0x8d); //写显示地址,将十位数字显示在第2行第11列
write(1,ma4[i]); //将十位数字的字符常量写入LCD
write(1,ma4[j]); //将个位数字的字符常量写入LCD
}
/******************************************************************************
函数功能:显示小时
******************************************************************************/
voiБайду номын сангаас DisplayHour()
{
unsigned char i,j;
i=h/10;
j=h%10;
write(0,0x89); //写显示地址,将十位数字显示在第2行第5列
函数功能:显示小时
******************************************************************************/
void shi()
{
unsigned char i,j;
i=hh/10;
j=hh%10;
write(0,0x89); //写显示地址,将十位数字显示在第2行第5列
write(1,ma4[i]); //将十位数字的字符常量写入LCD
write(1,ma4[j]); //将个位数字的字符常量写入LCD
}
/******************************************************************************
函数功能:显示年
PSB=0; ;//串口驱动模式;PSB=1时为并行
// RESET=0; delaynms(1); RESET=1; //复位LCD
// CS=1; //串行数据口
write(0,0x30); // DL=0,4位数据;DL=1,8位数据RE=1,扩充指令操作;RE=0,基本指令操作;
write(0,0x0c); //显示打开,光标关,反白关
******************************************************************************/
void nian()
{
unsigned char i,j,k,l;
i=n/1000; //取整运算,求得千位数字
j=n%1000/100; //取余取整运算,求得百位数字
unsigned char code ma4[]={"0123456789"};
unsigned char code ma5[]={"年"};
unsigned charcode ma6[]={"月"};
unsigned char code ma7[]={"日"};
unsigned int count; //定义变量统计中断累计次数
******************************************************************************/
void DisplayMinute()
{
unsigned char i,j;
i=m/10;
j=m%10;
write(0,0x8b); //写显示地址,将十位数字显示在第2行第8列
else start_data=0xfa; //写数据
Hdata=ddata&0xf0;//取高四位
Ldata=(ddata<<4)&0xf0;//取低四位
sendbyte(start_data);//发送起始信号
delaynms(5); //延时是必须的
sendbyte(Hdata);//发送高四位
SCLK=1;
SCLK=0;
bbyte<<=1; //左移
}
}
void delaynms(unsigned int di) //延时
{
unsigned int da,db;
for(da=0;da<di;da++)
for(db=0;db<10;db++);
}
/******************************************************************************
void lcdtest(void);
void lcdcls(void);
/*存放字符串的数组*/
unsigned char code ma[] ={"2015年08月24日"};
unsigned char code ma2[]={"时分秒"};
unsigned char code ma3[]={"12864液晶时钟"};
unsigned int s,m,h; //定义变量储存秒、分钟和小时
unsigned int ss,mm,hh; //定义变量储存秒、分钟和小时
unsigned int n,u,r; //定义变量储存年、月、日
void lcdinit(void)//初始化LCD
{
delaynms(10); //启动等待,等LCM讲入工作状态
***********************************************************************/
void main(void)
{
unsigned char i;
lcdinit();
write(1,ma4[i]); //将十位数字的字符常量写入LCD
write(1,ma4[j]); //将个位数字的字符常量写入LCD
}
/******************************************************************************
函数功能:显示秒
void write(bit start, unsigned char ddata);//bit start;定义一个位的变量,他是1或0
void sendbyte(unsigned char bbyte);
相关文档
最新文档