1. 数据手册中说明了 i2c 2 的配置功能号是SDA为50,SCL为51,如果是I2C1 就是48 和49,对应时钟是FG1
2.全局宏定义:
//全局宏定义
/* 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) //
//
3.硬件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初始化函数
}
4.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;
}
5.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
}
6.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");
}
}
7.把文件的全部内容放下面:
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
2.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); //
}
}
3.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)
******************************************************************************/