在线时间613 小时
UID252169
注册时间2010-12-5
NXP金币0
TA的每日心情 | 开心 2019-2-14 16:49 |
---|
签到天数: 296 天 连续签到: 1 天 [LV.8]以坛为家I
金牌会员
 
- 积分
- 4473
- 最后登录
- 2020-4-14
|
本帖最后由 zhjb1 于 2017-3-10 21:04 编辑
实验XX 采用mbed开发LPC824用I2C接口驱显OLED
最近为了实验只有4个输出IO口的开发板,专门买了一款I2C口的OLED。见照片F1。因为采用mbed工程开发的LPC824编程比较简单,自然她成了首选。于是开始编程。
打开i2c.h,精简的代码实例如下:
* I2C i2c(p28, p27);
* int main() {
* int address = 0x62;
* char data[2];
* i2c.read(address, data, 2);
* }
再查看PinNames.h,得知标准的I2C的IO口为P0_10,P0_11。于是按照编程方法直接开始。为了简单和功能模块化,先创建一个文件:oled.h,打开首先定义i2c对象:
#include "mbed.h"
//Define Object
I2C i2c(P0_10,P0_11);//SDA,SCL
由于OLED不带字库,因此需要自编点阵字库,为了字库占的小点,设计成为6X8点阵的,字库较大省了。定义一个延时函数,也省了。
定义i2c的速度函数:
//I2C speed
void i2cInit(void){i2c.frequency(200000);}//300K就不正常了
定义i2c写函数:
//Write a byte to OLED
void i2cWri(int dat0){i2c.write(dat0);}
判断写入的是命令还是数据函数:
//?Command ?Data
void i2cCov(unsigned char dat,int com){
i2c.start();
if(com){//write data
i2cWri(0x78);
i2cWri(0x40);
i2cWri(dat);
}else{//write command
i2cWri(0x78);//Slave address,SA0=0
i2cWri(0x00);
i2cWri(dat);
}
i2c.stop();
}
设置写入数据的X,Y坐标
//Set OLED X,Y
void setXy(unsigned char x,unsigned char y){
i2cCov(0xb0+y,0);
i2cCov(x&0x0f,0);
i2cCov(0x10|((x&0xf0)>>4),0);
}
充满屏幕——实际上就是清除屏幕
//OLED Fill
void lcdClear(unsigned char vola){
unsigned char y,x;
for(y=0;y<8;y++){
i2cCov(0xb0+y,0);
i2cCov(0x01,0);
i2cCov(0x10,0);
for(x=0;x<128;x++)
i2cCov(vola,1);
}
}
写一个ASCII字符到OLED
//Send a word to OLED
void c2l(unsigned char x,unsigned char y,int cc){
unsigned char line;
setXy(x*6,y);
for (line=0;line<6;line++)
i2cCov(asc2[cc][line],1);
}
初始化OLED函数:
//12864_OLED Intial
void lcdInit(void){
delay0(500000);//初始化之前的延时很重要!
i2cCov(0xAE,0);//turn off oled panel
i2cCov(0x00,0);//set low column address
i2cCov(0x10,0);//set high column address
i2cCov(0x40,0);//set start line address Set Mapping RAM Display Start Line (0x00~0x3F)
i2cCov(0x81,0);//set contrast control register
i2cCov(0xCF,0);// Set SEG Output Current Brightness
i2cCov(0xA1,0);//Set SEG/Column Mapping 0xa0左右反置 0xa1正常
i2cCov(0xC8,0);//Set COM/Row Scan Direction 0xc0上下反置 0xc8正常
i2cCov(0xA6,0);//set normal display
i2cCov(0xA8,0);//set multiplex ratio(1 to 64)
i2cCov(0x3F,0);//1/64 duty
i2cCov(0xD3,0);//set display offset Shift Mapping RAM Counter (0x00~0x3F)
i2cCov(0x00,0);//not offset
i2cCov(0xD5,0);//set display clock divide ratio/oscillator frequency
i2cCov(0x80,0);//set divide ratio, Set Clock as 100 Frames/Sec
i2cCov(0xD9,0);//set pre-charge period
i2cCov(0xF1,0);//Set Pre-Charge as 15 Clocks & Discharge as 1 Clock
i2cCov(0xDA,0);//set com pins hardware configuration
i2cCov(0x12,0);
i2cCov(0xDB,0);//set vcomh
i2cCov(0x40,0);//Set VCOM Deselect Level
i2cCov(0x20,0);//Set Page Addressing Mode (0x00/0x01/0x02)
i2cCov(0x02,0);//
i2cCov(0x8D,0);//set Charge Pump enable/disable
i2cCov(0x14,0);//set(0x10) disable
i2cCov(0xA4,0);//Disable Entire Display On (0xa4/0xa5)
i2cCov(0xA6,0);//Disable Inverse A7 Normorn A6
i2cCov(0xAf,0);//turn on oled panel
delay0(1000);
}
显示所有ASCII码函数:
//Display ASCiI Test
void dispAsc(void){
int i,j,k=0;
for(i=0;i<8;i++){
for(j=0;j<20;j++){
c2l(j,i,k);
if(k<91){k++;}else{k=0;}
}
}
}
主函数:
#include "mbed.h"
#include "oled.h"
//DEFINE GPIO
DigitalOut led0(P0_15);
//MAIN Program
void main(void){
i2cInit();
lcdInit();
lcdClear(0x00);
while(true){
led0 = !led0;
dispAsc();
wait(0.2f);
lcdClear(0x00);
}
}
下载运行,结果见照片F2。
注意一个问题,在PinNames.h中i2c的定义是:
// I2C pins
SCL = P0_10,
SDA = P0_11,
I2C_SCL = P0_10,
I2C_SDA = P0_11,
实际上是反的:SCL为P0_11,SDA为P0_10.发现此问题是在程序完成下载后,总不显示。当输出减少到40K时,用示波器看波形是方波了,再看两个管脚才发现P0_11管脚的波形频率高于P0_10的,说明P0_11是CLK,而P0_10才是SDA,换过来后立马显示了。但是最快稳定的速率为200K,300K是就乱码出现了——示波器看波形已成了近似锯齿状。当然没有外接上拉电阻。可以保证此文档是自己一字一字敲出来的,实验是自己做的。代码风格可以看出一切,没有抄袭。
|
-
只有4引脚的真OLED
-
ASCII码刷屏效果
|