3018|1

63

帖子

0

TA的资源

一粒金砂(中级)

楼主
 

【小华HC32F448测评】关于HC32f448的I2C学习及硬件I2C驱动OLED [复制链接]

  本帖最后由 学学学学学学学 于 2023-8-25 17:24 编辑
  1. 全局宏定义:
    • /* Define port and pin for SDA and SCL */
    • #define I2C_SDA_PORT (GPIO_PORT_D)//类似HAL库的配置
    • #define I2C_SDA_PIN (GPIO_PIN_00)
    • #define I2C_SCL_PORT (GPIO_PORT_D)
    • #define I2C_SCL_PIN (GPIO_PIN_01)
    • #define I2C_SDA_FUNC (GPIO_FUNC_50) //pin脚功能配置号
    • #define I2C_SCL_FUNC (GPIO_FUNC_51) //详情见数据手册引脚配置页
    • /* I2C unit define */
    • #define I2C_UNIT (CM_I2C2) //硬件I2C地址
    • #define I2C_FCG (FCG1_PERIPH_I2C2) //开启时钟
    • /**
    • * @defgroup I2C_Configuration BSP I2C Configuration
    • * @{
    • */
    • #define I2C_BAUDRATE (400000UL) //I2C波特率配置
    • #define I2C_TIMEOUT (0x64U) //
    数据手册中说明了 i2c 2 的配置功能号是SDA为50,SCL为51,如果是I2C1 就是48 和49,对应时钟是FG1 
       
  2. 硬件 I2C的GOIO口配置函数:主要需要看数据手册中关于引脚配置页的引脚功能定义
    • /**
    • * @brief I2C_Init0 配置gpio口功能,主要是功能号I2C_SCL_FUNC和SDA_FUNC,要按照数据手册写
    • * @param
    • * @retval LL_OK
    • */
    • static void I2C_GPIO_Init(void)
    • {
    • stc_gpio_init_t stcGpioInit;
    • /* Configuration I2C GPIO */
    • (void)GPIO_StructInit(&stcGpioInit);
    • (void)GPIO_Init(I2C_SCL_PORT, I2C_SCL_PIN, &stcGpioInit);//初始化gpio
    • (void)GPIO_Init(I2C_SDA_PORT, I2C_SDA_PIN, &stcGpioInit);
    • GPIO_SetFunc(I2C_SCL_PORT, I2C_SCL_PIN, I2C_SCL_FUNC);//配置功能为SCL
    • GPIO_SetFunc(I2C_SDA_PORT, I2C_SDA_PIN, I2C_SDA_FUNC);//SDA
    • /* Enable I2C Peripheral*/
    • FCG_Fcg1PeriphClockCmd(I2C_FCG, ENABLE);//开启外设时钟
    • (void)I2C_Init(I2C_UNIT);//I2C初始化函数
    • }
  3. I2C 2初始化函数
    • /**
    • * @brief I2C_Init1 配置i2c的波特率,边沿时长,分频系数,总线命令
    • * @param CM_I2C_TypeDef *I2Cx:I2C1 or I2C2 ,you only need to write a i2c base dar directly
    • * @retval LL_OK
    • */
    • int32_t I2C_2_Init(CM_I2C_TypeDef *I2Cx)
    • {
    • int32_t i32Ret;
    • float32_t fErr;
    • stc_i2c_init_t stcI2cInit;
    • I2C_DeInit(I2Cx);
    • (void)I2C_StructInit(&stcI2cInit);
    • stcI2cInit.u32Baudrate = I2C_BAUDRATE;
    • stcI2cInit.u32SclTime = 0U;
    • stcI2cInit.u32ClockDiv = I2C_CLK_DIV2;
    • i32Ret = I2C_Init(I2Cx, &stcI2cInit, &fErr);
    • if (LL_OK == i32Ret) {
    • I2C_BusWaitCmd(I2Cx, ENABLE);
    • }
    • I2C_Cmd(I2Cx, ENABLE);
    • return i32Ret;
    • }
  4. main函数
    • /**
    • * @brief Main function
    • * @param None
    • */
    • int32_t main(void)
    • {
    • /* Unlock peripherals or registers */
    • LL_PERIPH_WE(LL_PERIPH_ALL);
    • /* Initialize BSP system clock. */
    • // BSP_CLK_Init();不要取消这行注释,时钟冲突了
    • /* Initialize BSP expand IO. */
    • BSP_IO_Init();//也把SDA和SCL初始化成功了
    • /* Initialize BSP LED. */
    • BSP_LED_Init();
    • /* Initialize DDL_Printf */
    • DDL_PrintfInit(BSP_PRINTF_DEVICE, BSP_PRINTF_BAUDRATE, BSP_PRINTF_Preinit);
    • /* Initialize I2C2 */
    • I2C_GPIO_Init();
    • LED_Init();
    • oled_init();
    • /* Peripheral registers write protected */
    • LL_PERIPH_WP(LL_PERIPH_ALL);
    • oled_cls();
    • DDL_DelayMS(200);
    • for (;;) {
    • //oled_cls();
    • //显示一个汉字标题,如果没有oledfont中没有title数组,就换显示个字符串或数组的函数
    • show_title();
    • //DDL_DelayMS(50UL);
    • // LED_G_TOGGLE();
    • // BSP_LED_Toggle(LED_YELLOW);
    • // DDL_Printf("advance\n");
    • }
    • }

     

  5. oled.c和oled.h文件中I2C的驱动程序函数
    • #include "oledfont.h"
    • #include "oled.h"
    • #include "hc32_ll_i2c.h"//很重要的头文件,I2C_trans等函数的来源
    • /**
    • * @defgroup I2C_Configuration
    • * @{
    • */
    • #define I2C_BAUDRATE (400000UL) //I2C波特率配置
    • #define I2C_TIMEOUT (0x64U) //
    • #define OLED_ADD (0x3c) //写入OLED初始地址
    • #define DATA_Len (0x02) //写入数据长度
    • #define I2C_DIR_TX2 (0x00) //写入标志
    • /**
    • * @brief OLED_WR_Byte 写入一字节/两字节
    • * @param *dat
    • * @retval 返回 LL_OK
    • *用法举例:OLED_WR_Byte(buf),buf定义:可定义为数组,如 int8_t buf[2];
    • */
    • int32_t OLED_WR_Byte(uint8_t *dat)
    • {
    • int32_t i32Ret;
    • I2C_SWResetCmd(I2C_UNIT,ENABLE);//I2C复位
    • I2C_SWResetCmd(I2C_UNIT,DISABLE);
    • i32Ret = I2C_Start(I2C_UNIT, I2C_TIMEOUT);//启动I2C
    • if(LL_OK==i32Ret)
    • {
    • //写入基地址
    • i32Ret=I2C_TransAddr(I2C_UNIT,(uint8_t)OLED_ADD,I2C_DIR_TX2,I2C_TIMEOUT );
    • if(LL_OK==i32Ret)
    • {
    • //写入指令数据,这里DATA_Len=2,一次性传输 *dat 两个数据过去,第一个数据是固定寄存器地址,一
    • //个是实时指令
    • i32Ret=I2C_TransData(I2C_UNIT,dat,DATA_Len ,I2C_TIMEOUT );
    • //如果把寄存器地址和数据指令两个字节分开传输,就解出这几行注释,上面先传寄存器地址,下面这几行传
    • //数据
    • // if(LL_OK==i32Ret)
    • // {
    • // i32Ret=I2C_TransData(I2C_UNIT,dat,DATA_Len ,I2C_TIMEOUT );
    • // }
    • }
    • // if(LL_OK != i32Ret)
    • // {
    • // (void)I2C_Stop(BSP_TCA9539_I2C_UNIT,100);
    • // I2C_SWResetCmd(BSP_TCA9539_I2C_UNIT,ENABLE);
    • // I2C_SWResetCmd(BSP_TCA9539_I2C_UNIT,DISABLE);
    • // }
    • }
    • (void)I2C_Stop(I2C_UNIT,I2C_TIMEOUT );
    • return i32Ret;
    • }
    • /**
    • * @brief oled_cmd 写入oled指令
    • * @param i2c_cmd,一个8位无符号整数
    • * @retval void
    • */
    • static void oled_cmd(uint8_t i2c_cmd)
    • {
    • uint8_t u8TXBuf[2];
    • u8TXBuf[0]=0x00;
    • u8TXBuf[1]=i2c_cmd;
    • OLED_WR_Byte(u8TXBuf);
    • // uint8_t *cmd;
    • // uint8_t adr1;
    • // uint8_t *adr;
    • // adr1=0x00;
    • // adr=&adr1;
    • // cmd=&i2c_cmd;
    • // BSP_I2C_Write(BSP_TCA9539_I2C_UNIT, OLED_ADD, adr,1,cmd, 1);
    • }
    • /**
    • * @brief oled_data�
    • * @param i2c_data 传数据
    • * @retval
    • */
    • static void oled_data(uint8_t i2c_data)
    • {
    • uint8_t u8TXBuf[2];
    • u8TXBuf[0]=0x40;
    • u8TXBuf[1]=i2c_data;
    • OLED_WR_Byte(u8TXBuf);
    • // uint8_t *dat;
    • // uint8_t adr1;
    • // uint8_t *adr;
    • // adr1=0x40;
    • // adr=&adr1;
    • // dat=&i2c_data;
    • // BSP_I2C_Write(BSP_TCA9539_I2C_UNIT, OLED_ADD,adr ,1,dat, 1);
    • }
  6.  oled初始化
    • /**
    • * @brief oled_init 初始化oled
    • * @param
    • * @retval
    • */
    • void oled_init(void)
    • {
    • DDL_DelayMS(800);
    • oled_cmd(0xAE); //display off
    • oled_cmd(0x20); //Set Memory Addressing Mode
    • oled_cmd(0x10); //00,Horizontal Addressing Mode;01,Vertical Addressing Mode;10,Page Addressing Mode (RESET);11,Invalid
    • oled_cmd(0xb0); //Set Page Start Address for Page Addressing Mode,0-7
    • oled_cmd(0xc8); //Set COM Output Scan Direction
    • oled_cmd(0x00); //---set low column address
    • oled_cmd(0x10); //---set high column address
    • oled_cmd(0x40); //--set start line address
    • oled_cmd(0x81); //--set contrast control register
    • oled_cmd(0xff); // 0x00~0xff
    • oled_cmd(0xa1); //--set segment re-map 0 to 127
    • oled_cmd(0xa6); //--set normal display
    • oled_cmd(0xa8); //--set multiplex ratio(1 to 64)
    • oled_cmd(0x3F); //
    • oled_cmd(0xa4); //0xa4,Output follows RAM content;0xa5,Output ignores RAM content
    • oled_cmd(0xd3); //-set display offset
    • oled_cmd(0x00); //-not offset
    • oled_cmd(0xd5); //--set display clock divide ratio/oscillator frequency
    • oled_cmd(0xf0); //--set divide ratio
    • oled_cmd(0xd9); //--set pre-charge period
    • oled_cmd(0x22); //
    • oled_cmd(0xda); //--set com pins hardware configuration
    • oled_cmd(0x12);
    • oled_cmd(0xdb); //--set vcomh
    • oled_cmd(0x20); //0x20,0.77xVcc
    • oled_cmd(0x8d); //--set DC-DC enable
    • oled_cmd(0x14); //
    • oled_cmd(0xaf); //--turn on oled panel
    • }

    效果:

     

    其他主要的文件和函数放在附件里了,有需要可看
     

 

OLED_I2C.zip

59.76 KB, 下载次数: 13

最新回复

大佬,这文学设计,一看就是经过大赛洗理的高手,期待大佬在社区多露几手!  详情 回复 发表于 2023-8-27 08:33
点赞 关注
 
 

回复
举报

7204

帖子

11

TA的资源

版主

沙发
 
大佬,这文学设计,一看就是经过大赛洗理的高手,期待大佬在社区多露几手!
 
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
推荐帖子
阻抗匹配与史密斯(Smith)圆图: 基本原理

阻抗匹配与史密斯(Smith)圆图: 基本原理

两粒电子的爱情 god......

一、缘起虚无 很久很久以前,在某一片星云里有两粒电子。 他们围绕着同一个原子核旋转着,她在内层,他在外层。 他们的轨道很接 ...

CCS完美版

简体中文,从应用者的实际经验出发来讲授CCS,是有着丰富经验的老师和研究生写的。。。。

如何设计2个按键同时按的键盘扫描C程序

4*4键盘扫描C程序,每次只能扫到一个按键,如果要两个按键同时按,是不是先按下去的按键是进入中断

教程:如何为BBB制作cape(或:如何在系统启动时自动加载dtbo)

本帖最后由 wytalfred 于 2014-3-22 00:11 编辑 一、引子 如果你买来BBB是为了搞跟硬件相关的项目,那你八成需要制作一个c ...

ST BLE的线上研讨会: ST BLE多连接技术的原理分析与应用

在一个小时的webinar中,我们将介绍ST最新的基于BLE多连接的市场应用案例,包括在电表,冷链运输系统,运动器械,中央空调系统, ...

STM32F1接额定5伏旋转编码器可以实现中断吗?【萌新求助】

最近在学stm32的外部中断,用的是旋转编码器作为中断源,但是我只有额定5伏的旋转编码器,编码之后发现失灵,请问是硬件问题吗 ...

无线射频识别技术-RFID理论与应用

无线射频识别技术-RFID理论与应用

求电子书

有谁分享ESD揭秘:静电防护原理和典型应用 (美)沃尔德曼 著,来萍 等译,出版社:机械工业出版社 出版时间:2014年06月 ,多谢

【树莓派Pico 2 RP2350开发板】 温控器小项目实现

使用PCIO2实现温控器,用PCIO2做为主控,操作GPIO,控制风扇与加热装置,再使用TFT实现人机交互功能,并实现小项目完成项目测评 ...

关闭
站长推荐上一条 1/10 下一条
有奖直播:当AI遇见仿真,会有什么样的电子行业革新之路?
首场直播:Simcenter AI 赋能电子行业研发创新
直播时间:04月15日14:00-14:50

查看 »

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

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

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

北京市海淀区中关村大街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
快速回复 返回顶部 返回列表