下面这段PCF8563读写程序不知道哪里出问题了,在proteus仿真时出现错误 Internal Exception:access violation in module 'PCF8563.DLL' ,请问是我程序问题还是软件问题proteus可以仿真其他电路。谢谢了~附程序:#include<reg52.h>#include<intrins.h>#define uchar unsigned char#define uint unsigned intsbit 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(':');}
此帖出自小平头技术问答
一周热门 更多>