新闻中心

EEPW首页>嵌入式系统>设计应用> 简易12684液晶和Atmega32的电子万年历

简易12684液晶和Atmega32的电子万年历

作者: 时间:2013-12-12 来源:网络 收藏


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

//从DS1302读一个字节数据
unsigned char DS1302_ReadByte(void)
{
unsigned char i,dat = 0; //dat存放读出的数据,初始化为0
PORTB = ~(1 PB1); //DS1302的I/O口上拉不使能,
DDRB = ~(1 PB1); //DS1302的I/O口设置为输入口,准备读数据

for(i = 0;i 8;i++) //读8位,低位在前,右移
{
dat >>= 1; //读出的数据右移一位
PORTB |= (1 PB0); //DS1302的SCLK端口拉高
Delayus(10); //
PORTB = ~(1 PB0); //DS1302的SCLK端口拉低,产生下降沿,
Delayus(10);
if(PINB (1 PB1)) //读数据端口状态
{
dat |= 0x80; //如果数据端口位高,相应数据位置1
}
}
DDRB |= (1 PB1); //最后将数据端口设置为输出
return dat; //返回读出的数据
}

//向DS1302写一个字节数据
void DS1302_WriteByte(unsigned char dat)
{
unsigned char i;

for(i = 0;i 8;i++) //写8位,低位在前
{
PORTB = ~(1 PB0); //DS1302的SCLK置低
if(dat 0x01) //写数据位
{
PORTB |= (1 PB1); //如果该位为1,则I/O口置高
}
else
{
PORTB = ~(1 PB1); //如果该位为0,则I/O口置低
}
Delayus(10); //
PORTB |= (1 PB0); //DS1302的SCLK置高,产生上升沿
dat >>= 1; //数据右移1位
}
}

//从DS1302的指定地址读一个字节数据
unsigned char DS1302_ReadData(unsigned addr)
{
unsigned char data;

PORTB = ~(1 PB2); //拉低片选端
PORTB = ~(1 PB0);//拉低时钟端
Delayus(10);
PORTB |= (1 PB2);//拉高片选端
Delayus(10);
DS1302_WriteByte(addr);//写入操作命令(地址)
Delayus(10);
data = DS1302_ReadByte();//读出数据
Delayus(10);
PORTB = ~(1 PB0); //拉低时钟端
PORTB = ~(1 PB2); //拉低片选端

return data;
}

//向DS1302的指定地址写一个字节数据
void DS1302_WriteData(unsigned char addr,unsigned data)
{
PORTB = ~(1 PB2); //拉低片选端
PORTB = ~(1 PB0);//拉低时钟端
Delayus(10);
PORTB |= (1 PB2);//拉高片选端
Delayus(10);
DS1302_WriteByte(addr);//写入操作命令(地址)
Delayus(10);
PORTB = ~(1 PB0);//拉低时钟端
Delayus(10);
DS1302_WriteByte(data);//写入数据
PORTB = ~(1 PB0); //拉低时钟端

Delayus(10);
PORTB = ~(1 PB2); //拉低片选端
}

//对DS1302设置时间
void DS1302_SetTime(unsigned char *time)
{
unsigned char i;
unsigned char addr = 0x80;//写入地址从秒寄存器开始

DS1302_WriteData(WR_PROTECT | WR,UPROTECT);//控制命令,WP位为0,允许写操作
Delayms(5);
for(i = 0;i 7;i++)
{
DS1302_WriteData(addr | WR,time[i]);// 秒 分 时 日 月 星期 年
addr += 2;
Delayms(1);
}
DS1302_WriteData(WR_PROTECT | WR,PROTECT);//控制命令,WP位为1,不允许写操作
}

//从DS1302读取时间
void DS1302_GetTime(void)
{
unsigned char i;
PORTB = ~(1 PB2);
Delayus(10);
PORTB |= (1 PB2);
Delayus(10);
DS1302_WriteByte(0xbf);
for(i = 0;i 8;i++)
{
Get_Time[i] = DS1302_ReadByte();
}
PORTB = ~(1 PB2);
PORTB = ~(1 PB0);
}

//DS1302是否工作检测
unsigned char DS1302_Check(void)
{
DS1302_WriteData(WR_PROTECT | WR,UPROTECT);
DS1302_WriteData(RAMBASE | WR,0x31);

if(DS1302_ReadData(RAMBASE | WR) == 0x31)
{
return TURE;
}
else
{
return FALSE;
}
}

void DS1302_DisCharge(void)
{
DS1302_WriteData(CHARGE|WR,TC_DISABLED);
Delayus(10);
}

unsigned char DS1302_Alarm(unsigned char hour,unsigned char min)
{

}

void System_Beep(void)
{

}

//DS1302初始化
void DS1302_Init(void)
{
DS1302_WriteData(WR_PROTECT | WR,UPROTECT); //写入写允许命令
DS1302_WriteData(SECOND | WR,CLK_START); //启动振荡器,DS1302开始工作
DS1302_WriteData( WR_PROTECT | WR,PROTECT); //控制命令,WP位为1,不允许写操作
}


//us级别的延时函数
void Delayus(unsigned int lus)
{
while(lus--)
{
_delay_loop_2(3); //_delay_loop_2(1)是延时4个时钟周期,参数为3则延时12
//个时钟周期,本实验用12M晶体,则12个时钟周期为12/12=1us
}
}

//ms级别的延时函数
void Delayms(unsigned int lms)
{
while(lms--)
{
Delayus(800); //延时1ms
}
}

晶振相关文章:晶振原理

上一页 1 2 3 下一页

评论


相关推荐

技术专区

关闭