导航: 老古网老古论坛XMOS公共讨论区XMOS开源项目区单片机程序设计嵌入式系统广告区域
→请教![苹果啃牙]

 *第13159篇: 请教!

  
楼 主:苹果啃牙 2003年6月6日19:26
 请教!
不知道我这个程序出错出在哪里,请各位大侠帮帮小妹我!
谢谢··!!

#include   <reg52.h>  
#include   <intrins.h>  
//#define uint unsigned int

//下面是引脚连接关系

sbit scl_ds1302 =p3^2;
sbit io_ds1302  =p3^3;
sbit rst_ds1302 =p3^4;
sbit wr = p3^6;
sbit b0=p1^0;
sbit button1=p1^4;
sbit button2=p1^5;
sbit button3=p1^6;
sbit button4=p1^7;


unsigned int data display_buffer1[8],display_buffer2[8];
unsigned char bdata data_ds1302;
sbit bit_data0=data_ds1302^0;
sbit bit_data7=data_ds1302^7;
unsigned char bdata x;
sbit x0   =x^0;
sbit x7   =x^7;

void open_write_bit();
void initial_ds1302();
unsigned char read_ds1302(char command);
void open_write_bit();
void close_write_bit();
void read_time();
void set_time();
unsigned int zhuanhuan( unsigned int b);
void display1();
void display2();
void button();
 
void main( void)

 initial_ds1302();  //上电启用,否则不走时
 read_time();   //读取当前的年月日时分秒在数组
 b0=0;
 display_buffer2[5]=0x00;
 display_buffer2[4]=0x03;
 display_buffer2[3]=0x00;
 display_buffer2[2]=0x06;
 display_buffer2[1]=0x01;
 display_buffer2[0]=0x04;
 display_buffer1[5]=0x00;
 display_buffer1[4]=0x08;
 display_buffer1[3]=0x01;
 display_buffer1[2]=0x00;
 display_buffer1[1]=0x05;
 display_buffer1[0]=0x08; //将03年6月14日08时10分58秒设置为当前时间
 set_time();    //将数组中的时间置入ds1302
 while(1)
 {
  button();
     read_time();
 }
}

void display1()
{
   unsigned int *p;
 unsigned int i, j, k; 
 p = display_buffer1;
 j = 0xa0;
 for(i=0;i  <8;i++)
 {
 k = *p;
 k = zhuanhuan( k);
 p2 = j;
 wr = 0;
//  while(1);
 _nop_( ); _nop_( ); _nop_( ); _nop_( );
 p0 = k;
 _nop_( ); _nop_( );
 wr = 1;
 p = p + 1;
 j = j + 4;
 }
}

void display2()
{
   unsigned int *p;
 unsigned int i, j, k; 
 p = display_buffer2;
 j = 0xa0;
 for(i=0;i  <8;i++)
 {
 k = *p;
 k = zhuanhuan( k);
 p2 = j;
 wr = 0;
//  while(1);
 _nop_( ); _nop_( ); _nop_( ); _nop_( );
 p0 = k;
 _nop_( ); _nop_( );
 wr = 1;
 p = p + 1;
 j = j + 4;
 }
}

unsigned int zhuanhuan( unsigned int b)
{
 switch( b)
 {
 case 0: b = 0xc0; break;
 case 1: b = 0xf9; break;
 case 2: b = 0xa4; break;
 case 3: b = 0xb0; break;
 case 4: b = 0x99; break;
 case 5: b = 0x92; break;
 case 6: b = 0x82; break;
 case 7: b = 0xf8; break;
 case 8: b = 0x80; break;
 case 9: b = 0x98; break;
 default: break;
 }
 return b;
}

void close_write_bit()
{
 char i;
 scl_ds1302=0;
 _nop_();
 rst_ds1302=1;
 _nop_();_nop_();
 data_ds1302=0x8e;   //write control redister
 for (i=1;i  <=8;i++) {
       scl_ds1302=0;io_ds1302=bit_data0;
       _nop_();scl_ds1302=1;
       data_ds1302=data_ds1302>  >  1; 
      }
 data_ds1302=0x80;   //close write protect bit
 io_ds1302=0;
 for (i=1;i  <=8;i++) {
       scl_ds1302=0;io_ds1302=bit_data0;
       _nop_();scl_ds1302=1;
       data_ds1302=data_ds1302>  >  1; 
         }
}


void open_write_bit()
{
 char i;
 scl_ds1302=0;
 _nop_();
 rst_ds1302=1;
 _nop_();_nop_();
 data_ds1302=0x8e;   //write control redister
 for (i=1;i  <=8;i++) {
       scl_ds1302=0;io_ds1302=bit_data0;
       _nop_();scl_ds1302=1;
       data_ds1302=data_ds1302>  >  1; 
         }
 data_ds1302=0x00;   //open write protect bit
 io_ds1302=0;
 for (i=1;i  <=8;i++) {
       scl_ds1302=0;io_ds1302=bit_data0;
       _nop_();scl_ds1302=1;
       data_ds1302=data_ds1302>  >  1; 
         }
}

void initial_ds1302()
{
unsigned char i;
 scl_ds1302=0;
 _nop_();
 rst_ds1302=1;
 _nop_();_nop_();
 data_ds1302=0x8e;   //write control redister
 for (i=1;i  <=8;i++) {
       scl_ds1302=0;io_ds1302=bit_data0;
       _nop_();scl_ds1302=1;
       data_ds1302=data_ds1302>  >  1; 
      }
 data_ds1302=0x80;   //close write protect bit
 io_ds1302=0;
 for (i=1;i  <=8;i++) {
       scl_ds1302=0;io_ds1302=bit_data0;_nop_();
       scl_ds1302=1;data_ds1302=data_ds1302>  >  1; 
      }
 rst_ds1302=0;
 _nop_();
 scl_ds1302=0;
 scl_ds1302=0;
 _nop_();
 rst_ds1302=1;
 _nop_();_nop_();
 data_ds1302=0x90;   //recharge register 
 for (i=1;i  <=8;i++) {
       scl_ds1302=0;io_ds1302=bit_data0;_nop_();
       scl_ds1302=1;data_ds1302=data_ds1302>  >  1; 
      }
 data_ds1302=0xa4;   //no rechaarge for battery
 for (i=1;i  <=8;i++) {
       scl_ds1302=0;io_ds1302=bit_data0;
       _nop_();scl_ds1302=1;
       data_ds1302=data_ds1302>  >  1; 
      }
 rst_ds1302=0;
 _nop_();
 scl_ds1302=0;
 scl_ds1302=0;
 _nop_();
 rst_ds1302=1;
 _nop_();_nop_();
 data_ds1302=0x80;
 for (i=1;i  <=8;i++) {
       scl_ds1302=0;io_ds1302=bit_data0;
       _nop_();scl_ds1302=1;
       data_ds1302=data_ds1302>  >  1; 
     }
 data_ds1302=0x80;
 for (i=1;i  <=8;i++) {
       scl_ds1302=0;io_ds1302=bit_data0;
       _nop_();scl_ds1302=1;
       data_ds1302=data_ds1302>  >  1; 
      }
 rst_ds1302=0;
 _nop_();
 scl_ds1302=0;
}

unsigned char read_ds1302(char command)
{
char i;
 data_ds1302=(command  <  <1)|0x81;
 scl_ds1302=0;
 _nop_();
 rst_ds1302=1;
 for (i=1;i  <=8;i++) {
       scl_ds1302=0;io_ds1302=bit_data0;
       _nop_();scl_ds1302=1;
       data_ds1302=data_ds1302>  >  1; 
      }
 scl_ds1302=1;
 for (i=1;i  <=8;i++) {
       data_ds1302=data_ds1302>  >  1;
       scl_ds1302=0;_nop_();
       bit_data7=io_ds1302;scl_ds1302=1;
      }
 rst_ds1302=0;
 _nop_();
 scl_ds1302=0;
 return(data_ds1302);
}


void write_ds1302(unsigned char address,unsigned char numb) //写入时间
{
 char i;
 rst_ds1302=0;
 scl_ds1302=0;
 rst_ds1302=0;
 rst_ds1302=1;
 data_ds1302=0x80|(address  <  <1);
 for (i=1;i  <=8;i++) {
       scl_ds1302=0;io_ds1302=bit_data0;
       _nop_();scl_ds1302=1;
       data_ds1302=data_ds1302>  >  1; 
      }
 data_ds1302=numb;
 for (i=1;i  <=8;i++) {
       scl_ds1302=0;io_ds1302=bit_data0;
       _nop_();scl_ds1302=1;
       data_ds1302=data_ds1302>  >  1; 
      }
 rst_ds1302=0;
 scl_ds1302=1;
}
void read_time()       //读取时间
{
 unsigned char second,minute,hour,date,month,year,d;
 second=0;        //read second address
 d=read_ds1302(second);
 display_buffer1[0]=d&0x0f;
 display_buffer1[1]=d>  >  4;
 minute=1;        //read minute address
 d=read_ds1302(minute);
 display_buffer1[2]=d&0x0f;
 display_buffer1[3]=(d>  >  4);
 hour=2;         //read hour address
 d=read_ds1302(hour);
 display_buffer1[4]=d&0x0f;
 display_buffer1[5]=(d>  >  4);
    date=3;
 d=read_ds1302(date);
    display_buffer2[0]=d&0x0f;
 display_buffer2[1]=(d>  >  4);               //read data address
    month=4;
 d=read_ds1302(month);
 display_buffer2[2]=d&0x0f;
 display_buffer2[3]=(d>  >  4);               //read month address
 year=6;
 d=read_ds1302(year);
 display_buffer2[4]=d&0x0f;
 display_buffer2[5]=(d>  >  4);               //read year address
}

void set_time()
{
unsigned char data temp;
unsigned char data hour_address,minute_address,second_address,year_address,month_address,date_address;
    year_address=6;
 month_address=4;
 date_address=3;
    hour_address = 2;
 minute_address = 1;
 open_write_bit();
    temp=(display_buffer2[5]  <  <4)|display_buffer2[4];
 write_ds1302(year_address,temp);
 temp=(display_buffer2[3]  <  <4)|display_buffer2[2];
 write_ds1302(month_address,temp);
 temp=(display_buffer2[1]  <  <4)|display_buffer2[0];
 write_ds1302(date_address,temp);
 temp=(display_buffer1[5]  <  <4)|display_buffer1[4];
 write_ds1302(hour_address,temp);
 temp=(display_buffer1[3]  <  <4)|display_buffer1[2];
 write_ds1302(minute_address,temp);
 temp=(display_buffer1[1]  <  <4)|display_buffer1[0];
 write_ds1302(second_address,temp);
 close_write_bit();
}

void button()
{
unsigned char data button1,button2,button3,button4;
char i;
    if(button1=0)
 {  
    for(i=0;i  <8;i++)
    {
      display_buffer1[i]=0;
         display2();
  }
 }
 else if(button2=0)
  {  display_buffer1[5]=display_buffer1[5]+1; }
    else if(button3=0)
  {  display_buffer1[3]=display_buffer1[3]+1; }
 else if(button4=0)
  {  display_buffer2[1]=display_buffer2[1]+1; }
    else{ display1(); }     
}

  
2楼:我是一条鱼 2003年6月6日21:37
 我以前也用过1302,不过是用汇编语言的
我以前也用过1302,不过是用汇编语言的,c语言不是很懂,不过我看了你的程序后看到你犯了和我当初一样的错误,你在初始化之后已经禁止写入了,而随后又有读程序,读程序是要先写入控制命令的,你既然已经禁止写了,又怎么能写入控制命令呢,也即写不进去地址了,也就读不出数据了,我想其他的都不算大问题,你自己应该能发现错误的。
  
3楼:我是一条鱼 2003年6月7日12:25
 你好:
 我看你的初始化程序真的有问题

你好:
 我看你的初始化程序真的有问题,你在初始化的开始就给8eh中送80h,这就已经禁止数据写入1302了,而接下来你又设置充电程序,这个根本就不行了,而初始化之后的读程序也不行了,因为读数据之前必须先写入地址,你在之前已经禁止写了,怎么能写入地址呢。至于其它的我也看不出问题。
   我给呢讲讲我的设计思路吧。在上电复位的时候就把1302设置为允许写入状态(这一点很重要,就是给8eh中送#00h),然后就是主循环程序,主程序是不断的进行读1302数据和键盘扫描程序。设置程序(进入设置程序后就停止振荡)就是,假如调整小时,就是在小时加一后,就把数据写入1302,其它的一样。
   我建议你在程序调试的时候要分开调试,比如可以先调试显示程序、时间设置程序等等
    你可以,也许有帮助。
  
4楼:苹果啃牙 2003年6月7日15:42
 你能不能把你的汇编程序给我看看?
  
5楼:我是一条鱼 2003年6月7日22:01
 ;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;

我把主程序和调整程序给你参考吧,其它的程序因硬件电路不同而不同。

                              ;;;;主程序;;;;
                             ;;;;;;;;;;;;;;;;;;;
                START:  SETB EA
                          MOV SCON,#00H  ;串行输出,方式0
                          MOV TMOD,#10H  ;计数器1,方式1
                          MOV TL1,#00H
                          MOV TH1,#00H
                          MOV DS1302_ADDR,#8EH
                          MOV DS1302_DATA,#00H ;允许写1302
                          LCALL WRITE
                          MOV  DS1302_ADDR,#90H
                          MOV  DS1302_DATA,#0A6H;1302充电,充电电流1.1MA
                          LCALL  WRITE
              MAIN1:     MOV  DS1302_ADDR,#8DH   ;读出年
                          LCALL  READ
                          MOV   year,DS1302_DATA
                          MOV   DS1302_ADDR,#8BH  ;读出星期
                          LCALL  READ
                          MOV    week ,DS1302_DATA
                          MOV   DS1302_ADDR,#89H   ;读出月
                          LCALL  READ
                          MOV    month,DS1302_DATA
                          MOV    DS1302_ADDR,#87H  ;读出日
                          LCALL  READ
                          MOV    day,DS1302_DATA
                          MOV    DS1302_ADDR,#85H  ;读出小时
                          LCALL   READ
                          MOV     hour,DS1302_DATA
                          MOV    DS1302_ADDR,#83H  ;读出分钟
                          LCALL   READ
                          MOV    mintue,DS1302_DATA
                          MOV    DS1302_ADDR,#81H  ;读出秒
                          LCALL  READ
                          MOV   second,DS1302_DATA


  ;;公历设置程序;;;
                   ;;;;;;;;;;;;;;;;;
                  SETG : SETB TR1
                           SETB ET1
                           MOV DS1302_ADDR,#8EH
                           MOV DS1302_DATA,#00H  ;允许写1302
                           LCALL WRITE
                           MOV DS1302_ADDR,#80H
                           MOV DS1302_DATA,#80H  ;1302停止振荡
                           LCALL WRITE
                  GWAIT: LCALL DISPLAY
                           JNB P1.1,GWAIT
                  SETG1: LCALL DISPLAY
                           JNB P1.1,SETG2
                           JNB P1.2,GADDYEAR
                           AJMP SETG1
              GADDYEAR:MOV R7,66H      ;年加一
                           LCALL ADD1
                           MOV 66H,A
                           CJNE A,#51H, GADDYEAR1
                           MOV 66H,#01H
             GADDYEAR1:MOV DS1302_ADDR,#8CH ;年值送人1302
                           MOV DS1302_DATA,66H
                           LCALL WRITE
                           MOV R0,66H
                           LCALL DIVIDE  ;年分离送显示缓存
                           MOV 4BH,R1
                           MOV 7BH,R1
                           MOV 4CH,R2
                           MOV 7CH,R2
                  WAITT1:LCALL DISPLAY
                           JNB P1.2,WAITT1
                           AJMP SETG1
                  SETG2: SETB 0AH      ;调月时闪标志
                GWAIT2:  LCALL DISPLAY
                           JNB P1.1,GWAIT2
                  SETG3: LCALL DISPLAY
                           JNB P1.1,SETG4
                           JNB P1.2,GADDMONTH
                           AJMP SETG3
            GADDMONTH:MOV R7,65H     ;月加一
                           LCALL ADD1
                           MOV 65H,A
                           CJNE A,#13H,GADDMONTH1
                           MOV 65H,#01H
         GADDMONTH1:  MOV DS1302_ADDR,#88H  ;月值送人1302
                           MOV DS1302_DATA,65H
                           LCALL WRITE
                           MOV R0,65H
                           LCALL DIVIDE  ;月分离,送显示缓存
                           MOV 79H,R1
                           MOV 49H,R1
                           MOV 7AH,R2
                           MOV 4AH,R2
               WAITT2:  LCALL DISPLAY
                           JNB P1.2,WAITT2
                           AJMP SETG3
                SETG4:   SETB 0BH    ;调日时闪标志
                GWAIT4:  LCALL DISPLAY
                           JNB P1.1,GWAIT4
                SETG5:   LCALL DISPLAY
                           JNB P1.1,SETG6
                           JNB P1.2,GADDDAY
                           AJMP SETG5
             GADDDAY:  MOV R7,63H     ;日加一
                           LCALL ADD1
                           MOV 63H,A
                           CJNE A,#32H,GADDDAY1
                           MOV  63H,#01H
             GADDDAY1: MOV DS1302_ADDR,#86H ;日值送人1302
                           MOV DS1302_DATA,63H
                           LCALL WRITE
                           MOV R0,63H
                           LCALL DIVIDE  ;日分离,送显示缓存
                           MOV 76H,R1
                           MOV 46H,R1
                           MOV 77H,R2
                           MOV 47H,R2
                  WAITT3:LCALL DISPLAY
                           JNB P1.2,WAITT3
                           AJMP SETG5
                SETG6:   SETB 0CH    ;调星期时闪标志
               GWAIT6:   LCALL DISPLAY
                           JNB P1.1,GWAIT6
                SETG7:   LCALL DISPLAY
                           JNB P1.1,SETG8
                           JNB P1.2,GADDWEEK
                           AJMP SETG7
            GADDWEEK:  MOV R7,64H  ;星期加一
                           LCALL ADD1
                           MOV 64H,A
                           CJNE A,#08H,GADDWEEK1
                           MOV  64H,#01H
          GADDWEEK1:  MOV DS1302_ADDR,#8AH
                           MOV DS1302_DATA,64H  ;星期值送人1302
                           LCALL WRITE
                           MOV R0,64H
                           LCALL DIVIDE  ;星期值分离送显示缓存
                           MOV 48H,R1
                           MOV 78H,R1
                  WAITT4:LCALL DISPLAY
                           JNB P1.2,WAITT4
                           AJMP SETG7
                SETG8:   SETB 0DH   ;调小时时闪标志
                GWAIT8:  LCALL DISPLAY
                           JNB P1.1,GWAIT8
                 SETG9:  LCALL DISPLAY
                           JNB P1.1,SETG10
                           JNB P1.2,GADDHOUR
                           AJMP SETG9
            GADDHOUR:  MOV R7,62H  ;小时加一
                           LCALL ADD1
                           MOV 62H,A
                           CJNE A,#24H,GADDHOUR1
                           MOV 62H,#00H
          GADDHOUR1:  MOV DS1302_ADDR,#84H ;小时值送人1302
                           MOV DS1302_DATA,62H
                           LCALL WRITE
                           MOV R0,62H
                           LCALL DIVIDE ;小时值分离送显示缓存
                           MOV 74H,R1
                           MOV 44H,R1
                           MOV 75H,R2
                           MOV 45H,R2
                 WAITT5: LCALL DISPLAY
                           JNB P1.2,WAITT5
                           AJMP SETG9
               SETG10:   SETB 0EH   ;调分时候闪标志
              GWAIT10:   LCALL DISPLAY
                           JNB P1.1,GWAIT10
               SETG11:   LCALL DISPLAY
                           JNB P1.1,SETGOUT
                           JNB P1.2,GADDMINTUE
                           AJMP SETG11
        GADDMINTUE:   MOV R7,61H    ;分钟加一
                           LCALL ADD1
                           MOV 61H,A
                           CJNE A,#60H,GADDMINTUE1
                           MOV 61H,#00H
       GADDMINTUE1:   MOV DS1302_ADDR,#82H ;分钟值送人1302
                           MOV DS1302_DATA,61H
                           LCALL WRITE
                           MOV R0,61H
                           LCALL DIVIDE ;分钟值分离送显示缓存
                           MOV 72H,R1
                           MOV 42H,R1
                           MOV 73H,R2
                           MOV 43H,R2
                 WAITT6: LCALL DISPLAY
                           JNB P1.2,WAITT6
                           AJMP SETG11
              SETGOUT:  LCALL DISPLAY
                           JNB P1.1,SETGOUT
                           LCALL GENGXIAN
                           MOV    DS1302_ADDR,#80H
                           MOV    DS1302_DATA,#00H ;1302晶振开始振荡
                           LCALL  WRITE
                           MOV    DS1302_ADDR,#8EH
                           MOV    DS1302_DATA,#80H ;禁止写入1302
                           LCALL  WRITE
                           CLR 08H
                           CLR 09H
                           CLR 0AH
                           CLR 0BH
                           CLR 0CH
                           CLR 0DH
                           CLR 0EH
                           CLR 0FH
                           CLR ET1  ;关闪中断
                           CLR TR1
                           LJMP MAIN1

  
6楼:guest 2004年3月13日20:12
 你的程序可读性太差,太冗长。
你的程序可读性太差,太冗长。
  
7楼:苹果啃牙 2003年6月7日15:39
 谢谢你!但是……
谢谢你的帮忙,但是我这个程序开始是正确的!

以前我没有使用按键,走时是没有问题的,现在我想加入按键,让这个时钟可以实现更新调时的功能。
main中开始我之所以用:b0=0;是想加一个按键设置的子程序,我用的按键是矩阵键盘中的一部分,所以要将按键其中一脚置0。
至于写保护位开始打开,然后关闭,是为了走时的准确性。
:)
我现在的问题是,我加的用于调时的按键,按下之后数码管出现乱码现象。我就不明白了。

  
8楼:苹果啃牙 2003年6月7日10:13
 不是这样的问题吧!

>>>>>>对该主题发表你的看法

本主题贴数8,分页: [第1页]


[上一篇主题]:8019as数据发不出去一般会是什么原因?

[下一篇主题]:tasking196的外部编译器编译出的警告???