本文主要是通过迁移的思维,记录本人初次使用NXP MCUXpresso SDK API进行BSP开发

前面调通了SDRAM Flash GPIO之后,接下来调试EEPROM AT24C16功能,硬件设计如下所示

1. 首先阅读原理图


针对EEPROM的调试一般需要配置i2c总线的时钟源,总线的通讯速率,对i2c总脚的引脚进行初始化,发送i2c 地址命令判断i2c设备工作是否正常,接下来就是通过官方的接口对i2c设备进行操作。

2. 调试过程

2. 1 时钟初始化

void bsp_i2c5_eeprom_clock_init(){/* Configure LPI2C5 using OSC_24M */rootCfg.mux = kCLOCK_LPI2C5_ClockRoot_MuxOsc24MOut;rootCfg.div = 1;CLOCK_SetRootClock(kCLOCK_Root_Lpi2c5, &rootCfg);
}

2. 2 引脚初始化

/*** @brief i2c5 pin mux init** @param [in] None* @param [out] None* * @return * * @history* 1.Date         : 2021-5-27 17:13:28*   Author       : panzidong*   Modification : Created function*/
void bsp_i2c5_eeprom_pin_init(){CLOCK_EnableClock(kCLOCK_Iomuxc_Lpsr);      /* LPCG on: LPCG is ON. */IOMUXC_SetPinMux(IOMUXC_GPIO_LPSR_04_LPI2C5_SDA,         /* GPIO_LPSR_04 is configured as LPI2C5_SDA */1U);                                    /* Software Input On Field: Input Path is determined by functionality */IOMUXC_SetPinMux(IOMUXC_GPIO_LPSR_05_LPI2C5_SCL,         /* GPIO_LPSR_05 is configured as LPI2C5_SCL */1U);          IOMUXC_SetPinConfig(IOMUXC_GPIO_LPSR_04_LPI2C5_SDA,         /* GPIO_LPSR_04 PAD functional properties : */0x10U);                                 /* Slew Rate Field: Slow Slew RateDrive Strength Field: normal driverPull / Keep Select Field: Pull DisablePull Up / Down Config. Field: Weak pull downOpen Drain LPSR Field: Enabled */IOMUXC_SetPinConfig(IOMUXC_GPIO_LPSR_05_LPI2C5_SCL,         /* GPIO_LPSR_05 PAD functional properties : */0x10U);                                 /* Slew Rate Field: Slow Slew RateDrive Strength Field: normal driverPull / Keep Select Field: Pull DisablePull Up / Down Config. Field: Weak pull downOpen Drain LPSR Field: Enabled */
}

2.3 总线初始化

/*** @brief i2c5 bus init** @param [in] void  * @param [out] None* * @return * * @history* 1.Date         : 2021-5-27 17:35:18*   Author       : panzidong*   Modification : Created function*/
void  bsp_i2c5_eeprom_init(void)
{lpi2c_master_config_t masterConfig;/** masterConfig.debugEnable = false;* masterConfig.ignoreAck = false;* masterConfig.pinConfig = kLPI2C_2PinOpenDrain;* masterConfig.baudRate_Hz = 100000U;* masterConfig.busIdleTimeout_ns = 0;* masterConfig.pinLowTimeout_ns = 0;* masterConfig.sdaGlitchFilterWidth_ns = 0;* masterConfig.sclGlitchFilterWidth_ns = 0;*/LPI2C_MasterGetDefaultConfig(&masterConfig);/* Change the default baudrate configuration */masterConfig.baudRate_Hz = LPI2C_BAUDRATE;/* Initialize the LPI2C master peripheral */LPI2C_MasterInit(EEPROM_I2C_MASTER, &masterConfig, 24000000UL);//LPI2C5_Bus_Driver_Init();}

2.4 总线设备探测

/*** @brief print i2c devices on i2c bus 5** @param [in] None* @param [out] None* * @return * * @history* 1.Date         : 2021-6-7 16:3:18*   Author       : panzidong*   Modification : Created function*/
uint32_t bsp_i2c5_bus_detect()
{lpi2c_master_transfer_t masterXfer = {0};status_t reVal = kStatus_Fail;uint8_t temp_buf[1] = {0};uint8_t i = 0;for(i = 0 ;i < 127; i++){masterXfer.slaveAddress = (i<<1) ;masterXfer.direction = kLPI2C_Read;masterXfer.subaddress = 0;masterXfer.subaddressSize = 0x01;masterXfer.data = temp_buf;masterXfer.dataSize = 1;masterXfer.flags = kLPI2C_TransferDefaultFlag;reVal = LPI2C_MasterTransferBlocking(EEPROM_I2C_MASTER, &masterXfer);if (reVal == kStatus_Success){PRINTF("find i2c device i2caddr = %x \r\n", i);}}return 0;
}

只要对应的i2c设备地址有回答,才能说明外设工作正常。

2.5 EEPROM读写

虽然官方提供了AT24C02的例程,针对AT24C16的操作还是有所区别。主由容量变大,所以8位地址空间无法满足,操作地址的高位在从设备地址当中。再则原来的接口没有返回值可以判断,最后重新写了一份。

/*** @brief lpi2c5  wait for standby state** @param [in] uint8_t ClientAddr  * @param [out] None* * @return * * @history* 1.Date         : 2021-5-27 17:36:19*   Author       : panzidong*   Modification : Created function*/
uint8_t I2C_EEPROM_WaitStandbyState(uint8_t ClientAddr)
{status_t lpi2c_status;uint32_t delay_count = 10*256;   do{LPI2C_MasterClearStatusFlags(EEPROM_I2C_MASTER, kLPI2C_MasterNackDetectFlag);lpi2c_status = LPI2C_MasterStart(EEPROM_I2C_MASTER, (ClientAddr>>1), kLPI2C_Write);SDK_DelayAtLeastUs(40,SystemCoreClock);}while(EEPROM_I2C_MASTER->MSR & kLPI2C_MasterNackDetectFlag && delay_count-- );LPI2C_MasterClearStatusFlags(EEPROM_I2C_MASTER, kLPI2C_MasterNackDetectFlag);lpi2c_status = LPI2C_MasterStop(EEPROM_I2C_MASTER);SDK_DelayAtLeastUs(10,SystemCoreClock);if(delay_count == 0 || lpi2c_status != kStatus_Success){return 1;}return 0;
}/*** @brief at24c16 page innet read/write** @param [in] uint8_t         slave_addr  * @param [in] uint32_t        subaddr     * @param [in] uint8_t         *p_buf      * @param [in] uint32_t        len         * @param [in] bool            is_read     * @param [out] None* * @return * * @history* 1.Date         : 2021-5-28 9:49:22*   Author       : panzidong*   Modification : Created function*/
int __eeprom_program_data (    uint8_t         slave_addr,uint32_t        subaddr,uint8_t         *p_buf,uint32_t        len,bool            is_read)
{lpi2c_master_transfer_t masterXfer = {0};status_t reVal = kStatus_Fail;if(len > EEPROM_PAGE_SIZE){PRINTF("len > EEPROM_PAGE_SIZE\r\n");return 1;} /*calculate slave address and register address,some register bits are embeded in slave address*/masterXfer.slaveAddress = (slave_addr>>1) | ((subaddr >> 8) & 0x7);masterXfer.direction = is_read;masterXfer.subaddress = (uint16_t)(subaddr & 0xff);masterXfer.subaddressSize = EEPROM_INER_ADDRESS_SIZE;masterXfer.data = p_buf;masterXfer.dataSize = len;masterXfer.flags = kLPI2C_TransferDefaultFlag;reVal = LPI2C_MasterTransferBlocking(EEPROM_I2C_MASTER, &masterXfer);if (reVal != kStatus_Success){return 1;} /* add one more tick to make sure has enough time to program */if(! is_read){I2C_EEPROM_WaitStandbyState(slave_addr);}return 0;}/*** @brief eeprom write/read func** @param [in] int                     start        * @param [in] uint8_t                 *p_buf    * @param [in] size_t                   len      * @param [in] bool                     is_read  is_read      false : eeprom writeis_read      true  : eeprom read* @param [out] None* * @return   0: success*           other: fail* @history* 1.Date         : 2021-5-28 9:54:13*   Author       : panzidong*   Modification : Created function*/
int  bsp_eeprom_rw (   int                  start,uint8_t                 *p_buf,size_t                   len,bool                     is_read)
{int ret = 0;/* start address beyond this eeprom's capacity */if (start > EEPROM_MAX_NUM) {return -1;}/* no data will be read or written */if (len == 0) {return 0;}/* adjust len that will not beyond eeprom's capacity */if ((start + len) > EEPROM_MAX_NUM) {len = EEPROM_MAX_NUM - start;}/* write the unaligned data of the start */int len_tmp = (EEPROM_PAGE_SIZE - start%EEPROM_PAGE_SIZE);if (len < len_tmp) {len_tmp = len;}ret = __eeprom_program_data(LPI2C_MASTER_SLAVE_ADDR_8BIT, start, p_buf, len_tmp, is_read);if (ret != 0) {ret = -1;goto exit;}len   -= len_tmp;start += len_tmp;p_buf += len_tmp;/* write the rest data */while (len) {len_tmp = len > EEPROM_PAGE_SIZE ? EEPROM_PAGE_SIZE : len;ret = __eeprom_program_data(LPI2C_MASTER_SLAVE_ADDR_8BIT, start, p_buf, len_tmp, is_read);if (ret != 0) {ret = -1;goto exit;}len   -= len_tmp;start += len_tmp;p_buf += len_tmp;}exit:return ret;
}uint8_t bsp_eeprom_test(void)
{uint16_t i;int   result = 0;PRINTF("Write data:\n");for ( i=0; i<EEPROM_TEST_NUM; i++ ){   EEPROM_Buffer_Write[i] = i % 256;PRINTF("0x%02X ", EEPROM_Buffer_Write[i]);if((i+1)%16 == 0 || i == (EEPROM_TEST_NUM-1))    PRINTF("\r\n");    }result = bsp_eeprom_rw(0x0,EEPROM_Buffer_Write,EEPROM_TEST_NUM,false);if(result != 0){PRINTF("Write Failed \r\n");return 1;}PRINTF("Write SUCCESS \r\n");PRINTF("Read data: \r\n");result = bsp_eeprom_rw(0x0,EEPROM_Buffer_Read,EEPROM_TEST_NUM,true);if(result != 0){PRINTF("Read Failed \r\n");return 1;}PRINTF("Read SUCCESS \r\n");for (i=0; i<EEPROM_TEST_NUM; i++){ if(EEPROM_Buffer_Read[i] != EEPROM_Buffer_Write[i]){PRINTF("0x%02X ", EEPROM_Buffer_Read[i]);PRINTF("data ERROR!\r\n");return 1;}PRINTF("0x%02X ", EEPROM_Buffer_Read[i]);if((i+1)%16 == 0 || i == (EEPROM_TEST_NUM-1))    PRINTF("\r\n");}PRINTF("I2C(AT24C016) SUCCESS!\r\n");return 0;
}

3. 总结

以前从来没有写过裸机代码,eeprom的driver在linux下面是很常见的,但是以前也没有细看,主要是通过配置,驱动起来,通过相关的/sys/路径进行访问,在这次机会下重新深入学习。

嵌入式实操----基于RT1170 首板硬件之EEPROM AT24C16调试(十五)相关推荐

  1. 嵌入式实操----基于RT1170 使能展频功能(二十七)

    本文主要是通过迁移的思维,记录本人初次使用NXP MCUXpresso SDK API进行BSP开发 车载电子设备对EMC的要求比较高,本文主要讲述在RT1170上面,使能spread spectru ...

  2. 嵌入式Linux下基于FFmpeg的视频硬件编解码

    嵌入式Linux下基于FFmpeg的视频硬件编解码[图] http://www.c114.net ( 2012/3/1 15:41 ) 摘要: 对FFmpeg多媒体解决方案中的视频编解码流程进行研究. ...

  3. 从零实操基于WSL2 Docker部署Asp.Net Core项目

    前言 平日在公司里都是基于阿里Teambition中的飞流进行Docker部署Api项目或服务,已经习惯了那一套成熟的操作流程,开发和部署确实快捷方便,但是还没在自己的电脑上进行操作过,特别是Wind ...

  4. 嵌入式Linux下基于FFmpeg的视频硬件编解码[图]

    转自:http://tech.c114.net/167/a674033.html 摘要: 对FFmpeg多媒体解决方案中的视频编解码流程进行研究.结合对S3C6410处理器视频硬件编解码方法的分析,阐 ...

  5. 嵌入式开发-迅为IMX6开发板硬件详情介绍

    迅为-I.MX6开发板 Cortex-A9四核I.MX6Q,主频1G,2G内存,16G存储,支持4G全网通,GPS WIFI蓝牙模块,千兆以太网,摄像头,SATA等接口,多屏异显,双屏同显 2.POW ...

  6. stm32 读取sd卡图片显示_「正点原子STM32Mini板资料连载」第三十五章 汉字显示实验...

    1)实验平台:正点原子STM32mini开发板 2)摘自<正点原子STM32 不完全手册(HAL 库版)>关注官方微信号公众号,获取更多资料:正点原子 第三十五章 汉字显示实验 汉字显示在 ...

  7. 个推0代码数据可视化实操 | 基于Tableau的中国奥运数据探索

    8月8日,东京奥运会正式落下帷幕.经过17天的激烈角逐,中国代表团在本届奥运会上共斩获38金32银18铜,位居奖牌榜第二,追平了在伦敦奥运会取得的境外参赛最好成绩. 奥运会期间,奖牌榜上的每一次变动都 ...

  8. 嵌入式linux/鸿蒙开发板(IMX6ULL)开发(三十五)驱动程序基石

    文章目录 1.1 休眠与唤醒 1.1.1 适用场景 1.1.2 内核函数 1.1.2.1 休眠函数 1.1.2.2 唤醒函数 19.1.3 驱动框架 1.1.4 编程 1.1.4.1 驱动程序关键代码 ...

  9. 基于VC709开发板的光纤收发的调试与实现,以及过程中遇到的问题与解决。

    VC709是xilinx旗下的一款开发板,搭载了强大的Virtex-7芯片.有着丰富存储资源,时钟资源与高速接口.具体可参考xilinx官网的ug887手册,本次主要是想记录一下自己的学习过程与遇到的 ...

最新文章

  1. Kappa:比Lambda更好更灵活的实时处理架构
  2. 基于 Spring Boot 的 Restful 风格实现增删改查
  3. java中各种流的详细使用
  4. liferay跳转页面
  5. [恢]hdu 1019
  6. subline3插件html,Sublime Text3与html的插件
  7. 面向对象(OOP)基本概念
  8. java中的文本框_java里的JTextField文本框怎么设置大小?
  9. 微服务化之服务拆分与服务发现
  10. openssl学习笔记--CA及https网站证书配置
  11. iOS 解决导航栏左右 BarButtonItem偏移位置的问题
  12. 【原创】Nginx+PHP-FPM优化技巧总结
  13. 6*6数独,要求输出结果
  14. 中秋之际献上【中秋快乐】藏头诗
  15. 大白话讲解,大数据基本术语
  16. Js、 replace 全部内容替换、替换全部匹配内容、替换第一个
  17. 美的楼宇科技荆州工厂正式投产;华为加入国际电联P2C数字联盟 | 美通企业日报...
  18. python pdf解析毕业论文_电影数据读取、分析与展示毕业论文+任务书+Python项目源码...
  19. 移动互联网安全技术研究
  20. 微信小程序:扫描身份证读取身份信息

热门文章

  1. 喜讯!双驰企业正式成为欧盟地平线2020 项目合作伙伴
  2. 三年的php简历_【完整模板】PHP工程师简历-简洁橙色-1-3年经验-Word简历模板
  3. Oracle序列相关命令
  4. 用于大规模视觉定位的直接2D-3D匹配(IROS 2021)
  5. (附源码)小程序springboot口腔诊所预约系统 毕业设计 201738
  6. 131-从键盘输入一个字符串,将其中的小写字母全部换成大写字母,然后输出到一个磁盘文件
  7. 如何使用 vimdiff 来 git diff
  8. mico3165嵌入式开发板IAR环境搭建以及Demo运行
  9. Socket和ServerSocket的介绍
  10. React构造函数中为什么要写 super(props)