2370|2

270

帖子

0

TA的资源

一粒金砂(高级)

楼主
 

RTT&瑞萨高性能 CPK-RA6M4 开发板测评——SPI驱动OLED [复制链接]

一、硬件

1、OLED引脚介绍

OLED引脚,是7针SPI模式。

1). GND 电源地

2). VCC 电源正(3~5.5V)

3). D0 OLED 的 D0 脚,在 SPI 和 IIC 通信中为时钟管脚

4). D1 OLED 的 D1 脚,在 SPI 和 IIC 通信中为数据管脚

5). RES OLED 的 RES#脚,用来复位(低电平复位)

6). DC OLED 的 D/C#E 脚,数据和命令控制管脚

如图所示:实物引脚。

关于OLED的显示原理就不介绍。

2、接线

1)、VCC接板载3.3V引脚,与板子共地

2)、把SPI0的相应时钟SCLK、数据MOSI关机与OLED的时钟和数据管脚,使用杜邦线连接起来,再使用其他引脚,作为普通管脚,控制OLED的片选CS、复位RES、DC引脚。

二、软件操作

1、RA Smart Configurator操作

1)、使用瑞萨灵活配置软件添加SPI0的复用引脚相关的时钟与MOSI引脚,注意,程序中是软件配置片选,因此SPI0硬件片选引脚CS 配置为普通引脚(P703)。同时设置P406(对应OLED的DC)、P405(对应OLED的RES)为普通输出引脚。

2)、设置三个普通引脚模式为输出模式,并且设置为初始化为高电平

3)、添加SPI的配置,设置SPI0的回调函数为spi0_callback。其他都默认,可以在对应的参数设置中,设置SPI工作模式、速率、相位、极性等。另外也可以直接在RTThread中修改相应的配置。

2、RTThread-Studio操作

1)、添加RTThread对RA6M4支持的SPI驱动。

2)、使能SPI0驱动。

3、代码

1)、OLED驱动代码

/*
 * Copyright (c) 2006-2021, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2022-05-01     LD       the first version
 */
#include "OLED.h"
#include "oledfont.h"
#include <rtthread.h>
#include <stdio.h>
#include <drv_spi.h>
//static struct rt_spi_device spi_dev_lcd;

/*OLED段码分布
正常
(page0)      SEG0-SEG128
                    COM0
                     |
                    COM7

反置
(page0)       SEG128-SEG0
                    COM63
                     |
                    COM56

写命令,其实是写寄存器
*/
static struct rt_spi_device spi_dev_oled;

static int rt_hw_oled_config(void)
{
    char user_data[] = {1};
    if (rt_spi_bus_attach_device(&spi_dev_oled, "oled", "spi0", user_data) != RT_EOK)
        return -RT_ERROR;

    /* config spi */
    {
        struct rt_spi_configuration cfg;
        cfg.data_width = 8;
        cfg.mode = RT_SPI_MASTER | RT_SPI_MODE_0 | RT_SPI_MSB;
        cfg.max_hz = 5 * 1000 * 1000; /* 42M,SPI max 42MHz,lcd 4-wire spi */

        rt_spi_configure(&spi_dev_oled, &cfg);
    }

    rt_pin_mode(OLED_DC, PIN_MODE_OUTPUT);
    rt_pin_mode(OLED_RES, PIN_MODE_OUTPUT);

    return RT_EOK;
}


/****************************************************************************
* 名 称:void OLED_Init(void)
* 功 能:OLED初始化
* 入口参数:无
* 出口参数:无
* 说 明:参照上电序列初始化(24/40)
****************************************************************************/
int OLED_Init(void)
{
    rt_hw_oled_config();

    OLED_CS_High;
    //复位OLED
    OLED_RST_High;
    rt_thread_mdelay(200);
    OLED_RST_Low;
    rt_thread_mdelay(200);
    OLED_RST_High;

    OLED_Write_Operate(OLED_Mode_Cmd,0xAE); //关闭OLED
    OLED_Write_Operate(OLED_Mode_Cmd,0x00); //设置列低位地址
    OLED_Write_Operate(OLED_Mode_Cmd,0x10); //设置列高位地址
    OLED_Write_Operate(OLED_Mode_Cmd,0x40); //设置起始行地址及映射RAM显示起始行 (0x00~0x3F)
    OLED_Write_Operate(OLED_Mode_Cmd,0xB0); //设置页地址
    OLED_Write_Operate(OLED_Mode_Cmd,0x81); //对比度设置
    OLED_Write_Operate(OLED_Mode_Cmd,0xCF); //Set SEG Output Current Brightness

    OLED_Write_Operate(OLED_Mode_Cmd,0xA1); //Set SEG/Column Mapping     0xa0左右反置 0xa1正常
    OLED_Write_Operate(OLED_Mode_Cmd,0xA6); //
    OLED_Write_Operate(OLED_Mode_Cmd,0xA8); //设置驱动路数(1 to 64)
    OLED_Write_Operate(OLED_Mode_Cmd,0x3F); //*duty = 1/64*/
    OLED_Write_Operate(OLED_Mode_Cmd,0xC8); //0xc0上下反置 0xc8正常
    OLED_Write_Operate(OLED_Mode_Cmd,0xD3); //设置显示偏移(0x00~0x3F)
    OLED_Write_Operate(OLED_Mode_Cmd,0x00); //not offset
    OLED_Write_Operate(OLED_Mode_Cmd,0xD5); //--set Display clock divide ratio/oscillator frequency
    OLED_Write_Operate(OLED_Mode_Cmd,0x80); //--set divide ratio, Set Clock as 100 Frames/Sec
    OLED_Write_Operate(OLED_Mode_Cmd,0xD9); //*set pre-charge period*/
    OLED_Write_Operate(OLED_Mode_Cmd,0Xf1); //Set Pre-Charge as 15 Clocks & Discharge as 1 Clock
    OLED_Write_Operate(OLED_Mode_Cmd,0xDA); //*set COM pins*/
    OLED_Write_Operate(OLED_Mode_Cmd,0x12); //
    OLED_Write_Operate(OLED_Mode_Cmd,0xdb); //*set vcomh*/
    OLED_Write_Operate(OLED_Mode_Cmd,0x40); //Set VCOM Deselect Level
    /**/
    OLED_Write_Operate(OLED_Mode_Cmd,0x20); //设置存储模式(0x00,0x02,0x01)
    OLED_Write_Operate(OLED_Mode_Cmd,0x02); //页地址模式

    OLED_Write_Operate(OLED_Mode_Cmd,0x8d); //*set charge pump disable*/
    OLED_Write_Operate(OLED_Mode_Cmd,0x14); //--set(0x10) disable
    /**/
    OLED_Write_Operate(OLED_Mode_Cmd,0xA4); //显示开启(A4,显示,A5无显示)
    OLED_Write_Operate(OLED_Mode_Cmd,0xA6); //背景正反向显示(0xa6,正显,0xa7,反显)


    OLED_Display_Clear();                                       //清屏
    OLED_Write_Operate(OLED_Mode_Cmd,0xAF); //打开显示

    return 0;
}
INIT_COMPONENT_EXPORT(OLED_Init);

/****************************************************************************
* 名 称:u8 SPI1_WriteReadByte(u8 Data)
* 功 能:SPI1读写一个字节
* 入口参数:无
* 出口参数:接收的数据
* 返回值  :0,发送接收超时,1成功
* 说 明:无
****************************************************************************/
uint8_t g_master_rx_buff[6] = {0};
static rt_err_t SPI0_WriteReadByte(const rt_uint8_t Data)
{
    rt_size_t len = 0;

    rt_spi_transfer(&spi_dev_oled, (const void *)&Data, NULL, 1);
    if (len != 1)
    {
        LOG_I("ssd1306_write_data error. %d", len);
        return -RT_ERROR;
    }
    else
    {
        return RT_EOK;
    }
    return RT_EOK;
}

/****************************************************************************
* 名 称:u8 OLED_Write_Byte(u8 data)
* 功 能:OLED写一个字节
* 入口参数:无
* 出口参数:接收的数据
* 返回值  :0失败,1成功
* 说 明:无
****************************************************************************/
u8 OLED_Write_Byte(u8 data)
{
    if(SPI0_WriteReadByte(data))
        return 0;
    else
        return 1;
}


/****************************************************************************
* 名 称:void OLED_Write_Operate(u8 mode,u8 data)
* 功 能:OLED写操作
* 入口参数:模式,数据
* 出口参数:无
* 返回值  :无
* 说 明:无
****************************************************************************/
void OLED_Write_Operate(u8 mode,u8 data)
{
    OLED_CS_Low;

    if(mode)
    {
        OLED_Write_Data;
    }
    else
    {
        OLED_Write_Cmd;
    }

    OLED_Write_Byte(data);

    OLED_CS_High;
}


/****************************************************************************
* 名 称:void OLED_Display_Clear(void)
* 功 能:OLED清屏
* 入口参数:无
* 出口参数:无
* 返回值  :无
* 说 明:无
****************************************************************************/
void OLED_Display_Clear(void)
{
    u8 page = 0;
    u8 i=0;
    OLED_CS_Low;

    for(page=0;page < 8; page++)
    {
        OLED_Write_Operate(OLED_Mode_Cmd,0xB0+page);//设置页地址
        OLED_Write_Operate(OLED_Mode_Cmd,0x00);     //设置显示位置-列低地址
        OLED_Write_Operate(OLED_Mode_Cmd,0x10);     //设置显示位置-列高地址

        for(i = 0;i< 128; i++)
        {
            OLED_Write_Operate(OLED_Mode_Data,0x00);  //清屏
        }
    }
}



/****************************************************************************
* 名 称:void OLED_Set_Positon(void)
* 功 能:设置显示坐标
* 入口参数:x,y
* 出口参数:无
* 返回值  :无
* 说 明:无
****************************************************************************/
void OLED_Set_Positon(u8 x,u8 y)
{

    OLED_Write_Operate(OLED_Mode_Cmd,0xB0 + y);                             //设置页地址
    OLED_Write_Operate(OLED_Mode_Cmd,((x & 0xf0) >>4 ) | 0x10); //设置列高四位地址
    OLED_Write_Operate(OLED_Mode_Cmd,(x & 0x0f) | 0x01);          //设置列低四位地址

}


/****************************************************************************
* 名 称:void OLED_Display_on(void)
* 功 能:显示打开
* 入口参数:无
* 出口参数:无
* 返回值  :无
* 说 明:无
****************************************************************************/
void OLED_Display_on(void)
{

    OLED_Write_Operate(OLED_Mode_Cmd,0x8d); //写充电泵寄存器
    OLED_Write_Operate(OLED_Mode_Cmd,0x14); //打开充电泵
    OLED_Write_Operate(OLED_Mode_Cmd,0xAF); //打开OLED显示

}


/****************************************************************************
* 名 称:void OLED_Display_offvoid)
* 功 能:显示关闭
* 入口参数:无
* 出口参数:无
* 返回值  :无
* 说 明:无
****************************************************************************/
void OLED_Display_off(void)
{

    OLED_Write_Operate(OLED_Mode_Cmd,0x8d); //写充电泵寄存器
    OLED_Write_Operate(OLED_Mode_Cmd,0x10); //关闭充电泵
    OLED_Write_Operate(OLED_Mode_Cmd,0xAE); //关闭OLED显示

}


/****************************************************************************
* 名 称:void OLED_Display_onechar(u8 x,u8 y,u8 character,u8 size)
* 功 能:显示单个字符
* 入口参数:
x ,y坐标位置
character 字符
size 字号大小
* 出口参数:无
* 返回值  :无
* 说 明:无
****************************************************************************/
void OLED_Display_onechar(u8 x,u8 y,u8 character,u8 size)
{
    u8 c=0,i=0;
    c = character-' ';
    if(x > MAX_COLUMN - 1)
    {
        x= 0;
        if(size == SIZE8)
        {
            y = y+1;
        }
        if(size == SIZE16)
        {
            y = y+2;
        }
    }
    if(size == SIZE16)
    {
        OLED_Set_Positon(x,y);
        for( i =0;i< 8; i++)
        {
            OLED_Write_Operate(OLED_Mode_Data,F8X16[c*16 + i]);
        }
        OLED_Set_Positon(x,y+1);
        for( i =0;i< 8; i++)
        {
            OLED_Write_Operate(OLED_Mode_Data,F8X16[c*16 + i+8]);
        }
    }
    else
    {
        OLED_Set_Positon(x,y+1);
        for( i =0;i< 6; i++)
        {
            OLED_Write_Operate(OLED_Mode_Data,F6x8[c]);
        }
    }
}


/****************************************************************************
* 名 称:void OLED_Display_string(u8 x,u8 y,u8 *str,u8 size)
* 功 能:显示字符串
* 入口参数:
x ,y坐标位置
str 字符串
size 字号大小
* 出口参数:无
* 返回值  :无
* 说 明:无
****************************************************************************/
void OLED_Display_string(u8 x,u8 y,u8 *str,u8 size)
{
    u8 i=0;
    while(str!='\0')
    {
        OLED_Display_onechar(x,y,str,size);
        x += 8;
        if(x > 120)
        {
            x = 0;
            y += 2;
        }
        i++;
    }
}


/****************************************************************************
* 名 称:void OLED_Display_Chinese(u8 x,u8 y,u8 Sno)
* 功 能:显示单个字符
* 入口参数:
x ,y坐标位置
Sno 表示汉字数组中一个字的码所占的序号
* 出口参数:无
* 返回值  :无
* 说 明:无
****************************************************************************/
void OLED_Display_Chinese(u8 x,u8 y,u8 Sno)
{
    u8 adder=0,i=0;
    OLED_Set_Positon(x,y);
    for(i = 0;i< 16;i++)
    {
        OLED_Write_Operate(OLED_Mode_Data,Hzk[2*Sno]);
        adder += 1;
    }
  OLED_Set_Positon(x,y+1);
    for(i = 0;i< 16;i++)
    {
        OLED_Write_Operate(OLED_Mode_Data,Hzk[2*Sno+1]);
        adder += 1;
    }
}



/****************************************************************************
* 名 称:u32 OLED_POW(u8 m, u8 n)
* 功 能:m的n次方
* 入口参数:
m为底数,n为指数
* 出口参数:无
* 返回值  :无
* 说 明:无
****************************************************************************/
u32 OLED_POW(u8 m, u8 n)
{
    u32 result=1;
    while(n--)
    {
        result *= m;
    }
    return result;
}


/****************************************************************************
* 名 称:void OLED_Display_Num(u8 x,u8 y,u32 num, u8 Len,u8 size)
* 功 能:显示单个字符
* 入口参数:
x ,y坐标位置
Sno 表示汉字数组中一个字的码所占的序号
* 出口参数:无
* 返回值  :无
* 说 明:无
****************************************************************************/
void OLED_Display_Num(u8 x,u8 y,u32 num, u8 len,u8 size)
{
    u8 i=0;
    u8 endisplay=0;
    u8 temp=0;
    for(i = 0;i < len;i++)
    {
        temp = (num / (OLED_POW(10,len-i-1)))%10;
        if(endisplay == 0 && i < len-1)
        {
            if(temp == 0)
            {
                OLED_Display_onechar(x + (size / 2) * i,y,' ',size);
                continue;
            }
            else
            {
                endisplay = 1;
            }
        }
        OLED_Display_onechar(x + (size / 2) * i,y,temp + '0',size);
    }
}


/****************************************************************************
* 名 称:void OLED_Display_Picture(u8 x0, u8 y0, u8 x1, u8 y1, u8 BMP[])
* 功 能:显示一张图片
* 入口参数:
x0 ,y0,x1,y1图片的大小
BMP[] 图片的码
* 出口参数:无
* 返回值  :无
* 说 明:无
****************************************************************************/
void OLED_Display_Picture(u8 x0, u8 y0, u8 x1, u8 y1, u8 BMP[])
{
    u8 i=0;
    u8 x,y;
  if(y1 == 8)
  {
   y= y1/ 8;
    }
    else
    {
        y = y1/ 8 + 1;
    }
    for(y = y0;y < y1;y++)
    {
        OLED_Set_Positon(x0,y);
        for(x = x0;x< x1; x++)
        {
            OLED_Write_Operate(OLED_Mode_Data,BMP[i++]);
        }
    }
}

 

2)、hal_entry函数


void hal_entry(void)
{
        rt_kprintf("\nHello RT-Thread!\n");
        OLED_Display_string(0,0,"CPK-RA6M4 Board Evaluation",SIZE8);
        while (1)
        {
            rt_thread_mdelay(50);
            breathing_light();
        }
}

测试现象

最后,整个代码工程会在最后一篇测评中附上git链接。

最新回复

nmg
要是现在已经上传了,可以单独给出这个工程师文件夹链接   详情 回复 发表于 2022-5-23 15:40
点赞 关注

回复
举报

7452

帖子

2

TA的资源

五彩晶圆(高级)

沙发
 

全是代码,谢谢分享!

 
个人签名

默认摸鱼,再摸鱼。2022、9、28

 

回复

5220

帖子

236

TA的资源

管理员

板凳
 

要是现在已经上传了,可以单独给出这个工程师文件夹链接

加EE小助手好友,
入技术交流群
EE服务号
精彩活动e手掌握
EE订阅号
热门资讯e网打尽
聚焦汽车电子软硬件开发
认真关注技术本身
 
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表