RT_Thread学习笔记(6) OLED驱动移植 IIC

STM32F103C8T6移植RTT驱动实现SSD1306 OLED IIC通信

RT THREAD OLED IIC驱动移植

1.硬件环境

在这里插入图片描述

MCU:STM32F103C8T6

OLED:SSD1306 0.96

关键用u8g2的话内存开销太大了,所以正好学习一下IIC驱动


2.程序开发

2.1 开启IIC

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HTMgc0wO-1625904982998)(https://note.youdao.com/yws/res/2/WEBRESOURCE205552f156293d564bed747aa3a47f22)][外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PVvQnVzm-1625904982999)(https://note.youdao.com/yws/res/d/WEBRESOURCE732f85cd041e92ec3c1cd3db725069bd)]
在这里插入图片描述

记得下载后在MSH中查看是否真的开启了IIC总线

2.2程序移植

首先需要明确一点 rtt和传统驱动的区别

rtthread把地址和读写位是分开的,底层发送的数据是将地址左移1位再或上读写位,如果你发0xa0,左移后再或上写,这个数据不对了,应该发0x50左移后变成0xa0再或上写就对了,相关的解释网址如下:

https://club.rt-thread.org/ask/question/8065.html

其实我当时在驱动AT24C256的时候是十分困惑的,为什么在文档里写的0xa0为什么在程序中要设置为0x50,直到我自己真正动手驱动的时候才知道了原因

所以既然OLED的从机地址是0x78,对应0111 1000

那我们右移一位 0011 1100变成0x3c


然后在整个驱动的过程中最终要的还是写指令的操作,代码如下:

static rt_err_t WriteCmd(struct rt_i2c_bus_device *bus, rt_uint8_t data)
{
   
   
    rt_uint8_t buf[2];
    struct rt_i2c_msg msgs;

    buf[0] = 0x00;
    buf[1] = data;


    msgs.addr = OLED_ADDR;
    msgs.flags = RT_I2C_WR;
    msgs.buf = buf;
    msgs.len = 2;

    /* 调用I2C设备接口传输数据 */
    if (rt_i2c_transfer(bus, &msgs, 1) == 1)
    {
   
   
        return RT_EOK;
    }
    else
    {
   
   
        return -RT_ERROR;
    }
}

static rt_err_t WriteDat(struct rt_i2c_bus_device *bus, rt_uint8_t data)
{
   
   
    rt_uint8_t buf[2];
    struct rt_i2c_msg msgs;

    buf[0] = 0x40;
    buf[1] = data;


    msgs.addr = OLED_ADDR;
    msgs.flags = RT_I2C_WR;
    msgs.buf = buf;
    msgs.len = 2;

    /* 调用I2C设备接口传输数据 */
    if (rt_i2c_transfer(bus, &msgs, 1) == 1)
    {
   
   
        return RT_EOK;
    }
    else
    {
   
   
        return -RT_ERROR;
    }
}

初始化函数

void OLED_INIT(void)
{
   
   
    rt_thread_mdelay(100);

    WriteCmd(i2c_bus,0xAE); //display off
    WriteCmd(i2c_bus,0x20); //Set Memory Addressing Mode
    WriteCmd(i2c_bus,0x10); //00,Horizontal Addressing Mode;01,Vertical Addressing Mode;10,Page Addressing Mode (RESET);11,Invalid
    WriteCmd(i2c_bus,0xb0); //Set Page Start Address for Page Addressing Mode,0-7
    WriteCmd(i2c_bus,0xc8); //Set COM Output Scan Direction
    WriteCmd(i2c_bus,0x00); //---set low column address
    WriteCmd(i2c_bus,0x10); //---set high column address
    WriteCmd(i2c_bus,0x40); //--set start line address
    WriteCmd(i2c_bus,0x81); //--set contrast control register
    WriteCmd(i2c_bus,0xff); //亮度调节 0x00~0xff
    WriteCmd(i2c_bus,0xa1); //--set segment re-map 0 to 127
    WriteCmd(i2c_bus,0xa6); //--set normal display
    WriteCmd(i2c_bus,0xa8); //--set multiplex ratio(1 to 64)
    WriteCmd(i2c_bus,0x3F); //
    WriteCmd(i2c_bus,0xa4); //0xa4,Output follows RAM content;0xa5,Output ignores RAM content
    WriteCmd(i2c_bus,0xd3); //-set display offset
    WriteCmd(i2c_bus,0x00); //-not offset
    WriteCmd(i2c_bus,0xd5); //--set display clock divide ratio/oscillator frequency
    WriteCmd(i2c_bus,0xf0); //--set divide ratio
    WriteCmd(i2c_bus,0xd9); //--set pre-charge period
    WriteCmd(i2c_bus,0x22); //
    WriteCmd(i2c_bus,0xda); //--set com pins hardware configuration
    WriteCmd(i2c_bus,0x12);
    WriteCmd(i2c_bus,0xdb); //--set vcomh
    WriteCmd(i2c_bus,0x20); //0x20,0.77xVcc
    WriteCmd(i2c_bus,0x8d); //--set DC-DC enable
    WriteCmd(i2c_bus,0x14); //
    WriteCmd(i2c_bus,0xaf); //--turn on oled panel

}

下载程序后看到一片花就对了

其余相关函数都放进来了

//全屏填充
void OLED_FILL(unsigned char fill_data)
{
   
   
    unsigned char m,n;
    for(m=0;m<8;m++){
   
   
        WriteCmd(i2c_bus,0xb0+m);
        WriteCmd(i2c_bus,0x00);
        WriteCmd(i2c_bus,0x10);

        for(n=0;n<128;n++){
   
   
            WriteDat(i2c_bus,fill_data);
        }
    }
}

//OLED清屏
void OLED_CLS(void)
{
   
   
    OLED_FILL(0x00);
}




void OLED_SetPos(unsigned char x, unsigned char y) //设置起始点坐标
{
   
   
    WriteCmd(i2c_bus,0xb0+y);
    WriteCmd(i2c_bus,((x&0xf0)>>4)|0x10);
    WriteCmd(i2c_bus,(x&0x0f)|0x01);
}


const unsigned char F6x8[][6] =
{
   
   
    {
   
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00},// sp
    {
   
   0x00, 0x00, 0x00, 0x2f, 0x00, 0x00},// !
    {
   
   0x00, 0x00, 0x07, 0x00, 0x07, 0x00},// "
    {
   
   0x00, 0x14, 0x7f, 0x14, 0x7f, 0x14},// #
    {
   
   0x00, 0x24, 0x2a, 0x7f, 0x2a, 0x12},// $
    {
   
   0x00, 0x62, 0x64, 0x08, 0x13, 0x23},// %
    {
   
   0x00, 0x36, 0x49, 0x55, 0x22, 0x50},// &
    {
   
   0x00, 0x00, 0x05, 0x03, 0x00, 0x00},// '
    {
   
   0x00, 0x00, 0x1c, 0x22, 0x41, 0x00},// (
    {
   
   0x00, 0x00, 0x41, 0x22, 0x1c, 0x00},// )
    {
   
   0x00, 0x14, 0x08, 0x3E, 0x08, 0x14},// *
    {
   
   0x00, 0x08, 0x08, 0x3E, 0x08, 0x08},// +
    {
   
   0x00, 0x00, 0x00, 0xA0, 0x60, 0x00},// ,
    {
   
   0x00, 0x08, 0x08, 0x08, 0x08, 0x08},// -
    {
   
   0x00, 0x00, 0x60, 0x60, 0x00, 0x00},// .
    {
   
   0x00, 0x20, 0x10, 0x08, 0x04, 0x02},// /
    {
   
   0x00, 0x3E, 0x51, 0x49, 0x45, 0x3E},// 0
    {
   
   0x00, 0x00, 0x42, 0x7F, 0x40, 0x00},// 1
    {
   
   0x00, 0
RT-Thread作品秀】OLED显示演示作者:谢博翔 概述初步体验 RT-Thread出的RTT核心版 ART-Pi,使用RTT用OLED显示 开发环境硬件:ART-Pi RT-Thread版本:4.0.3 开发工具及版本:RT-Thread Studio 2.0 RT-Thread使用情况概述软件包:使用u8g2 U8g2是嵌入式设备的单色图形库,目前支持单色OLED和LCD,包括以下控制器:SSD1305,SSD1306等 选用u8g2的原因: U8g2库平台支持性好,基本上支持绝大部分开发板,并且RTT已经有对应的软件包 U8g2库显示控制器支持性好,基本上市面上的OLED都完美支持; U8g2库API众多,特别支持了中文,支持了不同字体,这是一个对于开发者俩说不小的福利 硬件框架软件框架说明添加u8g2软件包,修改I2C接口和显示文字,编译、烧录。运行程序,打开监视串口:输入shell:u8g2_ssd1306_12864_sw_i2c_example 软件模块说明修改I2C接口 输入显示的内容 定义 RT_USINF_PIN 演示效果视频地址比赛感悟应改要多学习,多认真思考,多动手实践,不应该只停留在基础的实践,应该多coding,而且掌握好时间; 未来应该是RTOS和Linux的天下,现在 RT-Thread开源,是一件很好的事情;虽然国内开源的RTOS的已经好几家, 但现在看来,生态做的又好,软件又好用的,可能 RT-Thread 是最好的! 也感谢电路城这次的活动,以前对电路城并不是很了解,这次上传资料,简单看了下,感觉收获多多,也希望 后面能在这里学到和提供一些东西~ 加油
评论 8
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值