现在的位置: 首页 > 综合 > 正文

PIC单片机(PIC16F877A)DS1302芯片程序

2013年05月02日 ⁄ 综合 ⁄ 共 3113字 ⁄ 字号 评论关闭
#include<pic.h>
typedef unsigned char uchar;
typedef unsigned int uint;
#define rs_h PORTC|=0x01
#define rs_l PORTC&=0xfe
#define rw_h PORTC|=0x02
#define rw_l PORTC&=0xfd
#define en_h PORTC|=0x04 
#define en_l PORTC&=0xfb
#define rst_h PORTC|=0x08
#define rst_l PORTC&=0xf7
#define sck_h PORTC|=0x10
#define sck_l PORTC&=0xef
#define io_h PORTC|=0x20
#define io_l PORTC&=0xdf
#define SECADD 0X80//秒寄存器地址
#define MINADD 0x82
#define HRADD 0x84
#define DATEADD 0x86
#define MONTHADD 0x88
#define DAYADD 0x8a
#define YEARADD 0x8c
#define CONTROLADD 0x8e
#define PORT (PORTB)
void delayms(uint x);
void lcd_com(uchar com);
void lcd_dat(uchar dat);
void lcd_write(uchar c,uchar r,uchar dat);
void lcd_init(void);
void Ds1302Init(void);
void WriteByte(uchar dat);
uchar ReadByte(void);
uchar BCDtoDex(uchar dat);
uchar DextoBCD(uchar dat);
uchar ReadByte(void);
void Ds1302Write(uchar add,uchar dat);
uchar Ds1302Read(uchar add);

void main(void)
{
	uchar sec,min,hr,date,month,day,year;
	TRISB=0x00;
	TRISC&=0xc0;
	lcd_init();
	Ds1302Init();
	while(1)
	{
		sec=Ds1302Read(SECADD);
		min=Ds1302Read(MINADD);
		hr=Ds1302Read(HRADD);
		date=Ds1302Read(DATEADD);
		month=Ds1302Read(MONTHADD);
		day=Ds1302Read(DAYADD);
		year=Ds1302Read(YEARADD);

		sec=BCDtoDex(sec);
		min=BCDtoDex(min);
		hr=BCDtoDex(hr);
		date=BCDtoDex(date);
		month=BCDtoDex(month);
		day=BCDtoDex(day);
		year=BCDtoDex(year);

		lcd_write(0,1,0x32);
		lcd_write(0,2,0x30);
		lcd_write(0,3,0x30+year/10);
		lcd_write(0,4,0x30+year%10);
		lcd_write(0,6,0x30+month/10);
		lcd_write(0,7,0x30+month%10);
		lcd_write(0,9,0x30+date/10);
		lcd_write(0,10,0x30+date%10);
		lcd_write(0,14,0x30+day);
		lcd_write(1,4,0x30+hr/10);
		lcd_write(1,5,0x30+hr%10);
		lcd_write(1,7,0x30+min/10);
		lcd_write(1,8,0x30+min%10);
		lcd_write(1,10,0x30+sec/10);
		lcd_write(1,11,0x30+sec%10);
		delayms(1005);//1ms
	}

}
void Ds1302Init(void)
{
	rst_l;
	sck_l;
	Ds1302Write(CONTROLADD,0);//关闭写保护
	Ds1302Write(MINADD,DextoBCD(06));
	Ds1302Write(HRADD,DextoBCD(19));
	Ds1302Write(DATEADD,DextoBCD(20));
	Ds1302Write(MONTHADD,DextoBCD(5));
	Ds1302Write(DAYADD,DextoBCD(7));
	Ds1302Write(YEARADD,DextoBCD(12));
	Ds1302Write(SECADD,DextoBCD(30));//写秒,同时启动时钟
}
void WriteByte(uchar dat)//上升沿输出
{
	uchar i;
	TRISC&=0xdf;
	for(i=8;i>0;i--)
	{
		sck_l;//低电平时数据线可变
		if(dat&0x01)
			io_h;
		else
			io_l;
		sck_h;
		dat>>=1;
	}
}
uchar BCDtoDex(uchar dat)//BCD码转十进制
{
	uchar i;
	i=dat/16;
	dat%=16;
	i=i*10+dat;
	return i;
}
uchar DextoBCD(uchar dat)//十进制转BCD码
{
	uchar i;
	i=dat/10;
	dat%=10;
	i=i*16+dat;
	return i;
}
uchar ReadByte(void)//下降沿输出
{
	uchar i;
	uchar dat;
	TRISC|=0x20;
	for(i=8;i>0;i--)//要考虑之前写完后的状态,第一次进入此循环体即有下降沿
	{
		dat>>=1;
		sck_l;
		if(PORTC&0x20)
			dat|=0x80;
		sck_h;	
	}
	return dat;
}
void Ds1302Write(uchar add,uchar dat)
{
	rst_l;
	sck_l;
	rst_h;
	WriteByte(add);//最低位置0表示写
	WriteByte(dat);
	rst_l;
}
uchar Ds1302Read(uchar add)
{
	uchar dat;
	rst_l;
	sck_l;
	rst_h;
	WriteByte(add+1);//地址最低位置1表示读
	dat=ReadByte();
	rst_l;
	return dat;
}
void delayms(uint x) //8M晶振下,延时1ms
{
	uint y,z;
	for(y=x;y>0;y--)
		for(z=220;z>0;z--);
}
void lcd_init(void)//LCD1602初始化
{
	lcd_com(0x38);
	lcd_com(0x0c);
	lcd_com(0x06);
	lcd_write(0,5,0xb0);
	lcd_write(0,8,0xb0);
	lcd_write(1,6,0x3a);
	lcd_write(1,9,0x3a);
}
void lcd_com(uchar com)//向LCD1602写命令
{
	rs_l;
	rw_l;
	PORT=com;
	delayms(1);
	en_h;
	delayms(1);	
	en_l;
}
void lcd_dat(uchar dat)//向LCD1602写数据
{
	rs_h;
	rw_l;
	PORT=dat;
	delayms(1);
	en_h;
	delayms(1);
	en_l;
}
void lcd_write(uchar c,uchar r,uchar dat)//向LCD1602指定行、指定列、写数据
{
	lcd_com(0x80+0x40*c+r);
	lcd_dat(dat);
	delayms(1);
}


 

抱歉!评论已关闭.