* 文件名称: 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;
}
}[page]
/*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]]);
}
}
视频地址:
上一篇:AVR M16实验之八 AT24C02测试
下一篇:AVR M16实验之六 DS18B20测温
推荐阅读最新更新时间:2024-03-16 14:39