下面这段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(':'); }
|