标题:
请问如何将单片机万年历程序修改一下使LCD1602正确显示?
[打印本页]
作者:
墨芜
时间:
2019-11-10 17:07
标题:
请问如何将单片机万年历程序修改一下使LCD1602正确显示?
新建 DOC 文档.doc
(42.5 KB, 下载次数: 3)
2019-11-10 17:05 上传
点击文件名下载附件
51hei图片20191110170422.png
(47.54 KB, 下载次数: 49)
下载附件
2019-11-10 17:05 上传
请问如何将程序修改一下使LCD1602正确显示
发现下载附件要花费黑币,所以我把代码发出来吧
/****************************main.c************************************/
#include <reg51.h>
#include <intrins.h>
#include <string.h>
#define uchar unsigned char
#define uint unsigned int
uchar *week[] = {"sun","mon","tus","wes","thu","fri","sat"}; //周信息,周一到周日。
uchar lcd_buf1[] = "00-00-00 "; //日期信息。
uchar lcd_buf2[] = "00:00:00 "; //时间信息。
extern void InitTIMER0();
extern void lcd_init();
extern void lcd_showstring(uchar ,uchar ,uchar *);
extern uchar l_tmpdate[7];
extern bit ReadRTC_Flag;
extern void delay(uint i);
extern void Read_RTC();
extern void Set_RTC();
//将日期和时间信息转化为数字字符。
void format_datetime(uint d,uchar * a)
{
*a=(d>>4)+'0';
*(a+1)=(d&0x0f)+'0';
}
void main()
{
lcd_init(); //LCD的初始化。
InitTIMER0(); //初始化定时器0。
Set_RTC(); //写入时钟值(写入时钟初值),如果不用改时间可以不用这一项。
while(1)
{
if(ReadRTC_Flag)
{
ReadRTC_Flag = 0;
Read_RTC();
//日期转换。
format_datetime(l_tmpdate[6],lcd_buf1+5);
format_datetime(l_tmpdate[4],lcd_buf1+8);
format_datetime(l_tmpdate[3],lcd_buf1+11);
//星期转换。
strcpy(lcd_buf1 + 13,week[l_tmpdate[5]-1]);
//定义一个字符串char a[20],和一个字符串c[]="i am a teacher!";
//把c复制到a中就可以这样用:strcpy(a,c);
//时间转换。
format_datetime(l_tmpdate[2],lcd_buf2+5);
format_datetime(l_tmpdate[1],lcd_buf2+8);
format_datetime(l_tmpdate[0],lcd_buf2+11);
lcd_showstring(0,0,lcd_buf1); //将lcd_buf1和lcd_buf2字符输出。
lcd_showstring(1,0,lcd_buf2);
}
}
}
/******************************************************************1602.h**************************************************************************/
typedef bit bool;
sbit RS = P2^6; //复位端
sbit RW = P2^5; //写数据端
sbit EN = P2^7; //使能端
#define uint unsigned int
#define uchar unsigned char
void delay(int i);
bit lcd_bz();
void lcd_wcmd(int cmd);
void lcd_showstring(uchar r,uchar c,uchar *str);
void lcd_wdat(uchar dat);
void lcd_init();
/******************************************************************1602.c***************************************************************************/
#include <reg51.h>
#include <intrins.h>
#include "1602.h"
//延时函数
void delay(int i)
{
int j;
while(i--)
{
for(j=0;j<250;j++)
{
_nop_();
_nop_();
_nop_();
_nop_();
}
}
}
//侧忙,判断LCD是否为忙
bool lcd_bz()
{
bool result;
RS = 0;
RW = 1;
EN = 1;
_nop_();
_nop_();
_nop_();
_nop_();
result = (bool)(P0 & 0x80);//检测P0最高位是否为1.
EN = 0;
return result; //返回判断的结果。
}
//写命令函数。
void lcd_wcmd_8bit(int cmd)
{
while(lcd_bz());
RS = 0;
RW = 0;
EN = 0; //先为低电平。
_nop_();
_nop_();
P0 = cmd; //获得数据。
_nop_();
_nop_();
_nop_();
_nop_();
EN = 1; //将电平拉高。
_nop_();
_nop_();
_nop_();
_nop_();
EN = 0; //再拉低。
}
//写命令函数。
void lcd_wcmd(int cmd)
{
while(lcd_bz());
RS = 0;
RW = 0;
EN = 0; //先为低电平。
_nop_();
_nop_();
P0 = cmd; //获得高四位数据。
_nop_();
_nop_();
_nop_();
_nop_();
EN = 1; //拉高。
_nop_();
_nop_();
_nop_();
_nop_();
EN = 0; //再拉低。
P0 = (cmd & 0x0f)<<4; //再获得低四位数据。
_nop_();
_nop_();
_nop_();
_nop_();
EN = 1; //将电平拉高。
_nop_();
_nop_();
_nop_();
_nop_();
EN = 0; //再拉低。
}
void lcd_showstring(uchar r,uchar c,uchar *str)
{
uchar i=0;
code uchar DDRAM[] = {0x80,0xc0}; //设定显示的位置。
lcd_wcmd(DDRAM[r] | c);
for(i=0;str[i] && i<16;i++)
lcd_wdat(str[i]);
for(;i<16;i++)
lcd_wdat(' ');
}
//数据写入的函数。
void lcd_wdat(uchar dat)
{
while(lcd_bz());
RS = 1;
RW = 0;
EN = 0; //先处于低电平。
P0 = dat; //获得数据高四位。
_nop_();
_nop_();
_nop_();
_nop_();
EN = 1;
_nop_();
_nop_(); //再产生一个负脉冲。
_nop_();
_nop_();
EN = 0;
RS = 1;
RW = 0;
EN = 0;
_nop_();
_nop_();
_nop_();
_nop_();
P0 = (dat & 0x0f)<<4; //同理获得低四位。
_nop_();
_nop_();
_nop_();
_nop_();
EN = 1;
_nop_();
_nop_();
_nop_();
_nop_();
EN = 0;
}
//LCD初始化。
void lcd_init()
{
lcd_wcmd_8bit(0x38);
delay(1);
lcd_wcmd_8bit(0x38);
delay(1);
lcd_wcmd_8bit(0x38);
delay(1);
lcd_wcmd(0x38);
delay(1);
lcd_wcmd(0x0c);
delay(1);
lcd_wcmd(0x02);
delay(1);
lcd_wcmd(0x01);
delay(1);
}
/****************************************************************ds1302.c****************************************************/
#include <reg52.h>
#include <intrins.h>
sbit SCK = P3^6; //时钟线
sbit IO = P3^4; //数据线
sbit RST = P3^5; //DS1302复位线
bit ReadRTC_Flag; //读DS1302的标志
#define uint unsigned int
#define uchar unsigned char
//七项数据:秒分时日月周年
uchar l_tmpdate[7] = {0,0,12,19,11,5,1};
//用来存放转化好的时间数据
uchar l_tmpdisplay[8];
//7个数据的写地址
code uchar write_rtc_add[7] = {0x80,0x82,0x84,0x86,0x88,0x8a,0x8c};
//7个数据的读地址
code uchar read_rtc_add[7] = {0x81,0x83,0x85,0x87,0x89,0x8b,0x8d};
//函数的声明
void Write_Ds1302_byte(uchar temp);
void write_Ds1302(uchar add,uchar dat);
uchar Read_Ds1302(uchar add);
void Read_RTC();
void Set_RTC();
void InitTIMER0();
//定时器的初始化
void InitTIMER0()
{
TMOD |= 0x01;
TH0 = 0xef;
TL0 = 0xf0;
ET0 = 1;
TR0 = 1;
EA = 1;
}
//向1302中发送一个字节数据。
void Write_Ds1302_Byte(uchar temp)
{
uchar i;
for(i=0;i<8;i++) //循环8位依次写入数据
{
SCK = 0;
IO = temp & 0x01; //传输时从低到高
temp>>=1; //右移1位。
SCK = 1;
}
}
//向1302中写入数据。参数有要写入的地址和数据
void Write_Ds1302(uchar add,uchar dat)
{
RST = 0;
_nop_();
SCK = 0;
_nop_();
RST = 1;
_nop_();
Write_Ds1302_Byte(add); //发送地址
Write_Ds1302_Byte(dat); //发送数据
RST = 0;
}
//从1302中的读出数据
uchar Read_Ds1302(uchar add)
{
uchar i,temp=0x00;
RST = 0;
_nop_();
_nop_();
SCK = 0;
_nop_();
_nop_();
RST = 1;
_nop_();
_nop_();
Write_Ds1302_Byte(add); //发送地址,找到地址
for(i=0;i<8;i++) //循环8次读出数据
{
if(IO) //传输从低到高
temp |= 0x80;
SCK = 0;
temp>>=1; //右移1位
_nop_();
_nop_();
_nop_();
SCK = 1;
}
RST = 0; //之后为DS1302复位
_nop_();
_nop_();
// RST = 0; //试验时去掉该句没有影响
SCK = 0;
_nop_();
_nop_();
_nop_();
_nop_();
SCK = 1;
_nop_();
_nop_();
IO = 0;
_nop_();
_nop_();
IO = 1;
_nop_();
_nop_();
return temp; //将读到的数据返回
}
//从时钟中读取数据
void Read_RTC()
{
uchar i,*p;
p = read_rtc_add; //读日历数据对应的地址
for(i=0;i<7;i++) //分7次分别将:时分秒日月周年读出
{
l_tmpdate[i] = Read_Ds1302(*p);
p++;
}
}
//设定时钟的时间数据
void Set_RTC()
{
uchar i,*p,tmp;
for(i=0;i<7;i++) //将数从BCD码转化出来,因为1302中用BCD码表示数值
{
tmp = l_tmpdate[i]/10;
l_tmpdate[i] = l_tmpdate[i]%10;
l_tmpdate[i] = l_tmpdate[i] + tmp*16;
}
Write_Ds1302(0x8e,0x00); //清除写入保护
p = write_rtc_add; //传送地址
for(i=0;i<7;i++) //将数据依次写入
{
Write_Ds1302(*p,l_tmpdate[i]);
p++;
}
Write_Ds1302(0x8e,0x80); //打开写入保护,不能再写入
}
//定时器中断函数
void tim() interrupt 1 using 1
{
static uchar i,num;
TH0 = 0xf5;
TL0 = 0xe0;
i++;
if(i==8)
{
i=0;
num++;
if(10==num) //间隔一定时间读取1302中数据,更新数码管数据
{
ReadRTC_Flag = 1; //置标志位,从而进行判断
num = 0;
}
}
}
复制代码
求大佬解答。
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1