新聞中心

        EEPW首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > ATMEGA16四線驅(qū)動(dòng)LCD顯示時(shí)間-DS1302

        ATMEGA16四線驅(qū)動(dòng)LCD顯示時(shí)間-DS1302

        作者: 時(shí)間:2016-11-23 來(lái)源:網(wǎng)絡(luò) 收藏
        #include

        #include

        本文引用地址:http://www.104case.com/article/201611/320229.htm

        #define uchar unsigned char
        #define uint unsigned int
        //定義LCD1602的端口應(yīng)用
        #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數(shù)據(jù)端口
        #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//秒數(shù)據(jù)地址
        #define ds1302_min_add0x82//分?jǐn)?shù)據(jù)地址
        #define ds1302_hr_add0x84//時(shí)數(shù)據(jù)地址
        #define ds1302_date_add0x86//日數(shù)據(jù)地址
        #define ds1302_month_add0x88//月數(shù)據(jù)地址
        #define ds1302_day_add0x8a//星期數(shù)據(jù)地址
        #define ds1302_year_add0x8c//年數(shù)據(jù)地址
        #define ds1302_control_add0x8e//控制數(shù)據(jù)地址
        #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; //啟動(dòng)DS1302,進(jìn)行寫操作
        IO_OUT; //定義數(shù)據(jù)口為輸出模式
        addr=addr&0xfe; //最低位為0表示寫入。為1時(shí)表示讀取
        for(i=0;i<8;i++)
        {
        if(addr&0x01) //DS1320發(fā)送數(shù)據(jù)是先低位后高位,當(dāng)傳送第一位時(shí)與0x01相與,
        { //如果相等,表示傳送的位為高電平,不等則為低電平,第一次送完第一次后ADDR左移一位準(zhǔn)備傳送第二位數(shù)據(jù)
        IO_SEI; //如果相等表示傳送的位為高電平,不等則為低電平,如此循環(huán)8次之后,要寫入的數(shù)據(jù)就寫完了
        }
        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++)//讀數(shù)據(jù)和寫數(shù)據(jù)正好相反,手法相同;先判斷讀取到的值是高位還是低位,在經(jīng)行保存
        {
        temp=temp>>1;//為下一次保存數(shù)據(jù)做準(zhǔn)備先讀低位后讀高位
        if(IO_R)//如果讀取到的數(shù)據(jù)為高,則置高
        {
        temp|=0x80;
        }
        else//如果讀取到的數(shù)據(jù)為低,則啦低
        {
        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);//當(dāng)寫保護(hù)寄存器的最高位為0 時(shí)允許數(shù)據(jù)寫入寄存器,
        //當(dāng)寫保護(hù)寄存器的最高位為1 時(shí)禁止數(shù)據(jù)寫入寄存器
        DS1302_WriteByte(ds1302_sec_add,0x80);//秒寄存器的第7 位時(shí)鐘停止位設(shè)置為0 時(shí)起動(dòng)時(shí)鐘開(kāi)始、設(shè)置為1時(shí)時(shí)鐘停止運(yùn)行

        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); //小時(shí)
        DS1302_WriteByte(ds1302_min_add,0x00); //分
        DS1302_WriteByte(ds1302_sec_add,0x00); //秒

        DS1302_WriteByte(ds1302_control_add,0x80);//當(dāng)寫保護(hù)寄存器的最高位為1 時(shí)禁止數(shù)據(jù)寫入寄存器
        }

        void DS1302_WriteTime1(void)
        {
        uchar i=0,addr=ds1302_year_add;
        DS1302_WriteByte(ds1302_control_add,0x00);//當(dāng)寫保護(hù)寄存器的最高位為0 時(shí)允許數(shù)據(jù)寫入寄存器,
        //當(dāng)寫保護(hù)寄存器的最高位為1 時(shí)禁止數(shù)據(jù)寫入寄存器
        DS1302_WriteByte(ds1302_sec_add,0x80);//秒寄存器的第7 位時(shí)鐘停止位設(shè)置為0 時(shí)起動(dòng)時(shí)鐘開(kāi)始、設(shè)置為1時(shí)時(shí)鐘停止運(yùn)行
        for(i=1;i<8;i++)
        {
        DS1302_WriteByte(addr,time_buf1[i]);
        addr-=2;
        }
        DS1302_WriteByte(ds1302_control_add,0x80);//當(dāng)寫保護(hù)寄存器的最高位為1 時(shí)禁止數(shù)據(jù)寫入寄存器
        }

        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 //寫數(shù)據(jù)
        RS_SEI;
        RW_CLI;
        PORTB&=0X0F; //先清除PORTB的高四位
        PORTB|=(data&0XF0); //將寫入的數(shù)據(jù)取出高四位先發(fā)送
        LCD_EN_Write(); //使能LCD
        delay_us(35); //延時(shí) 確保高四位的寫入正確
        data=data<<4; //屏蔽高四位
        PORTB&=0X0F; // 取出數(shù)據(jù)的低四位數(shù)據(jù)
        PORTB|=(data&0XF0); //發(fā)送低四位數(shù)據(jù)
        LCD_EN_Write(); //使能LCD
        }

        void LCD_Clear(void)
        {
        LCD_Write(0,0X01);
        delay(5);
        }

        void lcd_init(void)
        {
        delay(15);
        LCD_Write(0,0x28);//四線數(shù)據(jù)線、16X2顯示、5x7點(diǎn)陣
        LCD_EN_Write(); //這句很重要,切忌,丟失可能LCD就是一塊黑板,什么都沒(méi)有
        delay(5);
        LCD_Write(0,0x28);//四線數(shù)據(jù)線、16X2顯示、5x7點(diǎn)陣
        LCD_Write(0,0x08);//關(guān)閉顯示
        delay(5);
        LCD_Write(0,0x01);//清除屏幕顯示

        LCD_Write(0,0x06);//當(dāng)讀寫一字符后地址指針加一光標(biāo)加一,整屏不移動(dòng)
        delay(5);

        LCD_Write(0,0x0c);//開(kāi)顯示、顯示光標(biāo)、光標(biāo)閃爍
        delay(5);
        }

        void LCD_Write_Byte(uchar Line,uchar addr,uchar data)
        {
        if(1==Line)
        LCD_Write(0,0x80+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,0x80+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; //時(shí)顯示
        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; //時(shí)顯示
        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(); //注釋掉的三條語(yǔ)句也是OK的,調(diào)試一下
        DS1302_DispalyTime1();
        }
        }

        protues方針圖如下:


        評(píng)論


        技術(shù)專區(qū)

        關(guān)閉
        主站蜘蛛池模板: 启东市| 象山县| 台湾省| 寿阳县| 蛟河市| 定边县| 昌宁县| 抚远县| 贺州市| 措美县| 黄龙县| 台南市| 聂荣县| 奉节县| 临洮县| 娱乐| 本溪市| 黄冈市| 灵宝市| 太康县| 西平县| 张北县| 南岸区| 杨浦区| 延庆县| 太康县| 报价| 襄樊市| 滨州市| 墨竹工卡县| 晋江市| 榆中县| 漠河县| 开平市| 读书| 辽阳市| 正蓝旗| 昌邑市| 汉寿县| 镇平县| 沾化县|