这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 论坛服务 » 论坛公告 » CVAVR 编写的ds130212864液晶调试问题

共2条 1/1 1 跳转至

CVAVR 编写的ds130212864液晶调试问题

菜鸟
2009-11-13 19:31:14     打赏
LCD12864串行传输数据,现在走时有问题,走时1,2秒,停上7秒钟,又走两秒在显示3,4,往后也是这样,大家看看是发送数据的问题还是DS1302的问题
#include <mega16.h>
#include <delay.h>  #define uchar unsigned char
#define uint unsigned int
 uchar line1[11]={' ',' ','-',' ',' ','-',' ',' ',' ',' ','\0'};//显示第1行的字符数组
 uchar line2[9]={' ',' ',':',' ',' ',':',' ',' ','\0'}; //显示第2行的字符数组
 uchar settime[7]={49,58,14,10,11,07,07}; //设置的秒,分,时,日,月,星期,年
 uchar asc[2]={0,0};                                 
  uchar time[9]={0,0}; uchar ptTimeD[];
#define SCLK   PORTA.6 并行使能端, H有效, L无效
#define SID PORTA.5   //并行读写选择信号, H读, L写
#define CS PORTA.4   //并行的指令/数据选择信号, H数据, L命令  
#define SCLK_DIR   DDRA.6    //并行使能端, H有效, L无效
#define SID_DIR  DDRA.5   //并行读写选择信号, H读, L写
#define CS_DIR   DDRA.4   //并行的指令/数据选择信号, H数据, L命令  

/******************RTC常量******************/
#define RTC_CLK       4
#define RTC_DATA      3
#define RTC_CS        2
#define DDC4          4
#define DDC3          3
#define DDC2          2
    //命令
#define RD          0x01
#define WR          0x00
#define C_SEC        0x80    
#define C_MIN        0x82    
#define C_HR        0x84    
#define C_DAY        0x86    
#define C_MTH        0x88    
#define C_WK        0x8A    
#define C_YR        0x8C    
#define C_WP        0x8E    
#define C_CHARGE    0x90    
#define C_BURST        0xBE    
    //配置
#define CLK_HALT        0x80    
#define CLK_START        0x00    
#define M12_24            0x80    
#define PROTECT            0x80    
#define UPROTECT        0x00   
    //涓流充电控制常量
#define TC_D1R2            0xA5    
#define TC_D2R8            0xAB    
#define TC_DISABLED        0x00    
    //RAM 命令
#define C_RAMBASE        0xC2    
void Delayus(uint US)          
{
 uint i;
 US=US*5/4;              
 for( i=0;i<US;i++); 
}
void Delayms(uint MS)          
{
 uint i,j;
 for( i=0;i<MS;i++)
 for(j=0;j<1141;j++);    
}
void  swrite(unsigned char dc,unsigned char da)   
{
             uchar i,j;
              CS=1;
             SCLK=0;
             SID=1;
             for( i=5;i>0;--i)
              {
             SCLK = 1;
             #asm("nop");
             #asm("nop");
             #asm("nop");
             #asm("nop");
             #asm("nop");
             #asm("nop");                                                                                             
             SCLK = 0;
             #asm("nop");
             #asm("nop");
             #asm("nop");                                                                                                          
              }
             SID  = 0;//数据从MCU到LCD                                                                 //RW = 0;
             SCLK = 1;
             #asm("nop");
             #asm("nop");
             #asm("nop");
             #asm("nop");
             #asm("nop");
             #asm("nop");  
             SCLK = 0;
             if(dc) //是1的话表示传输数据             
             SID = 1;             //RS = 1,写数据                                                                                                                      
             else
             SID = 0;  //是0是传输指令             
                                                                                                                                                                                      
             SCLK = 1; 
             #asm("nop");
             #asm("nop");
             #asm("nop");
             #asm("nop");  
             SCLK = 0;
             SID  = 0;
             
             SCLK = 1;
             #asm("nop");
             #asm("nop");
             #asm("nop");
             #asm("nop");  
             SCLK    = 0;                                                                                                                                                                                                   
          for(i=0;i<2;i++)  //数据先高后低,4位地传输
          {
             for(j=0;j<4;j++)  //高4位数据
             {
             da<<=1;
             SID=SREG.0;             //将移出的数据送出测试                          
             SCLK= 1;
             #asm("nop");
             #asm("nop");
             #asm("nop");
             #asm("nop");
             #asm("nop");  
             SCLK= 0;
             #asm("nop");
             #asm("nop");
             #asm("nop");  
             }             
             SID = 0;
             for(j=0;j<4;j++ )
             {                          
             SCLK= 1;
             #asm("nop");
             #asm("nop");
             #asm("nop");
             #asm("nop");  
             SCLK= 0;
             #asm("nop");
             #asm("nop");
             #asm("nop");  
             }                          
           }
}
 void writeString(flash uchar *aa)
{
    uchar i = 0;
    while(aa[i]!='\0')
    {
        swrite(1,aa[i++]);//数据指令 
    }
}
 
void writeString1(uchar *a)
{
    uchar i = 0;
    while(a[i]!='\0')
    {
        swrite(1,a[i++]);//数据指令 
    }


 void setPosition(uchar x, uchar y)
{
    uchar p;
    switch(x%4)
    {
        case 0: p = 0x80; break; //第一行开始地址
        case 1: p = 0x90; break; //第二行
        case 2: p = 0x88; break; //第三行
        case 3: p = 0x98; break; //第四行
    }
    p += y;
    swrite(0,p);      //位置信息指令  
}    

//初始化LCD
void init(void)
{
    delay_ms(20);
    swrite(0,0x30); //基本指令, 扩充指令为34H
    delay_ms(1);
    swrite(0,0x0c); //显示开, 关光标 0c  ,,0d允许反白
    delay_ms(1);
    swrite(0,0x01); //清屏
    delay_ms(10);

}

/*******************************************
函数名称: DS1302_init
功    能: 初始化DS1302的数据接口
参    数: 无
返回值  : 无
********************************************/
void DS1302_portinit(void)          
{
 DDRC|=(1<<DDC4)|(1<<DDC3)|(1<<DDC2);//将时钟端(RTC_CLK)数据端(RTC_DATA)片选端(RTC_CS)设置为输出
}
/*******************************************
函数名称: DS1302_writeB
功    能: 向DS1302写入一个字节数据
参    数: byte--要写入的数据
返回值  : 无
********************************************/
void DS1302_writeB(uchar byte)
{
 uchar i;
 for(i=0;i<8;i++)               
 {
  PORTC&=~(1<<RTC_CLK);          
  if(byte&0x01)                  
  {
   PORTC|=(1<<RTC_DATA);      
  }
  else                          
  {
   PORTC&=~(1<<RTC_DATA);      
  }  
  Delayus(20);                 
  PORTC|=(1<<RTC_CLK);          
  byte>>=1;                      
 }
}
/*******************************************
函数名称: DS1302_readB
功    能: 从DS1302读出一个字节数据(没有RST操作)
参    数: 无
返回值  : byte--读出的数据
********************************************/
uchar DS1302_readB(void)
{
 uchar i,byte=0;
 DDRC&=~(1<<DDC3);         //将数据端口设置为输入          
 PORTC&=~(1<<RTC_DATA);         //无上拉电阻
 for(i=0;i<8;i++)             //8位数据计数
 {
  byte>>=1;                   //保存读入的数据位
  PORTC|=(1<<RTC_CLK);         //时钟上升沿
  Delayus(20);                 //延时,调整时钟脉冲宽度
  PORTC&=~(1<<RTC_CLK);         //时钟下降沿,DS1302输出数据位
  Delayus(20);                 //等待数据变化(MEGA16太快,必须等待DS1302的数据位输出,否则不能正确读出)
  if(PINC&(1<<RTC_DATA))     //当前位是否是高电平
  {
   byte|=(1<<RTC_CLK);             //是高电平就将返回数据的当前位置1
  }
  else
  {
   byte&=~(1<<RTC_CLK);             //是低电平就将返回数据的当前位置0
  }
 }
 DDRC|=(1<<RTC_DATA);         //最后将数据端口设置为输出
 return byte;                 //返回读出的数据
}
/*******************************************
函数名称: DS1302_writeD
功    能: 向DS1302的某个地址写入一个字节数据
参    数: addr--地址值(寄存器或RAM)
            data--要写入的地址
返回值  : 无
********************************************/
void DS1302_writeD(uchar addr,uchar data)
{
 PORTC&=~(1<<RTC_CS);     //拉低片选端
 PORTC&=~(1<<RTC_CLK);     //拉低时钟端
 Delayus(5);
 PORTC|=(1<<RTC_CS);     //拉高片选端
 Delayus(20);              //调整片选脉冲
 DS1302_writeB(addr);     //写入操作命令(地址)
 Delayus(20);
 PORTC&=~(1<<RTC_CLK);     //拉低时钟端
 Delayus(20);
 DS1302_writeB(data);     //写入数据
 PORTC&=~(1<<RTC_CLK);     //拉低时钟端
 Delayus(20);             //调整片选脉冲
 PORTC&=~(1<<RTC_CS);     //拉低片选端
}
/*******************************************
函数名称: DS1302_readD
功    能: 从DS1302的某个地址读出一个字节数据
参    数: addr--地址值(寄存器或RAM)
返回值  : data--读出的数据
********************************************/
uchar DS1302_readD(uchar addr)
{
 uchar data;
 PORTC&=~(1<<RTC_CS);     //拉低片选端
 PORTC&=~(1<<RTC_CLK);     //拉低时钟端
 Delayus(10);
 PORTC|=(1<<RTC_CS);     //拉高片选端
 Delayus(10);              //调整片选脉冲
 DS1302_writeB(addr);     //写入操作命令(地址)
 Delayus(10);
 data=DS1302_readB();     //读出数据
 Delayus(10);
 PORTC&=~(1<<RTC_CLK);     //拉低时钟端
 PORTC&=~(1<<RTC_CS);      //拉低片选端
 return data;             //返回读出的数据
}
/*******************************************
函数名称: DS1302_setT
功    能: 设置DS1302的时间
参    数: ptTimeD--设置时间数组指针
返回值  : 无
********************************************/
void DS1302_setT(void)
{
    uchar i;
    uchar addr = 0x80;                    //写入地址从秒寄存器开始
    DS1302_writeD(C_WP|WR,UPROTECT); //控制命令,WP位为0,允许写操作
    Delayms(10);
    for(i=0;i<7;i++)
    {
        DS1302_writeD(addr|WR,ptTimeD[i]);   // 秒 分 时 日 月 星期 年         
        addr+=2;
        Delayms(20);
    }
    DS1302_writeD(C_WP|WR,PROTECT);         //控制命令,WP位为1,不允许写操作
}
/*******************************************
函数名称: DS1302_getT
功    能: 读取DS1302的当前时间
参    数: time[]--读取的时间数组
返回值  : 无
********************************************/
void DS1302_getT(uchar time[])
{
    uchar i;
////////下面的是单次读写//////////////////////////    
    uchar addr = 0x80;                              //读取地址从秒寄存器开始 
    for(i=0;i<7;i++)
    {
        time[i]=DS1302_readD(addr|RD);    // 秒 分 时 日 月 星期 年        
        addr+=2;
    }
////////////////////////////////////////////////////    
    /*///////下面是多字节读取/////////////// 
     PORTC&=~(1<<RTC_CS);     //拉低片选端
     Delayus(10);
     PORTC|=(1<<RTC_CS);     //拉高片选端
     Delayus(10);              //调整片选脉冲
     DS1302_writeB(0xbf);       // 0xbf:时钟多字节读取命令 
     for (i=0;i<8;i++)       //时间数据的存放格式是:
       {                        //秒,分,时,日,月,星期,年,控制
         time[i]=DS1302_readB(); //【7个数据(BCD格式)+1个控制】
         Delayus(10); 
       }
                
     PORTC&=~(1<<RTC_CS);      //拉低片选端
 /////////////////////////////////////////////
 */
     PORTC&=~(1<<RTC_CLK);                       //拉低时钟端(时钟端在不操作时为低)
}
/*******************************************
函数名称: DS1302_init
功    能: 初始化DS1302
参    数: 无
返回值  : 无
********************************************/
void DS1302_init(void)
{
 DS1302_writeD(C_WP|WR,UPROTECT);          //写入写允许命令
 DS1302_writeD(C_SEC|WR,CLK_START);        //启动振荡器,DS1302开始工作
 DS1302_writeD(C_WP|WR,PROTECT);         //控制命令,WP位为1,不允许写操作      
}
/*******************************************
函数名称: BCD_ASCII
功    能: 将压缩BCD码转换成ascii码
参    数: BCD--将要转换的压缩BCD码
            ptasc--转换后的ASCII码数组指针
返回值  : 无
********************************************/
void BCD_ASCII(uchar BCD,uchar ptasc[])
{   
    ptasc[0]=(BCD/16)+48;    //0X58    35  38 //转换十位
    ptasc[1]=(BCD&0x0F)+48;  //转换个位
}


/*******************************************
函数名称: main
功    能: 1. 在1602液晶上显示当前时间 2.可以设置时间(M1-M9为数字0-9,M13为设置模式和显示模式选择,M14为当前设置位选择)
参    数: 无
返回值  : 无
********************************************/
void main(void)
{
 uchar i,j;
 PORTA=0x00;
 DDRA=0xFF;
  PORTC=0x00;   
  DDRC=0xFF;  
 init();  
 DS1302_portinit();  //初始化DS1302的三根数据线
 DS1302_init();  
 DS1302_setT(); //设置初始时间
 DS1302_writeD(C_SEC,0x00);//启动振荡器,DS1302开始工作        
 while(1)                    //以下程序完成显示和设置时间
 {  
  
    uchar addr = 0x80;    
    for(j=0;j<7;j++)
    {
        time[j]=DS1302_readD(addr|RD);    // 秒 分 时 日 月 星期 年        
        addr+=2;
    }
     for(i=0;i<3;i++)       为第2行的字符数组赋值
    {
      BCD_ASCII(time[2-i],asc);
      line2[i*3]=asc[0];
      line2[i*3+1]=asc[1];
    } 
   BCD_ASCII(time[6],asc);                             //为第1行的年赋值
   line1[0]=asc[0];
   line1[1]=asc[1];
   BCD_ASCII(time[4],asc);                          //为第1行的月赋值
   line1[3]=asc[0];
   line1[4]=asc[1];
   BCD_ASCII(time[3],asc);                          //为第1行的日赋值
   line1[6]=asc[0];
   line1[7]=asc[1];
   BCD_ASCII(time[5],asc);                          //为第1行的星期赋值
    line1[9]=asc[1];
    
    setPosition(0, 0);
    writeString1(line1);

    setPosition(2, 0);
    writeString1(line2);
    
    
 }
}



关键词: CVAVR     写的     ds130212864     液晶         

院士
2009-11-24 11:27:28     打赏
2楼

怎么发到这里来了~~~~~


共2条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]