源代码(DS1302+LCD1602)
#include<STC12C5A.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
#define LCD_DB P0
#define DS1302_SECOND_W 0x80
#define DS1302_MINUTE_W 0x82
#define DS1302_HOUR_W 0x84
#define DS1302_DAY_W 0x86
#define DS1302_MONTH_W 0x88
#define DS1302_YEAR_W 0x8C
#define DS1302_WEEK_W 0x8A
#define WP 0x8E
sbit LCD_RS= P2^4;
sbit LCD_RW= P2^5;
sbit LCD_EP= P2^6;
sbit SCLK_1302=P3^6;
sbit IO_1302=P3^4;
sbit CE_1302=P3^5;
void Init_DS1302(void);
uchar DS1302Read(uchar cmd);
void DS1302Write(uchar cmd, uchar dat);
void DS1302WriteByte(uchar dat);
uchar DS1302ReadByte();
void LCD_init();
void LCD_busy();
void LCD_wcmd(uchar cmd);//写指令
void LCD_wdata(uchar dat);//写数据
//void LCD_dis_char(uchar x,uchar y,uchar *dat);//单字符
void LCD_dis_word(uchar x,uchar y,uchar *word);
void LCD_w_num(uchar x,uchar y,uchar num);//单数字
void LCD_Dis_longnum(uchar x,uchar y, ulong number);
void delay(uint n);
//*****************主程序***************************
void main()
{uchar DATA[8],i;
//uchar add=0x80;
P3M1=0X00;
P3M0=0X00;
P2M1=0X00;
P2M0=0X00;
P0M1=0X00;
P0M0=0X00;
Init_DS1302();
LCD_init();
//LCD_dis_word(0,2,"asf1 3132");//字符显示
LCD_Dis_longnum(0,2,20);//数据显示
//DS1302Write(WP,0x00);//写保护关
//DATA=DS1302Read(DS1302_SECOND_W+1);
//LCD_Dis_longnum(1,1,DATA);
while(1)
{
for(i=0;i<7;i++)
{
DATA[i]=DS1302Read(DS1302_SECOND_W+1+2*i);
}
LCD_Dis_longnum(4,1,DATA[2]/10);//时
LCD_Dis_longnum(5,1,DATA[2]%10);
LCD_dis_word(6,1,":");
LCD_Dis_longnum(7,1,DATA[1]/10);//分
LCD_Dis_longnum(8,1,DATA[1]%10);
LCD_dis_word(9,1,":");
LCD_Dis_longnum(10,1,DATA[0]/10);//秒
LCD_Dis_longnum(11,1,DATA[0]%10);
//LCD_dis_word(9,1,":");
LCD_Dis_longnum(2,2,DATA[6]/10);//年
LCD_Dis_longnum(3,2,DATA[6]%10);
LCD_dis_word(4,2,"-");
LCD_Dis_longnum(5,2,DATA[4]/10);//月
LCD_Dis_longnum(6,2,DATA[4]%10);
LCD_dis_word(7,2,"-");
LCD_Dis_longnum(8,2,DATA[3]/10);//日
LCD_Dis_longnum(9,2,DATA[3]%10);
LCD_Dis_longnum(12,2,DATA[5]/10);//日
LCD_Dis_longnum(13,2,DATA[5]%10);
}
}
//***********************************************
/************************************************
*名称: void Init_DS1302(void)
*说明: 给1302写入一个初始的值
*功能: 写入日期,和时钟的值
*调用: DS1302Write()
*输入: 无
*输出: 无
*************************************************/
void Init_DS1302(void)
{
DS1302Write(WP,0x00);//写保护关
DS1302Write(DS1302_SECOND_W,0x00); //初始秒值为0
DS1302Write(DS1302_MINUTE_W,0x00);//初始分钟值为0
DS1302Write(DS1302_HOUR_W,0x00); //初始为24小时模式初始时间为0点
DS1302Write(DS1302_DAY_W,0x07); //2011年1月1日星期6
DS1302Write(DS1302_MONTH_W,0x01);
DS1302Write(DS1302_YEAR_W,0x12);
DS1302Write(DS1302_WEEK_W,0x06);
DS1302Write(0x90,0x01); //充电
DS1302Write(0xc0,0xf0); //初始化一次标示
DS1302Write(WP,0x80);
}
/************************************************
*名称: uchar DS1302Read()
*说明: 先写地址,后读数据
*功能: 从cmd相应地址中读取一个字节的数据
*调用: DS1302WriteByte(),DS1302ReadByte()
*输入: cmd:要写入的控制字节
*输出: dat:读取的数据
*************************************************/
uchar DS1302Read(uchar cmd)
{
uchar dat,BCD,BCDS;
CE_1302=0;//初始CE线置为0
SCLK_1302=0;//初始时钟线置为0
CE_1302=1;//初始CE置为1,传输开始
DS1302WriteByte(cmd);//传输命令字,要读取的时间/日历地址
dat=DS1302ReadByte();//读取要得到的时间/日期
SCLK_1302=1;//时钟线拉高
CE_1302=0;//读取结束,CE置为0,结束数据的传输
//*******BCD*********
BCD=dat&0X0F;
BCDS=(dat&0X0F0)>>4;
dat=BCDS*10+BCD;
return dat;//返回得到的时间/日期
}
/************************************************
*名称: DS1302Write
*说明: 先写地址,后写数据
*功能: 向cmd相应地址中写一个字节的数据
*调用: DS1302WriteByte()
*输入: cmd:要写入的控制字,dat:要写入的数据
*输出: 无
*************************************************/
void DS1302Write(uchar cmd, uchar dat)
{
CE_1302=0; //初始CE线置为0
SCLK_1302=0; //初始时钟线置为0
CE_1302=1; //初始CE置为1,传输开始
DS1302WriteByte(cmd); //传输命令字,要写入的时间/日历地址
DS1302WriteByte(dat); //写入要修改的时间/日期
SCLK_1302=1; //时钟线拉高
CE_1302=0; //读取结束,CE置为0,结束数据的传输
}
/************************************************
*名称: DS1302WriteByte
*说明: 无
*功能: 写入8bit数据
*调用: delayus()
*输入: dat:要写入的数据
*输出: 无
*************************************************/
void DS1302WriteByte(uchar dat)
{
uchar i;
SCLK_1302=0;//初始时钟线置为0
delay(2);
for(i=0;i<8;i++)//开始传输8个字节的数据
{
IO_1302=dat&0x01;//取最低位,注意DS1302的数据和地址都是从最低位开始传输的
delay(2);
SCLK_1302=1;//时钟线拉高,制造上升沿,SDA的数据被传输
delay(2);
SCLK_1302=0;//时钟线拉低,为下一个上升沿做准备
dat>>=1;//数据右移一位,准备传输下一位数据
}
}
/************************************************
*名称: DS1302ReadByte()
*说明: 无
*功能: 读取8bit的数据
*调用: delayus()
*输入: 无
*输出: dat:读取的数据
*************************************************/
uchar DS1302ReadByte()
{
uchar i,dat;
delay(2);
for(i=0;i<8;i++)
{
dat>>=1;//要返回的数据左移一位
if(IO_1302==1)//当数据线为高时,证明该位数据为1
dat|=0x80;//要传输数据的当前值置为1,若不是,则为0
SCLK_1302=1;//拉高时钟线
delay(2);
SCLK_1302=0;//制造下降沿
delay(2);
}
return dat;//返回读取出的数据
}
/************************************************
*名称: void LCD_init()
*说明:
*功能:
*调用: LCD_wcmd(=),delay()
*输入:
*输出:
*************************************************/
void LCD_init()
{
LCD_wcmd(0x38);//8位总线,双行,5X7
delay(50);
LCD_wcmd(0x0C);//开总显,关光标,不闪
LCD_wcmd(0x06);//光标右移,文字不移
LCD_wcmd(0x01);//clear
delay(500);
}
void LCD_busy()
{
uchar result=0x80;
while(result==0x80)
{
LCD_RS=0;
LCD_RW=1;
LCD_EP=1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
result=P0&0X80;
LCD_EP=0;
delay(10);
}
}
void LCD_wcmd(uchar cmd)
{
LCD_busy();
LCD_DB=cmd;//代码
LCD_RS=0;//指令
LCD_RW=0;//写
LCD_EP=1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
LCD_EP=0;//执行
delay(100);
}
void LCD_wdata(uchar dat)
{
LCD_busy();
LCD_DB=dat;
LCD_RS=1;
LCD_RW=0;
LCD_EP=1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
LCD_EP=0;
delay(50);
}
/*
void LCD_dis_char(uchar x,uchar y,uchar *dat)
{
uchar address;
if(y==1)
address=0x80+x;
else
address=0x0c0+x;
LCD_wcmd(address);
LCD_wdata(*dat);
}
*/
void LCD_dis_word(uchar x,uchar y,uchar *word)
{uchar address;
while(*word)
{
if(y==1)
address=0x80+x;
else
address=0x0c0+x;
LCD_wcmd(address);
LCD_wdata(*word);
//LCD_dis_char(x,y,*word);
x++;
word++;
}
}
void LCD_w_num(uchar x,uchar y,uchar num)
{
uchar address;
if(y==1)
address=0x80+x;
else
address=0x0c0+x;
LCD_wcmd(address);
LCD_wdata(num+0x30);
}
void LCD_Dis_longnum(uchar x,uchar y, ulong number)
{
uchar i,j,k;
//uchar j;
uchar num[10];
//j=number;
if(number==0) //number 0 时候
LCD_w_num(x,y,0);
else{
for(i=0;number>0;i++)
{
num[i]=number%10;//每位以字符表示
//LCD_w_num(x+i,y,j%10);
number/=10;
}
k=i;
for(j=0;j<k;j++)
{
--i;
LCD_w_num(x+j,y,num[i]);
}
}
}
void delay(uint n)
{
uint i;
uchar j;
for(i=n;i>0;i--)
{
for(j=0;j<10;j++);
}
}
回复
有奖活动 | |
---|---|
【有奖活动】分享技术经验,兑换京东卡 | |
话不多说,快进群! | |
请大声喊出:我要开发板! | |
【有奖活动】EEPW网站征稿正在进行时,欢迎踊跃投稿啦 | |
奖!发布技术笔记,技术评测贴换取您心仪的礼品 | |
打赏了!打赏了!打赏了! |
打赏帖 | |
---|---|
与电子爱好者谈读图四被打赏50分 | |
与电子爱好者谈读图二被打赏50分 | |
【FRDM-MCXN947评测】Core1适配运行FreeRtos被打赏50分 | |
【FRDM-MCXN947评测】双核调试被打赏50分 | |
【CPKCORRA8D1B评测】---移植CoreMark被打赏50分 | |
【CPKCORRA8D1B评测】---打开硬件定时器被打赏50分 | |
【FRDM-MCXA156评测】4、CAN loopback模式测试被打赏50分 | |
【CPKcorRA8D1评测】--搭建初始环境被打赏50分 | |
【FRDM-MCXA156评测】3、使用FlexIO模拟UART被打赏50分 | |
【FRDM-MCXA156评测】2、rt-thread MCXA156 BSP制作被打赏50分 |