[方案相关]

小华HC32F448驱动硬件I2C

[复制链接]
94|8
手机看帖
扫描二维码
随时随地手机跟帖
t60yz|  楼主 | 2024-2-28 19:31 | 显示全部楼层 |阅读模式
数据手册中说明了 i2c 2 的配置功能号是SDA为50,SCL为51,如果是I2C1 就是48 和49,对应时钟是FG1
3484465df1976eaf0d.png

使用特权

评论回复
t60yz|  楼主 | 2024-2-28 19:31 | 显示全部楼层
全局宏定义:
//全局宏定义
/* 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)                 //

//

使用特权

评论回复
t60yz|  楼主 | 2024-2-28 19:31 | 显示全部楼层
硬件I2C 的GPIO口配置


/**
* @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初始化函数

}

使用特权

评论回复
t60yz|  楼主 | 2024-2-28 19:31 | 显示全部楼层
I2C 初始化函数:
/**
* @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;
}

使用特权

评论回复
t60yz|  楼主 | 2024-2-28 19:32 | 显示全部楼层
I2C写字节函数和 传输cmd、传输data函数,还有初始化函数
#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);
}


/**
  * @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   
}

使用特权

评论回复
t60yz|  楼主 | 2024-2-28 19:32 | 显示全部楼层
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");
    }
}

使用特权

评论回复
t60yz|  楼主 | 2024-2-28 19:32 | 显示全部楼层
把文件的全部内容放下面:
        1.oled.h
//
//本程序只供学习使用,未经作者许可,不得用于其它任何用途
//  文 件 名   :
//  版 本 号   :
//  作    者   : huang jin
//  生成日期   : 2014/3/16
//  最近修改   : 2023/8/25
//  功能描述   : 0.96寸OLED 接口演示例程(HC32F448系列硬件IIC)
//              说明:
//              ----------------------------------------------------------------
//              GND   电源地
//              VCC   接5V或3.3v电源
//              SCL   接PD1(SCL)
//              SDA   接PD0(SDA)
//              ----------------------------------------------------------------
//Copyright(C) 中景园电子2014/3/16
//All rights reserved
//
#ifndef __OLED_H
#define __OLED_H

#include "stdlib.h"
#include "hc32_ll.h"
#include "ev_hc32f448_lqfp80_bsp.h"

#define OLED_MODE 0
#define SIZE 8
#define XLevelL                0x00
#define XLevelH                0x10
#define Max_Column        128
#define Max_Row                64
#define        Brightness        0xFF
#define X_WIDTH         128
#define Y_WIDTH         64
//-----------------OLED IIC端口定义----------------

#define OLED_CMD  0        //写命令
#define OLED_DATA 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)        //开启时钟


//OLED控制用函数
int32_t OLED_WR_Byte(uint8_t *dat);//I2C传输字节函数
void oled_init(void);//初始化
void oled_display_char(uint8_t x,uint8_t y,uint8_t chr,uint8_t Char_Size);
void oled_show_string(uint8_t x, uint8_t y, char ch[], uint8_t TextSize);//显示字符串,TextSize是尺寸大小
void oled_showCN(unsigned char x, unsigned char y, unsigned char CN[],unsigned char N); //显示汉字
void oled_drawBMP(unsigned char x0,unsigned char y0,unsigned char x1,unsigned char y1,unsigned char BMP[]);        //画图
void oled_showNum(uint8_t x,uint8_t y,uint32_t num,uint8_t len,uint8_t size1); //显示数字
void oled_full(uint8_t data);
void oled_cls(void);  //清屏
void oled_on(void);   //开启
void oled_off(void);        //关闭
void show_title(void);//显示一个固定标题
#endif



使用特权

评论回复
t60yz|  楼主 | 2024-2-28 19:32 | 显示全部楼层
.oled.c
//
//本程序只供学习使用,未经作者许可,不得用于其它任何用途
//  文 件 名   :
//  版 本 号   :
//  作    者   : huang jin
//  生成日期   : 2014/3/16
//  最近修改   : 2023/8/25
//  功能描述   : 0.96寸OLED 接口演示例程(HC32F448系列硬件IIC)
//              说明:
//              ----------------------------------------------------------------
//              GND   电源地
//              VCC   接5V或3.3v电源
//              SCL   接PD1(SCL)
//              SDA   接PD0(SDA)
//              ----------------------------------------------------------------
//Copyright(C) 中景园电子2014/3/16
//All rights reserved
//
#include "oledfont.h"
#include "oled.h"
#include "hc32_ll_i2c.h"//很重要的头文件
/**
* @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);
}

/**
  * @brief  oled_setPos 坐标设置函数
  * @param  x,y,
  * @retval  
  */
static void oled_setPos(uint8_t x, uint8_t y)
{
    oled_cmd(0xb0+y);
        oled_cmd(((x&0xf0)>>4)|0x10);
        oled_cmd((x&0x0f)|0x01);
}

/**
  * @brief  oled_full 满屏填充数据
  * @param  data:      Ҫ��������
  * @retval ��
  */
void oled_full(uint8_t data)//0xff
{
    uint8_t m,n;
        for(m=0;m<8;m++)
        {
                oled_cmd(0xb0+m);                //page0-page1
                oled_cmd(0x00);                //low column start address
                oled_cmd(0x10);                //high column start address
                for(n=0;n<128;n++)
                        {
                                oled_data(data);
                        }
        }
}

/**
  * @brief  oled_cls 清屏
  * @param  
        * @retval
  */
void oled_cls(void)
{
        oled_full(0x00);
}

/**
        * @brief  OLED_ON 开启oled显示
  * @param  
        * @retval
  */
void oled_on(void)
{
        oled_cmd(0X8D);  //SET DCDC命令
        oled_cmd(0X14);  //DCDC ON
        oled_cmd(0XAF);  //OLED DISPLAY ON
}

/**
  * @brief  OLED_OFF 关闭oled
  * @param  
        * @retval
  */
void oled_off(void)
{
        oled_cmd(0X8D);  SET DCDC命令
        oled_cmd(0X10);  //DCDC ON
        oled_cmd(0XAE);  //OLED DISPLAY ON
}

/**
  * @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
}

/**
  * @brief  oled_display_char
  * @param  x,y : 坐标可填范围:x:0-127, y:0-7
*                                        chr:- 显示字符
        *                                        Char_Size : 字符大小(填16/8)
        * @retval ��
  */
void oled_display_char(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_setPos(x,y);       
                        for(i=0;i<8;i++)
                        oled_data(F8X16[c*16+i]);
                        oled_setPos(x,y+1);
                        for(i=0;i<8;i++)
                        oled_data(F8X16[c*16+i+8]);
                }
                else
                {       
                        oled_setPos(x,y);
                        for(i=0;i<6;i++)
                        oled_data(F6x8[c][i]);
                }
}

/**
        * @brief  oled_show_string 显示一串string
  * @param  x,y : 坐标可填范围:x:0-127, y:0-7
        *        ch[] : 字符串
        *        TextSize : you can write 1 or 2 (1和2代表的尺寸:1:6*8 ; 2:8*16)
        * @retval ��
  */
void oled_show_string(uint8_t x, uint8_t y, char ch[], uint8_t TextSize)
{
    uint8_t c = 0,i = 0,j = 0;
       
        switch(TextSize)
        {
                case 1:
                {
                        while(ch[j] != '\0')
                        {
                                c = ch[j] - 32;
                                if(x > 126)
                                {
                                        x = 0;
                                        y++;
                                       
                                }
                               
                                oled_setPos(x,y);
                                for(i=0;i<6;i++)
                                        oled_data(F6x8[c][i]);
                                x += 6;
                                j++;
                        }
                }break;
                case 2:
                {
                        while(ch[j] != '\0')
                        {
                                c = ch[j] - 32;
                                if(x > 120)
                                {
                                        x = 0;
                                        y++;
                                }
                               
                                oled_setPos(x,y);
                                for(i=0;i<8;i++)
                                        oled_data(F8X16[c*16+i]);
                                oled_setPos(x,y+1);
                                for(i=0;i<8;i++)
                                        oled_data(F8X16[c*16+i+8]);
                                x += 8;
                                j++;
                        }
                }break;
        }
       
}

/**
* @brief  oled_showCN  显示汉字
  * @param  x,y: (x:0~127, y:0~7);
        *                                        N:oledfont.h
        * @retval
  */
void oled_showCN(unsigned char x, unsigned char y, unsigned char CN[],unsigned char N)
{
        unsigned char wm=0;
        unsigned int  adder=32*N;
        oled_setPos(x , y);
        for(wm = 0;wm < 16;wm++)
        {
                oled_data(CN[adder]);
                adder += 1;
        }
        oled_setPos(x,y + 1);
        for(wm = 0;wm < 16;wm++)
        {
                oled_data(CN[adder]);
                adder += 1;
        }
}

/**
  * @brief  oled_drawBMP
* @param  x0,y0 : 坐标上下限(x0:0~127, y0:0~7);
        *                                        x1,y1 : (x1:1~128,y1:1~8)
        * @retval
  */
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_setPos(x0,y);
    for(x=x0;x<x1;x++)
                {
                        oled_data(BMP[j++]);
                }
        }
}

//m^n
uint32_t oled_pow(uint8_t m,uint8_t n)
{
        uint32_t result=1;
        while(n--)
        {
          result*=m;
        }
        return result;
}

/**
* @brief  oled_showNum 显示数字
  * @param  x,y: (x:0~127, y:0~7);
                        num
                        len         数字长度
                        sizel 数字大小 12/16/24
  * @retval
  */
void oled_showNum(uint8_t x,uint8_t y,uint32_t num,uint8_t len,uint8_t size1)
{
        uint8_t t,temp;
        for(t=0;t<len;t++)
        {
                //        BSP_LED_Toggle(LED_BLUE);
                temp=(num/oled_pow(10,len-t-1))%10;
                if(temp==0)
                {
                        oled_display_char(x+(size1/2)*t,y,'0',size1);
                }
                else
                {
                        oled_display_char(x+(size1/2)*t,y,temp+'0',size1);
                }
  }
}

/**
* @brief  show_title 显示一个汉字标题,仅用以测试
  * @param  
  * @retval
  */
void show_title(void)
{
        uint32_t i;
       
        oled_cls();
        for(i=0; i<=10; i++)  
        {
                if(i<=4)
                        oled_showCN(20+i*16,1,Title,i);  //
                else
                        oled_showCN(10+(i-5)*16,4,Title,i);  //
        }
}

使用特权

评论回复
t60yz|  楼主 | 2024-2-28 19:32 | 显示全部楼层
main.c ,注意要把oled头文件加进去
/**
*******************************************************************************
* @file  i2c/i2c_bl24c256/source/main.c
* @brief Main program of I2C for the Device Driver Library.
@verbatim
   Change Logs:
   Date             Author          Notes
   2023-05-31       CDT             First version
@endverbatim
*******************************************************************************
* Copyright (C) 2022-2023, Xiaohua Semiconductor Co., Ltd. All rights reserved.
*
* This software component is licensed by XHSC under BSD 3-Clause license
* (the "License"); You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
*                    opensource.org/licenses/BSD-3-Clause
*
*******************************************************************************
*/

/*******************************************************************************
* Include files
******************************************************************************/
#include "main.h"

/**
* @addtogroup HC32F448_DDL_Examples
* @{
*/

/*******************************************************************************
* Local type definitions ('typedef')
******************************************************************************/

/*******************************************************************************
* Local pre-processor symbols/macros ('#define')
******************************************************************************/
#define LED_G_PORT          (GPIO_PORT_A)
#define LED_G_PIN           (GPIO_PIN_02)
/* LED toggle definition */
#define LED_G_TOGGLE()      (GPIO_TogglePins(LED_G_PORT, LED_G_PIN))

/* 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)                 //
/*******************************************************************************
* Global variable definitions (declared in header file with 'extern')
******************************************************************************/

/*******************************************************************************
* Local function prototypes ('static')
******************************************************************************/

/*******************************************************************************
* Local variable definitions ('static')
******************************************************************************/

/*******************************************************************************
* Function implementation - global ('extern') and local ('static')
******************************************************************************/
/**
* @brief  LED Init,显示一个板上的灯配合测试
* @param  None
* @retval None
*/

static void LED_Init(void)
{
    stc_gpio_init_t stcGpioInit;

    (void)GPIO_StructInit(&stcGpioInit);
    stcGpioInit.u16PinState = PIN_STAT_RST;
    stcGpioInit.u16PinDir = PIN_DIR_OUT;
    (void)GPIO_Init(LED_G_PORT, LED_G_PIN, &stcGpioInit);
}

/**
* @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;
}

/**
* @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);
    (void)GPIO_Init(I2C_SDA_PORT, I2C_SDA_PIN, &stcGpioInit);
    GPIO_SetFunc(I2C_SCL_PORT, I2C_SCL_PIN, I2C_SCL_FUNC);
    GPIO_SetFunc(I2C_SDA_PORT, I2C_SDA_PIN, I2C_SDA_FUNC);
    /* Enable I2C Peripheral*/
                FCG_Fcg1PeriphClockCmd(I2C_FCG, ENABLE);
    (void)I2C_2_Init(I2C_UNIT);

}

/**
* @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");
    }
}

/**
* @}
*/

/**
* @}
*/

/*******************************************************************************
* EOF (not truncated)
******************************************************************************/

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

100

主题

839

帖子

0

粉丝