C51 DS1302芯片+lcd12864 显示时间

本文档展示了使用STM32微控制器与LCD12864显示器配合DS1302实时时钟模块进行时间显示的程序代码。主要涉及配置头文件、初始化LCD、DS1302的读写操作以及时间数据显示在LCD上的功能。程序中包含了LCD的初始化、数据传输函数以及DS1302的读写和时间转换函数,实现了实时时间的精确显示。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.原理图

1302芯片部分

 lcd12864部分

 2.代码部分

config.h

#ifndef __CONFIG_H
#define __CONFIG_H
#include <reg51.h>
#include "lcd12864.h"
#include "intrins.h" 
#define  uchar unsigned char
#define uint unsigned int
#endif 

lcd12864.c

#include"lcd12864.h"
	
void lcdinit(void)	//初始化LCD 
{

  write(0,0x30);  //功能设定
  write(0,0x0c);  //显示开关设置
  write(0,0x01);  //清除指令 
}

void sendbyte(uchar bbyte) //发送一个字节  数据发送函数
{
uchar i;
 for(i=0;i<8;i++)
   {
	if((bbyte&0x80)==0x80)
   		SID=1; //取高四位	 串行数据输入端打开
	else
		SID=0;
   SCLK=1;				  //取低四位 使能信号发送
   NOP();NOP();NOP();NOP();//NOP指令通常用于控制时序的目的,强制内存对齐
   SCLK=0;				  
   bbyte<<=1; //左移
   NOP();NOP();NOP();NOP();
   }  
}

void lcd_setwindow(uchar x, uchar y)	   //x只是定位这一行,具体位置通过+y操作   return pos
{
uchar pos;

	if(x == 0)	   // 第一行的地址是80H
	{
		x = 0x80;
	}
		
	else if(x == 1)  //第二行的地址是90H
	{
		x = 0x90;	
	}
	
	else if(x == 2)  //第三行的地址是88H
	{
		x = 0x88;
	}
	
	else if(x == 3)		//第四行地址98H
	{
		x = 0x98;
	}
	
	pos = x + y;
	write(0,pos);
}

void lcd_writedata(uchar d)		 //lcd写指令
{

	write(1,d);

}

void write(uchar start, uchar ddata) //写指令或数据
{
  uchar start_data,Hdata,Ldata;	  //Hdata -highdata Ldata-lowdata
  if(start==0) start_data=0xf8;	 //写指令
    else       start_data=0xfa;  //写数据
  
  Hdata=ddata &0xf0;		  //取高四位highdata
  Ldata=(ddata<<4)&0xf0;  //取低四位lowdata
  sendbyte(start_data);	  //发送起始信号  指令or数据
  delaynms(10); //延时是必须的
  sendbyte(Hdata);	      //发送高四位		 控制串口通信输入端
  delaynms(5);  //延时是必须的
  sendbyte(Ldata);		  //发送低四位
  delaynms(5);  //延时是必须的
}

void lcd_writechar(uchar a[])   //lcd写字符
{
		uchar *p=a;
	while(*p!='\0')		//判断字符串数组是否结束	
	{	
		write(1,*p);
		p++;
		
	}
	write(1,0x00);
} 
void line_disp(uchar str[],int line) //直接把数组显示在这一行  line是行数,第一行就写1
{ 	
	lcd_writedata('0');	 
	lcd_setwindow(line-1,0);	// pos=x+y;	
	lcd_writechar(str);
}

lcd12864.h

#ifndef __LCD12864_H
#define __LCD12864_H
#define uchar unsigned char
#define uint unsigned int
#include <reg51.h>
#include "intrins.h" 
#define NOP(); _nop_();

  //引脚定义

sbit SID=P3^7;	//数据
sbit SCLK=P3^6;	//时钟
sbit BACK=P2^0;   //控制背光 BACK=0  背光不亮

void write(uchar start, uchar ddata);
void sendbyte(uchar bbyte);
void delaynms(uint di);
void lcdinit(void);
void lcd_setwindow(uchar x, uchar y);
void lcd_writedata(uchar d);
void lcd_writechar(uchar dat[]);
void line_disp(uchar str[],int line);
#endif

main.c

#include "config.h"
sbit SCK=P0^5;
sbit SDA=P0^6;
sbit RST=P0^7;
uchar readaddre[7]={0x81,0x83,0x85,0x87,0x89,0x8b,0x8d};		//“读寄存器的地址”
uchar writeaddre[7]={0x80,0x82,0x84,0x86,0x88,0x8a,0x8c};   //“写”寄存器的地址
uchar time[7]={0x00,0x30,0x19,0x11,0x08,0x04,0x20};//初始时间数组
/*--------------------精准延时函数---------------------*/
void delaynms(unsigned int t) //@11.0592MHZ
{
	unsigned int i,j;
	for(i=0;i<t;i++)
	for(j=0;j<113;j++);
}
/*-------------------------------------------*/
//1302写入数据
void DS1302write(uchar addre,uchar dat)
{
	uchar i;
	RST=0;
	_nop_();
	SCK=0;
	_nop_();
	RST=1;
	_nop_();
	for (i=0;i<8;i++)
	{
		SDA=addre&0x01;
		addre>>=1;
		SCK=1;
		_nop_();
		SCK=0;
		_nop_();
	}
	for (i=0;i<8;i++)
	{
		SDA=dat&0x01;
		dat>>=1;
		SCK=1;
		_nop_();
		SCK=0;
		_nop_();
	}
	RST=0;
}

//1302读数据
uchar DS1302read(uchar addre)
{
	uchar i,dat1,dat;
	RST=0;
	_nop_();
	SCK=0;
	_nop_();
	RST=1;
	_nop_();
	for (i=0;i<8;i++)
	{
		SDA=addre&0x01;
		addre>>=1;
		SCK=1;
		_nop_();
		SCK=0;
		_nop_();
	}
	_nop_();
	for (i=0;i<8;i++)
	{
		dat1=SDA;
		dat=(dat>>1)|(dat1<<7);
		SCK=1;
		_nop_();
		SCK=0;
		_nop_();
	}
	RST=0;
	_nop_();
	SCK=1;
	_nop_();
	SDA=1;
	_nop_();
	SDA=0;
	_nop_();
	return dat;
}


//初始化1302
void DS1302init()
{
	uchar i;
	DS1302write(0x8e,0x00);
	for (i=0;i<7;i++)
	{
		DS1302write(writeaddre[i],time[i]);
	}
	DS1302write(0x8e,0x80);
}
//读取(初始化后)的1302的时间
void DS1302readtime()
{
	uchar i;
	for (i=0;i<7;i++)
	{
		time[i]=DS1302read(readaddre[i]);
	}
}

void time_change()    //存在time里的时间是BCD码,转换为十进制数,同时拆成两个字符显示在lcd12864
{		
	uint sec,min,hour,mon,year,day,week;
		
		DS1302readtime();
		
		time[0]=(time[0]/16)*10+time[0]%16;
		sec=time[0];
		time[1]=(time[1]/16)*10+time[1]%16;
		min=time[1];
		time[2]=(time[2]/16)*10+time[2]%16;
		hour=time[2];
		time[3]=(time[3]/16)*10+time[3]%16;
		day=time[3];
		time[4]=(time[4]/16)*10+time[4]%16;
		mon=time[4];
		time[5]=(time[5]/16)*10+time[5]%16;
		week=time[5];
		time[6]=(time[6]/16)*10+time[6]%16;
		year=time[6];
		lcd_setwindow(1,0);	
		lcd_writedata('0'+year/10);	
		lcd_writedata('0'+year%10);
	    lcd_setwindow(1,2);	
		lcd_writedata('0'+mon/10);	
		lcd_writedata('0'+mon%10);
		lcd_setwindow(1,4);	
		lcd_writedata('0'+day/10);	
		lcd_writedata('0'+day%10);
		lcd_setwindow(1,6);	
	  //lcd_writedata('0'+week/10);	
		lcd_writedata('0'+week%10);
		lcd_setwindow(3,0);	
		lcd_writedata('0'+hour/10);	
		lcd_writedata('0'+hour%10);
		lcd_writechar(":");
		lcd_writedata('0'+min/10);	
		lcd_writedata('0'+min%10);
		lcd_writechar(":");
		lcd_writedata('0'+sec/10);	
		lcd_writedata('0'+sec%10);
	
}
void frame()
{
	  lcd_setwindow(0,0);
		lcd_writechar("今天是:");
		lcd_setwindow(1,1);		
		lcd_writechar("年  月  日");
		lcd_setwindow(1,5);	
		lcd_writechar("周");	
		lcd_setwindow(2,0);
		lcd_writechar("现在时间是:");
}
void main(void)
{
	BACK=0;
	lcdinit();
//DS1302init();//每一次上电初始化时间,初始化一次即可。
	lcd_writedata('0');	 //	 写指令
	frame();
	while(1)
	{ 
		time_change();//时间转换,将BCD码转换为10进制数
		delaynms(100);
	}
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值