#include
#include
#define uchar unsigned char
#define uint unsigned int
//界说LCD1602的端口使用
#define RS_CLI PORTB&=~BIT(PB1)
#define RS_SEI PORTB|=BIT(PB1)
#define RW_CLI PORTB&=~BIT(PB2)
#define RW_SEI PORTB|=BIT(PB2)
#define EN_CLI PORTB&=~BIT(PB3)
#define EN_SEI PORTB|=BIT(PB3)
//界说DS1302数据端口
#define RST_CLI PORTC&=~BIT(PC4)
#define RST_SEI PORTC|=BIT(PC4)
#define RST_IN DDRC&=~BIT(PC4)
#define RST_OUT DDRC|=BIT(PC4)
#define SCLK_CLI PORTC&=~BIT(PC2)
#define SCLK_SEI PORTC|=BIT(PC2)
#define SCLK_IN DDRC&=~BIT(PC2)
#define SCLK_OUT DDRC|=BIT(PC2)
#define IO_CLI PORTC&=~BIT(PC3)
#define IO_SEI PORTC|=BIT(PC3)
#define IO_R PINC&BIT(PC3)
#define IO_IN DDRC&=~BIT(PC3)
#define IO_OUT DDRC|=BIT(PC3)
#define ds1302_sec_add0x80//秒数据地址
#define ds1302_min_add0x82//分数据地址
#define ds1302_hr_add0x84//时数据地址
#define ds1302_date_add0x86//日数据地址
#define ds1302_month_add0x88//月数据地址
#define ds1302_day_add0x8a//星期数据地址
#define ds1302_year_add0x8c//年数据地址
#define ds1302_control_add0x8e//操控数据地址
#define ds1302_charger_add0x90
#define ds1302_clkburst_add0xbe
unsigned char time_buf[8] = {0x20,0x09,0x04,0x28,0x17,0x13,0x00,0x02};
unsigned char time_buf1[8] = {0x20,0x10,0x04,0x12,0x23,0x18,0x22,0x00};
void DS1302_WriteByte(uchar addr,uchar data)
{
uchar i=0;
RST_SEI; //发动DS1302,进行写操作
IO_OUT; //界说数据口为输出形式
addr=addr&0xfe; //最低位为0表明写入。为1时表明读取
for(i=0;i<8;i++)
{
if(addr&0x01) //DS1320发送数据是先低位后高位,当传送第一位时与0x01相与,
{ //假如持平,表明传送的位为高电平,不等则为低电平,第一次送完第一次后ADDR左移一位预备传送第二位数据
IO_SEI; //假如持平表明传送的位为高电平,不等则为低电平,如此循环8次之后,要写入的数据就写完了
}
else
{
IO_CLI;
}
SCLK_SEI;
SCLK_CLI;
addr=addr>>1;
}
IO_OUT;
for(i=0;i<8;i++)
{
if(data&0x01)
{
IO_SEI;
}
else
{
IO_CLI;
}
SCLK_SEI;
SCLK_CLI;
data=data>>1;
}
RST_CLI;
}
uchar DS1302_ReadByte(uchar addr)
{
uchar temp=0,i=0;
RST_SEI;
IO_OUT;
addr=addr|0x01;
for(i=0;i<8;i++)
{
if(addr&0x01)
{
IO_SEI;
}
else
{
IO_CLI;
}
SCLK_SEI;
SCLK_CLI;
addr=addr>>1;
}
IO_IN;
for(i=0;i<8;i++)//读数据和写数据正好相反,方法相同;先判别读取到的值是高位仍是低位,在经行保存
{
temp=temp>>1;//为下一次保存数据做预备先读低位后读高位
if(IO_R)//假如读取到的数据为高,则置高
{
temp|=0x80;
}
else//假如读取到的数据为低,则啦低
{
temp&=0x7f;
}
SCLK_SEI;
SCLK_CLI;
}
RST_CLI;
return temp;
}
void DS1302_Init(void)
{
RST_CLI;
SCLK_CLI;
RST_OUT;
SCLK_OUT;
}
void DS1302_WriteTime(void)
{
DS1302_WriteByte(ds1302_control_add,0x00);//当写保护寄存器的最高位为0 时答应数据写入寄存器,
//当写保护寄存器的最高位为1 时制止数据写入寄存器
DS1302_WriteByte(ds1302_sec_add,0x80);//秒寄存器的第7 位时钟中止位设置为0 时起动时钟开端、设置为1时时钟中止运转
DS1302_WriteByte(ds1302_year_add,0x10); //年
DS1302_WriteByte(ds1302_month_add,0x12); //月
DS1302_WriteByte(ds1302_day_add,0x04); //星期
DS1302_WriteByte(ds1302_date_add,0x23); //日
DS1302_WriteByte(ds1302_hr_add,0x16); //小时
DS1302_WriteByte(ds1302_min_add,0x00); //分
DS1302_WriteByte(ds1302_sec_add,0x00); //秒
DS1302_WriteByte(ds1302_control_add,0x80);//当写保护寄存器的最高位为1 时制止数据写入寄存器
}
void DS1302_WriteTime1(void)
{
uchar i=0,addr=ds1302_year_add;
DS1302_WriteByte(ds1302_control_add,0x00);//当写保护寄存器的最高位为0 时答应数据写入寄存器,
//当写保护寄存器的最高位为1 时制止数据写入寄存器
DS1302_WriteByte(ds1302_sec_add,0x80);//秒寄存器的第7 位时钟中止位设置为0 时起动时钟开端、设置为1时时钟中止运转
for(i=1;i<8;i++)
{
DS1302_WriteByte(addr,time_buf1[i]);
addr-=2;
}
DS1302_WriteByte(ds1302_control_add,0x80);//当写保护寄存器的最高位为1 时制止数据写入寄存器
}
void DS1302_GetTime(void)
{
time_buf[1]=DS1302_ReadByte(ds1302_year_add);
time_buf[2]=DS1302_ReadByte(ds1302_month_add);
time_buf[3]=DS1302_ReadByte(ds1302_date_add);
time_buf[4]=DS1302_ReadByte(ds1302_day_add);
time_buf[5]=DS1302_ReadByte(ds1302_hr_add);
time_buf[6]=DS1302_ReadByte(ds1302_min_add);
time_buf[7]=(DS1302_ReadByte(ds1302_sec_add))&0x7f;
}
void DS1302_GetTime1(void)
{
uchar i=0,addr=ds1302_year_add;
for(i=1;i<8;i++)
{
time_buf1[i]=DS1302_ReadByte(addr);//0x8c=ds1302_year_add
addr=addr-2;
}
}
void delay(uint ms)
{
uint i=0,j=0;
for(i=ms;i>0;i–)
for(j=1141;j>0;j–);
}
void delay_us(uint us)
{
uint i,j;
for(i=0;i<8;i++)
{
for(j=0;j NOP();
}
}
void port_init(void)
{
DDRB=0XFF;
PORTB=0XFF;
}
void LCD_EN_Write(void)
{
EN_CLI;
delay_us(5);
EN_SEI;
delay_us(5);
}
void LCD_Write(uchar icom,uchar data)
{
if(0==icom) //写指令
RS_CLI;
else //写数据
RS_SEI;
RW_CLI;
PORTB&=0X0F; //先铲除PORTB的高四位
PORTB|=(data&0XF0); //将写入的数据取出高四位先发送
LCD_EN_Write(); //使能LCD
delay_us(35); //延时 保证高四位的写入正确
data=data<<4; //屏蔽高四位
PORTB&=0X0F; // 取出数据的低四位数据
PORTB|=(data&0XF0); //发送低四位数据
LCD_EN_Write(); //使能LCD
}
void LCD_Clear(void)
{
LCD_Write(0,0X01);
delay(5);
}
void lcd_init(void)
{
delay(15);
LCD_Write(0,0×28);//四线数据线、16X2显现、5×7点阵
LCD_EN_Write(); //这句很重要,切忌,丢掉或许LCD便是一块黑板,什么都没有
delay(5);
LCD_Write(0,0×28);//四线数据线、16X2显现、5×7点阵
LCD_Write(0,0×08);//封闭显现
delay(5);
LCD_Write(0,0×01);//铲除屏幕显现
LCD_Write(0,0×06);//当读写一字符后地址指针加一光标加一,整屏不移动
delay(5);
LCD_Write(0,0x0c);//开显现、显现光标、光标闪耀
delay(5);
}
void LCD_Write_Byte(uchar Line,uchar addr,uchar data)
{
if(1==Line)
LCD_Write(0,0×80+addr);
else if(2==Line)
LCD_Write(0,0xc0+addr);
LCD_Write(1,data);
}
void LCD_Write_Str(uchar Line,uchar addr,uchar *p)
{
if(1==Line)
LCD_Write(0,0×80+addr);
else if(2==Line)
LCD_Write(0,0xc0+addr);
while(*p)
{
LCD_Write(1,*p);
p++;
}
}
void DS1302_DispalyTime(void)
{
uchar temp;
temp=(time_buf[0]>>4)+0; //年显现
LCD_Write_Byte(1,0,temp);
temp=(time_buf[0]&0x0f)+0;
LCD_Write_Byte(1,1,temp);
temp=(time_buf[1]>>4)+0;
LCD_Write_Byte(1,2,temp);
temp=(time_buf[1]&0x0f)+0;
LCD_Write_Byte(1,3,temp);
LCD_Write_Byte(1,4,-);
temp=(time_buf[2]>>4)+0; //月显现
LCD_Write_Byte(1,5,temp);
temp=(time_buf[2]&0x0f)+0;
LCD_Write_Byte(1,6,temp);
LCD_Write_Byte(1,7,-);
temp=(time_buf[3]>>4)+0; //日显现
LCD_Write_Byte(1,8,temp);
temp=(time_buf[3]&0x0f)+0;
LCD_Write_Byte(1,9,temp);
LCD_Write_Str(2,0,”week:”); //星期显现
temp=(time_buf[4])+0;
LCD_Write_Byte(2,5,temp);
temp=(time_buf[5]>>4)+0; //时显现
LCD_Write_Byte(2,8,temp);
temp=(time_buf[5]&0x0f)+0;
LCD_Write_Byte(2,9,temp);
LCD_Write_Byte(2,10,:);
temp=(time_buf[6]>>4)+0; //分显现
LCD_Write_Byte(2,11,temp);
temp=(time_buf[6]&0x0f)+0;
LCD_Write_Byte(2,12,temp);
LCD_Write_Byte(2,13,:);
temp=(time_buf[7]>>4)+0; //秒显现
LCD_Write_Byte(2,14,temp);
temp=(time_buf[7]&0x0f)+0;
LCD_Write_Byte(2,15,temp);
}
void DS1302_DispalyTime1(void)
{
uchar temp;
temp=(time_buf1[0]>>4)+0; //年显现
LCD_Write_Byte(1,0,temp);
temp=(time_buf1[0]&0x0f)+0;
LCD_Write_Byte(1,1,temp);
temp=(time_buf1[1]>>4)+0;
LCD_Write_Byte(1,2,temp);
temp=(time_buf1[1]&0x0f)+0;
LCD_Write_Byte(1,3,temp);
LCD_Write_Byte(1,4,-);
LCD_Write_Str(2,0,”week:”); //星期显现
temp=(time_buf1[2])+0;
LCD_Write_Byte(2,5,temp);
temp=(time_buf1[3]>>4)+0; //月显现
LCD_Write_Byte(1,5,temp);
temp=(time_buf1[3]&0x0f)+0;
LCD_Write_Byte(1,6,temp);
LCD_Write_Byte(1,7,-);
temp=(time_buf1[4]>>4)+0; //日显现
LCD_Write_Byte(1,8,temp);
temp=(time_buf1[4]&0x0f)+0;
LCD_Write_Byte(1,9,temp);
temp=(time_buf1[5]>>4)+0; //时显现
LCD_Write_Byte(2,8,temp);
temp=(time_buf1[5]&0x0f)+0;
LCD_Write_Byte(2,9,temp);
LCD_Write_Byte(2,10,:);
temp=(time_buf1[6]>>4)+0; //分显现
LCD_Write_Byte(2,11,temp);
temp=(time_buf1[6]&0x0f)+0;
LCD_Write_Byte(2,12,temp);
LCD_Write_Byte(2,13,:);
temp=(time_buf1[7]>>4)+0; //秒显现
LCD_Write_Byte(2,14,temp);
temp=(time_buf1[7]&0x0f)+0;
LCD_Write_Byte(2,15,temp);
}
void main(void)
{
port_init();
DS1302_Init();
lcd_init();
LCD_Clear();
delay(10);
//DS1302_WriteTime();
DS1302_WriteTime1();
while(1)
{
//DS1302_GetTime();
DS1302_GetTime1();
//DS1302_DispalyTime(); //注释掉的三条句子也是OK的,调试一下
DS1302_DispalyTime1();
}
}
protues政策图如下:
声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/zhishi/shuzi/261058.html