【前言】:前面移植了沁恒的CH32V307以后,感受一下移植GD32VF103R的速度。利用原有的库,复制粘贴过来,熟悉的话,几分钟就可以了。
【环境】:与CH32V307同一个开发环境MounRiver Studio。i2c的驱动库利用原来GD32VF103G的硬件i2c驱动。
【步骤】
1、有了前面移植CH32V307 基于硬件i2c的经验,利用原有的库,直接复制csrc目录。csrc的目录原封不用动就OK:
2、复制两个回调函数,再修改i2c发送函数即可:my_i2c.c如下:
- /*
- * my_i2c.c
- *
- * Created on: 2022年5月22日
- * Author: Administrator
- */
- #include "my_i2c.h"
- #include "gd32vf103.h"
- #include "systick.h"
- /*!
- brief enable the peripheral clock
- param[in] none
- param[out] none
- retval none
- */
- static void rcu_config(void)
- {
- /* enable GPIOB clock */
- rcu_periph_clock_enable(RCU_GPIOB);
- /* enable I2C0 clock */
- rcu_periph_clock_enable(RCU_I2C0);
- }
- /*!
- brief configure the GPIO ports
- param[in] none
- param[out] none
- retval none
- */
- static void gpio_config(void)
- {
- gpio_init(GPIOB, GPIO_MODE_AF_OD, GPIO_OSPEED_50MHZ, GPIO_PIN_6 | GPIO_PIN_7);
- }
- /*!
- brief configure the I2C0 and I2C1 inter faces
- param[in] none
- param[out] none
- retval none
- */
- static void i2c_config(void)
- {
- /* configure I2C clock */
- i2c_clock_config(I2C0,400000,I2C_DTCY_2);
- /* configure I2C address */
- i2c_mode_addr_config(I2C0,I2C_I2CMODE_ENABLE,I2C_ADDFORMAT_7BITS,OLED_ADDRESS);
- /* enable I2C0 */
- i2c_enable(I2C0);
- /* enable acknowledge */
- i2c_ack_config(I2C0,I2C_ACK_ENABLE);
- }
- /*!
- brief 初始化i20
- param[in] none
- param[out] none
- retval none
- */
- void my_i2c0_init(void)
- {
- rcu_config();
- gpio_config();
- i2c_config();
- }
- void IIC_send_data(uint8_t *data,uint8_t len )
- {
- if (len<=0) {
- return;
- }
- /* wait until I2C bus is idle */
- while(i2c_flag_get(I2C0, I2C_FLAG_I2CBSY));
- /* send a start condition to I2C0 bus */
- i2c_start_on_bus(I2C0);
- /* wait until SBSEND bit is set */
- while(!i2c_flag_get(I2C0, I2C_FLAG_SBSEND));
- /* send slave address to I2C bus */
- i2c_master_addressing(I2C0, OLED_ADDRESS, I2C_TRANSMITTER);
- /* wait until ADDSEND bit is set */
- while(!i2c_flag_get(I2C0, I2C_FLAG_ADDSEND));
- /* clear ADDSEND bit */
- i2c_flag_clear(I2C0, I2C_FLAG_ADDSEND);
- /* wait until the transmit data buffer is empty */
- for (uint8_t i = 0; i < len; ++ i) {
- i2c_data_transmit(I2C0, data[i]);
- /* wait until the TBE bit is set */
- while(!i2c_flag_get(I2C0, I2C_FLAG_TBE));
- }
- /* send a stop condition to I2C bus */
- i2c_stop_on_bus(I2C0);
- /* wait until stop condition generate */
- while(I2C_CTL0(I2C0) & 0x0200);
- }
- uint8_t u8x8_byte_hw_i2c(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
- {
- /* u8g2/u8x8 will never send more than 32 bytes between START_TRANSFER and END_TRANSFER */
- static uint8_t buffer[128];
- static uint8_t buf_idx;
- uint8_t *data;
- switch (msg)
- {
- case U8X8_MSG_BYTE_INIT:
- {
- /* add your custom code to init i2c subsystem */
- my_i2c0_init(); //I2C初始化
- }
- break;
- case U8X8_MSG_BYTE_START_TRANSFER:
- {
- buf_idx = 0;
- }
- break;
- case U8X8_MSG_BYTE_SEND:
- {
- data = (uint8_t *)arg_ptr;
- while (arg_int > 0)
- {
- buffer[buf_idx++] = *data;
- data++;
- arg_int--;
- }
- }
- break;
- case U8X8_MSG_BYTE_END_TRANSFER:
- {
- IIC_send_data(buffer,buf_idx);
- }
- break;
- case U8X8_MSG_BYTE_SET_DC:
- break;
- default:
- return 0;
- }
- return 1;
- }
- uint8_t u8x8_gpio_and_delay(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
- {
- switch (msg)
- {
- case U8X8_MSG_DELAY_100NANO: // delay arg_int * 100 nano seconds
- //__NOP();
- break;
- case U8X8_MSG_DELAY_10MICRO: // delay arg_int * 10 micro seconds
- for (uint16_t n = 0; n < 320; n++)
- {
- //__NOP();
- }
- break;
- case U8X8_MSG_DELAY_MILLI: // delay arg_int * 1 milli second
- delay_1ms(500);
- break;
- case U8X8_MSG_DELAY_I2C: // arg_int is the I2C speed in 100KHz, e.g. 4 = 400 KHz
- delay_1us(1);
- break; // arg_int=1: delay by 5us, arg_int = 4: delay by 1.25us
- case U8X8_MSG_GPIO_I2C_CLOCK: // arg_int=0: Output low at I2C clock pin
- break; // arg_int=1: Input dir with pullup high for I2C clock pin
- case U8X8_MSG_GPIO_I2C_DATA: // arg_int=0: Output low at I2C data pin
- break; // arg_int=1: Input dir with pullup high for I2C data pin
- case U8X8_MSG_GPIO_MENU_SELECT:
- u8x8_SetGPIOResult(u8x8, /* get menu select pin state */ 0);
- break;
- case U8X8_MSG_GPIO_MENU_NEXT:
- u8x8_SetGPIOResult(u8x8, /* get menu next pin state */ 0);
- break;
- case U8X8_MSG_GPIO_MENU_PREV:
- u8x8_SetGPIOResult(u8x8, /* get menu prev pin state */ 0);
- break;
- case U8X8_MSG_GPIO_MENU_HOME:
- u8x8_SetGPIOResult(u8x8, /* get menu home pin state */ 0);
- break;
- default:
- u8x8_SetGPIOResult(u8x8, 1); // default return value
- break;
- }
- return 1;
- }
- void u8g2Init(u8g2_t *u8g2)
- {
- u8g2_Setup_ssd1306_i2c_128x64_noname_f(u8g2, U8G2_R0, u8x8_byte_hw_i2c, u8x8_gpio_and_delay); // 初始化 u8g2 结构体
- u8g2_InitDisplay(u8g2); // 根据所选的芯片进行初始化工作,初始化完成后,显示器处于关闭状态
- u8g2_SetPowerSave(u8g2, 0); // 打开显示器
- u8g2_ClearBuffer(u8g2);
- }
复制代码
3、复制my_i2c.h:
- /*
- * my_i2c.h
- *
- * Created on: 2022年5月22日
- * Author: Administrator
- */
- #ifndef BSP_MY_I2C_H_
- #define BSP_MY_I2C_H_
- #include "ch32v30x.h"
- #include "u8g2.h"
- /* USER CODE BEGIN Includes */
- /* USER CODE END Includes */
- /* USER CODE BEGIN Private defines */
- /* USER CODE END Private defines */
- #define u8 unsigned char // ?unsigned char ????
- #define MAX_LEN 128 //
- #define OLED_ADDRESS 0x78 // oled模块从机地址
- #define OLED_CMD 0x00 // 写命令
- #define OLED_DATA 0x40 // 写数据
- /* USER CODE BEGIN Prototypes */
- uint8_t u8x8_byte_hw_i2c(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
- uint8_t u8x8_gpio_and_delay(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
- void u8g2Init(u8g2_t *u8g2);
- void IIC_send_data(uint8_t *data,uint8_t len );
- void IIC_Init(u32 bound, u16 address);
- #endif /* BSP_MY_I2C_H_ */
复制代码
4、main主函数复制与CH32V307的u8g2初始化代码即可:
- #include "gd32vf103.h"
- #include "gd32vf103r_start.h"
- #include "systick.h"
- #include "u8g2.h"
- u8g2_t u8g2; // a structure which will contain all the data for one display
- /*官方提供的Log绘制demo*/
- void test_draw(void)
- {
- u8g2_ClearBuffer(&u8g2);
- u8g2_SendBuffer(&u8g2);
- u8g2_SetFontMode(&u8g2, 1); /*字体模式选择*/
- u8g2_SetFontDirection(&u8g2, 0); /*字体方向选择*/
- u8g2_SetFont(&u8g2, u8g2_font_inb24_mf); /*字库选择*/
- u8g2_DrawStr(&u8g2, 0, 20, "U");
- u8g2_SetFontDirection(&u8g2, 1);
- u8g2_SetFont(&u8g2, u8g2_font_inb30_mn);
- u8g2_DrawStr(&u8g2, 21,8,"8");
- u8g2_SetFontDirection(&u8g2, 0);
- u8g2_SetFont(&u8g2, u8g2_font_inb24_mf);
- u8g2_DrawStr(&u8g2, 51,30,"g");
- u8g2_DrawStr(&u8g2, 67,30,"xb2");
- u8g2_DrawHLine(&u8g2, 2, 35, 47);
- u8g2_DrawHLine(&u8g2, 3, 36, 47);
- u8g2_DrawVLine(&u8g2, 45, 32, 12);
- u8g2_DrawVLine(&u8g2, 46, 33, 12);
- u8g2_SetFont(&u8g2, u8g2_font_4x6_tr);
- u8g2_DrawStr(&u8g2, 1,54,"github.com/olikraus/u8g2");
- u8g2_SendBuffer(&u8g2);
- delay_1ms(1000);
- u8g2_ClearBuffer(&u8g2);
- u8g2_SendBuffer(&u8g2);
- u8g2_DrawBox(&u8g2,0,0,20,20);
- u8g2_SendBuffer(&u8g2);
- delay_1ms(1000);
- u8g2_DrawBox(&u8g2,20,20,20,20);
- u8g2_SendBuffer(&u8g2);
- delay_1ms(1000);
- u8g2_DrawFrame(&u8g2,10,40,20,20);
- u8g2_SendBuffer(&u8g2);
- delay_1ms(1000);
- u8g2_SetFont(&u8g2,u8g2_font_DigitalDiscoThin_tf);
- u8g2_DrawStr(&u8g2,30,10,"TEST by LUGL");
- u8g2_SendBuffer(&u8g2);
- delay_1ms(1000);
- u8g2_DrawStr(&u8g2,60,60,"U8G2..");
- u8g2_SendBuffer(&u8g2);
- delay_1ms(1000);
- u8g2_DrawStr(&u8g2,50,30,"CH32V307");
- u8g2_SendBuffer(&u8g2);
- }
- /*!
- brief main function
- param[in] none
- param[out] none
- retval none
- */
- int main(void)
- {
- u8g2Init(&u8g2);
- while(1){
- test_draw();
- delay_1ms(2000);
- }
- }
复制代码
下载后就OK了:全程大约5分钟左右就OK了,速度非常好,与CH32V307速度几乎一模一样:
u8g2双屏
|