LPC1114单片机OLED驱动程序
oled.c文件内容如下:
#include "oled.h" #include "lpc11xx.h" #include "w25q16.h" //OLED // //[0]0 1 2 3 ... 127?? ? //[1]0 1 2 3 ... 127?? ? //[2]0 1 2 3 ... 127?? ? //[3]0 1 2 3 ... 127 uint8_t OLED_GRAM[128][4]; const unsigned char menu_op[3][16]={ {0x08,0x08,0x1C,0x1C,0x3E,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08},/* 向上的箭头 */ {0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x3E,0x1C,0x1C,0x08,0x08},/* 向下的箭头 */?? ? {0x08,0x08,0x1C,0x1C,0x3E,0x08,0x08,0x08,0x08,0x08,0x08,0x3E,0x1C,0x1C,0x08,0x08},/* 双向的箭头 */ }; void delay_ms(uint16_t ms) { ?? ?uint16_t i,j; ?? ?for(i=0;i<5000;i++) ?? ??? ?for(j=0;j<ms;j++); } void OLED_Refresh_Gram(void) { ?? ?uint8_t i,n;?? ??? ??? ? ?? ?for(i=0;i<4;i++) ? ?? ?{ ? ?? ??? ?OLED_WR_Byte (0xb4+i,OLED_CMD);??? //?????(0~7) ?? ??? ?OLED_WR_Byte (0x04,OLED_CMD);????? //?????????? ?? ??? ?OLED_WR_Byte (0x10,OLED_CMD);????? //??????????? ? ?? ??? ?for(n=0;n<128;n++) ?? ??? ??? ?OLED_WR_Byte(OLED_GRAM[n][i],OLED_DATA); ?? ?}? ? } void DATAOUT(uint8_t dat) { ?? ?if((dat&0x80)==0x80)LPC_GPIO0->DATA |= (1<<4);//DB7 ?? ?else LPC_GPIO0->DATA &= ~(1<<4); ?? ?if((dat&0x40)==0x40)LPC_GPIO2->DATA |= (1<<1);//DB6 ?? ?else LPC_GPIO2->DATA &= ~(1<<1); ?? ?if((dat&0x20)==0x20)LPC_GPIO2->DATA |= (1<<8);//DB5 ?? ?else LPC_GPIO2->DATA &= ~(1<<8); ?? ?if((dat&0x10)==0x10)LPC_GPIO2->DATA |= (1<<7);//DB4 ?? ?else LPC_GPIO2->DATA &= ~(1<<7); ?? ?if((dat&0x08)==0x08)LPC_GPIO2->DATA |= (1<<9);//DB3 ?? ?else LPC_GPIO2->DATA &= ~(1<<9); ?? ?if((dat&0x04)==0x04)LPC_GPIO0->DATA |= (1<<7);//DB2 ?? ?else LPC_GPIO0->DATA &= ~(1<<7); ?? ?if((dat&0x02)==0x02)LPC_GPIO3->DATA |= (1<<5);//DB1 ?? ?else LPC_GPIO3->DATA &= ~(1<<5); ?? ?if((dat&0x01)==0x01)LPC_GPIO2->DATA |= (1<<5);//DB0 ?? ?else LPC_GPIO2->DATA &= ~(1<<5); } void OLED_WR_Byte(uint8_t dat,uint8_t cmd) { ?? ?DATAOUT(dat);?? ? ?? ?if(cmd==1)OLED_DC_H; ?? ?else OLED_DC_L; ?? ?OLED_CS_L;?? ?? ? ?? ?OLED_WR_L;?? ? ?? ?OLED_WR_H; ?? ?OLED_CS_H;?? ? ? ?? ?OLED_DC_H;?? ? } void OLED_Clear(void) ? { ? ?? ?uint8_t i,n; ? ?? ?for(i=0;i<4;i++) ?? ??? ?for(n=0;n<128;n++) ?? ??? ??? ?OLED_GRAM[n][i]=0X00; ? ?? ?OLED_Refresh_Gram();// } void OLED_Init(void) { ?? ?LPC_GPIO2->DIR |= (1<<4);//OLED_RESET ?? ?LPC_GPIO2->DATA |= (1<<4); ?? ?LPC_GPIO1->DIR |= (1<<9);//OLED_CS ?? ?LPC_GPIO1->DATA |= (1<<9); ?? ?LPC_GPIO0->DIR |= (1<<3);//OLED_DC ?? ?LPC_GPIO0->DATA |= (1<<3); ?? ?LPC_GPIO3->DIR |= (1<<4);//OLED_RD ?? ?LPC_GPIO3->DATA |= (1<<4); ?? ?LPC_GPIO0->DIR |= (1<<5);//OLED_WR ?? ?LPC_GPIO0->DATA |= (1<<5); ?? ?LPC_GPIO0->DIR |= (1<<4);//DB7 ?? ?LPC_GPIO0->DATA |= (1<<4); ?? ?LPC_GPIO2->DIR |= (1<<1);//DB6 ?? ?LPC_GPIO2->DATA |= (1<<1); ?? ?LPC_GPIO2->DIR |= (1<<8);//DB5 ?? ?LPC_GPIO2->DATA |= (1<<8); ?? ?LPC_GPIO2->DIR |= (1<<7);//DB4 ?? ?LPC_GPIO2->DATA |= (1<<7); ?? ?LPC_GPIO2->DIR |= (1<<9);//DB3 ?? ?LPC_GPIO2->DATA |= (1<<9); ?? ?LPC_GPIO0->DIR |= (1<<7);//DB2 ?? ?LPC_GPIO0->DATA |= (1<<7); ?? ?LPC_GPIO3->DIR |= (1<<5);//DB1 ?? ?LPC_GPIO3->DATA |= (1<<5); ?? ?LPC_GPIO2->DIR |= (1<<5);//DB0 ?? ?LPC_GPIO2->DATA |= (1<<5); ?? ?OLED_RST_L; ?? ?delay_ms(100); ?? ?OLED_RST_H; ?? ?OLED_WR_Byte(0xAE,OLED_CMD); // ?? ?OLED_WR_Byte(0x00,OLED_CMD); // ?? ?OLED_WR_Byte(0x10,OLED_CMD);?? // ?? ?OLED_WR_Byte(0x40,OLED_CMD); // ?? ?OLED_WR_Byte(0X2E,OLED_CMD); // ?? ?OLED_WR_Byte(0x81,OLED_CMD); // ?? ?OLED_WR_Byte(0X32,OLED_CMD); // ?? ?OLED_WR_Byte(0x82,OLED_CMD); // ?? ?OLED_WR_Byte(0x80,OLED_CMD); // ?? ?OLED_WR_Byte(0xA1,OLED_CMD); // ?? ?OLED_WR_Byte(0xA6,OLED_CMD); // ?? ?OLED_WR_Byte(0xA8,OLED_CMD); // ?? ?OLED_WR_Byte(0x3F,OLED_CMD); // ?? ?OLED_WR_Byte(0xAD,OLED_CMD); // ?? ?OLED_WR_Byte(0x8E,OLED_CMD); // ?? ?OLED_WR_Byte(0xC8,OLED_CMD); // ?? ?OLED_WR_Byte(0xD3,OLED_CMD); // ?? ?OLED_WR_Byte(0x40,OLED_CMD); // ?? ?OLED_WR_Byte(0xD5,OLED_CMD); // ?? ?OLED_WR_Byte(0xf0,OLED_CMD); // ?? ?OLED_WR_Byte(0xD8,OLED_CMD); // ?? ?OLED_WR_Byte(0x05,OLED_CMD); // ?? ?OLED_WR_Byte(0xD9,OLED_CMD); // ?? ?OLED_WR_Byte(0xF1,OLED_CMD); //?? ??? ??? ??? ??? ??? ??? ?? ? ?? ?OLED_WR_Byte(0xDA,OLED_CMD); // ?? ?OLED_WR_Byte(0x12,OLED_CMD); ?? ?OLED_WR_Byte(0x91,OLED_CMD); ?? ?OLED_WR_Byte(0x3F,OLED_CMD); ?? ?OLED_WR_Byte(0x3F,OLED_CMD); ?? ?OLED_WR_Byte(0x3F,OLED_CMD); ?? ?OLED_WR_Byte(0x3F,OLED_CMD); ?? ?OLED_WR_Byte(0xAF,OLED_CMD); ?? ?OLED_Clear(); } void OLED_DrawPoint(uint8_t x,uint8_t y,uint8_t t) { ?? ?uint8_t pos,bx,temp=0; ?? ?if(x>127||y>31)return;// ?? ?pos=y/8; ?? ?bx=y%8; ?? ?temp=1<<bx; ?? ?if(t)OLED_GRAM[x][pos]|=temp; ?? ?else OLED_GRAM[x][pos]&=~temp;?? ??? ? } void fill(unsigned char dat1,unsigned char dat2) { ?? ?unsigned char x,y; ?? ?for(y=4;y<8;y++) ?? ?{ ?? ??? ?OLED_WR_Byte(0xb0+y,OLED_CMD); ?? ??? ?OLED_WR_Byte(0x00,OLED_CMD); ?? ??? ?OLED_WR_Byte(0x10,OLED_CMD); ?? ??? ?for(x=0;x<132;x++) ?? ??? ?{ ?? ??? ??? ?OLED_WR_Byte(dat1,OLED_DATA); ?? ??? ??? ?OLED_WR_Byte(dat2,OLED_DATA); ?? ??? ?} ?? ?} } /**********************************************/ /* 函数功能;从W25X16中提取点阵码???????????? */ /* 入口参数:code:GBK码第一个字节???????????? */ /*?????????? dz_data:存放点阵码的数组???????? */ /**********************************************/ void Get_GBK_DZK(uint8_t *code, uint8_t *dz_data) { ?? ?uint8_t GBKH,GBKL;?? // GBK码高位与低位?? ??? ??? ??? ??? ? ? ?? ?uint32_t offset; ?? ??? // 点阵偏移量 ?? ?GBKH=*code; ?? ?GBKL=*(code+1);?? ??? // GBKL=*(code+1); ?? ?if(GBKH>0XFE||GBKH<0X81)return; ?? ?GBKH-=0x81; ?? ?GBKL-=0x40; ?? ?offset=((uint32_t)192*GBKH+GBKL)*32;//得到字库中的字节偏移量 ?? ?W25Q16_Read(dz_data,offset+0x100,32); ?? ??? ? ? ?? ?return; } /**********************************************/ /* 函数功能:显示16*16点阵中文??????????????? */ /* 入口参数:x,y :起点坐标?? ? ?? ?????????????? */ /*?????????? *hz:汉字????????????? ??? ?? ??? ?? */ /*?????????? mode: 1,正常 2,反白??????????? */ /**********************************************/ void OLED_Show_hz(uint8_t x,uint8_t y,uint8_t *hz,uint8_t mode) { ?? ?uint8_t i,j,temp,xtemp; ?? ?uint8_t dz_data[32]; ?? ?xtemp = x; ?? ?Get_GBK_DZK(hz, dz_data); ? for(i=0;i<32;i++) ?? ?{ ?? ??? ?temp=dz_data[i]; ?? ? ?? ?for(j=0;j<8;j++) ?? ??? ?{ ?? ??? ? ?? ?if(temp&0x80)OLED_DrawPoint(x,y,mode); ?? ???? else OLED_DrawPoint(x,y,!mode);?? ? ?? ???? temp<<=1; ?? ??? ??? ?x++; ?? ??? ??? ?if(x-xtemp>15) ?? ??? ??? ?{ ?? ??? ??? ??? ?x = xtemp; ?? ??? ??? ??? ?y++; ?? ??? ??? ?} ?? ??? ?} ?? ?} //?? ?OLED_Refresh_Gram(); ?? ?return; } /**********************************************/ /* 函数功能;从W25X16中提取点阵码???????????? */ /* 入口参数:code:ASCII?????????????????????? */ /*?????????? dz_data:存放点阵码的数组???????? */ /**********************************************/ void Get_ASCII_DZK(uint8_t code,uint8_t *buf) {?? ??? ??? ??? ??? ? ?? ?uint32_t offset; ?? ??? // 点阵偏移量 ?? ?offset=code-0x20;//得到字库中的字节偏移量 ?? ?W25Q16_Read(buf,offset*16+0x0E0000,16); ?? ??? ? ? ?? ?return; } /**********************************************/ /* 函数功能:显示8*16点阵英文字符???????????? */ /* 入口参数:x,y :起点坐标?? ? ?? ?????????????? */ /*?????????? num:字母或符号??????? ??? ?? ??? ?? */ /* 注??? 意:x,y的取值要在240到320范围内????? */ /**********************************************/ void OLED_ShowChar(uint8_t x,uint8_t y,uint8_t asc,uint8_t mode) { ?? ?uint8_t i,j,temp,xtemp; ?? ?uint8_t asc_buf[16]; ?? ?xtemp = x; ?? ?Get_ASCII_DZK(asc,asc_buf); ??? ?for(i=0;i<16;i++) ?? ?{ ?? ??? ?temp=asc_buf[i]; ?? ? ?? ?for(j=0;j<8;j++) ?? ??? ?{ ?? ??? ? ?? ?if(temp&0x80)OLED_DrawPoint(x,y,mode); ?? ???? else OLED_DrawPoint(x,y,!mode);?? ? ?? ???? temp<<=1; ?? ??? ??? ?x++; ?? ??? ??? ?if(x-xtemp>7) ?? ??? ??? ?{ ?? ??? ??? ??? ?x = xtemp; ?? ??? ??? ??? ?y++; ?? ??? ??? ?} ?? ??? ?} ?? ?} //?? ?OLED_Refresh_Gram(); ?? ?return; } /*********************************************/ /* 函数功能:显示字符串(中文和英文)??????? */ /* 入口参数:x,y: 坐标?????????????????????? */ /*?????????? *p:字符串?????????????????????? */ /*********************************************/ void OLED_ShowString(uint8_t x,uint8_t y,uint8_t *p,uint8_t mode) {??????? ? ?? ?while(*p!='\0')?? ?// 如果没有结束 ?? ?{????? ? ??? if(*p>0x80)//如果是中文 ?? ??? ?{ ?? ??? ??? ?if((*p=='\n')||(x>224))? // 换段和换行 ?? ??? ??? ?{ ?? ??? ??? ??? ?y=y+16;?? //字体高16 ?? ??? ??? ??? ?x=0;????? // ?? ??? ??? ?} ?? ??? ??? ?OLED_Show_hz(x, y, p, mode); ?? ??? ??? ?x+=16; ?? ??? ??? ?p+=2; ?? ??? ?} ?? ??? ?else?? ??? //如果是英文 ?? ??? ?{ ?? ??? ??? ?if((*p=='\n')||(x>224))?? // 换段和换行 ?? ??? ??? ?{ ?? ??? ??? ??? ?y=y+16;?? //字体高16 ?? ??? ??? ??? ?x=0;????? // ?? ??? ??? ?} ?? ??? ??? ?OLED_ShowChar(x,y,*p,mode); ?? ??? ??? ?x+=8; ?? ??? ??? ?p++; ?? ??? ?} ? } ? } // opar=0表示画向上的箭头 //???? =1表示画向下的箭头 //???? =2表示画双向的箭头 //???? =3表示清空箭头 // hang=0表示在第一行画箭头 //???? =1表示在第二行画箭头 void OLED_SMenuOP(uint8_t opra,uint8_t hang) { ?? ?uint8_t temp,i,j; ?? ?uint8_t x,y; ?? ?if(hang==0) y = 0; ?? ?else y = 16; ?? ?x = 120; ?? ?if(opra==3) ?? ?{ ?? ??? ?for(i=0;i<16;i++) ?? ??? ?{ ?? ??? ??? ?for(j=0;j<8;j++) ?? ??? ??? ?{ ?? ??? ??? ??? ?OLED_DrawPoint(x,y,0);?? ? ?? ??? ??? ??? ?temp<<=1; ?? ??? ??? ??? ?x++; ?? ??? ??? ??? ?if(x>127) ?? ??? ??? ??? ?{ ?? ??? ??? ??? ??? ?x = 120; ?? ??? ??? ??? ??? ?y++; ?? ??? ??? ??? ?} ?? ??? ??? ?} ?? ??? ?} ?? ?} ?? ?else ?? ?{ ?? ??? ?for(i=0;i<16;i++) ?? ??? ?{ ?? ??? ??? ?temp = menu_op[opra][i]; ?? ??? ??? ?for(j=0;j<8;j++) ?? ??? ??? ?{ ?? ??? ??? ??? ?if(temp&0x80)OLED_DrawPoint(x,y,1); ?? ??? ??? ??? ?else OLED_DrawPoint(x,y,0);?? ? ?? ??? ??? ??? ?temp<<=1; ?? ??? ??? ??? ?x++; ?? ??? ??? ??? ?if(x>127) ?? ??? ??? ??? ?{ ?? ??? ??? ??? ??? ?x = 120; ?? ??? ??? ??? ??? ?y++; ?? ??? ??? ??? ?} ?? ??? ??? ?} ?? ??? ?} ?? ?} } /**********************************************/ /* 函数功能;求m的n次方?????????????????????? */ /**********************************************/ uint32_t mypow(uint8_t m,uint8_t n) { ?? ?uint32_t result=1;?? ? ?? ?while(n--)result*=m;?? ? ?? ?return result; }?? ??? ??? ? /**********************************************/ /* 函数功能:显示数字???????????????????????? */ /* 入口参数:x,y :起点坐标?? ? ?? ?????????????? */ /*?????????? len :数字的位数?? ??? ??? ??? ?? */ /*?????????? num:数值(0~4294967295);?? ?? ??? ?? */ /**********************************************/ void OLED_ShowNum(uint16_t x,uint16_t y,uint32_t num,uint8_t len,uint8_t mode) {??????? ??? ? ?? ?uint8_t t,temp; ?? ?uint8_t enshow=0;?? ??? ? // 此变量用来去掉最高位的0?? ? ?? ?for(t=0;t<len;t++) ?? ?{ ?? ??? ?temp=(num/mypow(10,len-t-1))%10; ?? ??? ?if(enshow==0&&t<(len-1)) ?? ??? ?{ ?? ??? ??? ?if(temp==0) ?? ??? ??? ?{ //?? ??? ??? ??? ?OLED_ShowChar(x+8*t,y,' ',mode); ?? ??? ??? ??? ?OLED_ShowChar(x+8*t,y,' ',1); ?? ??? ??? ??? ?continue; ?? ??? ??? ?}else enshow=1; ?? ??? ?} ?? ? ?? ?OLED_ShowChar(x+8*t,y,temp+'0',mode); ?? ?} }
oled.h文件内容如下:
#ifndef __OLED_H #define __OLED_H #include "lpc11xx.h" #define OLED_CMD? 0?? ?//写命令 #define OLED_DATA 1?? ?//写数据 #define OLED_CS_H LPC_GPIO1->DATA |= (1<<9) #define OLED_CS_L LPC_GPIO1->DATA &= ~(1<<9) #define OLED_RST_H? LPC_GPIO2->DATA |= (1<<4) #define OLED_RST_L? LPC_GPIO2->DATA &= ~(1<<4) #define OLED_DC_H LPC_GPIO0->DATA |= (1<<3) #define OLED_DC_L LPC_GPIO0->DATA &= ~(1<<3) #define OLED_WR_H LPC_GPIO0->DATA |= (1<<5)?? ? #define OLED_WR_L LPC_GPIO0->DATA &= ~(1<<5)?? ? #define OLED_RD_H LPC_GPIO3->DATA |= (1<<4) #define OLED_RD_L LPC_GPIO3->DATA &= ~(1<<4) extern uint8_t OLED_GRAM[128][4]; extern void OLED_W_COM(uint8_t regname); extern void OLED_W_VAL(uint8_t regval); extern void OLED_WR_Byte(uint8_t dat,uint8_t cmd); extern void OLED_Refresh_Gram(void); extern void OLED_Init(void); extern void OLED_Clear(void); extern void OLED_DrawPoint(uint8_t x,uint8_t y,uint8_t t); extern void delay_ms(uint16_t ms); extern void fill(unsigned char dat1,unsigned char dat2); extern void OLED_Show_hz(uint8_t x,uint8_t y,uint8_t *hz,uint8_t mode); extern void OLED_ShowChar(uint8_t x,uint8_t y,uint8_t asc,uint8_t mode); extern void OLED_ShowString(uint8_t x,uint8_t y,uint8_t *p,uint8_t mode); extern void OLED_SMenuOP(uint8_t opra,uint8_t hang); extern void OLED_ShowNum(uint16_t x,uint16_t y,uint32_t num,uint8_t len,uint8_t mode); #endif