904|3

2937

帖子

4

TA的资源

五彩晶圆(中级)

楼主
 

【瑞萨RA4E1评估板】IIC和OLED SSD1306测试 [复制链接]

IIC是一种常见的总线,这种总线的使用非常广泛,只要使用两条信号线就可以完成设备的连接,但是这种总线的编程要比较其它通讯方式复杂一些。RA4E1也是设计有IIC总线的,但是RA4E1有两种外设,一种是传统的专用IIC设备,一种是通用串行设备(SCI),本次测试的是专用IIC设备的主模式,具体设置如下:

 

通讯模式可以使用Fast模式,IIC的设备使用的是OLED 显示屏,控制器的接口使用IIC方式,地址使用0x3C,这个地址是由SSD1306控制的设置给定的,

   

IIC设备的测试很是不顺利,我尝试的很多次,都没有成功。使用了STM32的驱动方案修改了很多次都失败,其中的R_IIC_MASTER_Write()的中的最后参数,reset就是一直不能理解,直到看到一篇网络上的帖子才成功完成测试。下面主要的程序在oled.c中。

/*
 * oled.c
 *
 *  Created on: 2021?10?6?
 *      Author: Administrator
 */


#include "oled.h"
#include "oledfont.h"         
#include "hal_data.h"
#include "stdint.h"

uint8_t CMD_Data[]={
0xAE,
0x00,
0x10,
0x40,
0xB0,
0x81,
0xFF,
0xA1,
0xA6,
0xA8,
0x3F,
0xC8,
0xD3,
0x00,
0xD5,
0x80,
0xD8,
0x05,
0xD9,
0xF1,
0xDA,
0x12,
0xD8,
0x30,
0x8D,
0x14,
0xAF
};     

extern fsp_err_t err;
extern int  timeout_ms;
extern  i2c_master_event_t i2c_event ;

void WriteCmd(void)
{
    uint8_t i = 0;
    uint8_t ii[2]={0x00,0x00};

    for(i=0;i<27;i++)
    {
        ii[1]=CMD_Data[i];
        err = R_IIC_MASTER_Write(&g_i2c_master0_ctrl, ii, 0x02, true);
        assert(FSP_SUCCESS == err);



        /* Since there is nothing else to do, block until Callback triggers*/
        while ((I2C_MASTER_EVENT_TX_COMPLETE != i2c_event) && timeout_ms>0)
        {
            R_BSP_SoftwareDelay(1U, BSP_DELAY_UNITS_MICROSECONDS);
            timeout_ms--;
        }

        if (I2C_MASTER_EVENT_ABORTED == i2c_event)
        {
            __BKPT(0);
        }
        /* Read data back from the I2C slave */
        i2c_event = I2C_MASTER_EVENT_ABORTED;
        timeout_ms           = 100;


    }
}
    
    void OLED_WR_CMD(uint8_t cmd)
    {
        uint8_t ii[2]={0x00,0x00};

        ii[1]=cmd;
        err = R_IIC_MASTER_Write(&g_i2c_master0_ctrl, ii, 0x02, true);
        assert(FSP_SUCCESS == err);
        /* Since there is nothing else to do, block until Callback triggers*/
        //while ((I2C_MASTER_EVENT_TX_COMPLETE != i2c_event) && timeout_ms)
        while ((I2C_MASTER_EVENT_TX_COMPLETE != i2c_event) && timeout_ms>0)
        {
            R_BSP_SoftwareDelay(1U, BSP_DELAY_UNITS_MICROSECONDS);
            timeout_ms--;
        }

        if (I2C_MASTER_EVENT_ABORTED == i2c_event)
        {
            __BKPT(0);
        }
        /* Read data back from the I2C slave */
        i2c_event = I2C_MASTER_EVENT_ABORTED;
        timeout_ms           = 100;

    }

    void OLED_WR_DATA(uint8_t data)
    {
        uint8_t ii[2]={0x40,0x00};
        ii[1]=data;
        err = R_IIC_MASTER_Write(&g_i2c_master0_ctrl, ii, 0x02, true);
        assert(FSP_SUCCESS == err);
        /* Since there is nothing else to do, block until Callback triggers*/
        while ((I2C_MASTER_EVENT_TX_COMPLETE != i2c_event) && timeout_ms>0)
        {
            R_BSP_SoftwareDelay(1U, BSP_DELAY_UNITS_MICROSECONDS);
            timeout_ms--;
        }
        if (I2C_MASTER_EVENT_ABORTED == i2c_event)
        {
            __BKPT(0);
        }
        /* Read data back from the I2C slave */
        i2c_event = I2C_MASTER_EVENT_ABORTED;
        timeout_ms           = 100;
    }

void OLED_Clear(void)
{
    uint8_t i,n;
    for(i=0;i<8;i++)
    {
        OLED_WR_CMD(0xb0+i);//
        OLED_WR_CMD (0x00); //
        OLED_WR_CMD (0x10); //
        for(n=0;n<128;n++)
            OLED_WR_DATA(0);//
}

void OLED_Display_On(void)
{
    OLED_WR_CMD(0X8D);  //SET DCDC??
    OLED_WR_CMD(0X14);  //DCDC ON
    OLED_WR_CMD(0XAF);  //DISPLAY ON
}

void OLED_Display_Off(void)
{
    OLED_WR_CMD(0X8D);  //SET DCDC??
    OLED_WR_CMD(0X10);  //DCDC OFF
    OLED_WR_CMD(0XAE);  //DISPLAY OFF
}

void OLED_Set_Pos(uint8_t x, uint8_t y)
{
    OLED_WR_CMD(0xb0+y);
    OLED_WR_CMD(((x&0xf0)>>4)|0x10);
    OLED_WR_CMD(x&0x0f);
}



void OLED_On(void)
{
    uint8_t i,n;
    for(i=0;i<8;i++)
    {
        OLED_WR_CMD(0xb0+i);    
        OLED_WR_CMD(0x00);      
        OLED_WR_CMD(0x10);      
        for(n=0;n<128;n++)
            OLED_WR_DATA(1);
    } 
}
unsigned int oled_pow(uint8_t m,uint8_t n)
{
    unsigned int result=1;
    while(n--)result*=m;
    return result;
}


void OLED_ShowNum(uint8_t x,uint8_t y,unsigned int num,uint8_t len,uint8_t size2)
{
    uint8_t t,temp;
    uint8_t enshow=0;
    for(t=0;t<len;t++)
    {
        temp=(num/oled_pow(10,len-t-1))%10;
        if(enshow==0&&t<(len-1))
        {
            if(temp==0)
            {
                OLED_ShowChar(x+(size2/2)*t,y,' ',size2);
                continue;
            }else enshow=1;

        }
        OLED_ShowChar(x+(size2/2)*t,y,temp+'0',size2);
    }
}

void OLED_ShowChar(uint8_t x,uint8_t y,uint8_t chr,uint8_t Char_Size)
{
    unsigned char c=0,i=0;
        c=chr-' ';
        if(x>128-1)
        {
            x=0;
            y=y+2;
        }
        if(Char_Size ==16)
            {
            OLED_Set_Pos(x,y);
            for(i=0;i<8;i++)
                OLED_WR_DATA(F8X16[c*16+i]);
            OLED_Set_Pos(x,y+1);
            for(i=0;i<8;i++)
                OLED_WR_DATA(F8X16[c*16+i+8]);
            }
            else {
                OLED_Set_Pos(x,y);
                for(i=0;i<6;i++)
                OLED_WR_DATA(F6x8[c][i]);

            }
}


void OLED_ShowString(uint8_t x,uint8_t y,uint8_t *chr,uint8_t Char_Size)
{
    unsigned char j=0;
    while (chr[j]!='\0')
    {
        OLED_ShowChar(x,y,chr[j],Char_Size);
            x+=8;
        if(x>120){x=0;y+=2;}
            j++;
    }
}


void OLED_ShowCHinese(uint8_t x,uint8_t y,uint8_t no)
{
    uint8_t t,adder;
    OLED_Set_Pos(x,y);
    for(t=0;t<16;t++)
        {
                OLED_WR_DATA(Hzk1[2*no][t]);
                adder+=1;
     }
        OLED_Set_Pos(x,y+1);
    for(t=0;t<16;t++)
            {
                OLED_WR_DATA(Hzk1[2*no+1][t]);
                adder+=1;
      }
}


//--------------------------------------------------------------
// Prototype      : void OLED_DrawBMP(unsigned char x0,unsigned char y0,unsigned char x1,unsigned char y1,unsigned char BMP[]);
// Calls          :
// Parameters     : x0,y0 -- ?????(x0:0~127, y0:0~7); x1,y1 -- ?????(???)???(x1:1~128,y1:1~8)
// Description    : ??BMP??
//--------------------------------------------------------------
void OLED_DrawBMP(unsigned char x0,unsigned char y0,unsigned char x1,unsigned char y1,unsigned char BMP[])
{
    unsigned int j=0;
    unsigned char x,y;

  if(y1%8==0)
        y = y1/8;
  else
        y = y1/8 + 1;
    for(y=y0;y<y1;y++)
    {
        OLED_Set_Pos(x0,y);
    for(x=x0;x<x1;x++)
        {
        OLED_WR_DATA(BMP[j++]);
        }
    }
}

其中的程序是发送命令OLED_WR_CMD()和数据OLED_WR_DATA()函数,这个两个函数都是使用一次发送两个字节的程序,以前参考的发送数据都是一次多字节的版本,最成功的是一次产生了些乱码。

程序是这样的,

// Send data
void ssd1306_WriteData(uint8_t* buffer, size_t buff_size) {
	//HAL_I2C_Mem_Write(&SSD1306_I2C_PORT, SSD1306_I2C_ADDR, 0x40, 1, buffer, buff_size, HAL_MAX_DELAY);
	uint8_t iic_data=0x40;
	fsp_err_t  err = FSP_SUCCESS;

  err = R_IIC_MASTER_Write(&g_i2c_master0_ctrl, &iic_data, ONE_BYTE, false);
	//assert(FSP_SUCCESS == err);
	/* Since there is nothing else to do, block until Callback triggers*/
	while ((I2C_MASTER_EVENT_TX_COMPLETE != i2c_event) && timeout_ms>0)
	{
			R_BSP_SoftwareDelay(1U, BSP_DELAY_UNITS_MICROSECONDS);
			timeout_ms--;
	}
//	if (I2C_MASTER_EVENT_ABORTED == i2c_event)
//	{
//			__BKPT(0);
//	}
	/* Read data back from the I2C slave */
	i2c_event = I2C_MASTER_EVENT_ABORTED;
	timeout_ms           = 100;
	
	err = R_IIC_MASTER_Write(&g_i2c_master0_ctrl, buffer, buff_size, true);
	//assert(FSP_SUCCESS == err);
	/* Since there is nothing else to do, block until Callback triggers*/
	while ((I2C_MASTER_EVENT_TX_COMPLETE != i2c_event) && timeout_ms>0)
	{
			R_BSP_SoftwareDelay(1U, BSP_DELAY_UNITS_MICROSECONDS);
			timeout_ms--;
	}
//	if (I2C_MASTER_EVENT_ABORTED == i2c_event)
//	{
//			__BKPT(0);
//	}
	/* Read data back from the I2C slave */
	i2c_event = I2C_MASTER_EVENT_ABORTED;
	timeout_ms           = 100;
}

如果有知道原因的请给于指导,不知道为什么不行。其它的程序都没有成功。

本次的测试和以前的程序只有数据命令为一次两个字节。就可以顺利驱动程序,只是速度上要比较多字节的麻烦一些。猜测原因可能是中间的驱动多字节可能有什么IIC总线状态变换的原因。

 

后记

IIC测试是该板子最困难的测试,我前前后后花了大概快两周的时间才完的,但是也不是很完整,其中的多字节发送也是没有搞清什么原因。

最新回复

专用IIC设备和通用串行设备(SCI)有什么区别吗?感觉就是自己弄了一个标准接口出来了   详情 回复 发表于 2023-8-12 20:44
点赞 关注

回复
举报

6998

帖子

11

TA的资源

版主

沙发
 
恭喜通过测试!
 
 

回复

6502

帖子

10

TA的资源

版主

板凳
 

专用IIC设备和通用串行设备(SCI)有什么区别吗?感觉就是自己弄了一个标准接口出来了

点评

IIC的协议是比较复杂的,应该说专用的成熟一些,缺点是:不易扩展、不灵活。但是随着通用串口的设计越来越成熟,也会逐渐取代专用串口的。  详情 回复 发表于 2023-8-13 08:36
 
个人签名

在爱好的道路上不断前进,在生活的迷雾中播撒光引

 
 

回复

2937

帖子

4

TA的资源

五彩晶圆(中级)

4
 
秦天qintian0303 发表于 2023-8-12 20:44 专用IIC设备和通用串行设备(SCI)有什么区别吗?感觉就是自己弄了一个标准接口出来了

IIC的协议是比较复杂的,应该说专用的成熟一些,缺点是:不易扩展、不灵活。但是随着通用串口的设计越来越成熟,也会逐渐取代专用串口的。

 
 
 

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

查找数据手册?

EEWorld Datasheet 技术支持

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

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

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

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

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

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