73|2

2939

帖子

4

TA的资源

五彩晶圆(中级)

楼主
 

【MCXN947开发板测评】I2C总线设备的兼容性测试 [复制链接]

1、测试简介

测试如何使用 CMSIS i2c 驱动作为主机,通过I2C总线控制SSD1306 OLED显示图像。通过轮询方式进行I2C控制通讯。

硬件要求:
Type-C USB 线
FRDM - MCXN947 开发板

SSD1306 OLED屏
个人计算机

软件:

GCC ARM 嵌入式 13.2.1

Putty串口终端

2、设置与程序

OLED屏需按以下方式连接:
主机(LPI2C2)    连接    SSD1306
开发板                   OLED 
SCL     J2 引脚 20   <----------> SCL   
SDA     J2 引脚 18   <----------> SDA 
GND    J3 引脚 14  <----------> GND

P3.3V  J3 引脚 4  <----------> 3.3V

/*
 * Copyright 2017 NXP
 * All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

/*  Standard C Included Files */
#include <stdio.h>
#include <string.h>
#include "pin_mux.h"
#include "clock_config.h"
#include "board.h"
#include "fsl_debug_console.h"
#include "fsl_lpi2c.h"
#include "fsl_SSD1306_I2C.h" 

/*******************************************************************************
 * Definitions
 ******************************************************************************/
//#define EXAMPLE_I2C_MASTER_BASE (LPI2C2_BASE)

#define LPI2C_MASTER_CLOCK_FREQUENCY CLOCK_GetLPFlexCommClkFreq(2u)

#define WAIT_TIME 10U

//#define EXAMPLE_I2C_MASTER ((LPI2C_Type *)EXAMPLE_I2C_MASTER_BASE)

#define LPI2C_MASTER_SLAVE_ADDR_7BIT 0x3CU
#define LPI2C_BAUDRATE               100000U
#define LPI2C_DATA_LENGTH            33U

/*******************************************************************************
 * Prototypes
 ******************************************************************************/

/*******************************************************************************
 * Variables
 ******************************************************************************/


uint8_t g_master_txBuff[LPI2C_DATA_LENGTH];
uint8_t g_master_rxBuff[LPI2C_DATA_LENGTH];

/*******************************************************************************
 * Code
 ******************************************************************************/

/*!
 * [url=home.php?mod=space&uid=159083]@brief[/url] Main function
 */
int main(void)
{
    lpi2c_master_config_t masterConfig;
    //status_t reVal        = kStatus_Fail;
    //uint8_t deviceAddress = 0x01U;
    size_t txCount        = 0xFFU;

    /* attach FRO 12M to FLEXCOMM4 (debug console) */
    CLOCK_SetClkDiv(kCLOCK_DivFlexcom4Clk, 1u);
    CLOCK_AttachClk(BOARD_DEBUG_UART_CLK_ATTACH);

    /* attach FRO 12M to FLEXCOMM2 */
    CLOCK_SetClkDiv(kCLOCK_DivFlexcom2Clk, 1u);
    CLOCK_AttachClk(kFRO12M_to_FLEXCOMM2);

    BOARD_InitBootPins();
    BOARD_InitBootClocks();
    BOARD_InitDebugConsole();

    PRINTF("\r\nLPI2C board2board polling example -- Master transfer.\r\n");

    
    
    LPI2C_MasterGetDefaultConfig(&masterConfig);

    /* Change the default baudrate configuration */
    masterConfig.baudRate_Hz = LPI2C_BAUDRATE;

    /* Initialize the LPI2C master peripheral */
    LPI2C_MasterInit(EXAMPLE_I2C_MASTER, &masterConfig, LPI2C_MASTER_CLOCK_FREQUENCY);
  

    /* Initialize the SSD1306 display*/
    OLED_Init();
    OLED_Refresh();
    OLED_Clear();
   
    /*Print welcome message*/
    OLED_Copy_Image(&logo_nxp[0], sizeof(logo_nxp));
    OLED_Refresh();

    OLED_Set_Text(10, 52, kOLED_Pixel_Set, "MCXN947 I2C", 2);
    OLED_Refresh();
    PRINTF("\r\nEnd of LPI2C example .\r\n");
    
    while (1)
    {
    }
}

OLED SSD1306驱动程序fsl_SSD1306_I2C.c


/*----esta modificada para usar el I2C1, en caso de utilizar otro cambiar todo
 * lo que diga I2C1 por la base del I2C usado--- */
/*---- BASADO EN fsl_SSD1306.h para SPI de NXP ------*/

#include "fsl_gpio.h"
#include "fsl_lpi2c.h"
#include <fsl_SSD1306_I2C.h>

// #include "fsl_Systick_Delay.h"

/*******************************************************************************
 * Definitions
 ******************************************************************************/

/*******************************************************************************
 * Variables
 ******************************************************************************/
/*! @brief OLED buffer */
static uint8_t OLED_Buffer[(OLED_WIDTH * OLED_HEIGHT) / 8];

/*******************************************************************************
 * Code
 ******************************************************************************/

static void OLED_Command(uint8_t Cmd) {

  lpi2c_master_transfer_t xfer = {0};

	xfer.data = (uint8_t *)&Cmd;
	xfer.dataSize = sizeof(Cmd);
	xfer.flags = kLPI2C_TransferDefaultFlag;
	xfer.slaveAddress = SSD1306_ADDRESS_1;
	xfer.direction = kLPI2C_Write;
	xfer.subaddress = 0x0;
	xfer.subaddressSize = 1;

	LPI2C_MasterTransferBlocking(EXAMPLE_I2C_MASTER, &xfer);

}

static void OLED_Data(uint8_t *Data) {
  lpi2c_master_transfer_t xfer = {0};

	/*Start Transfer*/
	xfer.data = Data;
	xfer.dataSize = sizeof(OLED_Buffer);
	xfer.flags = kLPI2C_TransferDefaultFlag;
	xfer.slaveAddress = SSD1306_ADDRESS_1;
	xfer.direction = kLPI2C_Write;
	xfer.subaddress = 0x40;
	xfer.subaddressSize = 1;

	LPI2C_MasterTransferBlocking(EXAMPLE_I2C_MASTER, &xfer);

}

static void OLED_Reset(void) {
  OLED_Command(OLED_DISPLAYON);
  //	for(int i=0; i<5000; i++);					//delay
  //1ms
  //  SysTick_Delay_ms(1);
  OLED_Command(OLED_DISPLAYOFF);
  //	for(int i=0; i<5000; i++);					//delay
  //1ms
  //  SysTick_Delay_ms(1);
  OLED_Command(OLED_DISPLAYON);
  //	for(int i=0; i<50000; i++);					//delay
  //10ms
  //  SysTick_Delay_ms(10);
}

static void OLED_Config_Display(void) {

  OLED_Reset();

  // Turn the OLED Display off
  OLED_Command(OLED_DISPLAYOFF);

  // Configure the display for 128x64 pixels, KS0108 mode
  OLED_Command(OLED_SETDISPLAYCLOCKDIV);
  OLED_Command(0x80);
  OLED_Command(OLED_SETMULTIPLEX);
  OLED_Command(OLED_HEIGHT - 1); // LCD Height
  OLED_Command(OLED_SETDISPLAYOFFSET);
  OLED_Command(0x0);
  OLED_Command(OLED_SETSTARTLINE | 0x0);
  OLED_Command(OLED_CHARGEPUMP);
  OLED_Command(0x14); // Use 3.3V supply to generate high voltage supply
  OLED_Command(OLED_MEMORYMODE);
  OLED_Command(0x00);
  OLED_Command(OLED_SEGREMAP | 0x1);
  OLED_Command(OLED_COMSCANDEC);
  OLED_Command(OLED_SETCOMPINS);
  OLED_Command(0x12);
  OLED_Command(OLED_SETCONTRAST);
  OLED_Command(0xCF);
  OLED_Command(OLED_SETPRECHARGE);
  OLED_Command(0xF1);
  OLED_Command(OLED_SETVCOMDETECT);
  OLED_Command(0x40);
  OLED_Command(OLED_DISPLAYALLON_RESUME);
  OLED_Command(OLED_NORMALDISPLAY);
  OLED_Command(OLED_DEACTIVATE_SCROLL);

  OLED_Command(OLED_COLUMNADDR);
  OLED_Command(0);
  OLED_Command(OLED_WIDTH - 1);
  OLED_Command(OLED_PAGEADDR);
  OLED_Command(0);
  OLED_Command(OLED_HEIGHT / 8 - 1);

  // Turn the OLED display on!
  OLED_Command(OLED_DISPLAYON);

  OLED_Command(OLED_SETLOWCOLUMN | 0x0);  // low col = 0
  OLED_Command(OLED_SETHIGHCOLUMN | 0x0); // hi col = 0
  OLED_Command(OLED_SETSTARTLINE | 0x0);  // line #0
}

static int OLED_Render_Char(uint8_t X_axis, uint8_t Y_axis, uint8_t SC,
                            int8_t String, uint8_t Scale) {

  uint8_t px, py;
  uint16_t start_pos;

  if ((X_axis >= OLED_WIDTH) || (Y_axis >= OLED_HEIGHT)) {
    return 1;
  }
  if (String > 127) {
    return 2;
  }
  if (Scale > 3) {
    return 3;
  }

  start_pos = ((uint8_t)String) * 7; // Characters have a 7 row offset
  for (px = 0; px < 5; px++) {
    for (py = 0; py < 7; py++) {
      if ((font5x7[start_pos + py] >> (7 - px)) & 1) {
        switch (Scale) {
        case 3:
          OLED_Set_Pixel(X_axis + (px * Scale), Y_axis + (py * Scale), SC);
          OLED_Set_Pixel(X_axis + (px * Scale) + 1, Y_axis + (py * Scale), SC);
          OLED_Set_Pixel(X_axis + (px * Scale) + 2, Y_axis + (py * Scale), SC);
          OLED_Set_Pixel(X_axis + (px * Scale), Y_axis + (py * Scale) + 1, SC);
          OLED_Set_Pixel(X_axis + (px * Scale) + 1, Y_axis + (py * Scale) + 1,
                         SC);
          OLED_Set_Pixel(X_axis + (px * Scale) + 2, Y_axis + (py * Scale) + 1,
                         SC);
          OLED_Set_Pixel(X_axis + (px * Scale), Y_axis + (py * Scale) + 2, SC);
          OLED_Set_Pixel(X_axis + (px * Scale) + 1, Y_axis + (py * Scale) + 2,
                         SC);
          OLED_Set_Pixel(X_axis + (px * Scale) + 2, Y_axis + (py * Scale) + 2,
                         SC);
          break;
        case 2:
          OLED_Set_Pixel(X_axis + (px * Scale), Y_axis + (py * Scale), SC);
          OLED_Set_Pixel(X_axis + (px * Scale) + 1, Y_axis + (py * Scale), SC);
          OLED_Set_Pixel(X_axis + (px * Scale), Y_axis + (py * Scale) + 1, SC);
          OLED_Set_Pixel(X_axis + (px * Scale) + 1, Y_axis + (py * Scale) + 1,
                         SC);
          break;
        case 1:
        default:
          OLED_Set_Pixel(X_axis + px, Y_axis + py, SC);
          break;
        }
      }
    }
  }
  return 0;
}

void OLED_Init(void) {

  /*Give the display a reset*/
  OLED_Reset();

  /* Clear the framebuffer*/
  OLED_Clear();

  /*Configure the OLED display controller*/
  OLED_Config_Display();
}

void OLED_Refresh(void) {

  OLED_Command(0xb0);
  OLED_Command(((0 & 0xf0) >> 4) | 0x10);
  OLED_Command((0 & 0x0f) | 0x01);

  OLED_Data(&OLED_Buffer[0]);
}

void OLED_Clear(void) { memset(OLED_Buffer, 0, sizeof(OLED_Buffer)); }

void OLED_Fill(uint8_t Pattern) {

  memset(OLED_Buffer, Pattern, sizeof(OLED_Buffer));
}

void OLED_Display_Mode(uint8_t Mode) {

  if (Mode) {
    OLED_Command(OLED_INVERTDISPLAY);
  } else {
    OLED_Command(OLED_NORMALDISPLAY);
  }
}

void OLED_Set_Pixel(uint8_t X_axis, uint8_t Y_axis, uint8_t SC) {

  if ((X_axis >= OLED_WIDTH) || (Y_axis >= OLED_HEIGHT)) {
    // Do nothing
  } else {
    switch (SC) {
    case kOLED_Pixel_Clear:
      OLED_Buffer[X_axis + (Y_axis / 8) * OLED_WIDTH] &= ~(1 << (Y_axis & 7));
      break;
    case kOLED_Pixel_Set:
      OLED_Buffer[X_axis + (Y_axis / 8) * OLED_WIDTH] |= (1 << (Y_axis & 7));
      break;
    }
  }
}

void OLED_Set_Text(uint8_t X_axis, uint8_t Y_axis, uint8_t SC, char *String,
                   uint8_t Scale) {
  uint16_t Cont;
  uint16_t xscaled;

  if ((X_axis >= OLED_WIDTH) || (Y_axis >= OLED_HEIGHT)) {
    // Do nothing
  } else {
    if (Scale > 3) {
      // Do nothing
    } else {

      for (Cont = 0; String[Cont] != '\0'; Cont++) {
        // Catch overflow when scaling!
        xscaled = X_axis + (Cont * 5 * Scale);
        if (xscaled > OLED_WIDTH) {
          // Do nothing
        }

        else {
          OLED_Render_Char(xscaled, Y_axis, SC, String[Cont], Scale);
        }
      }
    }
  }
}

void OLED_Copy_Image(const uint8_t *Img, uint16_t size) {

  uint16_t CpyBuffer;

  OLED_Clear();

  for (CpyBuffer = 0; CpyBuffer < size - 1; CpyBuffer++) {
    OLED_Buffer[CpyBuffer] = *(Img + CpyBuffer);
  }
}

 

3、测试过程

将开发板与OLED相连接

 

 

4、总结

MCXN的I2C编程使用查询模式对MCU不断查询。所以对于MCU有一定的压力,对于双核的系统可以发挥效能。

 

此帖出自NXP MCU论坛

最新回复

我就挺喜欢NXP的MCU的   详情 回复 发表于 昨天 23:05
点赞 关注
 

回复
举报

6509

帖子

10

TA的资源

版主

沙发
 

这个NXP的图片看着挺有情调的  

此帖出自NXP MCU论坛
 
个人签名

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

 
 

回复

672

帖子

0

TA的资源

纯净的硅(高级)

板凳
 

我就挺喜欢NXP的MCU的

此帖出自NXP MCU论坛
 
 
 

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

随便看看
查找数据手册?

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
快速回复 返回顶部 返回列表