查看: 6838|回复: 2

[原创] 【我要创作】实验XX 采用mbed开发LPC824用I2C接口驱显OLED

[复制链接]
  • TA的每日心情
    开心
    2019-2-14 16:49
  • 签到天数: 296 天

    连续签到: 1 天

    [LV.8]以坛为家I

    241

    主题

    2239

    帖子

    6

    金牌会员

    Rank: 6Rank: 6

    积分
    4473
    最后登录
    2020-4-14
    发表于 2017-3-10 14:36:16 | 显示全部楼层 |阅读模式
    本帖最后由 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

    只有4引脚的真OLED

    ASCII码刷屏效果

    ASCII码刷屏效果
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2023-9-15 08:42
  • 签到天数: 1952 天

    连续签到: 1 天

    [LV.Master]伴坛终老

    1

    主题

    4686

    帖子

    0

    金牌会员

    Rank: 6Rank: 6

    积分
    9405
    最后登录
    2023-9-15
    发表于 2017-3-10 22:27:07 | 显示全部楼层
    学习啦!
    今天天气不错!签到!
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2018-7-24 08:30
  • 签到天数: 50 天

    连续签到: 1 天

    [LV.5]常住居民I

    22

    主题

    817

    帖子

    0

    金牌会员

    Rank: 6Rank: 6

    积分
    1713
    最后登录
    2019-12-7
    发表于 2017-3-11 13:04:04 | 显示全部楼层
    学习啦!   
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /3 下一条

    Archiver|手机版|小黑屋|恩智浦技术社区

    GMT+8, 2025-7-21 12:40 , Processed in 0.086328 second(s), 22 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.

    快速回复 返回顶部 返回列表