LPC1114单片机OLED驱动程序

  • 学习5127次

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

发表评论