2960|1

61

帖子

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
点赞 关注
 
 

回复
举报

6993

帖子

11

TA的资源

版主

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

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

随便看看
查找数据手册?

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