您好,欢迎来到刀刀网。
搜索
您的当前位置:首页使用LCD1602、DS1302时钟芯片的电子万历(C51芯片)

使用LCD1602、DS1302时钟芯片的电子万历(C51芯片)

来源:刀刀网
使用LCD1602、DS1302时钟芯片、DS18B20温度传感器完成该日历

/***********************************************************************************/

/************使用LCD1602、DS1302时钟芯片、DS18B20温度传感器完成该日历**************/

#include

#define uint unsigned int #define uchar unsigned char

sbit rs=\"P2\"^0; // 数据/命令选择端 sbit rw=\"P2\"^1; //读写选择端 sbit e=\"P2\"^2; //使能信号

sbit rst=\"P2\"^5; //时钟芯片复位端 sbit sck=\"P2\"^6; // 时钟信号 sbit io=\"P2\"^7; // 输入/输出端

sbit ds=\"P2\"^3; //温度传感器信号线 sbit led=\"P2\"^4; //小灯位定义 uint temp; // 整型温度值 float f_temp; //浮点型温度值 void init(); // 初始化函数 void delay(uchar z); //延时函数

void write_com(uchar com); //LCD写命令 void write_date(uchar date); //LCD写数据 uint get_temp(); //获得温度

void tempchange(void); //转换温度 void dsreset(void); //DS18B20复位

bit tempreadbit(void); //读DS118B20一位

uchar tempreadbyte(void); //读DS18B20一个字节 void tempwritebyte(uchar dat); void deal(); //温度处理函数

void Write_Ds1302_Byte(uchar temp);//写入一个字节 void Write_Ds1302(uchar address,uchar dat);//写入 uchar Read_Ds1302 ( uchar address ); //读取时间 void Read_RTC(void); //读取 日历 void Set_RTC(void); //设定 日历 void time_date(); //时间数据处理

void display(uchar *lp,uchar lc); //显示时间 void Temp_Display(); //温度显示 uchar table[]=\"01234567.C\"; uchar table0[]=\"01234567-\";

uchar table1[]=\"MONTUEWEDTHUFRISATSUN\"; uchar table2[]=\"01234567:!\";

uchar l_tmpdate[7]={21,59,23,28,10,2,8};

/*初始化时钟芯片,依次是秒分时日月星期年,用十六进制表示十进制,如0x1c表示 1*16+12即28,所以显示出来的就是28*/ uchar l_tmpdisplay[18];

code uchar write_rtc_address[7]={0x80,0x82,0x84,0x86,0x88,0x8a,0x8c}; //以上是写入时钟芯片的地址,顺序同上

code uchar read_rtc_address[7]={0x81,0x83,0x85,0x87,0x,0x8b,0x8d}; //读出数据的地址

/******************************日历主函数************************************/ void main() {

init(); //初始化LCD

Set_RTC();//初始化时钟芯片 while(1) {

tempchange();//温度转换命令 time_date();//显示时间 Temp_Display(); //显示温度 deal(); //温度处理

P1=0xf0;

IT0=1; // 选择外部中断0为电平触发方式(1为跳变沿触发方式) EX0=1; EA=\"1\";

} }

void inter0() interrupt 0 //外部中断0 {

P1=0xfe; if(P1!=0xfe)

delay(10); if(P1==0xee) { led=~led;

write_com(0x1c); }

if(P1==0xde) { led=~led;

write_com(0x18); }

}

/***************************以下为温度传感器相关程序************************/

void dsreset(void) //DS18B20复位,初始化函数 {

uint i; ds=0; i=103;

while(i>0)i--; ds=1; i=4;

while(i>0)i--; }

bit tempreadbit(void) //读一位数据函数 {

uint i; bit dat;

ds=0;i++; //i++起延时的作用 ds=1;i++;i++; dat=ds;

i=8;while(i>0)i--; return(dat); }

uchar tempreadbyte(void) //读一个字节数据函数 {

uchar i,j,dat; dat=0;

for(i=1;i<=8;i++) {

j=tempreadbit();

dat=(j<<7)|(dat>>1); //读出的数据最低位在最前面 }

return(dat); }

void tempwritebyte(uchar dat) { //写一个字节数据函数 uint i; char j; bit testb;

for(j=1;j<=8;j++) {

testb=dat&0x01; dat=dat>>1;

if(testb) //写1 {

ds=0; i++;i++;

ds=1;

i=8;while(i>0)i--; }

else //写0 {

ds=0;

i=8;while(i>0)i--; ds=1; i++;i++; } } }

void tempchange(void) //DS18B20开始获取温度并转换 {

dsreset(); delay(1);

tempwritebyte(0xcc); //写跳过读ROM指令 tempwritebyte(0x44); //写温度转换指令 }

uint get_temp() //读取寄存器中存储的温度数据 {

uchar a,b; dsreset(); delay(1);

tempwritebyte(0xcc);

tempwritebyte(0xbe); //读RAM内部9字节的温度数据 a=tempreadbyte(); //读低8位 b=tempreadbyte(); //读高8位 temp=b; temp<<=8;

temp=temp|a; //两个字节组合为一个字节

f_temp=temp*0.0625; // 温度在寄存器中为12位,分辨率为0.0625

temp=f_temp*10+0.5; //乘以10表示小数点后面只取1位,加0.5时四舍五入 f_temp=f_temp+0.05; return temp; }

void Temp_Display() //温度显示函数 {

write_com(0x80+0x40+0x0b); write_date(table[get_temp()/100]); write_com(0x80+0x40+0x0c);

write_date(table[get_temp()%100/10]); write_com(0x80+0x40+0x0d); write_date(table[10]);

write_com(0x80+0x40+0x0e); write_date(table[get_temp()%10]); write_com(0x80+0x40+0x0f); write_date(table[11]); }

void deal() //温度处理函数 {

uint i;

i=get_temp();

if(i>300||i<200) //当温度低于20度或大于30度时小灯闪烁 {

led=0;

delay(100); led=1;

// write_com(0x80+12); // write_date(table2[11]); }

// else led=\"1\"; }

/***********************以上为温度传感器相关程序***********************/ /***********************以下为时钟芯片相关程序***********************/ void Write_Ds1302_Byte(uchar temp) //写入一字节数据 {

uchar i;

for (i=0;i<8;i++) //循环8次 写入数据 ,上升沿写入 {

sck=\"0\";

io=\"temp\"&0x01; //每次传输低字节 temp>>=1; //右移一位 sck=\"1\"; } }

void Write_Ds1302(uchar address,uchar dat)//写入 {

rst=0; delay(1); sck=0; delay(1);

rst=1;

delay(1); //启动

Write_Ds1302_Byte(address); //发送地址 Write_Ds1302_Byte(dat); //发送数据 rst=0; //恢复 }

uchar Read_Ds1302 (uchar address) //读取时间 {

uchar i,time=0x00; rst=0; delay(1); sck=0; delay(1); rst=1; delay(1);

Write_Ds1302_Byte(address);

for (i=0;i<8;i++) //循环8次 读取数据 { if(io)

time|=0x80; //每次传输低字节

sck=1; //时钟下降沿读入数据????????? time>>=1; //右移一位 sck=0; }

rst=0;

delay(1); //以下为DS1302复位的稳定时间 rst=0; sck=0; delay(1); sck=1; delay(1); io=0; delay(1); io=1; delay(1);

return (time); }

void Read_RTC() //读取 日历 {

uchar i,*p;

p=read_rtc_address; //地址传递

for(i=0;i<7;i++) //分7次读取 年月日时分秒星期

{

l_tmpdate[i]=Read_Ds1302(*p); p++; } }

void Set_RTC(void) //设定 日历 {

uchar i,*p,tmp; for(i=0;i<7;i++) {

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_address; //传地址

for(i=0;i<7;i++) //7次写入 年月日时分秒星期 {

Write_Ds1302(*p,l_tmpdate[i]); p++; }

Write_Ds1302(0x8E,0x80); //禁止写入 }

void time_date() //时间数据处理 {

Read_RTC();

l_tmpdisplay[0]=l_tmpdate[2]/16;//时 l_tmpdisplay[1]=l_tmpdate[2]&0x0f; l_tmpdisplay[2]=10; //加入\":\"

l_tmpdisplay[3]=l_tmpdate[1]/16;//分 l_tmpdisplay[4]=l_tmpdate[1]&0x0f; l_tmpdisplay[5]=10;

l_tmpdisplay[6]=l_tmpdate[0]/16;//秒 l_tmpdisplay[7]=l_tmpdate[0]&0x0f;

l_tmpdisplay[8]=2; //显示2008的2

l_tmpdisplay[9]=0; //显示2008的第一个0 l_tmpdisplay[10]=l_tmpdate[6]/16; //年 l_tmpdisplay[11]=l_tmpdate[6]&0x0f; l_tmpdisplay[12]=10; //加入“-”

l_tmpdisplay[13]=l_tmpdate[4]/16;//月 l_tmpdisplay[14]=l_tmpdate[4]&0x0f; l_tmpdisplay[15]=10;

l_tmpdisplay[16]=l_tmpdate[3]/16;//日 l_tmpdisplay[17]=l_tmpdate[3]&0x0f;

display(l_tmpdisplay,8); }

void display(uchar *lp,uchar lc) //显示时间 {

unsigned char i; //定义变量

write_com(0x80); //液晶第一行显示时间和星期 for(i=0;iwrite_date(table2[lp[i]]); delay(1); }

write_com(0x80+0x09);

switch(l_tmpdate[5]) //用英文缩写显示星期 {

case 0: write_date(table1[0]); write_date(table1[1]); write_date(table1[2]); break;

case 1: write_date(table1[3]); write_date(table1[4]); write_date(table1[5]); break;

case 2: write_date(table1[6]); write_date(table1[7]); write_date(table1[8]); break;

case 3: write_date(table1[9]); write_date(table1[10]); write_date(table1[11]); break;

case 4: write_date(table1[12]); write_date(table1[13]); write_date(table1[14]); break;

case 5: write_date(table1[15]); write_date(table1[16]); write_date(table1[17]); break;

case 6: write_date(table1[18]);

write_date(table1[19]); write_date(table1[20]); break; }

write_com(0x80+0x40); //第二行显示年 for(i=8;iwrite_date(table0[lp[i]]); delay(1); } }

/********************以上为时钟芯片相关程序***************************/ void init() //LCD初始化函数 { e=0;

write_com(0x38);//显示模式的设置 delay(1);

write_com(0x0c);//开显示,光标显示 delay(1);

write_com(0x06);//光标位置 delay(1);

write_com(0x01); //清显示 delay(1); }

void write_com(uchar com) //LCD写命令 { rs=0; rw=0; P0=com; delay(1); e=1; delay(1); e=0; }

void write_date(uchar date) //LCD写数据 { rs=1; rw=0; P0=date; delay(1); e=1; delay(1); e=0; }

void delay(uchar z) //延时函数 {

uchar x,y;

for(x=0;xfor(y=0;y<110;y++); }

/***************END***********END******************************/

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- gamedaodao.com 版权所有 湘ICP备2022005869号-6

违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务