[求助] 各位高手帮个忙~

小宝的盼盼   2012-4-17 10:24 楼主
下面这段PCF8563读写程序不知道哪里出问题了,在proteus仿真时出现错误 Internal Exception:access violation in module 'PCF8563.DLL'   ,请问是我程序问题还是软件问题
proteus可以仿真其他电路。谢谢了~
附程序:#include<reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit LCD_RS = P2^5; /*LCD1602指令,数据控制端口*/          
sbit LCD_RW = P2^6;/*LCD1602读、写控制端口*/
sbit LCD_EN = P2^7;/*LCD1602使能*/
sbit pcf8563_scl=P2^2;
sbit pcf8563_sda=P2^3;
bit flag=1,hour=0,min=0;
bit year=0,month=0,day=0,week=0;
bit busy=0;
uchar  timecount=0,count=0; 
uchar code  mytab[8] = {0x01,0x1b,0x1d,0x19,0x1d,0x1b,0x01,0x00};/*小喇叭形状定义*/
uchar init [] ={0x00,0x00,0x00,0x00,0x00,0x00,0x00};  
uchar init2[] ={0x00,0x00,0x12,0x01,0x06,0x01,0x00}; 
               /*秒,分, 时, 日, 月,星期,年,默认时间设置*/
void  Set_place(uchar row,uchar col);
void  Play_nowtime();
void  start_pcf8563();
void  stop_pcf8563();
void read();
#define delayNOP(); {_nop_();_nop_();_nop_();_nop_();};    
void delay1(int ms)/*延时*/
{
 unsigned char y;
  while(ms--)
 {
  for(y = 0; y<250; y++)
  {
   _nop_();
   _nop_();
   _nop_();
   _nop_();
  }
 }
}  
/*检查LCD忙状态,lcd_busy为1时,忙,等待。lcd-busy为0时,闲,可写指令与数据*/     
bit lcd_busy()
 {                          
    bit result;
    LCD_RS = 0;
    LCD_RW = 1;
    LCD_EN = 1;
    delayNOP();
    result = (bit)(P0&0x80);
    LCD_EN = 0;
    return(result); 
 }
/*写指令数据到LCD,RS=L,RW=L,E=高脉冲,D0-D7=指令码*/                 
void lcd_wcmd(uchar cmd)
{                          
   while(lcd_busy());
    LCD_RS = 0;
    LCD_RW = 0;
    LCD_EN = 0;
    _nop_();
    _nop_(); 
    P0 = cmd;
    delayNOP();
    LCD_EN = 1;
    delayNOP();
    LCD_EN = 0;  
}
/*写显示数据到LCD,RS=H,RW=L,E=高脉冲,D0-D7=数据*/                     
void lcd_wdat(uchar dat)
{                          
   while(lcd_busy());
    LCD_RS = 1;
    LCD_RW = 0;
    LCD_EN = 0;
    P0 = dat;
    delayNOP();
    LCD_EN = 1;
    delayNOP();
    LCD_EN = 0; 
}
/*  LCD初始化设定 */                                                                                           
void init_lcd()
    delay1(15);   
    lcd_wcmd(0x01);      /*清除LCD的显示内容*/         
    lcd_wcmd(0x38);      /*设置16×2显示,5×7点阵,8位数据接口*/
    delay1(5);
    lcd_wcmd(0x38);         
    delay1(5);
    lcd_wcmd(0x38);         
    delay1(5);
    lcd_wcmd(0x0c);      /*显示开,关光标*/
    delay1(5);
    lcd_wcmd(0x06);      /*移动光标*/
    delay1(5);
    lcd_wcmd(0x01);      /*清除LCD的显示内容*/
    delay1(5);
}

                           
/*  设定显示位置*/                                        
void write_position(uchar row,uchar col)
 {
   uchar place;
   if(row==1)
   {
     place=0x80+col-1;
     lcd_wcmd(place);
   }
   else
   {
     place=0xc0+col-1;
     lcd_wcmd(place);
   }
 }
  
/*自定义字符写入CGRAM*/                                   
void  writetab()  
{  
    unsigned char i;
    lcd_wcmd(0x40);            /*写CGRAM*/
    for (i = 0; i< 8; i++)       
    lcd_wdat(mytab);        
}
void Send_pcf8563_byte(uchar bb) /*向PCF8563发送一个字节*/ 
uchar aa; 
pcf8563_scl=0; 
for(aa=0;aa<8;aa++) 
if((bb&0x80)==0x80) 
pcf8563_sda=1; 
else 
pcf8563_sda=0; 
pcf8563_scl=1; 
pcf8563_scl=0; 
bb=bb<<1; 
_nop_(); 
_nop_(); 
pcf8563_sda=1; 
pcf8563_scl=1; 
busy=0; 
if(pcf8563_sda) 
busy=1; 
else 
_nop_(); 
_nop_(); 
pcf8563_scl=0; 
busy=0; 
receive_pcf8563_byte() /*从PCF8563接受一个字节*/ 
{
uchar CC;
uchar k; 
k=0;
pcf8563_sda=1;  
for(CC=0;CC<8;CC++) 
k=(k<<1)|pcf8563_sda; 
pcf8563_scl=0; 
pcf8563_scl=1; 
_nop_(); 
_nop_();  
pcf8563_scl=0; 
_nop_(); 
_nop_(); 
return k;
void write_pcf8563(uchar subadd,uchar dat)/* 向PCF8563对应地址写数据*/ 
start_pcf8563(); 
Send_pcf8563_byte(0xa2); 
if(!busy) 
Send_pcf8563_byte(subadd); 
if(!busy) 
Send_pcf8563_byte(dat); 
stop_pcf8563();
void set_pcf8563(uchar addr,uchar *p,uchar n) /*写入n个数据*/
   for(;n>=0;n--)
   {
   write_pcf8563(addr,*p);
   p++;
   addr=addr+1;
   }
}
void read_pcf8563(void) /*读当时的时间,日期,月,星期,年*/
uchar i;
start_pcf8563(); 
Send_pcf8563_byte(0xa2); 
if(!busy) 
Send_pcf8563_byte(0x02); 
if(!busy) 
 for(i=0;i<8;i++)
  {
    start_pcf8563(); 
    Send_pcf8563_byte(0xa3); 
    init=receive_pcf8563_byte(); 
  } 
stop_pcf8563(); 
}
void start_pcf8563() /*开启PCF8563IIC*/ 
pcf8563_sda=1; 
pcf8563_scl=1; 
pcf8563_sda=0;/*SCL为低,SDA执行一个上跳*/ 
pcf8563_scl=0;/*SCL为低,嵌住数据线*/ 
void stop_pcf8563() /*关闭PCF8563IIC */
pcf8563_sda=0; 
pcf8563_scl=1; 
pcf8563_sda=1;/*SCL为高,SDA执行一个上跳 */
pcf8563_scl=0;/*SCL为低,嵌住数据线*/ 
}                                                                         
/* 主函数*/
void main()
{
   P1=0xff;
   TMOD=0x01;   /*定时器工作方式1,16位定时*/
   TH0=0x4c;          /*50ms定时*/
   TL0=0x00;
   EA=1;
   ET0=1;   /*允许定时器0中断*/
   TR0=1;
   init_lcd();                 /*初始化LCD*/
   writetab();               /*自定义字符写入CGRAM*/
   set_pcf8563(0x02,init2,7); /*自动设置初始时间,日期,年月*/
   read();                   
   Play_nowtime();
}
/*Time0中断函数*/
void Time0(void) interrupt 1 using 0
{
  TH0=0x4c; /*50ms定时*/
  TL0=0x00;
  timecount++;
  if(timecount>9)
   {
    timecount=0;    
    flag=~flag;             
   }  
}
/* 显示当前时间*/
void  Play_nowtime()
{

  write_position(2,1);
  lcd_wdat(((init[2]&0xf0)>>4)+0x30);
  write_position(2,2);
  lcd_wdat('0'+(init[2]&0x0f)); /*读小时*/
    write_position(2,4);
    lcd_wdat('0'+((init[1]&0xf0)>>4));
    write_position(2,5);
    lcd_wdat('0'+(init[1]&0x0f)); /*读分钟*/
    write_position(2,7);
    lcd_wdat('0'+((init[0]&0xf0)>>4));
    write_position(2,8);
lcd_wdat('0'+(init[0]&0x0f)); /*读秒*/
    write_position(1,3);
    lcd_wdat('0'+((init[6]&0xf0)>>4)); 
    write_position(1,4);
    lcd_wdat('0'+(init[6]&0x0f)); /*读年*/
    write_position(1,1); /*写入年的第一位*/
lcd_wdat('2'); 
write_position(1,2); /*写入年的第二位*/
lcd_wdat('0'); 
    write_position(1,6);
    lcd_wdat('0'+((init[5]&0xf0)>>4)); 
    write_position(1,7);
    lcd_wdat('0'+(init[5]&0x0f)); /*读月*/
    write_position(1,9);
    lcd_wdat('0'+((init[3]&0xf0)>>4)); 
    write_position(1,10);
    lcd_wdat('0'+(init[3]&0x0f)); /*读日*/
write_position(1,16);
    lcd_wdat('0'+(init[4]&0x07)); /*读星期*/
write_position(1,5);
lcd_wdat('/');
write_position(1,8);   /*在年月之间加上符号"/" */
lcd_wdat('/');
write_position(1,11);   /*在年月之间加上符号"/" */
lcd_wdat('/');
write_position(1,12);   /*在年月之间加上符号"/" */
lcd_wdat('W');
write_position(1,13);   /*在年月之间加上符号"/" */
lcd_wdat('e');
write_position(1,14);   /*在年月之间加上符号"/" */
lcd_wdat('e');
write_position(1,15);   /*在年月之间加上符号"/" */
lcd_wdat('k');
    write_position(2,3);
lcd_wdat(':');
write_position(2,6);   /*在时,分,秒之间加上符号":"*/
lcd_wdat(':');
}

回复评论 (3)

点赞  2012-4-18 00:18
这样贴出代码估计是没几个人有耐心看完的。你不如多描述下你的现象。
点赞  2012-4-18 08:49
这个程序用Proteus仿真出现   Internal Exception:access violation in module 'PCF8563.DLL',不知道是哪里错了。
点赞  2012-4-18 09:13
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复