打印
[AVR单片机]

请教AVR+1602+DS1302问题?

[复制链接]
2127|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
q779551869|  楼主 | 2011-11-6 10:10 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
问题描述:
读出来时钟的时间 在LCD1602上显示都是85 请教大侠帮吗解答疑问!真诚的谢谢!!!下面附有仿真的PROTEUS图片。
/*******************************
date:2011/11/2
time:20:45
write by:一棵小草
********************************/
/*------------------------------------------------------------------------
对1602的操作如下:  
1、读状态,输入:RS=L,RW=H,E=H。  输出:D0~D7=状态字  
2、写指令,输入:RS=L,RW=L,D0~D7=指令,E=高脉冲。输出:无  
3、读数据,输入:RS=H,RW=H,E=H。输出:D0~D7=数据  
4、写数据,输入:RS=H,RW=L,D0~D7=数据,E=高脉冲。输出:无 
-------------------------------------------------------------------------*/
#include<avr/io.h>

#define uint unsigned int
#define uchar unsigned char
//液晶相关宏定义
#define RS PD0
#define RW PD1
#define EN  PD2
#define LCD_Data PORTC
//DS1302相关宏定义
#define RST  PA0
#define SCLK PA1
#define IO  PA2
#define DS1302_Sec 0x80 //秒寄存器地址
#define DS1302_Min 0x82 //分寄存器地址
#define DS1302_Hour 0x84 //时寄存器地址
#define DS1302_Day 0x86 //日寄存器地址
#define DS1302_Month 0x88 //月寄存器地址
#define DS1302_Week 0x8a //周寄存器地址
#define DS1302_Year 0x8c //年寄存器地址
#define DS1302_Control 0x8e //控制寄存器
#define DS1302_Charger 0x90 //涓流充电
#define DS1302_Clkburst 0xbe //时钟多字节

void delay_ms(uint z);//1ms delay
void LCD_1602_init();
void write_com(uchar com);     // 写指令
void write_data(uchar date);    //写数据
void port_init(void);//端口初始化
void busy_check();

void write_ds1302(uchar addr,uchar data);
uchar read_ds1302(uchar addr);
//void ds1302_SetTime();
//void ds1302_GetTime();
//void trans();
void write_sfm(uchar add,uchar dat);
void init_1302();
uchar shi,fen,miao;
//uchar table1[]="time:21:01";
//uchar table2[]="date:2011-09-02";
//uchar table_time[8]={0,0,10,0,0,10,0,0};    //时间
//uchar time[7]={0,00,0,00,0,0,0};  
//uchar table_num[]="0123456789:- ";

int main(void)
{
//        uchar i,j;
        port_init();
        LCD_1602_init();
//        ds1302_SetTime();
        init_1302();
        while(1)
        {
                miao=read_ds1302(0x81);
                  fen=read_ds1302(0x83);
                  shi=read_ds1302(0x85);
                  write_sfm(10,miao);
                  write_sfm(7,fen);
                  write_sfm(4,shi);

        }
}
void port_init(void)
{
//        DDRA = 0XFF;
//        DDRB = 0XFF;
        DDRC = 0XFF;
        DDRD = 0XFF;
       
//        PORTA = 0X00;
//        PORTB = 0X00;
        PORTC = 0X00;
        PORTD = 0X00;       
}
void delay_ms(uint z)
{
        uint x,y;
        for(x=z;x>0;x--)
                for(y=419;y>0;y--);
}
void LCD_1602_init()
{
        write_com(0x38);//显示模式设置
        write_com(0x08);//关闭显示
        write_com(0x01);//清屏
        write_com(0x0c);//开显示
        write_com(0x06);//显示光标移动设置
               
}
void write_com(uchar com)
{
        busy_check();
        DDRC = 0Xff;
        PORTD &= ~_BV(RS);
        PORTD &= ~_BV(RW);  //RW=0;
        PORTD &= ~_BV(EN);  //EN=0;
        PORTC = com;
        PORTD |= _BV(EN);   //EN=1;
        delay_ms(10);
        PORTD &= ~_BV(EN);  //EN=0;
        PORTD |= _BV(RS);   //RS=1;
        PORTD |= _BV(RW);   //RW=1
                               
}
void write_data(uchar date)
{
        busy_check();
        DDRC = 0Xff;
        PORTD |= _BV(RS);   //RS=1;
        PORTD &= ~_BV(RW);  //RW=0;
        PORTD &= ~_BV(EN);  //EN=0;
        PORTC = date;
        PORTD |= _BV(EN);   //EN=1;
        delay_ms(10);
        PORTD &= ~_BV(EN);  //EN=0;
        PORTD &= ~_BV(RS);
        PORTD |= _BV(RW);   //RW=1               
}
void busy_check()
{
        DDRD |= 0X07;
        DDRC = 0X00;
        PORTD &= ~_BV(EN);  //EN=0;
        PORTD |= _BV(RW);   //RW=1;       
        PORTD &= ~_BV(RS);
        PORTD |= _BV(EN);   //EN=1;
        while(LCD_Data&&0x80==1);
        PORTD &= ~_BV(EN);  //EN=0;
        delay_ms(3);
}
/********写一个字节*********************/
void write_ds1302(uchar addr,uchar data)
{
        uchar i;
        DDRA |= _BV(IO);//I/O set output
        PORTA &= ~_BV(SCLK);
        PORTA |= _BV(RST);
        addr&=0xfe;       
        for(i=0;i<8;i++) //写地址、命令字节,上升沿有效
        {
                PORTA &= ~_BV(SCLK);
                if(addr&0x01) //判断地址字节的最低位
                        PORTA |= _BV(IO);
                else
                        PORTA &= ~_BV(IO);
                PORTA |= _BV(SCLK);
                addr>>=1;          //先发送低位       
        }
        for(i=0;i<8;i++)//写数据
        {
                PORTA &= ~_BV(SCLK);
                if(data&0x01) //判断数据字节的最低位
                        PORTA |= _BV(IO);
                else
                        PORTA &= ~_BV(IO);
                PORTA|=_BV(SCLK);
                data>>=1;               
        }
        PORTA &= ~_BV(RST);                       
}
/***************从DS1302中读一个字节******************/
uchar read_ds1302(uchar addr)
{
        uchar i,data,temp,temp1,temp2;
        DDRA |= _BV(IO); //设置IO为输出
        PORTA &= ~_BV(SCLK);
        PORTA |= _BV(RST);
        addr|=0x01; //地址字节的LSB设置为逻辑1
        for(i=0;i<8;i++) //写地址、命令字节,上升沿有效
        {
                PORTA &= ~_BV(SCLK);
                if(addr&0x01) //字节地址的LSB是否为1
                        PORTA |= _BV(IO);
                else
                        PORTA&=~_BV(IO);
                PORTA |= _BV(SCLK);
                addr>>=1;
        }
       
        DDRA &= ~_BV(IO); //改变IO为输入状态
        PORTA &= ~_BV(IO);
        for(i=0;i<8;i++) //读数据字节,下降沿有效
        {
                PORTA |= _BV(SCLK);
                if(PINA&_BV(IO)) data|=0x80; //判断PINA的IO位是否为1,是则读1
                PORTA &= ~_BV(SCLK);
                data>>=1;
        }
        PORTA &= ~_BV(RST); //拉低RST信号,读一个字节结束
        temp1 = data/16;
        temp2 = data%16;
        temp = temp1*10+temp2;
        return (temp); //返回数据
}
/*void ds1302_SetTime()
{
        uchar i,add;
        add=0x80;
        write_ds1302(0x8e,0x00);    //允许写入
        for(i=0;i<7;i++)
           {
                    write_ds1302(add,time[i]);
                    add+=2;
           }
        write_ds1302(0x90,0xa6);   //写充电控制寄存器.
        write_ds1302(0x8e,0x80);   //禁止写入
}*/

//-------------------------------
//---- 获取DS1302时间 --------
//---- 在主函数中调用 --------
//-------------------------------

/*void ds1302_GetTime()
{
        uchar i,add=0x81;
        write_ds1302(0x8e,0x00);     //允许向DS1302写入数据
        for(i=0;i<7;i++)
        {
           time[i]=read_ds1302(add); //获得的数据已转换为十进制  
           add+=2;
        }
        write_ds1302(0x8e,0x80);        //获取完一次时间,禁止向DS1302写入数据,提高可靠
}*/
/*void trans()
{
        table_time[0]=time[2]/10;   //小时十位   
        table_time[1]=time[2]%10;   //小时个位

        table_time[3]=time[1]/10;   //分十位
        table_time[4]=time[1]%10;   //分个位

        table_time[6]=time[0]/10;   //秒十位
        table_time[7]=time[0]%10;   //秒个位
}*/
void init_1302()
{
        write_ds1302(0x8e,0x00);
        write_ds1302(DS1302_Sec,0X31);
        write_ds1302(DS1302_Min,0X14);
        write_ds1302(DS1302_Hour,0X09);
        write_ds1302(0x8e,0x80);
}

void write_sfm(uchar add,uchar dat)  //往1602中写数据(即时间)
{
        uchar shi,ge;
        shi=dat/10;
        ge=dat%10;
        write_com(0x80+add);
        write_data(0x30+shi);
        write_data(0x30+ge);
}

相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

0

主题

4

帖子

1

粉丝