51定时器和lcd12864做的实时时钟显示(附图)
LCD12864显示实时时钟例程可运行
DS1302是美国DALLAS公司推出的一种高性能、低功耗的实时时钟芯片,附加31字节静态RAM,采用SPI三线接口与CPU进行同步通信,并可采用突发方式一次传送多个字节的时钟信号和RAM数据。
实时时钟可提供秒、分、时、日、星期、月和年,一个月小与31天时可以自动调整,且具有闰年补偿功能。
下面是一段12864液晶显示实时时钟的程序:/****************************************************************************** *********时间:2012.11.30晶振:11.0592MHz芯片:STC89C52RC功能描述:在12864上显示年、月、日、星期、时、分和秒等时间信息******************************************************************************* ********/#include<reg52.h>#define uchar unsigned charsbit CLK=P1^4; //DS1302引脚定义sbit IO=P1^5;sbit CE=P1^6;sbit ACC0=ACC^0;sbit ACC7=ACC^7;sbit RS=P2^4; //12864引脚定义数据口为P0sbit RW=P2^5;sbit EN=P2^6;sbit PSB=P2^1;sbit RET=P2^3;void Input_1byte(uchar TD) //DS1302输入一字节数据{uchar i;ACC=TD;for(i=8;i>0;i--){IO=ACC0;CLK=1;CLK=0;ACC=ACC>>1;}}uchar Output_1byte(void) //DS1302输出一字节数据{uchar i;for(i=8;i>0;i--){ACC=ACC>>1;ACC7=IO;CLK=1;CLK=0;}return(ACC);}void Write_DS1302(uchar add,uchar dat)//向DS1302写{CE=0;CLK=0;CE=1;Input_1byte(add);Input_1byte(dat);CE=0;}uchar Read_DS1302(uchar add) //从DS1302读{uchar inf; //信息临时存储变量CE=0;CLK=0;CE=1;Input_1byte(add);inf=Output_1byte();CE=0;return(inf);}/**********************DS1302初始化*****************************/void init_1302(){if(Read_DS1302(0xd1)==0x55) //判断内存单元的内容,是否进行初始化 {return;}else{Write_DS1302(0x8e,0x00); //关闭写保护Write_DS1302(0x90,0x00); //电池充电设置Write_DS1302(0x80,0x00); //秒Write_DS1302(0x82,0x54); //分Write_DS1302(0x84,0x20); //时Write_DS1302(0x86,0x30); //日Write_DS1302(0x88,0x11); //月Write_DS1302(0x8a,0x05); //星期Write_DS1302(0x8c,0x12); //年Write_DS1302(0xd0,0x55); //写RAMWrite_DS1302(0x8e,0x80); //打开写保护}}/**********************延时函数*****************************/ void DelayUs2x(unsigned char t){while(--t);}void DelayMs(unsigned char t){while(t--){//大致延时1mSDelayUs2x(245);DelayUs2x(245);}}/**********************12864判忙*****************************/ void check_busy(){RS=0;RW=1;EN=1;while((P0&0x80)==0x80);EN=0;}/**********************12864写指令*****************************/ void write_com(uchar com){check_busy();RS=0;RW=0;EN=1;P0=com;DelayUs2x(250);EN=0;DelayUs2x(250);}/**********************12864写数据*****************************/void write_data(uchar dat){check_busy();RS=1;RW=0;EN=1;P0=dat;DelayUs2x(250);EN=0;DelayUs2x(250);}/**********************12864初始化函数*****************************/void init(){DelayMs(40); //大于40MS的延时程序PSB=1; //设置为8BIT并口工作模式DelayMs(1); //延时RET=0; //复位DelayMs(1); //延时RET=1; //复位置高DelayMs(200);write_com(0x30); //选择基本指令集DelayUs2x(250); //延时大于100uswrite_com(0x30); //选择8bit数据流DelayUs2x(200); //延时大于37uswrite_com(0x0c); //开显示(无游标、不反白)DelayUs2x(250); //延时大于100uswrite_com(0x01); //清除显示,并且设定地址指针为00HDelayMs(200); //延时大于10mswrite_com(0x06); //指定在资料的读取及写入时,设定游标的移动方向及指定显示的移位,光标从右向左加1位移动DelayUs2x(250); //延时大于100us}/**********************清屏*****************************/void clrscreen(){write_com(0x01);DelayMs(15);}/*********************************************************主函数********************************************************/void main(){uchar sec,sec1,sec2;uchar min,min1,min2;uchar hour,hour1,hour2;uchar date,date1,date2;uchar mon,mon1,mon2;uchar day;uchar year,year1,year2;uchar table1[]="年月日时分秒星期温度摄氏"; //长度24uchar table2[]={0XD2,0XBB, 0XB6,0XFE, 0XC8,0XFD, 0XCB,0XC4, 0XCE,0XE5, 0XCE,0XF9, 0XC8,0XD5}; //长度14 uchar table3[]="0123456789"; //长度10init(); //液晶初始化clrscreen();DelayMs(200);init_1302(); //1302初始化只初始化一下就可以需要下载两次DelayMs(50);write_com(0x80); //显示20write_data('2');write_data('0');write_com(0x82); //显示年write_data(table1[0]);write_data(table1[1]);write_com(0x84); //显示月write_data(table1[2]);write_data(table1[3]);write_com(0x86); //显示日write_data(table1[4]);write_data(table1[5]);write_com(0x91); //显示时write_data(table1[6]);write_data(table1[7]);write_com(0x93); //显示分write_data(table1[8]);write_data(table1[9]);write_com(0x95); //显示秒write_data(table1[10]);write_data(table1[11]);write_com(0x88); //显示星期write_data(table1[12]);write_data(table1[13]);write_data(table1[14]);write_data(table1[15]);while(1){sec=Read_DS1302(0x81); ////读秒sec1=sec&0x0f; //个位sec2=sec>>4; //十位min=Read_DS1302(0x83); ////读分min1=min&0x0f; //个位min2=min>>4; //十位hour=Read_DS1302(0x85); ////读时hour1=hour&0x0f; //个位hour2=hour>>4; //十位date=Read_DS1302(0x87); ////读日date1=date&0x0f; //个位date2=date>>4; //十位mon=Read_DS1302(0x89); ////读月mon1=mon&0x0f; //个位mon2=mon>>4; //十位year=Read_DS1302(0x8d); ////读年year1=year&0x0f; //个位year2=year>>4; //十位day=Read_DS1302(0x8b); ////读星期write_com(0x94); //送显示内容write_data(table3[sec2]); //秒write_data(table3[sec1]);write_com(0x92);write_data(table3[min2]); //分write_data(table3[min1]);write_com(0x90);write_data(table3[hour2]); //时write_data(table3[hour1]);write_com(0x85);write_data(table3[date2]); //日write_data(table3[date1]);write_com(0x83);write_data(table3[mon2]); //月write_data(table3[mon1]);write_com(0x81);write_data(table3[year2]); //年write_data(table3[year1]);write_com(0x8a);write_data(table2[2*day-2]); //星期write_data(table2[2*day-1]);}}。
基于51单片机的12864液晶时钟完整程序(已通过)
{
uchar flag ;
flag=uc_R1302(0x81); // 在秒寄存器读数 ,ch=
if (flag&0x80) //
{
v_W1302(0x8e,0x00); //
v_W1302(0x80,0x45); //0秒
v_W1302(0x82,0x29); //35分钟
T_RST = 1;
v_WTInputByte(ucAddr); /* 地址,命令 */
ucDa = uc_RTOutputByte(); /* 读1Byte数据 */
T_CLK = 1;
T_RST =0;
return(ucDa);
}
/********************************************************/
void days()
{
if ( yue== 0x01 && ri== 0x01 ){ lcd_write_string(4,3,"元旦节"); }
if ( yue== 0x02 && ri== 0x14 ){ lcd_write_string(4,3,"情人节"); }
if ( yue== 0x03 && ri== 0x08 ){ lcd_write_string(4,3,"妇女节"); }
}
void WRI(char instru) //液晶写指令
{
lcd_check_busy();
RS = 0 ; //显示指令
RW = 0 ; //写
LCD12864液晶显示电子钟设计
《单片机原理及应用》课程设计说明书题目LCD12864 液晶显示电子钟设计系(部)专业(班级)姓名学号指导教师起止日期课程设计任务书系(部):专业:目录一、12864液晶的工作原理 (4)二、方案设计 (5)实物硬件设计 (5)系统硬件设计 (5)主芯片模块 (5)晶振和复位模块 (6)按钮模块 (7)系统软件设计 (7)主程序设计 (7)三、仿真和分析 (8)四、总结体会 (8)参考文献 (9)一、12864液晶的工作原理液晶显示屏中的业态光电显示材料,利用液晶的电光效应把电信号转换成数字符、图像等可见信号。
如图1-1,液晶正常情况下,其分子排列很有秩序,显得清澈透明,一旦加上直流电场后,分子的排列被打乱,一部分液晶变的不透明,颜色加深因而能显示数字和图像。
管脚一共1个CS1左半屏片选端,CS2右半屏片选端;V0液晶显示驱动电压,通过一个电位器接到VCC;RS数据指令选择信号,H为数据,L为指令,也叫D/I;R/W读写选择信号,H为读,L为写,。
E为LCD使能端,R/W为L时,E信号下降沿锁存DB7-DB0;R/W为H时,E为H,DDRAM数据读到DB7-DB0。
DB0-DB7数据传输端口。
RST复位信号。
-VOUT和V0为液晶显示驱动电压。
12864是一种图形点阵液晶显示器,它主要由行驱动器/列驱动器及128×64全点阵液晶显示器组成。
可完成图形显示,也可以显示8×4个(16×16点阵)汉字。
图1-1 12864LCD液晶显示屏二、方案设计实物硬件设计单片机控制液晶显示屏系统总共可分为六个环节,分别是单片机控制系统、12864字符显示模块、控制开关模块、晶振控制模块、复位电路模块和DS1302时钟控制模块。
通过这六个模块的协调工作就可以完成相应的液晶屏控制和显示功能。
这六个模块的相互连接如图2-1:图2-1 硬件组成框图系统硬件设计本硬件电路主要由四大模块组成:主芯片模块;晶振和复位电路模块;控制接钮模块;显示电路模块。
LCD12864显示实时时钟例程可运行
DS1302是美国DALLAS公司推出的一种高性能、低功耗的实时时钟芯片,附加31字节静态RAM,采用SPI三线接口与CPU进行同步通信,并可采用突发方式一次传送多个字节的时钟信号和RAM数据。
实时时钟可提供秒、分、时、日、星期、月和年,一个月小与31天时可以自动调整,且具有闰年补偿功能。
下面是一段12864液晶显示实时时钟的程序:/****************************************************************************** *********时间:2012.11.30晶振:11.0592MHz芯片:STC89C52RC功能描述:在12864上显示年、月、日、星期、时、分和秒等时间信息******************************************************************************* ********/#include<reg52.h>#define uchar unsigned charsbit CLK=P1^4; //DS1302引脚定义sbit IO=P1^5;sbit CE=P1^6;sbit ACC0=ACC^0;sbit ACC7=ACC^7;sbit RS=P2^4; //12864引脚定义数据口为P0sbit RW=P2^5;sbit EN=P2^6;sbit PSB=P2^1;sbit RET=P2^3;void Input_1byte(uchar TD) //DS1302输入一字节数据{uchar i;ACC=TD;for(i=8;i>0;i--){IO=ACC0;CLK=1;CLK=0;ACC=ACC>>1;}}uchar Output_1byte(void) //DS1302输出一字节数据{uchar i;for(i=8;i>0;i--){ACC=ACC>>1;ACC7=IO;CLK=1;CLK=0;}return(ACC);}void Write_DS1302(uchar add,uchar dat)//向DS1302写{CE=0;CLK=0;CE=1;Input_1byte(add);Input_1byte(dat);CE=0;}uchar Read_DS1302(uchar add) //从DS1302读{uchar inf; //信息临时存储变量CE=0;CLK=0;CE=1;Input_1byte(add);inf=Output_1byte();CE=0;return(inf);}/**********************DS1302初始化*****************************/void init_1302(){if(Read_DS1302(0xd1)==0x55) //判断内存单元的内容,是否进行初始化 {return;}else{Write_DS1302(0x8e,0x00); //关闭写保护Write_DS1302(0x90,0x00); //电池充电设置Write_DS1302(0x80,0x00); //秒Write_DS1302(0x82,0x54); //分Write_DS1302(0x84,0x20); //时Write_DS1302(0x86,0x30); //日Write_DS1302(0x88,0x11); //月Write_DS1302(0x8a,0x05); //星期Write_DS1302(0x8c,0x12); //年Write_DS1302(0xd0,0x55); //写RAMWrite_DS1302(0x8e,0x80); //打开写保护}}/**********************延时函数*****************************/ void DelayUs2x(unsigned char t){while(--t);}void DelayMs(unsigned char t){while(t--){//大致延时1mSDelayUs2x(245);DelayUs2x(245);}}/**********************12864判忙*****************************/ void check_busy(){RS=0;RW=1;EN=1;while((P0&0x80)==0x80);EN=0;}/**********************12864写指令*****************************/ void write_com(uchar com){check_busy();RS=0;RW=0;EN=1;P0=com;DelayUs2x(250);EN=0;DelayUs2x(250);}/**********************12864写数据*****************************/void write_data(uchar dat){check_busy();RS=1;RW=0;EN=1;P0=dat;DelayUs2x(250);EN=0;DelayUs2x(250);}/**********************12864初始化函数*****************************/void init(){DelayMs(40); //大于40MS的延时程序PSB=1; //设置为8BIT并口工作模式DelayMs(1); //延时RET=0; //复位DelayMs(1); //延时RET=1; //复位置高DelayMs(200);write_com(0x30); //选择基本指令集DelayUs2x(250); //延时大于100uswrite_com(0x30); //选择8bit数据流DelayUs2x(200); //延时大于37uswrite_com(0x0c); //开显示(无游标、不反白)DelayUs2x(250); //延时大于100uswrite_com(0x01); //清除显示,并且设定地址指针为00HDelayMs(200); //延时大于10mswrite_com(0x06); //指定在资料的读取及写入时,设定游标的移动方向及指定显示的移位,光标从右向左加1位移动DelayUs2x(250); //延时大于100us}/**********************清屏*****************************/void clrscreen(){write_com(0x01);DelayMs(15);}/*********************************************************主函数********************************************************/void main(){uchar sec,sec1,sec2;uchar min,min1,min2;uchar hour,hour1,hour2;uchar date,date1,date2;uchar mon,mon1,mon2;uchar day;uchar year,year1,year2;uchar table1[]="年月日时分秒星期温度摄氏"; //长度24uchar table2[]={0XD2,0XBB, 0XB6,0XFE, 0XC8,0XFD, 0XCB,0XC4, 0XCE,0XE5, 0XCE,0XF9, 0XC8,0XD5}; //长度14 uchar table3[]="0123456789"; //长度10init(); //液晶初始化clrscreen();DelayMs(200);init_1302(); //1302初始化只初始化一下就可以需要下载两次DelayMs(50);write_com(0x80); //显示20write_data('2');write_data('0');write_com(0x82); //显示年write_data(table1[0]);write_data(table1[1]);write_com(0x84); //显示月write_data(table1[2]);write_data(table1[3]);write_com(0x86); //显示日write_data(table1[4]);write_data(table1[5]);write_com(0x91); //显示时write_data(table1[6]);write_data(table1[7]);write_com(0x93); //显示分write_data(table1[8]);write_data(table1[9]);write_com(0x95); //显示秒write_data(table1[10]);write_data(table1[11]);write_com(0x88); //显示星期write_data(table1[12]);write_data(table1[13]);write_data(table1[14]);write_data(table1[15]);while(1){sec=Read_DS1302(0x81); ////读秒sec1=sec&0x0f; //个位sec2=sec>>4; //十位min=Read_DS1302(0x83); ////读分min1=min&0x0f; //个位min2=min>>4; //十位hour=Read_DS1302(0x85); ////读时hour1=hour&0x0f; //个位hour2=hour>>4; //十位date=Read_DS1302(0x87); ////读日date1=date&0x0f; //个位date2=date>>4; //十位mon=Read_DS1302(0x89); ////读月mon1=mon&0x0f; //个位mon2=mon>>4; //十位year=Read_DS1302(0x8d); ////读年year1=year&0x0f; //个位year2=year>>4; //十位day=Read_DS1302(0x8b); ////读星期write_com(0x94); //送显示内容write_data(table3[sec2]); //秒write_data(table3[sec1]);write_com(0x92);write_data(table3[min2]); //分write_data(table3[min1]);write_com(0x90);write_data(table3[hour2]); //时write_data(table3[hour1]);write_com(0x85);write_data(table3[date2]); //日write_data(table3[date1]);write_com(0x83);write_data(table3[mon2]); //月write_data(table3[mon1]);write_com(0x81);write_data(table3[year2]); //年write_data(table3[year1]);write_com(0x8a);write_data(table2[2*day-2]); //星期write_data(table2[2*day-1]);}}。
51单片机LCD12864绘图
LCD12864绘图方法如下:一、绘图方法:1、使用扩展指令集并关闭绘图显示2、输入y轴坐标3、输入x轴坐标4、写入数据D15-D85、写入数据D7-D06、开绘图显示7、返回普通指令对应程序如下:LCD_write_comm(0x34);//使用扩充指令集LCD_delay();LCD_write_comm(0x80+y);//y坐标起始地址LCD_delay();LCD_write_comm(0x80+x);//x坐标起始地址LCD_delay();LCD_write_date(0x55);//写入数据D15-D8LCD_delay();LCD_write_date(0x55);//写入数据D7-D0LCD_delay();LCD_write_comm(0x36);//显示RAMLCD_delay();LCD_write_comm(0x30);//退出扩展指令集LCD_delay();程序执行效果则是第一行的第1-16个像素点会描出0x5555的二进制像素点,则后面的整个屏幕则是花屏,如果只想看到这0x5555,这几个像素点,则必须要给LCD的RAM重新赋值,也可以说是清屏,程序如下:void LCD12864_RAM_Cls(){u8 x,y;//xy坐标LCD_write_comm(0x34);//使用扩充指令集LCD_delay();for(y=0;y<32;y++){LCD_write_comm(0x80+y);//y坐标起始地址LCD_delay();LCD_write_comm(0x80);//x坐标起始地址LCD_delay();for(x=0;x<16;x++){LCD_write_date(0x00);LCD_delay();LCD_write_date(0x00);LCD_delay();}}LCD_write_comm(0x36);//显示RAMLCD_delay();LCD_write_comm(0x30);//退出扩展指令集LCD_delay();}二、坐标与显示X轴坐标设定初始值后会自动加1,取值范围0-15Y轴需要人为加1,取值范围为0-31整个屏幕分为上下屏,上屏对应坐标为x(0-7)y(0-31),下屏对应坐标为x(8-15)y(0-31)三、LCD12864图片显示代码1、Main.c#include"common.h"#include"delay.h"#include"12864.h"unsigned char code Picture[]= // 图片数据表{//此处添加图片取模16进制码共1024Byte,取模方式:从左到右从上到下0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01, 0x80,0x06,0x30,0x01,0xE0,0x00,0x00,0x2A,0x00,0x00,0xD8,0x00,0x00,0x00,0x00,0x01, 0x80,0x0F,0x7B,0x63,0xE0,0x00,0x00,0x22,0x00,0x01,0x24,0x00,0x00,0x00,0x00,0x01,0x80,0x0D,0xDB,0x63,0x01,0xBC,0x00,0x08,0x00,0x00,0x88,0x00,0x00,0x00,0x00,0x01, 0x80,0x0C,0x1B,0x63,0x07,0xB0,0x00,0x00,0x00,0x00,0x50,0x00,0x00,0x00,0x00,0x01, 0x80,0x0C,0x1B,0x63,0xED,0xB0,0xDB,0x00,0x01,0x00,0x20,0x00,0x00,0x00,0x00,0x01, 0x80,0x0C,0x19,0xE1,0xE7,0xB0,0xDB,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x01, 0x80,0x0C,0x19,0xE1,0xE7,0xB0,0xDB,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x01, 0x80,0x00,0x00,0x60,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x01, 0x80,0x00,0x03,0xC0,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x01, 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x05,0x00,0x00,0x00,0x00,0x00,0x01, 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x0A,0x80,0x00,0x00,0x00,0x00,0x01, 0x80,0x00,0x00,0x0A,0x00,0x00,0xFF,0xF8,0xE0,0x05,0x00,0x00,0x00,0x00,0x00,0x01, 0x80,0x06,0xC0,0x15,0x00,0x1F,0xFF,0xFF,0xC0,0x02,0x00,0x00,0x00,0x00,0x00,0x01, 0x80,0x09,0x20,0x11,0x00,0xFB,0xFF,0xE1,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x01, 0x80,0x08,0x20,0x0A,0x03,0x9F,0x00,0x9E,0x3E,0x00,0x00,0x00,0x00,0x00,0x00,0x01, 0x80,0x04,0x40,0x04,0x0E,0x70,0x00,0x81,0xC7,0x80,0x01,0x40,0x00,0x00,0x00,0x01, 0x80,0x02,0x80,0x00,0x1D,0x80,0x00,0xE0,0x61,0xE0,0x02,0xA0,0x00,0x00,0x00,0x01, 0xC0,0x01,0x00,0x00,0x77,0x9F,0xFC,0xF0,0x18,0xF8,0x02,0x20,0x00,0x00,0x00,0x01, 0xC0,0x00,0x00,0x01,0xDF,0x00,0x00,0xF3,0x0C,0x3C,0x01,0x40,0x00,0x00,0x00,0x01, 0xC0,0x00,0x00,0x03,0x9E,0x00,0x00,0xF8,0x06,0x1E,0x00,0x80,0x00,0x00,0x00,0x01, 0x80,0x00,0x00,0x07,0x0E,0x30,0x01,0xFC,0x7F,0x07,0x00,0x00,0x00,0x00,0x00,0x01, 0x80,0x00,0x00,0x07,0x0E,0x30,0x01,0xFC,0x7F,0x07,0x00,0x00,0x00,0x00,0x00,0x01, 0x80,0x00,0x00,0x7E,0xFF,0xFF,0xFF,0xFF,0xFF,0x83,0xC0,0x00,0x00,0x00,0x00,0x01,0x80,0x00,0x0F,0xFD,0xFF,0xFF,0xFF,0xFF,0xFC,0x01,0xF0,0x00,0x00,0x00,0x00,0x01, 0x80,0x00,0x3F,0x81,0xFF,0x00,0x00,0x00,0x00,0x1F,0xF0,0x00,0x00,0x00,0x00,0x01, 0x80,0x00,0xFE,0xF0,0x00,0x00,0x01,0x00,0x00,0xC0,0x1C,0x00,0x00,0x00,0x00,0x01, 0x80,0x03,0xC0,0x07,0x80,0x00,0x03,0xE0,0x07,0x00,0x1C,0x00,0x00,0x00,0x00,0x01, 0x80,0x03,0x80,0x03,0x60,0x00,0x03,0xE0,0x0C,0x00,0x0E,0x00,0x00,0x00,0x00,0x01, 0x80,0x07,0x00,0x00,0xC0,0x00,0x00,0x20,0x18,0x00,0x07,0x00,0x00,0x00,0x00,0x01, 0x80,0x09,0x01,0x80,0x60,0x00,0x00,0x20,0x73,0x9F,0x03,0x80,0x00,0x00,0x00,0x01, 0x80,0x1E,0x0F,0xF2,0x20,0x00,0x00,0x20,0x67,0xFF,0xC1,0xC0,0x00,0x00,0x00,0x01, 0x80,0x1E,0x1F,0xF9,0x30,0x00,0x00,0x20,0xEF,0xFF,0xE0,0xE0,0x00,0x00,0x00,0x01, 0x80,0x38,0x3F,0xFC,0x90,0x00,0x00,0x20,0xCB,0xFF,0xF9,0xF0,0x00,0x00,0x00,0x01, 0x80,0x7F,0x7F,0xFE,0x10,0x00,0x00,0x20,0xDB,0xFF,0xFF,0xF0,0x00,0x00,0x00,0x01, 0x80,0x6E,0xF9,0xBF,0x10,0x00,0x00,0x20,0xF7,0xED,0xFF,0xF0,0x00,0x00,0x00,0x01, 0x80,0x7C,0xFC,0x3F,0x10,0x00,0x00,0x20,0x67,0xE1,0xFD,0xE0,0x00,0x00,0x00,0x01, 0x80,0x7C,0xFC,0x3F,0x10,0x00,0x00,0x20,0x67,0xE1,0xFD,0xE0,0x00,0x00,0x00,0x01, 0x80,0x38,0xFC,0x3F,0x18,0x00,0x00,0x20,0x87,0xE0,0xFD,0xC0,0x00,0x00,0x00,0x01, 0x80,0x38,0xF1,0x8F,0x18,0x00,0x1F,0xE7,0x87,0x9C,0x7D,0xC0,0x00,0x00,0x00,0x01, 0x80,0x1C,0xFE,0x1F,0x81,0xFF,0xFF,0xC0,0x0F,0xE0,0xFF,0x80,0x00,0x00,0x00,0x01, 0x80,0x0C,0xFC,0x3F,0x80,0x00,0x00,0x00,0x0F,0xE1,0xF8,0x00,0x00,0x00,0x00,0x01, 0x80,0x00,0xF9,0xBF,0xFF,0xFF,0xFF,0xFF,0xFF,0xEC,0xFE,0x00,0x00,0x00,0x00,0x01,0x80,0x03,0xF9,0xBF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC0,0x00,0x00,0x00,0x01,0x80,0x0F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC0,0x00,0x00,0x00,0x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03, 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03, 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03, 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01, 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01, 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01, 0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01, 0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01, 0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01, 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01, 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01, 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01, 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01, 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01, 0xE0,0x00,0x00,0x00,0x60,0x00,0x00,0x01,0xC0,0x02,0x80,0x00,0x00,0x00,0x1C,0x01, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};void main(){LCD12864_init();//LCD初始化//LCD12864_RAM_Cls();LCD_Picture_show(Picture);while(1);}2、common.h#ifndef __COMMON_H#define __COMMON_H#include<STC12C5A60S2.h>#include "intrins.h"#define u8 unsigned char//无符号字符型#define u16 unsigned int//无符号整型#endif3、delay.h#ifndef __DELAY_H#define __DELAY_H#include "common.h"#define MAIN_Fosc 24000000L //定义主时钟void delay_ms(u16 ms);void LCD_delay();//LCD延时函数#endif4、delay.c#include "delay.h"//-------毫秒延时函数---------------void delay_ms(u16 ms){u16 i;do{i = MAIN_Fosc / 13000;while(--i) ; //14T per loop }while(--ms);}//------LCD延时函数-----------------void LCD_delay(void){_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();}5、12864.h#ifndef __12864_H#define __12864_h#include "common.h"sbit CS =P1^1;//片选sbit SID=P1^2;//数据口sbit CLK=P1^3;//同步时钟void LCD_write_spi(u8 date);//LCD SPI数据写入void LCD_write_comm(u8 comm);//LCD写指令void LCD_write_date(u8 date);//LCD写数据void LCD12864_init();//LCD初始化void LCD12864_RAM_Cls();//RAM清屏void LCD_print(u8 *date);//LCD字符串显示void LCD_Picture_show(u8 *date);#endif6、12864.c#include"common.h"#include"delay.h"#include"12864.h"//------LCD SPI数据写入--------------------void LCD_write_spi(u8 date){u8 i;for(i=0;i<8;i++){CS=1;if(date&0x80){SID=1;}else{SID=0;}date <<= 1;CLK=1;LCD_delay();CLK=0;}}//------LCD写指令--------------------void LCD_write_comm(u8 comm){u8 date = 0xf8;//串行写入指令到LCD(数据手册)u8 comm_H = comm&0xf0;u8 comm_L = comm<<4;CS =0;CLK=0;SID=0;LCD_delay();LCD_write_spi(date);LCD_write_spi(comm_H);LCD_write_spi(comm_L);CS=0;}//------LCD写数据-----------------------void LCD_write_date(u8 date){u8 date2 = 0xfa;//串行写入指令到LCD(数据手册)u8 date_H = date&0xf0;u8 date_L = date<<4;CS =0;CLK=0;SID=0;LCD_delay();LCD_write_spi(date2);LCD_write_spi(date_H);LCD_write_spi(date_L);CS=0;}//-----LCD初始化--------------------------void LCD12864_init(){LCD_write_comm(0x01);//清屏幕delay_ms(1);LCD_write_comm(0x0c);//开显示,游标显示关闭LCD_delay();LCD_write_comm(0x81);//设定坐标LCD_delay();}//-----写RAM清屏--------------------------void LCD12864_RAM_Cls(){u8 x,y;//xy坐标LCD_write_comm(0x34);//使用扩充指令集LCD_delay();for(y=0;y<32;y++){LCD_write_comm(0x80+y);//y坐标起始地址LCD_delay();LCD_write_comm(0x80);//x坐标起始地址LCD_delay();for(x=0;x<16;x++){LCD_write_date(0x00);LCD_delay();LCD_write_date(0x00);LCD_delay();}}LCD_write_comm(0x36);//显示RAMLCD_delay();LCD_write_comm(0x30);//退出扩展指令集LCD_delay();}//----LCD字符串显示-----------------------void LCD_print(u8 *date){u8 j=0;while(date[j]!='\0'){LCD_write_date(date[j]);j++;LCD_delay();}}//----图片显示-----------------------------void LCD_Picture_show(u8 *date){u8 x,y;//xy坐标LCD_write_comm(0x34);//使用扩充指令集LCD_delay();for(y=0;y<32;y++){LCD_write_comm(0x80+y);//y坐标起始地址LCD_delay();LCD_write_comm(0x80);//x坐标起始地址LCD_delay();for(x=0;x<8;x++)//写上半屏幕{LCD_write_date(date[16*y+x*2]);LCD_delay();LCD_write_date(date[16*y+x*2+1]);LCD_delay();}for(x=0;x<8;x++)//写下半屏幕{LCD_write_date(date[16*(y+32)+x*2]);LCD_delay();LCD_write_date(date[16*(y+32)+x*2+1]);LCD_delay();}}LCD_write_comm(0x36);//显示RAMLCD_delay();LCD_write_comm(0x30);//退出扩展指令集LCD_delay();}四、程序执行效果。
基于51单片机的12864液晶显示的万年历
附录程序
/*****************说明*********************************** 基于 51 单片机的 12864 液晶显示的万年历
版权所有,如需转载请通知本人,不得用于商业用途 ,仅限学习交流之用
*****************************************************************/
3
图-1 主控制系统
2.3.2 时钟电路模块的设计 DS1302 是一种高性能、低功耗、带RAM的实时时钟电路,它可以对年、月、日、周日、
时、分、秒进行计时,具有闰年补偿功能,工作电压为2.5V~5.5V。采用三线接口与CPU进 行同步通信,并可采用突发方式一次传送多个字节的时钟信号或RAM数据。DS1302内部有一 个31×8的用于临时性存放数据的RAM寄存器。DS1302是DS1202的升级产品,与DS1202兼容, 但增加了主电源/后背电源双电源引脚,同时提供了对后背电源进行涓细电流充电的能力。
//延时 1MS/次
unsigned char
{
sec,min,hour,day,month,year,cen,week,
unsigned char i;
next,aa,bb,cc,dd,mm,temp0,LunarMonth,
while(--a)
LunarDay,LunarYear;
{
int temp;
9三三系统的软件设计系统的软件设计3131程序流程框图程序流程框图图图aa主程序流程图主程序流程图10图b计算阳历程序流程图计算阳历程序流程图1112图图cc时间调整程序流程图时间调整程序流程图yynnyynnyy图图dd设置温度报警闹钟的数据保存到设置温度报警闹钟的数据保存到at24c02at24c02中中是否进入温度报警上下限温度设置设置是否进入设置闹钟时间设置报警温度上下限开始设置闹钟的时间开始报警闹钟的开关是否开起at24c02存设置的功能保蜂鸣器开启闹钟报警功能开启结束设置13五五作品功能实现作品功能实现通过硬件的焊接与程序的编写本电子万年历终于完成了实现的功能如下
51单片机控制DS1302在液晶12864上的时间显示
} return DAT; }
/******************************************************************* 函数名称: UCHAR 1302_read( UCHAR add )
函数功能: 读出指定位置的数据 输入参数: add,地址; 输出函数: Temp
********************************************************************/
UCHAR DS1302_read( UCHAR add )
{
UCHAR Temp;
ce=0;
sclk=0;
ce=1; DS1302write_byte( add );
/******************************************************************* 函数名称:1302write_byte( UCHAR dat)
函数功能: 写入一个字节( 在 sclk 的上升沿写入,最低位先写入 ) 输入参数: dat 要写入的字节 输出函数: 无
********************************************************************/
UCHAR DS1302read_byte( ) { int i; UCHAR DAT;
sclk=0; for(i=0;i<8;i++)
{ DAT=DAT>>1; if(io==1) DAT|=0x80; sclk=1;
********************************************************************/ห้องสมุดไป่ตู้
51单片机实现定时器2、12864液晶显示、显示图片、滚动字符、DS18B20、转速、超声波测距、速
//*******************资源配置***********************////******计数器0用于超声波记录接收端高电平时长*******////******计数器1用于记录1s内外部脉冲数目即转速*******////********定时器2用于精确定时,定时时间50ms*********////*****************P3^5用于脉冲计数*****************//#include <reg52.H>#include <intrins.h>//*************特殊引脚定义*****************//sbit RX = P1^0; //超声波接收端sbit TX = P1^1; //超声波触发端sbit RS = P2^6;//LCD数据/命令控制端sbit RW = P2^5;//读写控制端sbit EN = P2^7; //使能端sbit RES= P2^4; //复位端sbit PSB= P2^3; //并口/串口选择端sbit DQ = P3^7; //DS18B20数据端sbit BEEP=P1^5; //蜂鸣器#define DataPort P0 //MCU P0<------> LCM#define uchar unsigned char#define uint unsigned int//***********Function Definition*********************////****************函数声明***************************//void LCD_Write_number(uchar s);void Write_char(bit start, uchar ddata); //写入某坐标void Send_byte(uchar bbyte);void Lcd_init(void);//lcd初始化void Disp_img(uchar *img);//显示图片void LCD_Write_string(uchar X,uchar Y,uchar*s); //写入某字符串void LCD_set_xy( uchar x,uchar y );void Lcd_Mark3(void); //画面3void Lcd_Mark2(void); //画面2bit temp_flag; //判断DS18B20正常工作位DS18B20_init();//DS18B20初始化void delay(uint num);//DS18B20延时函数void Delaynms(uint di);//短延时void delayms(uint x);//1ms延时函数readonebyte(void);//读一个字节函数void writeonebyte(uchar dat); //写一个字节函数void gettemperture(void);//获取温度值void temperture_display(); //温度显示函数void tempconv(); //温度转换void beep(); //蜂鸣器响一声函数void timer_init(); //中断初始化函数(计数器0,计数器1,定时器2)void zhuansu_display(); //转速显示函数void speed_conv(); //速度转换函数void speed_display(); //速度显示函数void chaoshengbo_conv(void); //超声波转换//***************变量定义*****************//uchar data temp_dat[2]={0}; //temp[0],temp[1]用来存放温度的低、高8位uchar data DQdisp_buf[5]={0}; //温度显示缓冲区uchar zhuansu_buff[6]={0}; //转速显示缓存uchar speed_buff[6]={0};//速度显示缓存uchar temp_comp; //存放温度整数部分uchar DS18B20_OK,speed2;//DS18B20_OK=0复位正常uchar t2=0,T,L,H,WENDU; //t2代表timer2中断次数,T代表温度整数部分//H:温度高8位,L:温度低8位uint time=0; //超声波往返时间long S=0,num1=0,speed; //s表示超声波距离,num1表示发动机转速// speed表示车轮转速=》速度bit flag =0; //超声波中断溢出标志位uchar disbuff[4]={0}; //超声波数据显示缓存uchar code num[]={"09 :.-℃"};uchar code line1_data[]={"速度:km/h"};uchar code line2_data[]={"转速:r/min"};uchar code line3_data[]={"前方车距:m"};uchar code line4_data[]={"车内温度: "};uchar code line5_data[]={" #**欢迎使用**# "};uchar code line6_data[]={" 您的安全"};uchar code line7_data[]={" 是全家人"};uchar code line8_data[]={" 最大的幸福···"};uchar code picture[]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0 0,0x00,0x06,0x30,0x01,0xE0,0x00,0x00,0x2A,0x00,0x00,0xD8,0x00,0x00,0x00,0x00,0x 00,0x00,0x0F,0x7B,0x63,0xE0,0x00,0x00,0x22,0x00,0x01,0x24,0x00,0x00,0x00,0x00,0x0 0,0x00,0x0F,0xFB,0x63,0x07,0x34,0x00,0x14,0x00,0x01,0x04,0x00,0x00,0x00,0x00,0x0 0,0x00,0x0D,0xDB,0x63,0x01,0xBC,0x00,0x08,0x00,0x00,0x88,0x00,0x00,0x00,0x00,0x0x00,0x0C,0x1B,0x63,0x07,0xB0,0x00,0x00,0x00,0x00,0x50,0x00,0x00,0x00,0x00,0x0 0,0x00,0x0C,0x1B,0x63,0xED,0xB0,0xDB,0x00,0x01,0x00,0x20,0x00,0x00,0x00,0x00,0x 00,0x00,0x0C,0x19,0xE1,0xE7,0xB0,0xDB,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x 00,0x00,0x0C,0x19,0xE1,0xE7,0xB0,0xDB,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x 00,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x0 0,0x00,0x00,0x03,0xC0,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x0 0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x05,0x00,0x00,0x00,0x00,0x00,0x0 0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x0A,0x80,0x00,0x00,0x00,0x00,0x0 0,0x00,0x00,0x00,0x0A,0x00,0x00,0xFF,0xF8,0xE0,0x05,0x00,0x00,0x00,0x00,0x00,0x0 0,0x00,0x06,0xC0,0x15,0x00,0x1F,0xFF,0xFF,0xC0,0x02,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x09,0x20,0x11,0x00,0xFB,0xFF,0xE1,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x0 0,0x00,0x08,0x20,0x0A,0x03,0x9F,0x00,0x9E,0x3E,0x00,0x00,0x00,0x00,0x00,0x00,0x0 0,0x00,0x04,0x40,0x04,0x0E,0x70,0x00,0x81,0xC7,0x80,0x01,0x40,0x00,0x00,0x00,0x0 0,0x00,0x02,0x80,0x00,0x1D,0x80,0x00,0xE0,0x61,0xE0,0x02,0xA0,0x00,0x00,0x00,0x 00,0x00,0x01,0x00,0x00,0x77,0x9F,0xFC,0xF0,0x18,0xF8,0x02,0x20,0x00,0x00,0x00,0x00x00,0x00,0x00,0x01,0xDF,0x00,0x00,0xF3,0x0C,0x3C,0x01,0x40,0x00,0x00,0x00,0x0 0,0x00,0x00,0x00,0x03,0x9E,0x00,0x00,0xF8,0x06,0x1E,0x00,0x80,0x00,0x00,0x00,0x0 0,0x00,0x00,0x00,0x07,0x0E,0x30,0x01,0xFC,0x7F,0x07,0x00,0x00,0x00,0x00,0x00,0x0 0,0x00,0x00,0x00,0x07,0x0E,0x30,0x01,0xFC,0x7F,0x07,0x00,0x00,0x00,0x00,0x00,0x0 0,0x00,0x00,0x00,0x7E,0xFF,0xFF,0xFF,0xFF,0xFF,0x83,0xC0,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x0F,0xFD,0xFF,0xFF,0xFF,0xFF,0xFC,0x01,0xF0,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x3F,0x81,0xFF,0x00,0x00,0x00,0x00,0x1F,0xF0,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0xFE,0xF0,0x00,0x00,0x01,0x00,0x00,0xC0,0x1C,0x00,0x00,0x00,0x00,0x0 0,0x00,0x03,0xC0,0x07,0x80,0x00,0x03,0xE0,0x07,0x00,0x1C,0x00,0x00,0x00,0x00,0x0 0,0x00,0x03,0x80,0x03,0x40,0x00,0x03,0xE0,0x0C,0x00,0x0E,0x00,0x00,0x00,0x00,0x0 0,0x00,0x07,0x00,0x00,0xC0,0x00,0x00,0x20,0x18,0x00,0x07,0x00,0x00,0x00,0x00,0x0 0,0x00,0x09,0x01,0x80,0x60,0x00,0x00,0x20,0x73,0x9F,0x03,0x80,0x00,0x00,0x00,0x0 0,0x00,0x1E,0x0F,0xF2,0x20,0x00,0x00,0x20,0x67,0xFF,0xC1,0xC0,0x00,0x00,0x00,0x0 0,0x00,0x1E,0x1F,0xF9,0x30,0x00,0x00,0x20,0xEF,0xFF,0xE0,0xE0,0x00,0x00,0x00,0x00 ,0x00,0x38,0x3F,0xFC,0x90,0x00,0x00,0x20,0xCB,0xFF,0xF9,0xF0,0x00,0x00,0x00,0x00 ,0x00,0x7F,0x7F,0xFE,0x10,0x00,0x00,0x20,0xDB,0xFF,0xFF,0xF0,0x00,0x00,0x00,0x00, 0x00,0x6E,0xF9,0xBF,0x10,0x00,0x00,0x20,0xF7,0xED,0xFF,0xF0,0x00,0x00,0x00,0x00 ,0x00,0x7C,0xFC,0x3F,0x10,0x00,0x00,0x20,0x67,0xE1,0xFD,0xE0,0x00,0x00,0x00,0x0 0,0x00,0x7C,0xFC,0x3F,0x10,0x00,0x00,0x20,0x67,0xE1,0xFD,0xE0,0x00,0x00,0x00,0x0 0,0x00,0x38,0xFC,0x3F,0x18,0x00,0x00,0x20,0x87,0xE0,0xFD,0xC0,0x00,0x00,0x00,0x0 0,0x00,0x38,0xF1,0x8F,0x18,0x00,0x1F,0xE7,0x87,0x9C,0x7D,0xC0,0x00,0x00,0x00,0x0 0,0x00,0x1C,0xFE,0x1F,0x81,0xFF,0xFF,0xC0,0x0F,0xE0,0xFF,0x80,0x00,0x00,0x00,0x00, 0x00,0x0C,0xFC,0x3F,0x80,0x00,0x00,0x00,0x0F,0xE1,0xF8,0x00,0x00,0x00,0x00,0x0 0,0x00,0x00,0xF9,0xBF,0xFF,0xFF,0xFF,0xFF,0xFF,0xEC,0xFE,0x00,0x00,0x00,0x00,0x00, 0x00,0x03,0xF9,0xBF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC0,0x00,0x00,0x00,0x00, 0x00,0x0F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0 0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0 0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0 0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0 0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0 0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0 0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0 0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0 0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0 0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0 0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0 0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0 0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0 0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0 0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0 0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0 0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0 0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0 0,0x00,0x00,0x00,0x00,0x00,0x00};//************************************************////********** DS18B20 ********////************************************************////************************************************////************蜂鸣器响一声函数*******//void beep(){BEEP=0; //开蜂鸣器delayms(500); //延时半秒BEEP=1; //关蜂鸣器delayms(500); //延时半秒}//************温度转换***************//void tempconv(){uchar sign=0; //定义符号标志位uchar temp; //定义温度数据暂存if(H>127) //大于127,即高4位全为1,即温度为负值{L=(~L)+1; //取反加1,将补码变成原码if((~L)>=0xff) //H=(~L)+1; //取反加一else H=~H; //否则只取反sign=1; //置符号标志位为1}temp=L&0x0f; //取小数位DQdisp_buf[0]=temp*0.625; //所获得的是四位数,所测温度加大了10倍DQdisp_buf[0]=DQdisp_buf[0]%1000%100%10;//将小数部分转换成ASCII码temp_comp=((L&0xf0)>>4|(H&0x0f)<<4); //取温度整数部分DQdisp_buf[3]=temp_comp/100; //温度百位temp=temp_comp%100; //温度的十位和个位一起DQdisp_buf[2]=temp/10; //温度十位DQdisp_buf[1]=temp%10; //温度个位if(DQdisp_buf[3]==0) //如果温度的百位为0{DQdisp_buf[3]=17; //则不显示,if(DQdisp_buf[2]==0) //在这种前提下,如果十位也为0的话,DQdisp_buf[2]=17; //不显示十位}if(sign)DQdisp_buf[3]=13; //如果符号标志位为1,则显示负号}//************温度显示函数**************//void temperture_display(){LCD_set_xy(4,4); //从第四行第5列开始显示LCD_Write_number(11);LCD_Write_number(DQdisp_buf[3]); //显示百位LCD_Write_number(DQdisp_buf[2]); //显示十位LCD_Write_number(DQdisp_buf[1]); //显示个位LCD_Write_number(12); //小数点LCD_Write_number(DQdisp_buf[0]); //十分位LCD_set_xy(4,7);Write_char(1,num[14]);Write_char(1,num[15]);}//************获取温度值*****************//void gettemperture(void){uchar i;DS18B20_init(); //DS18B20初始化if(DS18B20_OK==0) //如果正常{writeonebyte(0xcc); //跳过读序列号的操作writeonebyte(0x44); //启动温度转换for(i;i<100;i++) //调用显示函数延时,等待A/D转换完成,分辨率为12位的需要延时750ms以上temperture_display();DS18B20_init(); //DS18B20初始化writeonebyte(0xcc); //跳过读序列号的操作writeonebyte(0xbe); //读取温度寄存器temp_dat[0]=readonebyte(); //温度低8位放入temp_dat[0]temp_dat[1]=readonebyte(); //温度高8位放入temp_dat[1]L=temp_dat[0]; //温度低8位H=temp_dat[1]; //温度高8位temp_flag=1; //接收正常}else temp_flag=0; //否则接收不正常}//************写一个字节函数*****************//void writeonebyte(uchar dat){uchar i=0;for(i=8;i>0;i--){DQ=0;DQ=dat&0x01;delay(5);DQ=1;dat>>=1;}}//************读一个字节函数***************//readonebyte(void){uchar i=0;uchar dat=0;for(i=8;i>0;i--){DQ=0;dat>>=1;DQ=1;if(DQ)dat|=0x80;delay(4);}return (dat);}//***************DS18B20延时函数************//void delay(uint num){while(--num);}//***************DS18B20初始化*******************//DS18B20_init(void){DQ=1; //DQ复位delay(8); //延时DQ=0; //单片机将DQ拉低delay(90); //等待至少480us的时间DQ=1; //拉高总线delay(8); //等待DS18B20反馈存在低脉冲,单片机检测DS18B20_OK=DQ; //如果为0,则初始化成功,为1,初始化失败delay(100);DQ=1;return (DS18B20_OK); //返回信号,若DS18B20_OK为0,则存在,若DS18B20_OK=1;则不存在}//************************************************////********** LCD 12864 ********////************************************************////************************************************/void Lcd_init(void) //初始化LCD{delayms(40); //大于40MS的延时程序PSB=1; //设置为8BIT并口工作模式delayms(1); //延时RES=0; //复位delayms(1); //延时RES=1; //复位置高delayms(1);Write_char(0,0x30); //选择基本指令集delayms(1); //延时大于100usWrite_char(0,0x30); //选择8bit数据流delayms(1); //延时大于37usWrite_char(0,0x0c); //开显示(无游标、不反白)delayms(1); //延时大于100usWrite_char(0,0x01); //清除显示,并且设定地址指针为00Hdelayms(1); //延时大于10msWrite_char(0,0x06); //指定在资料的读取及写入时,设定游标的移动方向及指定显示的移位,光标从右向左加1位移动delayms(1); //延时大于100us}/******************************************************************** **********//*------------------------------------------------检测忙位------------------------------------------------*/void Check_Busy(){RS=0;RW=1;EN=1;DataPort=0xff;while((DataPort&0x80)==0x80);//忙则等待EN=0;}void Write_char(bit start, uchar ddata) //start=0写指令,start=1写数据{if(start==0) //如果start==0,检查忙碌位后写指令{ Check_Busy(); //忙碌则等待RS=0;RW=0;EN=0;DataPort=ddata; //发送指令_nop_();_nop_();EN=1;_nop_();_nop_();_nop_();_nop_();EN=0;}else //如果start==1,即可以开始{ Check_Busy(); //再次检查,进行些数据操作RS=1;RW=0;EN=1;DataPort=ddata;EN=0;}}/******************************************************************** **********/void Delaynms(uint di) //延时0.1ms左右{uint da,db;for(da=0;da<di;da++)for(db=0;db<10;db++);}/******************************************************************** **********/void Disp_img(uchar *img) //图形方式12864显示字模221 横向取膜{uchar i,j;uint k = 0;Write_char(0,0x34); //图形方式,关闭for(i=0;i<32;i++) //每行128位。
51单片机控制LCD12864液晶屏显示图形菜单
51单片机控制LCD12864液晶屏显示图形菜单想了很久,每次做菜单都受限于12864字符模式的各种限制,比如字体大小,不能显示图标等等,没有任何效果,这次就来个彻底的解脱,写一个单函数就能完成所有功能的函数,只需要2个图片就能完成任意菜单内容的菜单,可以有2的8次方=256个选择结果,应该能满足所有的要求了吧?菜单的内容就是图片的内容,因此可以显示任意大小的图形文字混合的菜单条目,比如使用字符模式,一屏只能显示4行菜单(64/16=4),且只能显示汉字和字符等,显示位置等等的都受限,而这个方法可以显示比如12*12(64/12=5行)的字符,8*8(64/8=8行)的字符,甚至不是字符,可以是图标+文字+任意其他的图像,只要是图片能显示的,都可以。
哈哈,比较复杂,现在只写了一少半,预期能够提供多种显示效果,希望我能完成。
void Lcd_Draw_BmpMenu(UINT8 *pMenu,UINT8*pTitleBmp,UINT8 *pMenuBmp){/*使用2张图片作为纯图形菜单来选择和操作,返回被选择的项,pMenu是一个指向菜单的各种参数的结构体的指针,pTitleBmp指向作为菜单标题的一张图片,pMenuBmp指向作为菜单内容的图片(液晶的控制芯片是ST7920)yx-->;>;|\|/*/xdata struct { //除非另有说明x坐标均为大列的坐标,一个大列是16个像素,一行共有8大列数据//========= 以下是入参基本参数,一旦确定,最好不要随意更改 ======UINT8 Title_x;//标题图片在屏幕上的显示起始位置X UINT8 Title_y;//标题图片在屏幕上的显示起始位置Y UINT8 Title_Len_x;//标题图片的宽UINT8 Title_Len_y;//标题图片的高UINT8 Menu_x;//菜单在屏幕上的显示起始位置XUINT8 Menu_y;//菜单在屏幕上的显示起始位置YUINT8 Menu_End_y;//菜单在屏幕上的显示结束位置Y UINT8 Menu_Bmp_x;//菜单图片的宽UINT8 Menu_Bmp_y;//菜单图片的高UINT8 Menu_Item_Height;//每一菜单项的高度(像素为单位)UINT8 Line_x;//最后下划线的起始坐标xUINT8 Line_y;//最后下划线的起始坐标YUINT8 Line_Len;//最后下划线的长度,如果为0,则表示不画出这条线(像素为单位)//====== 以下是菜单的风格设置 ========UINT8 Scroll_Speed;//菜单滚动的速度,0~9个级别,越低越快,越高越慢(液晶屏显示速度有快有慢,调整这个参数用于适用不同的液晶屏UINT8 Continue_Scroll;//指定菜单是否可以形成一个连续滚动选择的效果;0不连续,背景和反白位置都会根据实际情况滚动 1菜单连续滚动,反白位置不动UINT8 RePaint;//=0不重画菜单,=1重画整个菜单的图像,一般都是首次调用本函数的时候置1,用于画出整个菜单,以后调用置0就可以了UINT8 MenuEffect;//菜单运动的效果;0没有任何效果,只是最普通的菜单形态,1平滑滚动,2平滑滚动,具有惯性效果,3具有减速效果,没有惯性效果,4具有减速和惯性效果//====== 以下用于控制菜单的选择参数 =======UINT8 Last_Select_Item;//上次执行本函数后,所选择的菜单项UINT8 Select_Item;//本次执行本函数,要选择的菜单项}M;//============== 以下是变量定义 =============== UINT8 xdata Menu_Item_Count;//总共有几个菜单项UINT8 xdata Menu_Screen_Count;//当前一屏最多可以显示几个菜单项UINT8 xdataMenu_Box_x,Menu_Box_y,Menu_Box_End_x,Menu_Box_End _y;//需要刷新的区域的坐标UINT8 *pMenu_Box_Bmp;//需要显示的菜单项的指针StructCopy(&M.Title_x,pMenu,19);//把参数复制到本函数内,便于操作Menu_Item_Count=M.Menu_Bmp_y/M.Menu_Item_Height;/ /总共有几个菜单项Menu_Screen_Count=(M.Menu_End_y-M.Menu_y)/M.Menu_ Item_Height;//一屏最多可以显示多少项菜单//---------------------------------------------------------------------------if(M.RePaint==1)//如果需要重画整个菜单图像{Lcd_Draw_BMP(M.Title_x,M.Title_y,M.Title_x+M.Title_Len_x,M.Title_y+M.Title_Len_y,pTitleBmp);//画出标题的图片if(M.Line_Len!=0)Lcd_DrawRowLine(M.Line_x,M.Line_y,M.Line_Len,1);/ /画出最下面的线}//---------------------------------------------------------------------------//-----------需要刷新的图像的区域Menu_Box_x=M.Menu_x;Menu_Box_y=M.Menu_y;Menu_Box_End_x=M.Menu_x+M.Menu_Bmp_x;Menu_Box_End_y=M.Menu_End_y;。
用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();}}。
LCD12864液晶显示电子钟设计
LCD12864液晶显示电子钟设计
介绍:
设计目标:
设计一个能够实时显示时间和日期的电子钟,能够精确地获取当前的时间,并对用户的操作作出相应的响应。
设计原理:
该电子钟设计采用了单片机ATmega16作为核心,配合RTC(实时时钟)模块,通过控制液晶显示屏来显示时间和日期。
硬件设计:
1.电源电路:使用直流电源电压为5V,通过稳压芯片将输入电压稳定在5V。
2.单片机电路:将ATmega16与晶振、复位电路、电源电路等连接起来。
3.RTC电路:通过连接RTC芯片和单片机,实现对实时时钟的读取和控制功能。
4.液晶显示屏电路:将液晶显示屏与单片机进行连接,通过单片机控制液晶显示屏的显示。
软件设计:
1.初始化:对单片机和RTC进行初始化设置。
2.获取时间:从RTC读取当前时间和日期。
3.显示时间:将获取到的时间和日期分别显示在液晶显示屏的相应位置。
4.操作功能:通过按键控制,实现对时间和日期的调整和设置功能。
设计步骤:
1.确定电路设计需求和所需元器件。
2.搭建硬件电路,完成电路连接。
3.使用相关软件进行单片机和RTC的编程设置。
4.测试整个电路是否能够正确工作,如对时间进行调整并观察液晶显示屏的显示是否准确。
5.根据需求进行适当的优化和完善设计。
总结:。
基于51系列单片机的实时日历和时钟显示设计
河南机电高等专科学校综合实训论文实训题目:单片机毕业设计论文系部:电子通信工程系专业:应用电子班级:2011级应电113 班学生姓名:学号:1104152492013年11月1 日摘要本设计是基于51系列的单片机进行的实时日历和时钟显示设计,可以显示年月日时分秒及周信息,具有可调整日期和时间功能。
在设计的同时对单片机的理论基础和外围扩展知识进行了比较全面准备。
实时日历和时钟显示的设计过程在硬件与软件方面进行同步设计。
硬件部分主要由AT89S52单片机,LED显示电路,以及调时按键电路等组成,系统通过LED 显示数据,所以具有人性化的操作和直观的显示效果。
软件方面主要包括时钟程序、键盘程序,显示程序等。
本系统以单片机的汇编语言进行软件设计,为了便于扩展和更改,软件的设计采用模块化结构,使程序设计的逻辑关系更加简洁明了,以便更简单地实现调整时间及日期显示功能。
所有程序编写完成后,在wave 软件中进行调试,确定没有问题后,在Proteus软件中嵌入单片机内进行仿真。
关键词:AT89S52; DS1302; LED目录摘要 (I)绪论 (1)1.课题研究的意义 (1)2.本文研究的目的 (1)3.课题研究的主要内容 (2)第1章概述(含单片机的发展及其应用) (3)第2章设计方案论 (5)2.1功能 (5)2.2方案确定 (5)2.4电路设计最终方案确定 (7)第3章主控制器和外围器件 (8)3.1 AT89S52单片机 (8)3.2 DS1302时钟芯片 (8)3.3数码管LED (12)3.4译码器74HC138 (13)3.5锁存器74LS244 (13)第4章硬件设计 (14)4.1电路设计框图 (14)4.2系统概述 (14)4.3电源设计 (15)4.4单片机的复位电路 (15)4.5单片机系统的晶振电路 (16)4.6主电路设计 (17)第5章软件设计 (18)5.1主程序设计 (18)5.2键盘子程序设计 (20)5.3日历时钟子程序设计 (23)5.4显示子程序设计 (24)第6章系统调试 (25)6.1软件调试 (25)6.2硬件调试 (26)结论/展望 (27)心得体会 (28)致谢 (29)参考文献 (30)附录 (31)附录Ⅰ硬件电路图 (31)附录Ⅱ主程序源代码 (32)附录Ⅲ外文翻译原文 (33)附录Ⅳ外文翻译译文 (36)绪论1.课题研究的意义当代繁忙的工作与生活中,时间与我们每一个人都有非常密切的关系,每个人都受到时间的影响。
用51单片机做的万年历,显示用12864液晶
LCD12864.c#include "reg52.h"#include "intrins.h"#define uchar unsigned char#define uint unsigned int#define LCD_DB_PORT P0 //液晶DB0~DB7 #define LCD_START_ROW 0xc0 //起始行#define LCD_PAGE 0xb8 //页指令#define LCD_COL 0x40 //列指令//液晶引脚定义sbit LCD_DI=P2^0;sbit LCD_RW=P2^1;sbit LCD_E=P2^2;sbit LCD_CS1=P2^3;sbit LCD_CS2=P2^4;sbit LCD_RST=P2^5;bit Reverse_Display=0;//检查LCD是否忙bit LCD_Check_Busy(void){ LCD_DB_PORT=0xff;LCD_RW=1; _nop_(); LCD_DI=0;LCD_E=1; _nop_(); LCD_E=0;return(bit)(P0&0x80);}//向LCD发送命令void LCD_Write_Command(uchar c){ while(LCD_Check_Busy());LCD_DB_PORT=0xff; LCD_RW=0; _nop_(); LCD_DI=0;LCD_DB_PORT=c; LCD_E=1; _nop_(); LCD_E=0;}//向LCD发送数据void LCD_Write_Data(uchar d){ while(LCD_Check_Busy());LCD_DB_PORT=0xff;LCD_RW=0;_nop_();LCD_DI=1;//根据Reverse_Display决定是否反相显示if(!Reverse_Display)LCD_DB_PORT=d;else LCD_DB_PORT=~d;LCD_E=1;_nop_();LCD_E=0;}//初始化LCDvoid LCD_Initialize(void){ LCD_CS1=1;LCD_CS2=1;LCD_Write_Command(0x38);LCD_Write_Command(0x0f);LCD_Write_Command(0x01);LCD_Write_Command(0x06);LCD_Write_Command(LCD_START_ROW);}//通用显示函数//从第P页第L列开始显示W个字节数据,数据在r所指向的缓冲//每字节8位是垂直显示的,高位在下,低位在上//每个8*128的矩形区域为一页//整个LCD右由64*64的左半屏和64*64的右半屏构成void Common_Show(uchar P,uchar L,uchar W,uchar *r){ uchar i;if(L<64) //显示在左半屏或左右半屏{ LCD_CS1=1;LCD_CS2=0;LCD_Write_Command(LCD_PAGE+P);LCD_Write_Command(LCD_COL+L);if(L+W<64) //全部显示在左右半屏{ for(i=0;i<W;i++)LCD_Write_Data(r[i]);}else //如果越界则跨左右半屏显示{ for(i=0;i<64-L;i++)LCD_Write_Data(r[i]); //左半屏显示LCD_CS1=0;LCD_CS2=1; //右半屏显示LCD_Write_Command(LCD_PAGE+P);LCD_Write_Command(LCD_COL);for(i=64;i<W;i++)LCD_Write_Data(r[i]);}}else //全部显示在右半屏{ LCD_CS1=0;LCD_CS2=1;LCD_Write_Command(LCD_PAGE+P);LCD_Write_Command(LCD_COL+L-61);for(i=0;i<W;i++)LCD_Write_Data(r[i]);}}//显示8*16点阵字符void Display_A_Char_8X16(uchar P,uchar L,uchar *M) { Common_Show(P,L,8,M);Common_Show(P+1,L,8,M+8);}//显示一个16*16点阵汉字void Display_A_WORD(uchar P,uchar L,uchar *M) { Common_Show(P,L,16,M); //显示汉字上半部分Common_Show(P+1,L,16,M+16);}Main.c#include "reg52.h"#include "intrins.h"#include "string.h"#include "LCD_12864.c"#define uchar unsigned char#define uint unsigned int/*extern void LCD_Initialize(void);extern void Display_A_Char_8X16(uchar P,uchar L,uchar *M); extern void Display_A_WORD(uchar P,uchar L,uchar *M);//在调整日期时间时,用该位决定是否反白显示extern bit Reverse_Display=0;*/sbit SDA=P1^0; //DS1302数据线sbit CLK=P1^1; //DS1302时钟线sbit RST=P1^2; //DS1302复位线sbit k1=P3^4; //选择sbit k2=P3^5; //加sbit k3=P3^6; //减sbit k4=P3^7; //确定uchar tCount=0;//一年中每个月的天数,2月的天数由年份决定uchar MonthsDays[]={0,31,0,31,30,31,30,31,31,30,31,30,31};//所读取的日期时间uchar DateTime[7];//当前调整的时间对象:秒,分,时,日,月,年(0,1,2,3,4,6)//5对应星期,星期调节由年月日调整自动完成char Adjust_Index=-1;//水平与垂直偏移uchar H_Offset=10,V_Page_Offset=0;//年月日,星期,时分秒汉字点阵(16*16)------------------------------- uchar code DATE_TIME_WORDS[]={/*-- 文字: 年--*//*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/0x00,0x20,0x18,0xC7,0x44,0x44,0x44,0x44,0xFC,0x44,0x44,0x44,0x44,0x 04,0x00,0x00,0x04,0x04,0x04,0x07,0x04,0x04,0x04,0x04,0xFF,0x04,0x04,0x04,0x04,0x 04,0x04,0x00,/*-- 文字: 月--*//*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/0x00,0x00,0x00,0xFE,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0xFE,0x 00,0x00,0x00,0x80,0x40,0x30,0x0F,0x02,0x02,0x02,0x02,0x02,0x02,0x42,0x82,0x7F,0x/*-- 文字: 日--*//*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/0x00,0x00,0x00,0xFE,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0xFE,0x00,0x 00,0x00,0x00,0x00,0x00,0x00,0xFF,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0xFF,0x00,0x 00,0x00,0x00,/*-- 文字: 星--*//*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/0x00,0x00,0x00,0xBE,0x2A,0x2A,0x2A,0xEA,0x2A,0x2A,0x2A,0x3E,0x00, 0x00,0x00,0x00,0x00,0x44,0x42,0x49,0x49,0x49,0x49,0x7F,0x49,0x49,0x49,0x49,0x41,0x 40,0x00,0x00,/*-- 文字: 期--*//*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/0x00,0x04,0xFF,0x24,0x24,0x24,0xFF,0x04,0x00,0xFE,0x22,0x22,0x22,0xF E,0x00,0x00,0x88,0x48,0x2F,0x09,0x09,0x19,0xAF,0x48,0x30,0x0F,0x02,0x42,0x82,0x 7F,0x00,0x00,/*-- 文字: 时--*//*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/0x00,0xFC,0x84,0x84,0x84,0xFC,0x00,0x10,0x10,0x10,0x10,0x10,0xFF,0x0x00,0x3F,0x10,0x10,0x10,0x3F,0x00,0x00,0x01,0x06,0x40,0x80,0x7F,0x0 0,0x00,0x00,/*-- 文字: 分--*//*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/0x80,0x40,0x20,0x90,0x88,0x86,0x80,0x80,0x80,0x83,0x8C,0x10,0x20,0x 40,0x80,0x00,0x00,0x80,0x40,0x20,0x18,0x07,0x00,0x40,0x80,0x40,0x3F,0x00,0x00,0x 00,0x00,0x00,/*-- 文字: 秒--*//*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/0x24,0x24,0xA4,0xFE,0x23,0x22,0x00,0xC0,0x38,0x00,0xFF,0x00,0x08,0x 10,0x60,0x00,0x08,0x06,0x01,0xFF,0x01,0x06,0x81,0x80,0x40,0x40,0x27,0x10,0x0C,0x 03,0x00,0x00,};//星期几的汉字点阵(16*16)----------------------------------uchar code WEEDDAY_WORDS[]={/*-- 文字: 日--*//*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/0x00,0x00,0x00,0xFE,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0xFE,0x00,0x 00,0x00,0x00,0x00,0x00,0x00,0xFF,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0xFF,0x00,0x 00,0x00,0x00,/*-- 文字: 一--*//*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x 80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x 00,0x00,0x00,/*-- 文字: 二--*//*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/0x00,0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x 00,0x00,0x00,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x 10,0x10,0x00,/*-- 文字: 三--*//*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/0x00,0x04,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x 04,0x00,0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x 20,0x20,0x00,/*-- 文字: 四--*//*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/0x00,0xFC,0x04,0x04,0x04,0xFC,0x04,0x04,0x04,0xFC,0x04,0x04,0x04,0x FC,0x00,0x00,0x00,0x7F,0x28,0x24,0x23,0x20,0x20,0x20,0x20,0x21,0x22,0x22,0x22,0x 7F,0x00,0x00,/*-- 文字: 五--*//*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/0x00,0x02,0x42,0x42,0x42,0xC2,0x7E,0x42,0x42,0x42,0x42,0xC2,0x02,0x 02,0x00,0x00,0x40,0x40,0x40,0x40,0x78,0x47,0x40,0x40,0x40,0x40,0x40,0x7F,0x40,0x 40,0x40,0x00,/*-- 文字: 六--*//*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/0x20,0x20,0x20,0x20,0x20,0x20,0x21,0x22,0x2C,0x20,0x20,0x20,0x20,0x 20,0x20,0x00,0x00,0x40,0x20,0x10,0x0C,0x03,0x00,0x00,0x00,0x01,0x02,0x04,0x18,0x 60,0x00,0x00,};//半角数字点阵(8*16)---------------------------------------------------- uchar code DIGITS[]={/*-- 文字: 0 --*//*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x0F,0x10,0x20,0x20,0x10,0x0F,0x00,/*-- 文字: 1 --*//*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/0x00,0x10,0x10,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x 20,0x00,0x00,/*-- 文字: 2 --*//*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/0x00,0x70,0x08,0x08,0x08,0x88,0x70,0x00,0x00,0x30,0x28,0x24,0x22,0x 21,0x30,0x00,/*-- 文字: 3 --*//*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/0x00,0x30,0x08,0x88,0x88,0x48,0x30,0x00,0x00,0x18,0x20,0x20,0x20,0x 11,0x0E,0x00,/*-- 文字: 4 --*//*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/0x00,0x00,0xC0,0x20,0x10,0xF8,0x00,0x00,0x00,0x07,0x04,0x24,0x24,0x 3F,0x24,0x00,/*-- 文字: 5 --*//*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/0x00,0xF8,0x08,0x88,0x88,0x08,0x08,0x00,0x00,0x19,0x21,0x20,0x20,0x 11,0x0E,0x00,/*-- 文字: 6 --*//*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/0x00,0xE0,0x10,0x88,0x88,0x18,0x00,0x00,0x00,0x0F,0x11,0x20,0x20,0x 11,0x0E,0x00,/*-- 文字: 7 --*//*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/0x00,0x38,0x08,0x08,0xC8,0x38,0x08,0x00,0x00,0x00,0x00,0x3F,0x00,0x 00,0x00,0x00,/*-- 文字: 8 --*//*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/0x00,0x70,0x88,0x08,0x08,0x88,0x70,0x00,0x00,0x1C,0x22,0x21,0x21,0x 22,0x1C,0x00,/*-- 文字: 9 --*//*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x00,0x31,0x22,0x22,0x 11,0x0F,0x00,};//向DS1302写入一字节void Write_A_Byte_TO_DS1302(uchar x){ uchar i;for(i=0;i<8;i++){ SDA=x&1; CLK=1; CLK=0; x>>=1;}}//从DS1302读取一字节uchar Get_A_Byte_FROM_DS1302(void) { uchar i,b,t;for(i=0;i<8;i++){ b>>=1; t=SDA; b|=t<<7; CLK=1; CLK=0;}//BCD码转换return(b/16*10+b%16);}//从DS1302指定位置读数据uchar Read_Data(uchar addr){ uchar dat;RST=0; CLK=0; RST=1;Write_A_Byte_TO_DS1302(addr);dat=Get_A_Byte_FROM_DS1302();CLK=1; RST=0;return(dat);}//向DS1302某地址写入数据void Write_DS1302(uchar addr,uchar dat){ CLK=0; RST=1;Write_A_Byte_TO_DS1302(addr);Write_A_Byte_TO_DS1302(dat);CLK=0; RST=0;}//设置时间void SET_DS1302(void){ uchar i;Write_DS1302(0x8e,0x00);//秒分时日月年依次写入for(i=0;i<7;i++){ //秒的起始地址1000 0000(0x80)//后续依次是分,时,月,周,年,写入地址每次递增2Write_DS1302(0x80+2*i,(DateTime[i]/10<<4)|(DateTime[i]%10));}Write_DS1302(0x8e,0x80);}//读取当前日期时间void GetTime(void){ uchar i;for(i=0;i<7;i++){ DateTime[i]=Read_Data(0x81+2*i);}}//半断是否为闰年uchar isLeapYear(uint y){ return((y%4==0&&y%100!=0)||(y%400==0)); }//--------------------------------------------//求自2000.1.1开始的任何一天是星期几//函数没有通过,求出总天数后在求出星期几//因为求总天数可能会月出uint的范围//--------------------------------------------void RefreshWeekDay(void){ uint i,d,w=5; //已知1999.12.31是周五for(i=2000;i<2000+DateTime[6];i++){ d=isLeapYear(i)?366:365;w=(w+d)%7;}d=0;for(i=1;i<DateTime[4];i++)d+=MonthsDays[i];d+=DateTime[3];//保存星期,0~6表示星期日,星期一,二,、、、六,为了与DS1302的星期格式匹配,返回值需要加1DateTime[5]=(w+d)%7+1;}//年月日时分秒++/--void DateTime_Adjust(char x){ switch(Adjust_Index){ case 6: //年00-99if(x==1&&DateTime[6]<99)DateTime[6]++;if(x==-1&&DateTime[6]>0)DateTime[6]--;//获取2月天数MonthsDays[2]=isLeapYear(2000+DateTime[6])?29:28;//如果年份变化后当前月份的天数大于上限则设为上限if(DateTime[3]>MonthsDays[DateTime[4]])DateTime[3]=MonthsDays [DateTime[4]];RefreshWeekDay(); //刷新星期break;case 4: //月01-12if(x==1&&DateTime[4]<12)DateTime[4]++;if(x==-1&&DateTime[4]>1)DateTime[4]--;//获取2月份天数MonthsDays[2]=isLeapYear(2000+DateTime[6])?29:28;//如果月份变化后当前月份的天数大于上限则设为上限if(DateTime[3]>MonthsDays[DateTime[4]])DateTime[3]=MonthsDays [DateTime[4]];RefreshWeekDay(); //刷新星期break;case 3: //日00-28/29/30/31;调节之前首先根据年份得出该年中2月的天数MonthsDays[2]=isLeapYear(2000+DateTime[6])?29:28;//根据当前月份决定调节日期的上限if(x==1&&DateTime[3]<MonthsDays[DateTime[4]])DateTime[3]++;if(x==-1&&DateTime[3]>1)DateTime[3]--;RefreshWeekDay(); //刷新星期break;case 2: //时if(x==1&&DateTime[2]<23)DateTime[2]++;if(x==-1&&DateTime[3]>1)DateTime[2]--;break;case 1: //分if(x==1&&DateTime[1]<59)DateTime[1]++;if(x==-1&&DateTime[1]>1)DateTime[1]--;break;case 0: //秒if(x==1&&DateTime[0]<59)DateTime[0]++;if(x==-1&&DateTime[0]>1)DateTime[0]--;}}//定时器0每秒刷新LCD显示void T0_INT(void) interrupt 1{ TH0=-50000/256;TL0=-50000%256;if(++tCount!=2)return;tCount=0;if(Adjust_Index==-1)GetTime(); //如果未执行调整操作则正常读取当前时间//年后两位Reverse_Display=Adjust_Index==6; /*等同于{ if(Adjust_Index==6)Reverse_Display=1;else Reverse_Display=0; } */Display_A_Char_8X16(V_Page_Offset,16+H_Offset,DIGITS+DateTime [6]/10*16);Display_A_Char_8X16(V_Page_Offset,24+H_Offset,DIGITS+DateTime [6]%10*16);//月Reverse_Display=Adjust_Index==4;Display_A_Char_8X16(V_Page_Offset,48+H_Offset,DIGITS+DateTime [4]/10*16);Display_A_Char_8X16(V_Page_Offset,56+H_Offset,DIGITS+DateTime [4]%10*16);//日Reverse_Display=Adjust_Index==3;Display_A_Char_8X16(V_Page_Offset,80+H_Offset,DIGITS+DateTime [3]/10*16);Display_A_Char_8X16(V_Page_Offset,88+H_Offset,DIGITS+DateTime [3]%10*16);//星期Reverse_Display=Adjust_Index==5;Display_A_WORD(V_Page_Offset+2,96+H_Offset,WEEDDAY_WORDS +(DateTime[5]-1)*32);//时Reverse_Display=Adjust_Index==2;Display_A_Char_8X16(V_Page_Offset+5,16+H_Offset,DIGITS+DateTi me[2]/10*16);Display_A_Char_8X16(V_Page_Offset+5,24+H_Offset,DIGITS+DateTi me[2]%10*16);//分Reverse_Display=Adjust_Index==1;Display_A_Char_8X16(V_Page_Offset+5,48+H_Offset,DIGITS+DateTi me[1]/10*16);Display_A_Char_8X16(V_Page_Offset+5,56+H_Offset,DIGITS+DateTi me[1]%10*16);//秒Reverse_Display=Adjust_Index==0;Display_A_Char_8X16(V_Page_Offset+5,80+H_Offset,DIGITS+DateTi me[0]/10*16);Display_A_Char_8X16(V_Page_Offset+5,88+H_Offset,DIGITS+DateTi me[0]%10*16);}//键盘中断(INT0)void EX_INT0(void) interrupt 0{ if(k1==0) //选择调整对象{ if(Adjust_Index==-1||Adjust_Index==0)Adjust_Index=7;Adjust_Index--;if(Adjust_Index==5)Adjust_Index=4; //跳过对星期的调整}else if(k2==0)DateTime_Adjust(1); //加else if(k3==0)DateTime_Adjust(-1); //减else if(k4==0) //确定{ SET_DS1302(); //将调整后的时间写入DS1302Adjust_Index=-1; //操作索引重设为-1,时间继续正常显示}}//主程序void main(){ //液晶初始化LCD_Initialize();//显示年的固定前两位Display_A_Char_8X16(V_Page_Offset,0+H_Offset,DIGITS+2*16);Display_A_Char_8X16(V_Page_Offset,8+H_Offset,DIGITS);//显示固定汉字:年月日,星期,时分秒Display_A_WORD(V_Page_Offset,32+H_Offset,DATE_TIME_WORDS+ 0*32);Display_A_WORD(V_Page_Offset,64+H_Offset,DATE_TIME_WORDS+ 1*32);Display_A_WORD(V_Page_Offset,96+H_Offset,DATE_TIME_WORDS+ 2*32);Display_A_WORD(V_Page_Offset+2,64+H_Offset,DATE_TIME_WORD S+3*32);Display_A_WORD(V_Page_Offset+2,80+H_Offset,DATE_TIME_WORD S+4*32);Display_A_WORD(V_Page_Offset+5,32+H_Offset,DATE_TIME_WORD S+5*32);Display_A_WORD(V_Page_Offset+5,64+H_Offset,DATE_TIME_WORD S+6*32);Display_A_WORD(V_Page_Offset+5,96+H_Offset,DATE_TIME_WORD S+7*32);//允许INT0,T0中断IE=0x83;IP=0x01;IT0=0x01;TH0=-50000/256;TL0=-50000%256;TR0=1;while(1);}。
51单片机实时时间显示及调节
51单⽚机实时时间显⽰及调节程序代码由3个⽂件组成,main.c,DS1302.c,DS1302.h。
1. main.c/************************************************************************************** 实验现象:实时时间显⽰及调节* 接线说明:动态数码管段选接P0,位选接P2^2,3,4⼝,k1、k2、k3、k4接P3^1、0、2、3,beep接P1^5***************************************************************************************/#include "reg52.h"//此⽂件中定义了单⽚机的⼀些特殊功能寄存器#include "ds1302.h"typedef unsigned int u16; //对数据类型进⾏声明定义typedef unsigned char u8;sbit LSA = P2 ^ 2;sbit LSB = P2 ^ 3;sbit LSC = P2 ^ 4;sbit k1 = P3 ^ 1;sbit k2 = P3 ^ 0;sbit k3 = P3 ^ 2;sbit k4 = P3 ^ 3;sbit beep = P1 ^ 5;char num = 0;u8 DisplayData[8];u8 code smgduan[20] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f,0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71, 0x00, 0x40}; //显⽰0~F,⽆,'-'的值u8 clocks, minutes, seconds;u8 stopSwitch = 0;u8 beepSwitch = 0;/******************************************************************************** 函数名 : delay()* 函数功能 : 延时函数,i=1时,⼤约延时10us*******************************************************************************/void delay(u16 i){while (i--);}/******************************************************************************** 函数名 : DS1302WriteTime()* 函数功能 : 时分秒写⼊函数* 输⼊ : 时、分、秒* 输出 : ⽆*******************************************************************************/void DS1302WriteTime(u8 clocks, u8 minutes, u8 seconds){u8 clocks_16, minutes_16, seconds_16;clocks_16 = (clocks / 10 * 16) | (clocks % 10);minutes_16 = (minutes / 10 * 16) | (minutes % 10);seconds_16 = (seconds / 10 * 16) | (seconds % 10);Ds1302Write(0x8E, 0X00); //禁⽌写保护,就是关闭写保护功能Ds1302Write(WRITE_RTC_ADDR[2], clocks_16);Ds1302Write(WRITE_RTC_ADDR[1], minutes_16);Ds1302Write(WRITE_RTC_ADDR[0], seconds_16);Ds1302Write(0x8E, 0x80); //打开写保护功能}/******************************************************************************** 函数名 : getTime()* 函数功能 : 时间读取处理转换函数* 输⼊ : ⽆* 输出 : ⽆*******************************************************************************/void getTime(){if (stopSwitch){DS1302WriteTime(clocks, minutes, seconds);}else{Ds1302ReadTime();clocks = (TIME[2] / 16 * 10) + (TIME[2] % 16);minutes = (TIME[1] / 16 * 10) + (TIME[1] % 16);seconds = (TIME[0] / 16 * 10) + (TIME[0] % 16);}}/******************************************************************************* * 函数名 : DigDisplay* 函数功能 : 数码管显⽰函数* 参数 : ord为数码管次序,ch为该数码管显⽰符号*******************************************************************************/ void DigDisplay(u8 ord, u8 ch){switch (ord) //位选,选择点亮的数码管,{case (0):LSA = 1;LSB = 1;LSC = 1;break; //显⽰第0位case (1):LSA = 0;LSB = 1;LSC = 1;break; //显⽰第1位case (2):LSA = 1;LSB = 0;LSC = 1;break; //显⽰第2位case (3):LSA = 0;LSB = 0;LSC = 1;break; //显⽰第3位case (4):LSA = 1;LSB = 1;LSC = 0;break; //显⽰第4位case (5):LSA = 0;LSB = 1;LSC = 0;break; //显⽰第5位case (6):LSA = 1;LSB = 0;LSC = 0;break; //显⽰第6位case (7):LSA = 0;LSB = 0;LSC = 0;break; //显⽰第7位}P0 = smgduan[ch]; //发送段码if (beepSwitch)beep = ~beep;}/******************************************************************************* * 函数名 : timeDisplay* 函数功能 : 将时分秒显⽰在数码管上* 输⼊ : ⽆* 输出 : ⽆*******************************************************************************/ void timeDisplay(){u8 n = 0;u8 dig[10];getTime();dig[0] = clocks / 10;dig[1] = clocks % 10;dig[2] = 17;dig[3] = minutes / 10;dig[4] = minutes % 10;dig[6] = seconds / 10;dig[7] = seconds % 10;for (n = 0; n < 8; n++){DigDisplay(n, dig[n]);delay(10);DigDisplay(n, 16);}}/******************************************************************************* * 函数名 : keypros* 函数功能 : 按键处理* 输⼊ : ⽆* 输出 : ⽆*******************************************************************************/ void keypros(){u16 delayTimes = 10;//按键K1if (k1 == 0) //检测按键K1是否按下{while (delayTimes--)timeDisplay(); //消除抖动⼀般⼤约10msif (k1 == 0) //再次判断按键是否按下{if (++clocks == 24){clocks = 0;}DS1302WriteTime(clocks, minutes, seconds);}while (!k1)timeDisplay(); //检测按键是否松开}//按键K2if (k2 == 0) //检测按键是否按下{while (delayTimes--)timeDisplay(); //消除抖动⼀般⼤约10msif (k2 == 0) //再次判断按键是否按下{if (++minutes == 60){minutes = 0;}DS1302WriteTime(clocks, minutes, seconds);}while (!k2)timeDisplay(); //检测按键是否松开}//按键K3if (k3 == 0) //检测按键是否按下{while (delayTimes--)timeDisplay(); //消除抖动⼀般⼤约10msif (k3 == 0) //再次判断按键是否按下{if (++seconds == 60){seconds = 0;}DS1302WriteTime(clocks, minutes, seconds);}while (!k3)timeDisplay(); //检测按键是否松开}//按键K4if (k4 == 0) //检测按键是否按下{while (delayTimes--)timeDisplay(); //消除抖动⼀般⼤约10msif (k4 == 0) //再次判断按键是否按下{stopSwitch = (stopSwitch + 1) % 2;}while (!k4)timeDisplay(); //检测按键是否松开}}/******************************************************************************* * 函数名 : main* 函数功能 : 主函数* 输出 : ⽆*******************************************************************************/void main(){Ds1302Init(); //初始化while (1){keypros(); //按键处理timeDisplay(); //显⽰时间//蜂鸣器整点响应if (minutes == 59 && seconds == 59){beepSwitch = 1;}if (beepSwitch == 1){if (minutes == 0 && seconds == 3){beepSwitch = 0;}}}}2. ds1302.h#ifndef __DS1302_H_#define __DS1302_H_//---包含头⽂件---//#include<reg52.h>#include<intrins.h>//---重定义关键词---//#ifndef uchar#define uchar unsigned char#endif#ifndef uint#define uint unsigned int#endif//---定义ds1302使⽤的IO⼝---//sbit DSIO=P3^4;sbit RST=P3^5;sbit SCLK=P3^6;//---定义全局函数---//void Ds1302Write(uchar addr, uchar dat);uchar Ds1302Read(uchar addr);void Ds1302Init();void Ds1302ReadTime();//---加⼊全局变量--//extern uchar TIME[7]; //加⼊全局变量extern uchar code WRITE_RTC_ADDR[7];#endif3. ds1302.c#include"ds1302.h"//---DS1302写⼊和读取时分秒的地址命令---////---秒分时⽇⽉周年最低位读写位;-------//uchar code READ_RTC_ADDR[7] = {0x81, 0x83, 0x85, 0x87, 0x89, 0x8b, 0x8d}; uchar code WRITE_RTC_ADDR[7] = {0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c}; //---DS1302时钟初始化2016年5⽉7⽇星期六12点00分00秒。
基于51单片机的lcd12864的画图程序
} } 下面是图片:在(0,0)到(127,32)之间画线 在(0,0)到(63,63)之间画线 大家可以看到,直线越长其线性越差,主要是算法的问题
(原文件名:IMG_1765.JPG)
3、画圆部分 主要思路是用 Bresenham 算法先画 1/8 个圆,在利用对称行画出其余的部分 程序如下: /***************************************** 名称:Draw_circle (在任意位置画圆) 说明:使用 Bresenham 法画 1/8 个圆,在用对称性画出其他的 7/8 个圆
1、打点部分 /******************************************************** 名称:GUI_Point(打点) 说明:X:横坐标(代表列的位置,0~127) Y:纵坐标(代表行的位置,0~63) 根据 Datesheet 需先把数据写到 GDRAM,读取当前位置的数据,经过或和移位后再 把数据重新写入 GDRAM 每行有 16 个位元,共 64 行,每个位元有两个 8 位(高低 8 位) 计算出在那个位元,在该位元的哪一位 易出现的问题:1、打点位置的定位 2、读取当前显示的数据 3、或和移位,即重新写人的新数据 ********************************************************/ void GUI_Point(uchar x,uchar y,uchar flag) { uchar x_Dyte,x_byte; 哪1位 uchar y_Dyte,y_byte; 行地址(取值为 0~31) Write_command(0x36); /***X,Y 坐标互换,即普通的 X,Y 坐标***/ x_Dyte=x/16; x_byte=x&0x0f; y_Dyte=y/32; y_byte=y&0x1f; Write_command(0x80+y_byte); Write_command(0x80+x_Dyte+8*y_Dyte); yte 选定上下屏 Read_data(); GDRAM_hbit=Read_data(); GDRAM_lbit=Read_data(); delay_us(5); if(flag==1) { Write_command(0x80+y_byte); Write_command(0x80+x_Dyte+8*y_Dyte); _Dyte 选定上下屏 delay_us(5); if(x_byte<8) 低8位 { //判断其在高 8 位, 还是在 //设定行地址(y 坐标) //设定列地址(x 坐标),并通过 8*y //读取当前显示高 8 位数据 //读取当前显示低 8 位数据 //计算在 16 个字节中的哪一个 //计算在该字节中的哪一位 //0 为上半屏,1 为下半屏 //计算在 0~31 当中的哪一行 //设定行地址(y 坐标) //设定列地址(x 坐标),并通过 8*y_D //定义列地址的字节位, 及在字节中的 //定义为上下两个屏(取值为 0,1), //绘图模式命令
51单片机 定时器时钟
实验二定时器和实时时钟实验一、实验目的a)数码管动态显示技术b)定时器的应用c)按键功能定义二、实验实现的功能a)开机12个二极管同色灯依次点亮,通过按键选择定时器功能或者实时时钟功能b)当选择实时时钟功能时,用12个LED显示小时,用数码管显示分和秒,时间都由按键设定,同时具备复位功能c)当选择定时器功能时,12个LED闪烁,然后通过按键设定分和秒的时间,启动定时器,当定时时间到,12个LED闪烁,同时具备复位功能。
三、系统硬件设计四、系统软件设计#include <stc10.h>#define uchar unsigned char#define uint unsigned int#define N 10//0--F的共阴极字段码表ucharcodevalue[]={0X3F,0X06,0X5B,0X4F,0X66,0X6D,0X7D,0X07,0X7F,0X6F,0X77,0X7C,0X39,0 X5E,0X79,0X71};//小时显示uchartab[]={0x00,0x00,0xfe,0x3f,0xfc,0x3f,0xf8,0x3f,0xf0,0x3f,0xe0,0x3f,0xc0,0x3f,0x80,0x3f,0x00, 0x3f,0x00,0x38,0x00,0x30,0x00,0x20};//待显示的4位缓冲uchar Num_Buffer[]={0,0,0,0};char sec=0,min=0,hour=0,time=0,count=0;void delay(uint x) //延时函数{uchar i;while(x--){for(i=0;i<120;i++);}}void display() //显示函数{Num_Buffer[3]=min/10;Num_Buffer[2]=min%10;Num_Buffer[1]=sec/10;Num_Buffer[0]=sec%10;P0=0XFE;P1=codevalue[Num_Buffer[3]];delay(N);P0=0XFD;P1=codevalue[Num_Buffer[2]];delay(N);P0=0XFB;P1=codevalue[Num_Buffer[1]];delay(N);P0=0XF7;P1=codevalue[Num_Buffer[0]];delay(N);}uchar scan_key()//按键扫描函数{uchar a=0x40,i,ptr=0,m;for(i=0;i<2;i++){P3=~a;delay(N);m=P0;switch(m&0xe0){case 0xc0: ptr=i*3+1;return ptr;break;case 0xa0: ptr=i*3+2;return ptr;break;case 0x60: ptr=i*3+3;return ptr;break;default:break;}a=a<<1;}}void shan(){P2=0XB6;P3=0X37;delay(8N);P2=0X6D;P3=0X2F;delay(8N);P2=0XDB;P3=0X1B;delay(8N);}main(){ uchar i,k;P1M0=0XFF;P1M1=0X00;TMOD=0X11; //选择定时器0,1,工作方式1 TH0=-50000/256; //定时器0赋初值TL0=-50000%256;TH1=-50000/256; //定时器1赋初值TL1=-50000%256;EA=1; //开总中断ET0=1; //定时器0允许中断ET1=1; //定时器1允许中断while(1){P0=0XFF;shan();k=scan_key();if(k==1) //按键1按下,实现时钟功能{while(1){P2=tab[2*hour]; //小时用LED显示P3=tab[2*hour+1];display();k=scan_key();if(k==1) //按下1键设定小时{delay(40N);hour++;if(hour==12){hour=0;P2=tab[0];P3=tab[1];}}else if(k==2) //按下2键设定分{delay(20N);min++;if(min==60)min=0;}else if(k==3) //按下3键设定秒{delay(20N);sec++;if(sec==60)sec=0;}else if(k==4)//按下4键启动{TR0=1;}else if(k==5)//按下5键复位{TR0=0;hour=0;min=0;}else if(k==6) //按下6键返回break;}}else if(k==2) //按键2按下,实现定时器功能{while(1){display();if(min==0&&sec==0){TR1=0;P2=0;P3=0X83;for(i=0;i<20;i++){display();}P2=0XFF;P3=0XBF;for(i=0;i<20;i++){display();}}k=scan_key();if(k==2) //按下2键设定分{delay(20N);min++;if(min==60)min=0;}else if(k==3) //按下3键设定秒{delay(20N);sec++;if(sec==60)sec=0;}else if(k==4)//按下4键启动{}else if(k==5)//按下5键复位{TR1=0;min=0;sec=0;}else if(k==6) //按下6键返回break;}}}}void timer0(void) interrupt 1 //定时器0中断{TH0=-50000/256;TL0=-50000%256;count++;if(count==20){count=0;sec++;if(sec==60){sec=0;min++;if(min==60){min=0;hour++;if(hour==12)hour=0;}}}}void timer1(void) interrupt 3 //定时器1中断{TH1=-50000/256;TL1=-50000%256;count++;if(count==20){count=0;sec--;if(sec<0&&min!=0){sec=59;min--;}}}五、实验过程中遇到的问题及解决方法问题1:有一段中断程序如下void timer1(void) interrupt 3 //定时器1中断{TH1=-50000/256;TL1=-50000%256;count++;if(count==20){count=0;sec--;if(sec<0&&min!=0){sec=59;min--;}}}当秒减到0后,会出现乱码。
用51单片机在12864液晶上实现 电子钟.
#include<reg52.h>#include<intrins.h>#define uchar unsigned char#define uint unsigned intchar second=0;char minite=0;char hour=0;int n=0;bit s2=0;bit s3=0;bit s4=0;bit s5=0;//bit s6=0;/*共阳数码管字型码*//*0,1,2,3,4,5,6,7,8,9,p.,灭*/char code dis_code[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x0c,0xff,0xbf}; /*P点显示代码序号*/char data find_code[]={0,0,12,0,0,12,0,0};/********************************************************///函数名:void Delay1ms(uint count)//功能:延时时间为1ms//输入参数:count,1ms计数//说明:总共延时时间为1ms乘以count,crystal=12Mhz/********************************************************//* 延迟函数*/void Delay1ms(uint count){uint j;while(count--!=0){for(j=0;j<80;j++);}}/************************************************************************//*显示函数*//************************************************************************/ void disp(){char i,j=0xfe;char k;for(i=0;i<8;i++){P2=j;k=find_code[i];P0=dis_code[k];Delay1ms(1);j=_crol_(j,1);}P0=0xff;}/************************************************************************* 函数原型:keychuli();* 功能:处理与键盘相连的P1口的内容,作为键值。