PIC16F877与ds1302驱动程序????用12864显示,protues仿真

2019-03-25 19:28发布

#include<pic.h>
#define uchar unsigned char
#define uint unsigned int
#define nop() asm("nop")
#define ds1302_sec_add                        0x80                //秒数据地址
#define ds1302_min_add                        0x82                //分数据地址
#define ds1302_hr_add                        0x84                //时数据地址
#define ds1302_date_add                        0x86                //日数据地址
#define ds1302_month_add                0x88                //月数据地址
#define ds1302_day_add                        0x8a                //星期数据地址
#define ds1302_year_add                        0x8c                //年数据地址
#define ds1302_control_add                0x8e                //控制数据地址        写保护
#define ds1302_charger_add                0x90             //充电                                 
#define ds1302_clkburst_add                0xbe                //突发


#define cs1 RB7
#define cs2 RB6
#define rs RB5
#define rw RB4
#define e RB3
#define lcd RC
//sbit sck=P3^6;               
//sbit sda=P3^4;               
//sbit rest=P3^5;

#define rest RA4
#define sda RE0
#define sck RE1
//#define RST_DIR TRISE2
#define DATA_DIR TRISE0
//#define SCLK_DIR TRISE1

void busy_wait();
void setpos(uchar row , uchar col);
void write_com(uchar i);
void write_data(uchar i);
void disp1(uchar  *hz);
void disp2(uchar  *hz);
void init();
void delay(uchar i);

void select(uchar x);
void Display_font(uchar Choose,uchar Row,uchar Col,uchar *num);
void Display_num(uchar Choose,uchar Row,uchar Col,uchar *num);

void delay(uchar i)
{
        uchar x,y;
        for(x=i;x--;x>0)
                for(y=110;y--;y>0);
}
uchar t[]={11,3,3,18,51,55,2};
uchar a[8],b[7];
//显示字体
void Display_font(uchar Choose,uchar Row,uchar Col,uchar *num)
{       
select(Choose);
Col=Col*8;
setpos(Row,Col);
disp1(num);

setpos(Row+1,Col);    //下一页
disp2(num);
}
//显示数字或字母
void Display_num(uchar Choose,uchar Row,uchar Col,uchar *num)
{
        uchar i,j;
        select(Choose);
        Col=Col*8;
        setpos(Row,Col);
        for(i=0;i<8;i++)
        write_data(*(num+i));
        setpos(Row+1,Col);
        for(j=8;j<16;j++)
        write_data(*(num+j));
               
       
}

void ClearScreen(uchar Screen)
{
        uchar i,j;
       
        for(i=0;i<8;i++)
      {setpos(i,0);
      for(j=0;j<64;j++)
         write_data(0x00);
}
}


////////////////////////////////////////////////////////////
//按列取,且字符是倒着的,第二排是第一排的,显示汉字
// 0(0) 1(1) 2(2) 3(3) 4(4) 5(5) 6(6) 7(7) 8(8) 9(9)
uchar fenhao[16]={0x00,0x00,0x00,0xC0,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00};/*":",0*/

uchar num_0[16]={0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x0F,0x10,0x20,0x20,0x10,0x0F,0x00};/*"0",0*/

uchar num_1[16]={0x00,0x10,0x10,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00};/*"1",1*/

uchar num_2[16]={0x00,0x70,0x08,0x08,0x08,0x88,0x70,0x00,0x00,0x30,0x28,0x24,0x22,0x21,0x30,0x00};/*"2",2*/

uchar num_3[16]={0x00,0x30,0x08,0x88,0x88,0x48,0x30,0x00,0x00,0x18,0x20,0x20,0x20,0x11,0x0E,0x00};/*"3",3*/

uchar num_4[16]={0x00,0x00,0xC0,0x20,0x10,0xF8,0x00,0x00,0x00,0x07,0x04,0x24,0x24,0x3F,0x24,0x00};/*"4",4*/

uchar num_5[16]={0x00,0xF8,0x08,0x88,0x88,0x08,0x08,0x00,0x00,0x19,0x21,0x20,0x20,0x11,0x0E,0x00};/*"5",5*/

uchar num_6[16]={0x00,0xE0,0x10,0x88,0x88,0x18,0x00,0x00,0x00,0x0F,0x11,0x20,0x20,0x11,0x0E,0x00};/*"6",6*/

uchar num_7[16]={0x00,0x38,0x08,0x08,0xC8,0x38,0x08,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00};/*"7",7*/

uchar num_8[16]={0x00,0x70,0x88,0x08,0x08,0x88,0x70,0x00,0x00,0x1C,0x22,0x21,0x21,0x22,0x1C,0x00};/*"8",8*/

uchar num_9[16]={0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x00,0x31,0x22,0x22,0x11,0x0F,0x00};/*"9",9*/
uchar num_10[16]={0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
uchar *p[]={num_0,num_1,num_2,num_3,num_4,num_5,num_6,num_7,num_8,num_9,num_10};













//////////////////////////////////////////////////////////////
/*显示字符*/
//uchar  zifu[]="123";
void busy_wait()
{
e = 1;
rs = 0;
rw = 1;
PORTC = 0x00;
while(PORTC&0x80);

e=0;
}

void write_com(uchar i)   //输入控制字,
{
busy_wait();
//rw=1;
rs=0;
//PORTC=0x00;

e=1;
//do{ACC=lcd;   //是否忙
//  e=0; }
//while(busy);
//delay(5);
e=0;
rw=0;
PORTC=i;
//delay(1);
//busy_wait();

e=1;
//delay(5);
e=0;
}

void write_data(uchar i)   //输入数据,
{           
busy_wait();
//rw=1;
//rs=0;
//PORTC=0;
e=1;
//do{ACC=lcd;
//  e=0;}
//while(busy);
//delay(5);
e=0;
   rw=0;
rs=1;
PORTC=i;
//delay(1);
//busy_wait();

e=1;
//delay(5);
e=0;
}

void setpos(uchar row , uchar col)  //选择行(8行),列(左右各64列),
{   
    write_com(0xb8+row);
    write_com(0x40+col);   
}

void lcd_init(void)    //初始化
{
write_com(0xc0);
write_com(0x3f);
}

void disp1(uchar  *hz)    //显示汉字上半区,
{
uchar i;
for(i=0;i<16;i++)
write_data(*(hz+i));
}

void disp2(uchar  *hz)   //显示汉字下半区 ,
{
uchar i;
for(i=16;i<32;i++)
   write_data(*(hz+i));
}

void select(uchar x)
{ switch(x)
  {
    case 0: cs1=0;cs2=0;break;   //全屏
    case 1: cs1=0;cs2=1;break;   //左屏,
    case 2: cs1=1;cs2=0;break;   //右屏,
    //default:cs2=0;cs2=0;
  }
}

//////////////////////////

uchar readbyte()
{  
        uchar i,num;
DATA_DIR=1;

        for(i=0;i<8;i++)
        {       
               
                num >>=0x01;
                if(sda)num|=0x80;
       
                sck=1;
nop();nop();nop();
                sck=0;       
nop();nop();nop();

        }

        return num;
}

void writebyte(uchar addr)
{  
        uchar i;
DATA_DIR=0;

        for(i=0;i<8;i++)
        {       
                if(addr & 0x01)sda=1;
                else sda=0;
               

                sck=1;;
nop();nop();nop();
                sck=0;
nop();nop();nop();

addr >>=0x01;
        }

}

uchar read(uchar addr)
{
        uchar num;
        rest=1;


       
        writebyte(addr);
       
        num=readbyte();

nop();nop();nop();nop();nop();nop();

        rest=0;
nop();nop();nop();
        return num;
}

void write(uchar addr,uchar num)
{
        rest=1;


        writebyte(addr);

        writebyte(num);
nop();nop();nop();nop();nop();nop();

        rest=0;
nop();nop();nop();
}

void init()
{

        TRISB=0x00;
        TRISA=0x00;
        TRISC=0x00;
    TRISE1=0;
        TRISE2=0;
        TRISE0=0;

        PORTA=0x0f;
        TRISD=0x0f;
        sck=0;
        rest=0;
        sda=0;

}

void readtime()
{
        uchar i,temp;
        t[3]=read(ds1302_hr_add+1);//hour
        t[4]=read(ds1302_min_add+1);//min
        t[5]=read(ds1302_sec_add+1);//sec
        for(i=3;i<6;i++)
        {
                temp=t/16;
                t=temp*10+t%16;
        }
}

void writetime()
{
        uchar i,temp;
        for(i=0;i<7;i++)        //十进制转BCD码
        {
                temp=t/10;
                b=temp*16+t%10;
        }

        write(ds1302_control_add,0x00);        //关写保护
        write(ds1302_sec_add,0x80);                //暂停
//        write(ds1302_charger_add,0xa9);        //充电
        write(ds1302_year_add,b[0]);        //年
        write(ds1302_month_add,b[1]);        //月
        write(ds1302_day_add,b[2]);                //日
        write(ds1302_hr_add,b[3]);                //时
        write(ds1302_min_add,b[4]);                //分
        write(ds1302_sec_add,b[5]);                //秒
        write(ds1302_date_add,b[6]);         //周
        write(ds1302_control_add,0x80);        //开写保护
}
void delayus(uint i)
{
        while(i--);
}
void display_ds1302()
{
               
      
       

       //第二行
                Display_num(1,2,5,p[a[0]]);
                
               
                Display_num(1,2,6,p[a[1]]);
       
                Display_num(1,2,7,fenhao);

                Display_num(2,2,0,p[a[2]]);
       
                Display_num(2,2,1,p[a[3]]);

                Display_num(2,2,2,fenhao);
       
                Display_num(2,2,3,p[a[4]]);

                Display_num(2,2,4,p[a[5]]);
       
                delay(5);
}


void main()
{
        init();
lcd_init();
        writetime();
        while(1)
        {
                         readtime();
                        delay(50);
                        a[0]=t[3]/10;
                        a[1]=t[3]%10;
               
                        a[2]=t[4]/10;
                        a[3]=t[4]%10;
               
                        a[4]=t[5]/10;
                        a[5]=t[5]%10;
                        display_ds1302();
                        delay(1000);
        }
}


12864显示没问题,我显示过
pic单片机我选用的是4M晶振
调试了好几天,ds1302都没驱动,我的qq873283984 此帖出自小平头技术问答
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
5条回答
liujun00
2019-03-26 06:17
#include<pic.h>
#define uchar unsigned char
#define uint unsigned int
#define nop() asm("nop")
#define ds1302_sec_add                        0x80                //秒数据地址
#define ds1302_min_add                        0x82                //分数据地址
#define ds1302_hr_add                        0x84                //时数据地址
#define ds1302_date_add                        0x86                //日数据地址
#define ds1302_month_add                0x88                //月数据地址
#define ds1302_day_add                        0x8a                //星期数据地址
#define ds1302_year_add                        0x8c                //年数据地址
#define ds1302_control_add                0x8e                //控制数据地址        写保护
#define ds1302_charger_add                0x90             //充电                                 
#define ds1302_clkburst_add                0xbe                //突发


#define cs1 RB7
#define cs2 RB6
#define rs RB5
#define rw RB4
#define e RB3
#define lcd RC
//sbit sck=P3^6;               
//sbit sda=P3^4;               
//sbit rest=P3^5;

#define rest RB2
#define sda RB0
#define sck RB1
//#define RST_DIR TRISE2
#define DATA_DIR TRISB0
//#define SCLK_DIR TRISE1

void busy_wait();
void setpos(uchar row , uchar col);
void write_com(uchar i);
void write_data(uchar i);
void disp1(uchar  *hz);
void disp2(uchar  *hz);
void init();
void delay(uchar i);

void select(uchar x);
void Display_font(uchar Choose,uchar Row,uchar Col,uchar *num);
void Display_num(uchar Choose,uchar Row,uchar Col,uchar *num);

void delay(uchar i)
{
        uchar x,y;
        for(x=i;x--;x>0)
                for(y=110;y--;y>0);
}
uchar t[]={0,0,0,0,0,0,1,1};
uchar a[8],b[7];
//显示字体
void Display_font(uchar Choose,uchar Row,uchar Col,uchar *num)
{       
select(Choose);
Col=Col*8;
setpos(Row,Col);
disp1(num);

setpos(Row+1,Col);    //下一页
disp2(num);
}
//显示数字或字母
void Display_num(uchar Choose,uchar Row,uchar Col,uchar *num)
{
        uchar i,j;
        select(Choose);
        Col=Col*8;
        setpos(Row,Col);
        for(i=0;i<8;i++)
        write_data(*(num+i));
        setpos(Row+1,Col);
        for(j=8;j<16;j++)
        write_data(*(num+j));
               
       
}

void ClearScreen(uchar Screen)
{
        uchar i,j;
       
        for(i=0;i<8;i++)
      {setpos(i,0);
      for(j=0;j<64;j++)
         write_data(0x00);
}
}


////////////////////////////////////////////////////////////
//按列取,且字符是倒着的,第二排是第一排的,显示汉字
// 0(0) 1(1) 2(2) 3(3) 4(4) 5(5) 6(6) 7(7) 8(8) 9(9)
uchar fenhao[16]={0x00,0x00,0x00,0xC0,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00};/*":",0*/

uchar num_0[16]={0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x0F,0x10,0x20,0x20,0x10,0x0F,0x00};/*"0",0*/

uchar num_1[16]={0x00,0x10,0x10,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00};/*"1",1*/

uchar num_2[16]={0x00,0x70,0x08,0x08,0x08,0x88,0x70,0x00,0x00,0x30,0x28,0x24,0x22,0x21,0x30,0x00};/*"2",2*/

uchar num_3[16]={0x00,0x30,0x08,0x88,0x88,0x48,0x30,0x00,0x00,0x18,0x20,0x20,0x20,0x11,0x0E,0x00};/*"3",3*/

uchar num_4[16]={0x00,0x00,0xC0,0x20,0x10,0xF8,0x00,0x00,0x00,0x07,0x04,0x24,0x24,0x3F,0x24,0x00};/*"4",4*/

uchar num_5[16]={0x00,0xF8,0x08,0x88,0x88,0x08,0x08,0x00,0x00,0x19,0x21,0x20,0x20,0x11,0x0E,0x00};/*"5",5*/

uchar num_6[16]={0x00,0xE0,0x10,0x88,0x88,0x18,0x00,0x00,0x00,0x0F,0x11,0x20,0x20,0x11,0x0E,0x00};/*"6",6*/

uchar num_7[16]={0x00,0x38,0x08,0x08,0xC8,0x38,0x08,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00};/*"7",7*/

uchar num_8[16]={0x00,0x70,0x88,0x08,0x08,0x88,0x70,0x00,0x00,0x1C,0x22,0x21,0x21,0x22,0x1C,0x00};/*"8",8*/

uchar num_9[16]={0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x00,0x31,0x22,0x22,0x11,0x0F,0x00};/*"9",9*/
uchar num_10[16]={0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
uchar *p[]={num_0,num_1,num_2,num_3,num_4,num_5,num_6,num_7,num_8,num_9,num_10};













//////////////////////////////////////////////////////////////
/*显示字符*/
//uchar  zifu[]="123";
void busy_wait()
{
e = 1;
rs = 0;
rw = 1;
PORTC = 0x00;
while(PORTC&0x80);

e=0;
}

void write_com(uchar i)   //输入控制字,
{
busy_wait();
//rw=1;
rs=0;
//PORTC=0x00;

e=1;
//do{ACC=lcd;   //是否忙
//  e=0; }
//while(busy);
//delay(5);
e=0;
rw=0;
PORTC=i;
//delay(1);
//busy_wait();

e=1;
//delay(5);
e=0;
}

void write_data(uchar i)   //输入数据,
{           
busy_wait();
//rw=1;
//rs=0;
//PORTC=0;
e=1;
//do{ACC=lcd;
//  e=0;}
//while(busy);
//delay(5);
e=0;
   rw=0;
rs=1;
PORTC=i;
//delay(1);
//busy_wait();

e=1;
//delay(5);
e=0;
}

void setpos(uchar row , uchar col)  //选择行(8行),列(左右各64列),
{   
    write_com(0xb8+row);
    write_com(0x40+col);   
}

void lcd_init(void)    //初始化
{
write_com(0xc0);
write_com(0x3f);
}

void disp1(uchar  *hz)    //显示汉字上半区,
{
uchar i;
for(i=0;i<16;i++)
write_data(*(hz+i));
}

void disp2(uchar  *hz)   //显示汉字下半区 ,
{
uchar i;
for(i=16;i<32;i++)
   write_data(*(hz+i));
}

void select(uchar x)
{ switch(x)
  {
    case 0: cs1=0;cs2=0;break;   //全屏
    case 1: cs1=0;cs2=1;break;   //左屏,
    case 2: cs1=1;cs2=0;break;   //右屏,
    //default:cs2=0;cs2=0;
  }
}

//////////////////////////

uchar readbyte()
{  
        uchar i,num;
DATA_DIR=1;

        for(i=0;i<8;i++)
        {       
               
                num >>=0x01;
                if(sda)num|=0x80;
       
                sck=1;
nop();nop();nop();
                sck=0;       
nop();nop();nop();

        }

        return num;
}

void writebyte(uchar addr)
{  
        uchar i;
DATA_DIR=0;

        for(i=0;i<8;i++)
        {       
                if(addr & 0x01)sda=1;
                else sda=0;
               

                sck=1;;
nop();nop();nop();
                sck=0;
nop();nop();nop();

addr >>=0x01;
        }

}

uchar read(uchar addr)
{
        uchar num;
        rest=1;


       
        writebyte(addr);
       
        num=readbyte();

nop();nop();nop();nop();nop();nop();

        rest=0;
nop();nop();nop();
        return num;
}

void write(uchar addr,uchar num)
{
        rest=1;


        writebyte(addr);

        writebyte(num);
nop();nop();nop();nop();nop();nop();

        rest=0;
nop();nop();nop();
}

void init()
{

        TRISB=0x00;
        TRISA=0x00;
        TRISC=0x00;
    TRISE1=0;
        TRISE2=0;
        TRISE0=0;

        PORTA=0x0f;
        TRISD=0x0f;
        sck=0;
        rest=0;
        sda=0;

}

void readtime()
{
        uchar i,temp;
        t[3]=read(ds1302_hr_add+1);//hour
        t[4]=read(ds1302_min_add+1);//min
        t[5]=read(ds1302_sec_add+1);//sec
        for(i=3;i<6;i++)
        {
                temp=t/16;
                t=temp*10+t%16;
        }
}

void writetime()
{
        uchar i,temp;
        for(i=0;i<7;i++)        //十进制转BCD码
        {
                temp=t/10;
                b=temp*16+t%10;
        }

        write(ds1302_control_add,0x00);        //关写保护
nop();nop();nop();
//        write(ds1302_sec_add,0x80);                //暂停
//        write(ds1302_charger_add,0xa9);        //充电
        write(ds1302_year_add,b[0]);        //年
nop();nop();nop();
        write(ds1302_month_add,b[1]);        //月
nop();nop();nop();
        write(ds1302_day_add,b[2]);                //日
nop();nop();nop();
        write(ds1302_hr_add,b[3]);                //时
nop();nop();nop();
        write(ds1302_min_add,b[4]);                //分
nop();nop();nop();
        write(ds1302_sec_add,0x50);                //秒
nop();nop();nop();
        write(ds1302_date_add,b[6]);         //周
nop();nop();nop();
        write(ds1302_control_add,0x80);        //开写保护
//        delay(20);

}
void delayus(uint i)
{
        while(i--);
}
void display_ds1302()
{
               
      
                        a[0]=5;
                        a[1]=t[3]%10;
               
                        a[2]=t[4]/10;
                        a[3]=t[4]%10;
               
                        a[4]=t[5]/10;
                        a[5]=t[5]%10;

       //第二行
                Display_num(1,2,5,p[a[0]]);
                
               
                Display_num(1,2,6,p[a[1]]);
       
                Display_num(1,2,7,fenhao);

                Display_num(2,2,0,p[a[2]]);
       
                Display_num(2,2,1,p[a[3]]);

                Display_num(2,2,2,fenhao);
       
                Display_num(2,2,3,p[a[4]]);

                Display_num(2,2,4,p[a[5]]);
       
                delay(5);
}


void main()
{
        init();
lcd_init();
        writetime();
        while(1)
        {
                         readtime();
                //        delay(50);
               
                        display_ds1302();
                        delay(1000);
        }
}

一周热门 更多>