微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > 51单片机总线驱动

51单片机总线驱动

时间:11-29 来源:互联网 点击:

全部源代码下载:http://www.51hei.com/f/128yhj.rar

#include"reg51.h"sbit cd = P2^0;unsigned char pdata *addr;#define uchar unsigned  char#define uint unsigned shortvoid lcd_writecom_two(uchar onedat,uchar twodat,uchar com);void lcd_writedat_onebyte(uchar onedat,uchar com);uchar lcd_readdat_onebyte(uchar com);void lcd_writedat_nbyte(uchar *dat,uchar len);void lcd_readdat_nbyte(uchar *dat ,uchar len);void clear_point(uchar x,uchar y);void sel_point(uchar x,uchar y);void sel_rmiddling(uchar x,uchar y);void clr_rmiddling(uchar x,uchar y);void sel_rbig(uchar x,uchar y);void clr_rbig(uchar x,uchar y);void graph_mode_writeword(uchar x,uchar y,uchar *dat);void graph_mode_write_letter(uchar x,uchar y,uchar *dat);void rhorizontal(uchar x0,uchar x1,uchar y);void erect(uchar y0,uchar y1,uchar x);void Draw_line(uchar x0,uchar y0,uchar x1,uchar y1);void draw_circle(int x, int y, int r);void lcd_init();/**********************************读取lcd状态**********************************/uchar lcd_readcom(){uchar temp;cd=1;addr = 0xff;temp = *addr;return temp;}/*********************************判断指令/数据读写忙碌状态*********************************/void check_busy(){uchar temp;do{temp=lcd_readcom();}while((temp&0x03)!=0x03);}/*********************************判断数据自动写忙碌状态*********************************/void check_auto_write_busy(){uchar temp;do{temp=lcd_readcom();}while((temp&0x08)!=0x08);}/*********************************判断数据自动读忙碌状态*********************************/void check_auto_read_busy(){uchar temp;do{temp=lcd_readcom();}while((temp&0x04)!=0x04);}/*********************************向lcd写命令*********************************/void lcd_writecom(uchar dat){check_busy();cd=1;*addr = dat;}/************************************向lcd写数据************************************/void lcd_writedat(uchar dat){check_busy();cd=0;*addr = dat;}/********************************从lcd读数据*********************************/uchar lcd_readdat(){uchar temp;cd=0;addr = 0xff;temp = *addr;return temp;}				   /************************************************发出命令控制 参数 低onedat  高twodat 命令com*************************************************/void lcd_writecom_two(uchar onedat,uchar twodat,uchar com){lcd_writedat(onedat);lcd_writedat(twodat);lcd_writecom(com);}/**********************************************一次写一个数据    对应地址指针位置**********************************************/void lcd_writedat_onebyte(uchar onedat,uchar com){lcd_writedat(onedat);lcd_writecom(com);}/**********************************************一次读一个数据   对应地址指针位置**********************************************/uchar lcd_readdat_onebyte(uchar com){uchar dat;lcd_writecom(com);dat=lcd_readdat();return dat;}/****************************************一次写n个数据    对应地址指针位置****************************************/void lcd_writedat_nbyte(uchar *dat,uchar len){lcd_writecom(0xb0);check_auto_write_busy();while(len){lcd_writedat(*dat);dat++;len--;}lcd_writecom(0xb2);}/****************************************一次读n个数据   对应地址指针位置****************************************/void lcd_readdat_nbyte(uchar *dat ,uchar len){lcd_writecom(0xb1);check_auto_read_busy();while(len){*dat=lcd_readdat();dat++;len--;}lcd_writecom(0xb2);}/************************************************清除一个点坐标 X,Y  左上角第一个点为0,0************************************************/void clear_point(uchar x,uchar y){uint addr;uchar temp1,temp2;addr=(y<5)+(y<3)+(x>>3);//32+8temp1=addr;//&0x00ff;temp2=addr>>8;lcd_writecom_two(temp1,temp2,0x24);lcd_writecom(0xf7-(x&0x07));}/************************************************点亮一个点 坐标 X,Y  左上角第一个点为0,0************************************************/void sel_point(uchar x,uchar y){uint addr;uchar temp1,temp2;addr=(y<5)+(y<3)+(x>>3);//32+8temp1=addr;//&0x00ff;temp2=addr>>8;lcd_writecom_two(temp1,temp2,0x24);lcd_writecom(0xff-(x&0x07));}/*************************************************画中等大小的点 4*4(用画点方法   效率低)*************************************************//*sel_middling(uchar x,uchar y){uint addr;uchar temp1,temp2,n;addr=y*160+(x>>1);//x/8*4;for(n=0;n<4;n++){temp1=addr%6;temp2=addr>>8;lcd_writecom_two(temp1,temp2,0x24);if(x%2){lcd_writecom(0xfb);lcd_writecom(0xfa);lcd_writecom(0xf9);lcd_writecom(0xf8);}else{lcd_writecom(0xff);lcd_writecom(0xfe);lcd_writecom(0xfd);lcd_writecom(0xfc);}addr+=40;}}*//*************************************************画中等大小的点 4*4(用读修改写   效率高)*************************************************/void sel_rmiddling(uchar x,uchar y){uint addr;uchar temp1,temp2,n,dat;addr=(y<7)+(y<5)+(x>>1);//x/8*4;//128+32for(n=0;n<4;n++){temp1=addr;//&0x0ff;temp2=addr>>8;lcd_writecom_two(temp1,temp2,0x24);if(x&0x01)//x%2{dat=(lcd_readdat_onebyte(0xc5))|0x0f;lcd_writedat_onebyte(dat,0xc4);}else{dat=(lcd_readdat_onebyte(0xc5))|0xf0;lcd_writedat_onebyte(dat,0xc4);}addr+=40;}}/*************************************************清楚中等大小的点 4*4(用清点方式   效率底)*************************************************//*clr_middling(uchar x,uchar y){uint addr;uchar temp1,temp2,n;addr=y*160+(x>>1);//x/8*4;for(n=0;n<4;n++){temp1=addr%6;temp2=addr>>8;lcd_writecom_two(temp1,temp2,0x24);if(x%2){lcd_writecom(0xf3);lcd_writecom(0xf2);lcd_writecom(0xf1);lcd_writecom(0xf0);}else{lcd_writecom(0xf7);lcd_writecom(0xf6);lcd_writecom(0xf5);lcd_writecom(0xf4);}addr+=40;}}*//*************************************************清楚中等大小的点 4*4(用读修改写   效率高)*************************************************/void clr_rmiddling(uchar x,uchar y){uint addr;uchar temp1,temp2,n,dat;addr=(y<7)+(y<5)+(x>>1);//x/8*4;//128+32for(n=0;n<4;n++){temp1=addr;//&0xff;temp2=addr>>8;lcd_writecom_two(temp1,temp2,0x24);if(x&0x01){dat=(lcd_readdat_onebyte(0xc5))&0xf0;lcd_writedat_onebyte(dat,0xc4);}else{dat=(lcd_readdat_onebyte(0xc5))&0x0f;lcd_writedat_onebyte(dat,0xc4);}addr+=40;}}/*********************************************************画8*8的大点(用画点方式  速度慢)*********************************************************//*void sel_big(uchar x,uchar y){uint addr;uchar temp1,temp2,n;addr=(y<8)+(y<6)+(x);//x/8*4;y*320=y*(256+64)=(y<8)+(y<6)for(n=0;n<8;n++){temp1=addr&0x00ff;//addr%6temp2=addr>>8;lcd_writecom_two(temp1,temp2,0x24);lcd_writecom(0xfb);lcd_writecom(0xfa);lcd_writecom(0xf9);lcd_writecom(0xf8);lcd_writecom(0xff);lcd_writecom(0xfe);lcd_writecom(0xfd);lcd_writecom(0xfc);addr+=40;}}*//*********************************************************画8*8的大点(用读改写方式  速度快)*********************************************************/void sel_rbig(uchar x,uchar y){uint addr;uchar temp1,temp2,n,dat;addr=(y<8)+(y<6)+(x);//x/8*4;y*320=y*(256+64)=(y<8)+(y<6)for(n=0;n<8;n++){temp1=addr;//&0x00ff;//addr%6temp2=addr>>8;lcd_writecom_two(temp1,temp2,0x24);//dat=(lcd_readdat_onebyte(0xc5))|0xff;dat=0xff;lcd_writedat_onebyte(dat,0xc4);addr+=40;}}				   /*********************************************************清楚8*8的大点(用画点方式  速度慢)*********************************************************//*void clr_big(uchar x,uchar y){uint addr;uchar temp1,temp2,n;addr=(y<8)+(y<6)+(x);//x/8*4;y*320=y*(256+64)=(y<8)+(y<6)for(n=0;n<8;n++){temp1=addr&0x00ff;//addr%6temp2=addr>>8;lcd_writecom_two(temp1,temp2,0x24);lcd_writecom(0xf3);lcd_writecom(0xf2);lcd_writecom(0xf1);lcd_writecom(0xf0);lcd_writecom(0xf7);lcd_writecom(0xf6);lcd_writecom(0xf5);lcd_writecom(0xf4);addr+=40;}}*//*********************************************************清除8*8的大点(用读修改写方式  速度快)*********************************************************/void clr_rbig(uchar x,uchar y){uint addr;uchar temp1,temp2,n,dat;addr=(y<8)+(y<6)+(x);//x/8*4;y*320=y*(256+64)=(y<8)+(y<6)for(n=0;n<8;n++){temp1=addr;//&0x00ff;//addr%6temp2=addr>>8;lcd_writecom_two(temp1,temp2,0x24);//dat=(lcd_readdat_onebyte(0xc5))|0x00;dat=0x00;lcd_writedat_onebyte(dat,0xc4);addr+=40;}}/*************************************************************图形方式   屏上写汉字 16*16************************************************************/void graph_mode_writeword(uchar x,uchar y,uchar *dat){uint addr;uint temp1;uchar n;temp1=y;temp1=(temp1<9)+(temp1<7);//512+128addr=temp1+(x<1);for(n=0;n<16;n++){lcd_writecom_two((addr&0x00ff),(addr>>8),0x24);lcd_writedat_onebyte(*dat,0xc0);dat++;lcd_writedat_onebyte(*dat,0xc4);dat++;addr=addr+40;}}/*************************************************************图形方式   屏上写字母,数字 8*16************************************************************/void graph_mode_write_letter(uchar x,uchar y,uchar *dat){uint addr;uint temp1;uchar n;temp1=y;temp1=(temp1<9)+(temp1<7);//512+128addr=temp1+(x<1);for(n=0;n<16;n++){lcd_writecom_two((addr&0x00ff),(addr>>8),0x24);lcd_writedat_onebyte(*dat,0xc0);dat++;addr=addr+40;}}/******************************************************用画点的方式划横线  (可以用读改写的方式)******************************************************//*void horizontal(uchar x0,uchar x1,uchar y){uchar temp,n;if(x0>x1){temp=x0;x0=x1;x1=temp;}n=x1-x0;for(;n>0;n--){sel_point(x0+n,y);}}*//*************************************划横线  (用读改写的方式)***************************************/uchar get_num(uchar x0){uchar dat;switch(x0){case 0: dat=0xff;break;case 1: dat=0x7f;break;case 2: dat=0x3f;break;case 3: dat=0x1f;break;case 4: dat=0x0f;break;case 5: dat=0x07;break;case 6: dat=0x03;break;case 7: dat=0x01;break;}return dat;}uchar get_num_n(uchar x1){uchar dat;switch(x1){case 0: dat=0x80;break;case 1: dat=0xc0;break;case 2: dat=0xe0;break;case 3: dat=0xf0;break;case 4: dat=0xf8;break;case 5: dat=0xfc;break;case 6: dat=0xfe;break;case 7: dat=0xff;break;}return dat;}void rhorizontal(uchar x0,uchar x1,uchar y){uint addr;uchar temp,n,temp1,temp2,dat,dat1;if(x0>x1){temp=x0;x0=x1;x1=temp;}addr=(y<5)+(y<3)+(x0>>3);temp1=addr;//&0xff;temp2=addr>>8;lcd_writecom_two(temp1,temp2,0x24);lcd_writecom_two(temp1,temp2,0x24);n=x1-x0;dat1=lcd_readdat_onebyte(0xc5);if((x0>>3)!=(x1>>3)){lcd_writedat_onebyte((get_num(x0&0x3)|dat1),0xc0);temp1=x0>>3;temp2=x1>>3;temp=temp2-temp1-1;lcd_writecom(0xb0);check_auto_write_busy();while(temp){lcd_writedat(0xff);temp--;}lcd_writecom(0xb2);dat1=lcd_readdat_onebyte(0xc5);lcd_writedat_onebyte((get_num_n(x1&0x03)|dat1),0xc4);}else{x0=x0&0x07;x1=x1%0x07;dat =~(get_num(x0)^get_num_n(x1));lcd_writedat_onebyte((dat|dat1),0xc4);}}				   /*****************************************用画点的方式画竖线*****************************************/void erect(uchar y0,uchar y1,uchar x){uchar temp,n;if(y0>y1){temp=y0;y0=y1;y1=temp;}n=y1-y0;for(;n>0;n--){sel_point(x,y0+n);}}/*******************************************************布兰森汉姆(Bresenham)算法画线  两端点(x0,y0) (x1,y1)*******************************************************/void Draw_line(uchar x0,uchar y0,uchar x1,uchar y1){int dx,dy;                //定义X.Y轴上增加的变量值int  sub;int temp;                //起点、终点大小比较,交换数据时的中间变量uchar flag;if(x0>x1)                //X轴上,起点大于终点,交换数据{temp=x1;x1=x0;x0=temp; temp=y1;y1=y0;y0=temp;   }   dx=x1-x0;                //X轴方向上的增量dy=y1-y0;                //Y轴方向上的增量if(dx==0)               erect(y0,y1,x0);if(dy==0)                rhorizontal(x0,x1,y0);if(dy>0)flag=1;elseflag=0;if((dx!=0)&&(dy!=0)){// 布兰森汉姆(Bresenham)算法画线 /if(flag==1){if(dx>=dy)                  //*近X轴{sub=2*dy-dx;              //计算下个点的位置         while(x0!=x1){sel_point(x0,y0);        //画起点x0++;                  // X轴上加1if(sub>0)                // 判断下下个点的位置{y0++;                  // 为右上相邻点,即(x0+1,y0+1)sub+=2*dy-2*dx;}else         sub+=2*dy;            // 判断下下个点的位置         }sel_point(x0,y0);}else{sub=2*dy-dx;              //*近Y轴       while(y0!=y1){sel_point(x0,y0);        //画起点y0++;                 if(sub>0)              //判断下下个点的位置{x0++;               sub+=2*dx-2*dy;}elsesub+=2*dx;}sel_point(x0,y0);}}else{dy=y0-y1;if(dx>=dy)                  //*近X轴{sub=2*dy-dx;              //计算下个点的位置         while(x0!=x1){sel_point(x0,y0);        //画起点x0++;                  // X轴上加1if(sub>0)                // 判断下下个点的位置{y0--;                  // 为右上相邻点,即(x0+1,y0+1)sub+=2*dy-2*dx;}else         sub+=2*dy;            // 判断下下个点的位置         }sel_point(x0,y0);}else{sub=2*dx-dy;              //*近Y轴       while(y0!=y1){sel_point(x0,y0);        //画起点y0--;                 if(sub>0)              //判断下下个点的位置{x0++;               sub+=2*dx-2*dy;}elsesub+=2*dx;}sel_point(x0,y0);}}}  }/****************************************************画圆 圆点(x,y) 半径 r****************************************************/void draw_circle(int x, int y, int r){int a, b, num;a = 0;b = r;while(2 * b * b >= r * r)          // 1/8圆即可{sel_point(x + a, y - b); // 0~1sel_point(x - a, y - b); // 0~7sel_point(x - a, y + b); // 4~5sel_point(x + a, y + b); // 4~3sel_point(x + b, y + a); // 2~3sel_point(x + b, y - a); // 2~1sel_point(x - b, y - a); // 6~7sel_point(x - b, y + a); // 6~5a++;num = (a * a + b * b) - r*r;if(num > 0){b--;a--;}}}void lcd_init(){lcd_writecom_two(0x00,0x00,0x24);lcd_writecom_two(0x00,0x00,0x21);lcd_writecom_two(0x00,0x00,0x42);lcd_writecom_two(0x28,0x00,0x43);//28lcd_writecom_two(0x00,0x00,0x40);lcd_writecom_two(0x01e,0x00,0x41);//1elcd_writecom(0xa0);lcd_writecom(0x98);lcd_writecom(0x80);}main(){unsigned char i;lcd_init();Draw_line(0,0,239,127);Draw_line(0,127,239,0);Draw_line(0,0,239,0);Draw_line(0,127,239,127);Draw_line(0,0,0,127);Draw_line(239,0,239,127);while(1){for(i=60;i<150;i++)draw_circle(i,64, 60);}}

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top