- //-------------------------------------------------------
- // 写16位图形数据,将原座标系:x(0~15),y(0~31)变换为x(0~7),y(0~63)
- //mode为绘图模式:0:正常,1:或,2:与,3:取反
- //-------------------------------------------------------
- void LCD_Write16(U8 x,U8 y,U16 d,U8 mode)
- {
- idata U16 temp;
- if(x>7)return;
- if(y>63)return;
- if(y>31){y-=32;x+=8;}
- LCD_W_Cmd(BIT(7)+y);//x
- LCD_W_Cmd(BIT(7)+x);//y
- if(mode)
- {
- LCD_R_Dat();
- temp=LCD_R_Dat();
- temp=(temp<<8)|LCD_R_Dat();//读出数据
- LCD_W_Cmd(BIT(7)+y);//x
- LCD_W_Cmd(BIT(7)+x);//y //读取参数过后地址会改变,需重新设置地址
- if(mode==1)//or
- d|=temp;
- else if(mode==2)//and
- d&=temp;
- else if(mode==3)//xor
- d^=temp;
- }
- LCD_W_Dat(d>>8);
- LCD_W_Dat(d);
- }
- //-------------------------------------------------------
- // 读16位图形数据,将原座标系:x(0~15),y(0~31)变换为x(0~7),y(0~63)
- //-------------------------------------------------------
- U16 LCD_Read16(U8 x,U8 y)
- {
- idata U16 d=0;
- if(x>7)return 0;
- if(y>63)return 0;
- if(y>31){y-=32;x+=8;}
- LCD_W_Cmd(BIT(7)+y);//x
- LCD_W_Cmd(BIT(7)+x);//y
- LCD_R_Dat();
- d=LCD_R_Dat();
- d=(d<<8)|LCD_R_Dat();//读出数据
- return d;
- }
- //-------------------------------------------------------
- //绘图
- //x,y为座标,w为宽度,h为高度,d为数据
- //m 为模式:B0:0正常,1取反,B2&B1:00正常,01:OR,10:AND,11:XOR
- //-------------------------------------------------------
- void LCD_DrawPic(U8 x0,U8 y0,U8 w,U8 h,U8 m,U8* d)
- {
- idata U8 x,y,bs,px=0,dx=0,dw,m1,n=0;
- idata U32 temp;
- idata U16 ps;
- dw=(w+7)>>3;//数组横向字节数
- //一个横向16位里可能有3个字节
- px=x0&0x0f;//x方向的偏移(余数)
- bs=px;//起始位
- m1=(m>>1)&0x03;
- for(x=x0;(x<x0+w)&&(x<128);x++)
- {
- n++;
- if(((x&0x0f)==0x0f)||((x+1)==(x0+w)||((x+1)==128)))//横向16位
- {
- for(y=y0;(y<y0+h)&&(y<64);y++)
- {
- ps=y-y0;
- ps=ps*dw+dx;//数组中的位置
- temp=((U32)d[ps-1]<<16)|((U16)d[ps]<<8)|d[ps+1];//连续取三个字节
- if(m&BIT(0))temp=~temp;//数据取反
- temp=(temp>>px)&((0xffff<<(16-n))>>bs);//从bs位开始取n个位
- //---------------------------对绘图模式的处理->
- if((n<16)||(m>0))//小于16位,或在非正常模式,需要读出原位置的数据来处理
- ps=LCD_Read16(x>>4,y);
- if(m1==0)//正常
- {
- if(n<16)
- {
- temp=ps&(~((0xffff<<(16-n))>>bs))|temp;//ps|((0xffff<<(16-n))>>bs)&temp;
- //将读出的数从bs位开始n个位清0,再或上temp
- }
- }
- else if(m1==1)//OR
- {
- temp|=ps;
- }
- else if(m1==2)//AND
- {
- temp&=ps;
- }
- else if(m1==3)//XOR
- {
- temp^=ps;
- }
- //---------------------------对绘图模式的处理<-
- LCD_Write16(x>>4,y,temp,0);
- }
- dx++;//数组指向下一个
- if(n>8)dx++;//数据位多于8个,就要再向下移一个字节
- px&=0x07;//偏移没那么多了
- n=0;//数据位清0
- bs=0;//之后的起始位就为0了
- }
- }
- }