AVR M16实验之七 DS1302测试
时间:11-25
来源:互联网
点击:
/**********************************************************************
* 文件名称: main.c
* 程序作者: kidcao1987
* 程序版本: V1.0
* 功能描述: 装上LCD1602,在其上显示时间,年月等
* 编译器:WinAVR-20090313
* 芯片:ATmega16,外部11.0592MHZ晶振
* 技术支持:http://bbs.cepark.com
**********************************************************************/
#include
#include
#define uchar unsigned char
#define uint unsigned int
#define SCLK PA1
#define IO PA2
#define RST PA3
#define RS PA4
#define RW PA5
#define EN PA6
uchar DisplayNum[]={"0123456789"};
uint Calendar[]={0x10,0x02,0x4,0x12,0x22,0x40,0x00};//年月周日时分秒
uchar Weeks[7][3]={"Mon","Tue","Wen","Thu","Fri","Sat","Sun"};//字符数组
uchar ConversionResult[]={"20**-**:*-**-**-**-**"};//开辟空间存储转换结果
uchar i=1;
void LCD1602_Initial(void);
void LCD1602_CommandWrite(uchar com);
void LCD1602_ByteWrite(uchar date);
void LCD1602_Display(uchar adr,uchar date);
void LCD1602_BusyCheck(void);
void PORTx_Initial(void);
void Initial_DS1302(void);
void DS1302_RST(void);
void DS1302_ByteWrite(uchar command,uchar Byte);
uchar DS1302_ByteRead(uchar command);
void DS1302_TimeShow(void);
uchar BCD_Conversion(uchar date);
void Calendar_ReadBack(void);
int main(void)
{
PORTx_Initial();//初始化IO
LCD1602_Initial();//初始化1602
Initial_DS1302();//初始化DS1302
while(1)
{
DS1302_TimeShow();//显示时间
}
}
/*LCD1602初始化*/
void LCD1602_Initial(void)
{
LCD1602_CommandWrite(0x38);
_delay_ms(15);
LCD1602_CommandWrite(0x38);
_delay_ms(5);
LCD1602_CommandWrite(0x38);
_delay_ms(5);
LCD1602_CommandWrite(0x01);
_delay_ms(1);
LCD1602_CommandWrite(0x38);
_delay_ms(1);
LCD1602_CommandWrite(0x0c);
_delay_ms(1);
LCD1602_CommandWrite(0x06);
}
/*端口初始化函数*/
void PORTx_Initial(void)
{
PORTA&=~((1PORTA&=~((1<4)|(1<5)|(1<6));
DDRA|=(1
PORTB=0x00;
DDRB=0xff; //B口初始化为输出方向输出低电平
}
/*DS1302初始化函数*/
void Initial_DS1302(void)
{
DS1302_RST();
DS1302_ByteWrite(0x90,0xa9);//使能充电,双二极管,2K电阻
DS1302_RST();
DS1302_ByteWrite(0x8e,0x00);//关闭写保护
DS1302_RST();
DS1302_ByteWrite(0x8c,Calendar[0]);//10年
DS1302_RST();
DS1302_ByteWrite(0x88,Calendar[1]);//2月
DS1302_RST();
DS1302_ByteWrite(0x8a,Calendar[2]);//周三
DS1302_RST();
DS1302_ByteWrite(0x86,Calendar[3]);//10日
DS1302_RST();
DS1302_ByteWrite(0x84,Calendar[4]);//00时
DS1302_RST();
DS1302_ByteWrite(0x82,Calendar[5]);//00分
DS1302_RST();
DS1302_ByteWrite(0x80,0x00);//00秒
DS1302_RST();
}
/*DS1302复位函数*/
void DS1302_RST(void)
{
PORTA&=~(1_delay_us(1);
PORTA|=(1_delay_us(1);
}
/*DS1302字节写入函数*/
void DS1302_ByteWrite(uchar command,uchar Byte)
{
uchar n=0;
for(n=0;n<8;n++)
{
if(command&0x01)
PORTA|=(1else
PORTA&=~(1PORTA|=(1_delay_us(1);
PORTA&=~(1_delay_us(1);
command>>=1;
}
for(n=0;n<8;n++)
{
if(Byte&0x01)
PORTA|=(1else
PORTA&=~(1PORTA|=(1_delay_us(1);
PORTA&=~(1_delay_us(1);
Byte>>=1;
}
}
/*DS1302字节读取函数,注意下降沿读出数据和第八个下降沿*/
uchar DS1302_ByteRead(uchar command)
{
uchar i=0,n=0,readback=0;
PORTA|=(1DDRA|=(1for(n=0;n<8;n++)
{
PORTA&=~(1_delay_us(1);
if(command&0x01)
PORTA|=(1else
PORTA&=~(1command>>=1;
PORTA|=(1_delay_us(1);
}
PORTA|=(1DDRA&=~(1for(i=0;i<8;i++)
{
readback>>=1;
PORTA|=(1_delay_us(1);
PORTA&=~(1_delay_us(1);
if(PINA&(1readback|=0x80;
}
return readback;
}
/*读取DS1302数据,分别是年月周日时分秒*/
void Calendar_ReadBack(void)
{
DS1302_RST();
Calendar[0]=DS1302_ByteRead(0x8d);
DS1302_RST();
Calendar[1]=DS1302_ByteRead(0x89);
DS1302_RST();
Calendar[2]=DS1302_ByteRead(0x8b);
DS1302_RST();
Calendar[3]=DS1302_ByteRead(0x87);
DS1302_RST();
Calendar[4]=DS1302_ByteRead(0x85);
DS1302_RST();
Calendar[5]=DS1302_ByteRead(0x83);
DS1302_RST();
Calendar[6]=DS1302_ByteRead(0x81);
DS1302_RST();
}
/*1602写命令字子函数*/
void LCD1602_CommandWrite(uchar com)
{
LCD1602_BusyCheck();
PORTA&=~(1PORTB=com; //将数据送到8位并行数据口
PORTA|=(1_delay_ms(1); //延时5ms,保持EN电平
PORTA&=~(1}
/*1602写数据子函数*/
void LCD1602_ByteWrite(uchar date)
{
LCD1602_BusyCheck();
PORTA|=(1PORTB=date; //将数据送到8位并行数据口
PORTA|=(1_delay_ms(1); //延时5ms,保持EN电平
PORTA&=~(1}
/*在某位置显示某字符,参数adr为待写地址,date为待写字节*/
void LCD1602_Display(uchar adr,uchar date)
{
LCD1602_BusyCheck();
LCD1602_CommandWrite(adr);
LCD1602_BusyCheck();
LCD1602_ByteWrite(date);
}
void LCD1602_BusyCheck(void)
{
PORTB=0xff;
DDRB=0x00;
PORTA|=(1PORTA&=~(1PORTA|=(1_delay_us(5);
while(PINB&0x80);
PORTA&=~(1PORTA&=~(1PORTB=0xff;
DDRB=0xff;
}
/*将BCD码转换为10进制*/
uchar BCD_Conversion(uchar date)
{
uchar highbit=0,lowbit=0,Result;
highbit=date/16;
lowbit=date%16;
Result=highbit*10+lowbit;
return Result;
}
void DS1302_TimeShow(void)
{
Calendar_ReadBack();
ConversionResult[2]=(BCD_Conversion(Calendar[0]))/10;
ConversionResult[3]=(BCD_Conversion(Calendar[0]))%10;//转换后存入年
ConversionResult[5]=(BCD_Conversion(Calendar[1]))/10;
ConversionResult[6]=(BCD_Conversion(Calendar[1]))%10;//转换后存入月
ConversionResult[8]=Calendar[2];//不转换直接存入周
ConversionResult[10]=(BCD_Conversion(Calendar[3]))/10;
ConversionResult[11]=(BCD_Conversion(Calendar[3]))%10;//转换后存入日
ConversionResult[13]=(BCD_Conversion(Calendar[4]))/10;
ConversionResult[14]=(BCD_Conversion(Calendar[4]))%10;//转换后存入时
ConversionResult[16]=(BCD_Conversion(Calendar[5]))/10;
ConversionResult[17]=(BCD_Conversion(Calendar[5]))%10;//转换后存入分
ConversionResult[19]=(BCD_Conversion(Calendar[6]))/10;
ConversionResult[20]=(BCD_Conversion(Calendar[6]))%10;//转换后存入秒
uchar n;
/*以下为1602显示语句*/
for(n=0;n<2;n++)
{
LCD1602_Display(0x81+n,ConversionResult[n]);
}
for(n=2;n<4;n++)
{
LCD1602_Display(0x81+n,DisplayNum[ConversionResult[n]]);
}
LCD1602_Display(0x85,ConversionResult[4]);
for(n=5;n<7;n++)
{
LCD1602_Display(0x81+n,DisplayNum[ConversionResult[n]]);
}
LCD1602_Display(0x88,ConversionResult[4]);
for(n=8;n<10;n++)
{
LCD1602_Display(0x81+n,DisplayNum[ConversionResult[n+2]]);
}
for(n=0;n<3;n++)
{
LCD1602_Display(0x80+13+n,Weeks[ConversionResult[8]][n]);
}
for(n=0;n<2;n++)
{
LCD1602_Display(0x80+0x42+n,DisplayNum[ConversionResult[n+13]]);
}
LCD1602_Display(0x80+0x40+4,ConversionResult[7]);
for(n=3;n<5;n++)
{
LCD1602_Display(0x80+0x42+n,DisplayNum[ConversionResult[n+13]]);
}
LCD1602_Display(0x80+0x40+7,ConversionResult[7]);
for(n=6;n<8;n++)
{
LCD1602_Display(0x80+0x42+n,DisplayNum[ConversionResult[n+13]]);
}
}
* 文件名称: main.c
* 程序作者: kidcao1987
* 程序版本: V1.0
* 功能描述: 装上LCD1602,在其上显示时间,年月等
* 编译器:WinAVR-20090313
* 芯片:ATmega16,外部11.0592MHZ晶振
* 技术支持:http://bbs.cepark.com
**********************************************************************/
#include
#include
#define uchar unsigned char
#define uint unsigned int
#define SCLK PA1
#define IO PA2
#define RST PA3
#define RS PA4
#define RW PA5
#define EN PA6
uchar DisplayNum[]={"0123456789"};
uint Calendar[]={0x10,0x02,0x4,0x12,0x22,0x40,0x00};//年月周日时分秒
uchar Weeks[7][3]={"Mon","Tue","Wen","Thu","Fri","Sat","Sun"};//字符数组
uchar ConversionResult[]={"20**-**:*-**-**-**-**"};//开辟空间存储转换结果
uchar i=1;
void LCD1602_Initial(void);
void LCD1602_CommandWrite(uchar com);
void LCD1602_ByteWrite(uchar date);
void LCD1602_Display(uchar adr,uchar date);
void LCD1602_BusyCheck(void);
void PORTx_Initial(void);
void Initial_DS1302(void);
void DS1302_RST(void);
void DS1302_ByteWrite(uchar command,uchar Byte);
uchar DS1302_ByteRead(uchar command);
void DS1302_TimeShow(void);
uchar BCD_Conversion(uchar date);
void Calendar_ReadBack(void);
int main(void)
{
PORTx_Initial();//初始化IO
LCD1602_Initial();//初始化1602
Initial_DS1302();//初始化DS1302
while(1)
{
DS1302_TimeShow();//显示时间
}
}
/*LCD1602初始化*/
void LCD1602_Initial(void)
{
LCD1602_CommandWrite(0x38);
_delay_ms(15);
LCD1602_CommandWrite(0x38);
_delay_ms(5);
LCD1602_CommandWrite(0x38);
_delay_ms(5);
LCD1602_CommandWrite(0x01);
_delay_ms(1);
LCD1602_CommandWrite(0x38);
_delay_ms(1);
LCD1602_CommandWrite(0x0c);
_delay_ms(1);
LCD1602_CommandWrite(0x06);
}
/*端口初始化函数*/
void PORTx_Initial(void)
{
PORTA&=~((1
DDRA|=(1
PORTB=0x00;
DDRB=0xff; //B口初始化为输出方向输出低电平
}
/*DS1302初始化函数*/
void Initial_DS1302(void)
{
DS1302_RST();
DS1302_ByteWrite(0x90,0xa9);//使能充电,双二极管,2K电阻
DS1302_RST();
DS1302_ByteWrite(0x8e,0x00);//关闭写保护
DS1302_RST();
DS1302_ByteWrite(0x8c,Calendar[0]);//10年
DS1302_RST();
DS1302_ByteWrite(0x88,Calendar[1]);//2月
DS1302_RST();
DS1302_ByteWrite(0x8a,Calendar[2]);//周三
DS1302_RST();
DS1302_ByteWrite(0x86,Calendar[3]);//10日
DS1302_RST();
DS1302_ByteWrite(0x84,Calendar[4]);//00时
DS1302_RST();
DS1302_ByteWrite(0x82,Calendar[5]);//00分
DS1302_RST();
DS1302_ByteWrite(0x80,0x00);//00秒
DS1302_RST();
}
/*DS1302复位函数*/
void DS1302_RST(void)
{
PORTA&=~(1
PORTA|=(1
}
/*DS1302字节写入函数*/
void DS1302_ByteWrite(uchar command,uchar Byte)
{
uchar n=0;
for(n=0;n<8;n++)
{
if(command&0x01)
PORTA|=(1
PORTA&=~(1
PORTA&=~(1
command>>=1;
}
for(n=0;n<8;n++)
{
if(Byte&0x01)
PORTA|=(1
PORTA&=~(1
PORTA&=~(1
Byte>>=1;
}
}
/*DS1302字节读取函数,注意下降沿读出数据和第八个下降沿*/
uchar DS1302_ByteRead(uchar command)
{
uchar i=0,n=0,readback=0;
PORTA|=(1
{
PORTA&=~(1
if(command&0x01)
PORTA|=(1
PORTA&=~(1
PORTA|=(1
}
PORTA|=(1
{
readback>>=1;
PORTA|=(1
PORTA&=~(1
if(PINA&(1
}
return readback;
}
/*读取DS1302数据,分别是年月周日时分秒*/
void Calendar_ReadBack(void)
{
DS1302_RST();
Calendar[0]=DS1302_ByteRead(0x8d);
DS1302_RST();
Calendar[1]=DS1302_ByteRead(0x89);
DS1302_RST();
Calendar[2]=DS1302_ByteRead(0x8b);
DS1302_RST();
Calendar[3]=DS1302_ByteRead(0x87);
DS1302_RST();
Calendar[4]=DS1302_ByteRead(0x85);
DS1302_RST();
Calendar[5]=DS1302_ByteRead(0x83);
DS1302_RST();
Calendar[6]=DS1302_ByteRead(0x81);
DS1302_RST();
}
/*1602写命令字子函数*/
void LCD1602_CommandWrite(uchar com)
{
LCD1602_BusyCheck();
PORTA&=~(1
PORTA|=(1
PORTA&=~(1
/*1602写数据子函数*/
void LCD1602_ByteWrite(uchar date)
{
LCD1602_BusyCheck();
PORTA|=(1
PORTA|=(1
PORTA&=~(1
/*在某位置显示某字符,参数adr为待写地址,date为待写字节*/
void LCD1602_Display(uchar adr,uchar date)
{
LCD1602_BusyCheck();
LCD1602_CommandWrite(adr);
LCD1602_BusyCheck();
LCD1602_ByteWrite(date);
}
void LCD1602_BusyCheck(void)
{
PORTB=0xff;
DDRB=0x00;
PORTA|=(1
while(PINB&0x80);
PORTA&=~(1
DDRB=0xff;
}
/*将BCD码转换为10进制*/
uchar BCD_Conversion(uchar date)
{
uchar highbit=0,lowbit=0,Result;
highbit=date/16;
lowbit=date%16;
Result=highbit*10+lowbit;
return Result;
}
void DS1302_TimeShow(void)
{
Calendar_ReadBack();
ConversionResult[2]=(BCD_Conversion(Calendar[0]))/10;
ConversionResult[3]=(BCD_Conversion(Calendar[0]))%10;//转换后存入年
ConversionResult[5]=(BCD_Conversion(Calendar[1]))/10;
ConversionResult[6]=(BCD_Conversion(Calendar[1]))%10;//转换后存入月
ConversionResult[8]=Calendar[2];//不转换直接存入周
ConversionResult[10]=(BCD_Conversion(Calendar[3]))/10;
ConversionResult[11]=(BCD_Conversion(Calendar[3]))%10;//转换后存入日
ConversionResult[13]=(BCD_Conversion(Calendar[4]))/10;
ConversionResult[14]=(BCD_Conversion(Calendar[4]))%10;//转换后存入时
ConversionResult[16]=(BCD_Conversion(Calendar[5]))/10;
ConversionResult[17]=(BCD_Conversion(Calendar[5]))%10;//转换后存入分
ConversionResult[19]=(BCD_Conversion(Calendar[6]))/10;
ConversionResult[20]=(BCD_Conversion(Calendar[6]))%10;//转换后存入秒
uchar n;
/*以下为1602显示语句*/
for(n=0;n<2;n++)
{
LCD1602_Display(0x81+n,ConversionResult[n]);
}
for(n=2;n<4;n++)
{
LCD1602_Display(0x81+n,DisplayNum[ConversionResult[n]]);
}
LCD1602_Display(0x85,ConversionResult[4]);
for(n=5;n<7;n++)
{
LCD1602_Display(0x81+n,DisplayNum[ConversionResult[n]]);
}
LCD1602_Display(0x88,ConversionResult[4]);
for(n=8;n<10;n++)
{
LCD1602_Display(0x81+n,DisplayNum[ConversionResult[n+2]]);
}
for(n=0;n<3;n++)
{
LCD1602_Display(0x80+13+n,Weeks[ConversionResult[8]][n]);
}
for(n=0;n<2;n++)
{
LCD1602_Display(0x80+0x42+n,DisplayNum[ConversionResult[n+13]]);
}
LCD1602_Display(0x80+0x40+4,ConversionResult[7]);
for(n=3;n<5;n++)
{
LCD1602_Display(0x80+0x42+n,DisplayNum[ConversionResult[n+13]]);
}
LCD1602_Display(0x80+0x40+7,ConversionResult[7]);
for(n=6;n<8;n++)
{
LCD1602_Display(0x80+0x42+n,DisplayNum[ConversionResult[n+13]]);
}
}
AVRM16实验DS1302测 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)