| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554 |
- #include "STC8XXXX.H"
- #include "oled.h"
- #include "oledfont.h"
- #include <math.h>
- #include <stdlib.h>
- #include <string.h>
- unsigned char _buf[128*8]=0;
- unsigned char code height=8;
- unsigned char code width=128;
- bit _OLED_Reverse = 0;
- bit _OLED_Overlap = 1;
- static char __x, __y;
- void delay_ms(unsigned int ms)
- {
- unsigned int a;
- while(ms)
- {
- a=1800;
- while(a--);
- ms--;
- }
- return;
- }
- //反显函数
- void OLED_ColorTurn(u8 i)
- {
- if(i==0)
- {
- OLED_WR_Byte(0xA6,OLED_CMD);//正常显示
- }
- if(i==1)
- {
- OLED_WR_Byte(0xA7,OLED_CMD);//反色显示
- }
- }
- //屏幕旋转180度
- void OLED_DisplayTurn(u8 i)
- {
- if(i==0)
- {
- OLED_WR_Byte(0xC8,OLED_CMD);//正常显示
- OLED_WR_Byte(0xA1,OLED_CMD);
- }
- if(i==1)
- {
- OLED_WR_Byte(0xC0,OLED_CMD);//反转显示
- OLED_WR_Byte(0xA0,OLED_CMD);
- }
- }
- //延时
- void IIC_delay(void)
- {
- _nop_();
- }
- //起始信号
- void I2C_Start(void)
- {
- OLED_SDA_Set();
- OLED_SCL_Set();
- IIC_delay();
- OLED_SDA_Clr();
- IIC_delay();
- OLED_SCL_Clr();
-
- }
- //结束信号
- void I2C_Stop(void)
- {
- OLED_SDA_Clr();
- OLED_SCL_Set();
- IIC_delay();
- OLED_SDA_Set();
- }
- //等待信号响应
- void I2C_WaitAck(void) //测数据信号的电平
- {
- OLED_SDA_Set();
- IIC_delay();
- OLED_SCL_Set();
- IIC_delay();
- OLED_SCL_Clr();
- IIC_delay();
- }
- //写入一个字节
- void Send_Byte(u8 dat)
- {
- u8 i;
- for(i=0;i<8;i++)
- {
- OLED_SCL_Clr();//将时钟信号设置为低电平
- if(dat&0x80)//将dat的8位从最高位依次写入
- {
- OLED_SDA_Set();
- }
- else
- {
- OLED_SDA_Clr();
- }
- IIC_delay();
- OLED_SCL_Set();
- IIC_delay();
- OLED_SCL_Clr();
- dat<<=1;
- }
- }
- //发送一个字节
- //向SSD1306写入一个字节。
- //mode:数据/命令标志 0,表示命令;1,表示数据;
- void OLED_WR_Byte(u8 dat,u8 mode)
- {
- I2C_Start();
- Send_Byte(0x78);
- I2C_WaitAck();
- if(mode){Send_Byte(0x40);}
- else{Send_Byte(0x00);}
- I2C_WaitAck();
- Send_Byte(dat);
- I2C_WaitAck();
- I2C_Stop();
- }
- //坐标设置
- void OLED_Set_Pos(u8 x, u8 y)
- {
- OLED_WR_Byte(0xb0+y,OLED_CMD);
- OLED_WR_Byte(((x&0xf0)>>4)|0x10,OLED_CMD);
- OLED_WR_Byte((x&0x0f),OLED_CMD);
- }
- //开启OLED显示
- void OLED_Display_On(void)
- {
- OLED_WR_Byte(0X8D,OLED_CMD); //SET DCDC命令
- OLED_WR_Byte(0X14,OLED_CMD); //DCDC ON
- OLED_WR_Byte(0XAF,OLED_CMD); //DISPLAY ON
- }
- //关闭OLED显示
- void OLED_Display_Off(void)
- {
- OLED_WR_Byte(0X8D,OLED_CMD); //SET DCDC命令
- OLED_WR_Byte(0X10,OLED_CMD); //DCDC OFF
- OLED_WR_Byte(0XAE,OLED_CMD); //DISPLAY OFF
- }
- //清屏函数,清完屏,整个屏幕是黑色的!和没点亮一样!!!
- void OLED_Clear(void)
- {
- u8 i,n;
- for(i=0;i<8;i++)
- {
- OLED_WR_Byte (0xb0+i,OLED_CMD); //设置页地址(0~7)
- OLED_WR_Byte (0x00,OLED_CMD); //设置显示位置—列低地址
- OLED_WR_Byte (0x10,OLED_CMD); //设置显示位置—列高地址
- for(n=0;n<128;n++)OLED_WR_Byte(0,OLED_DATA);
- } //更新显示
- }
- //在指定位置显示一个字符,包括部分字符
- //x:0~127
- //y:0~63
- //sizey:选择字体 6x8 8x16
- void OLED_ShowChar(u8 x,u8 y,u8 chr,u8 sizey)
- {
- u8 c=0,sizex=sizey/2;
- u16 i=0,size1;
- if(sizey==8)size1=6;
- else size1=(sizey/8+((sizey%8)?1:0))*(sizey/2);
- c=chr-' ';//得到偏移后的值
- OLED_Set_Pos(x,y);
- for(i=0;i<size1;i++)
- {
- if(i%sizex==0&&sizey!=8) OLED_Set_Pos(x,y++);
- if(sizey==8) OLED_WR_Byte(asc2_0806[c][i],OLED_DATA);//6X8字号
- else if(sizey==16) OLED_WR_Byte(asc2_1608[c][i],OLED_DATA);//8x16字号
- // else if(sizey==xx) OLED_WR_Byte(asc2_xxxx[c][i],OLED_DATA);//用户添加字号
- else return;
- }
- }
- //m^n函数
- u32 oled_pow(u8 m,u8 n)
- {
- u32 result=1;
- while(n--)result*=m;
- return result;
- }
- //显示数字
- //x,y :起点坐标
- //num:要显示的数字
- //len :数字的位数
- //sizey:字体大小
- void OLED_ShowNum(u8 x,u8 y,u32 num,u8 len,u8 sizey)
- {
- u8 t,temp,m=0;
- u8 enshow=0;
- if(sizey==8)m=2;
- for(t=0;t<len;t++)
- {
- temp=(num/oled_pow(10,len-t-1))%10;
- if(enshow==0&&t<(len-1))
- {
- if(temp==0)
- {
- OLED_ShowChar(x+(sizey/2+m)*t,y,' ',sizey);
- continue;
- }else enshow=1;
- }
- OLED_ShowChar(x+(sizey/2+m)*t,y,temp+'0',sizey);
- }
- }
- //显示一个字符号串
- void OLED_ShowString(u8 x,u8 y,u8 *chr,u8 sizey)
- {
- u8 j=0;
- while (chr[j]!='\0')
- {
- OLED_ShowChar(x,y,chr[j++],sizey);
- if(sizey==8)x+=6;
- else x+=sizey/2;
- }
- }
- //显示汉字
- //void OLED_ShowChinese(u8 x,u8 y,u8 no,u8 sizey)
- //{
- // u16 i,size1=(sizey/8+((sizey%8)?1:0))*sizey;
- // for(i=0;i<size1;i++)
- // {
- // if(i%sizey==0) OLED_Set_Pos(x,y++);
- // if(sizey==16) OLED_WR_Byte(Hzk[no][i],OLED_DATA);//16x16字号
- //// else if(sizey==xx) OLED_WR_Byte(xxx[c][i],OLED_DATA);//用户添加字号
- // else return;
- // }
- //}
- //显示图片
- //x,y显示坐标
- //sizex,sizey,图片长宽
- //BMP:要显示的图片
- void OLED_DrawBMP(int x,int y,unsigned char sizex, unsigned char sizey,unsigned char BMP[])
- {
- int j=0;
- int i,m;
- sizey=sizey/8+((sizey%8)?1:0);
- for(i=0;i<sizey;i++)
- {
- OLED_Set_Pos(x,i+y);
- for(m=0;m<sizex;m++)
- {
- OLED_WR_Byte(BMP[j++],OLED_DATA);
- }
- }
- }
- //初始化
- void OLED_Init(void)
- {
- OLED_RES_Clr();
- delay_ms(200);
- OLED_RES_Set();
- delay_ms(200);
- OLED_WR_Byte(0xAE,OLED_CMD);//--turn off oled panel
- OLED_WR_Byte(0x00,OLED_CMD);//---set low column address
- OLED_WR_Byte(0x10,OLED_CMD);//---set high column address
- OLED_WR_Byte(0x40,OLED_CMD);//--set start line address Set Mapping RAM Display Start Line (0x00~0x3F)
- OLED_WR_Byte(0x81,OLED_CMD);//--set contrast control register
- OLED_WR_Byte(0xff,OLED_CMD); // Set SEG Output Current Brightness
- OLED_WR_Byte(0xA1,OLED_CMD);//--Set SEG/Column Mapping 0xa0左右反置 0xa1正常
- OLED_WR_Byte(0xC8,OLED_CMD);//Set COM/Row Scan Direction 0xc0上下反置 0xc8正常
- OLED_WR_Byte(0xA6,OLED_CMD);//--set normal display
- OLED_WR_Byte(0xA8,OLED_CMD);//--set multiplex ratio(1 to 64)
- OLED_WR_Byte(0x3f,OLED_CMD);//--1/64 duty
- OLED_WR_Byte(0xD3,OLED_CMD);//-set display offset Shift Mapping RAM Counter (0x00~0x3F)
- OLED_WR_Byte(0x00,OLED_CMD);//-not offset
- OLED_WR_Byte(0xd5,OLED_CMD);//--set display clock divide ratio/oscillator frequency
- OLED_WR_Byte(0x80,OLED_CMD);//--set divide ratio, Set Clock as 100 Frames/Sec
- OLED_WR_Byte(0xD9,OLED_CMD);//--set pre-charge period
- OLED_WR_Byte(0xF1,OLED_CMD);//Set Pre-Charge as 15 Clocks & Discharge as 1 Clock
- OLED_WR_Byte(0xDA,OLED_CMD);//--set com pins hardware configuration
- OLED_WR_Byte(0x12,OLED_CMD);
- OLED_WR_Byte(0xDB,OLED_CMD);//--set vcomh
- OLED_WR_Byte(0x40,OLED_CMD);//Set VCOM Deselect Level
- OLED_WR_Byte(0x20,OLED_CMD);//-Set Page Addressing Mode (0x00/0x01/0x02)
- OLED_WR_Byte(0x02,OLED_CMD);//
- OLED_WR_Byte(0x8D,OLED_CMD);//--set Charge Pump enable/disable
- OLED_WR_Byte(0x14,OLED_CMD);//--set(0x10) disable
- OLED_WR_Byte(0xA4,OLED_CMD);// Disable Entire Display On (0xa4/0xa5)
- OLED_WR_Byte(0xA6,OLED_CMD);// Disable Inverse Display On (0xa6/a7)
- OLED_Clear();
- OLED_WR_Byte(0xAF,OLED_CMD); /*display ON*/
- OLED_Clear();
- OLED_ColorTurn(0);
- OLED_DisplayTurn(0);
- OLED_Display_On();
- }
- void OLED_DrawPixel(unsigned char x, unsigned char y,unsigned char color)
- {
- unsigned char mask;
- unsigned char *pBuf;
- if(y%2 == 0)
- {
- y++;
- }
- if (__x > width)
- {
- __x = 0;
- __y += 1;
- }
- if (__y > height * 8)
- {
- __y = 0;
- }
- pBuf = &_buf[(y >> 3) * width + x];
- mask = 1 << (y & 7);
- if (!color)
- {
- *pBuf++ &= ~mask;
- }
- else
- {
- *pBuf++ |= mask;
- }
- }
- void _swap_char(unsigned char* a,unsigned char* b)
- {
- unsigned char tmp = *a;
- *a = *b;
- *b = tmp;
- }
- /*========================================================
- *????: ?0.96Oled???
- *????: x1 -> ??x1?? y1 -> ??y1??
- * x2 -> ??x1?? y2 -> ??y1??
- *????: ?
- *========================================================*/
- void OLED_DrawLine(unsigned char x1,unsigned char y1,unsigned char x2,unsigned char y2, unsigned char color)
- {
- unsigned char i = 0;
- char DeltaY = 0,DeltaX = 0;
- float k = 0,b = 0;
- if(x1>x2)
- {
- i = x2;x2 = x1;x1 = i;
- i = y2;y2 = y1;y1 = i;
- i = 0;
- }
- DeltaY = y2 - y1;
- DeltaX = x2 - x1;
- if(DeltaX == 0)
- {
- if(y1<=y2)
- {
- for(y1;y1<=y2;y1++)
- {
- OLED_DrawPixel(x1,y1,color);
- }
- }else if(y1>y2)
- {
- for(y2;y2<=y1;y2++)
- {
- OLED_DrawPixel(x1,y2,color);
- }
- }
- }
- else if(DeltaY == 0)
- {
- for(x1;x1<=x2;x1++)
- {
- OLED_DrawPixel(x1,y1,color);
- }
- }
- else
- {
- k = ((float)DeltaY)/((float)DeltaX);
- b = y2 - k * x2;
- if((k>-1&k<1))
- {
- for(x1;x1<=x2;x1++)
- {
- OLED_DrawPixel(x1,(int)(k * x1 + b),color);
- }
- }else if((k>=1)|(k<=-1))
- {
- if(y1<=y2)
- {
- for(y1;y1<=y2;y1++)
- {
- OLED_DrawPixel((int)((y1 - b) / k),y1,color);
- }
- }else if(y1>y2)
- {
- for(y2;y2<=y1;y2++)
- {
- OLED_DrawPixel((int)((y2 - b) / k),y2,color);
- }
- }
- }
- }
- }
- void OLED_display(void)
- {
- OLED_DrawBMP(0,0,128,64,_buf);
- //OLED_DrawBMP(0,6,width[1],heigth[1]*8,_buf1);
- }
- void OLED_display_clear()
- {
- memset(_buf, 0x00, width * height);
- }
- void OLED_Draw_Byte(unsigned char *pBuf, unsigned char mask, unsigned char offset, bit reserve_hl)
- {
- if (_OLED_Overlap)
- {
- if (_OLED_Reverse)
- *pBuf |= ~mask;
- else
- *pBuf |= mask;
- }
- else
- {
- if (_OLED_Reverse)
- {
- /* 保留高位
- Reserve upper */
- if (reserve_hl)
- {
- *pBuf &= (~mask) | (0xFF << (8 - offset));
- *pBuf |= (~mask) & (0xFF >> offset);
- }
- /* 保留低位
- Reserve lower */
- else
- {
- *pBuf &= (~mask) | (0xFF >> (8 - offset));
- *pBuf |= (~mask) & (0xFF << offset);
- }
- }
- else
- {
- /* 保留高位
- Reserve upper */
- if (reserve_hl)
- {
- *pBuf &= mask | (0xFF << (8 - offset));
- *pBuf |= mask & (0xFF >> offset);
- }
- /* 保留低位
- Reserve lower */
- else
- {
- *pBuf &= mask | (0xFF >> (8 - offset));
- *pBuf |= mask & (0xFF << offset);
- }
- }
- }
- }
- void OLED_DrawChar(unsigned char x, unsigned char y, unsigned char chr)
- {
- unsigned char c;
- unsigned char i;
- unsigned char mask;
- unsigned char *pBuf;
- unsigned char offset;
- offset = y & 7;
- c = chr - ' ';
- pBuf = &_buf[(y >> 3) * width + x];
- for (i = 0; i < 8; i++)
- {
- mask = asc2_1608[c][i] << offset;
- OLED_Draw_Byte(pBuf++, mask, offset, 0);
- }
- if (offset && y < 56 - 8)
- {
- pBuf = &_buf[((y >> 3) + 1) * 100 + x];
- for (i = 0; i < 6; i++)
- {
- mask = asc2_0806[c][i] >> (8 - offset);
- OLED_Draw_Byte(pBuf++, mask, 8 - offset, 1);
- }
- }
- }
- void OLED_Set_Posi(unsigned char x, unsigned char y)
- {
- __x = x;
- __y = y;
- }
- void OLED_DrawNum(unsigned char digit, unsigned char len)
- {
- unsigned char t, i, temp;
- unsigned char enshow = 0;
- i = 0;
- for (t = 0; t < len; t++)
- {
- temp = (digit / oled_pow(10, len - t - 1)) % 10;
- if (enshow == 0 && t < (len - 1))
- {
- if (temp == 0)
- {
- i++;
- continue;
- }
- else
- enshow = 1;
- }
- if (__x > 100 - 6)
- {
- __x = 0;
- __y += 8;
- }
- if (__y > 56 - 8)
- {
- __y = 0;
- }
- OLED_DrawChar(__x + (6) * (t - i), __y, temp + '0');
- }
- __x += len;
- }
- void OLED_DrawBMP_2(u8 x0, u8 page0, u8 xsize, u8 ysize, u8 *BMP)
- {
- u16 i, j;
- for(j = page0; j < page0+ysize/8; j++)
- {
- for(i = x0; i < x0+xsize; i++)
- {
- _buf[i+(j)*width]=BMP[(i-x0)+(j-page0)*xsize];
- }
- }
- }
|