AT32学习笔记-I2C_DMA_U8G2.md
# AT32移植U8G2
## 按照I2C_DMA.md配置I2C
## 编写HAL代码
```c
#include "u8g2_hal.h"
extern i2c_handle_type hi2cx;
// u8x8 gpio和delay函数
uint8_t u8x8_gpio_and_delay(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
switch(msg)
{
case U8X8_MSG_GPIO_AND_DELAY_INIT: // called once during init phase of u8g2/u8x8
break; // can be used to setup pins
case U8X8_MSG_DELAY_NANO: // delay arg_int * 1 nano second
break;
case U8X8_MSG_DELAY_100NANO: // delay arg_int * 100 nano seconds
break;
case U8X8_MSG_DELAY_10MICRO: // delay arg_int * 10 micro seconds
break;
case U8X8_MSG_DELAY_MILLI: // delay arg_int * 1 milli second
delay_ms(arg_int); // 只要写这一部分
break;
case U8X8_MSG_DELAY_I2C: // arg_int is the I2C speed in 100KHz, e.g. 4 = 400 KHz
break; // arg_int=1: delay by 5us, arg_int = 4: delay by 1.25us
case U8X8_MSG_GPIO_D0: // D0 or SPI clock pin: Output level in arg_int
//case U8X8_MSG_GPIO_SPI_CLOCK:
break;
case U8X8_MSG_GPIO_D1: // D1 or SPI data pin: Output level in arg_int
//case U8X8_MSG_GPIO_SPI_DATA:
break;
case U8X8_MSG_GPIO_D2: // D2 pin: Output level in arg_int
break;
case U8X8_MSG_GPIO_D3: // D3 pin: Output level in arg_int
break;
case U8X8_MSG_GPIO_D4: // D4 pin: Output level in arg_int
break;
case U8X8_MSG_GPIO_D5: // D5 pin: Output level in arg_int
break;
case U8X8_MSG_GPIO_D6: // D6 pin: Output level in arg_int
break;
case U8X8_MSG_GPIO_D7: // D7 pin: Output level in arg_int
break;
case U8X8_MSG_GPIO_E: // E/WR pin: Output level in arg_int
break;
case U8X8_MSG_GPIO_CS: // CS (chip select) pin: Output level in arg_int
break;
case U8X8_MSG_GPIO_DC: // DC (data/cmd, A0, register select) pin: Output level in arg_int
break;
case U8X8_MSG_GPIO_RESET: // Reset pin: Output level in arg_int
break;
case U8X8_MSG_GPIO_CS1: // CS1 (chip select) pin: Output level in arg_int
break;
case U8X8_MSG_GPIO_CS2: // CS2 (chip select) pin: Output level in arg_int
break;
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;
}
// u8x8 i2c发送函数
uint8_t u8x8_byte_i2c(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
static uint8_t buffer[32]; /* u8g2/u8x8 will never send more than 32 bytes between START_TRANSFER and END_TRANSFER */
static uint8_t buf_idx;
uint8_t *data;
switch(msg)
{
case U8X8_MSG_BYTE_SEND:
// 首先把数据记录下来,组成buffer数组,等待后面发送
data = (uint8_t *)arg_ptr;
while( arg_int > 0 )
{
buffer[buf_idx++] = *data;
data++;
arg_int--;
}
break;
case U8X8_MSG_BYTE_INIT:
/* add your custom code to init i2c subsystem */
break;
case U8X8_MSG_BYTE_SET_DC:
/* ignored for i2c */
break;
case U8X8_MSG_BYTE_START_TRANSFER:
buf_idx = 0;
break;
case U8X8_MSG_BYTE_END_TRANSFER:
// I2C发送
i2c_master_transmit_dma(&hi2cx, u8x8_GetI2CAddress(u8x8), buffer, buf_idx, I2C_TIMEOUT);
// 等待DMA发送结束
i2c_wait_end(&hi2cx, I2C_TIMEOUT);
break;
default:
return 0;
}
return 1;
}
```
```c
#ifndef __U8G2_HAL_H
#define __U8G2_HAL_H
#include "u8g2.h"
#include "at32f413_board.h"
#include "i2c_define.h"
#include "i2c_application.h"
uint8_t u8x8_gpio_and_delay(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
uint8_t u8x8_byte_i2c(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
#endif // __U8G2_HAL_H
```
## 配置U8G2文件
首先添加一个U8G2分组,用于存放U8G2文件

然后把C文件添加到该分组中(为u8g2项目中的csrc)

添加编译路径

修改编译器到AC6

## 编写代码
SSD1306的地址为0x78
```c
u8g2_t u8g2; // a structure which will contain all the data for one display
u8g2_Setup_ssd1306_i2c_128x64_noname_f(
&u8g2,
U8G2_R0,
//u8x8_byte_sw_i2c,
u8x8_byte_i2c,
u8x8_gpio_and_delay); // init u8g2 structure
u8x8_SetI2CAddress(&u8g2.u8x8, 0x78);
printf("u8g2_InitDisplay\r\n");
u8g2_InitDisplay(&u8g2); // send init sequence to the display, display is in sleep mode after this,
printf( "u8g2_SetPowerSave\r\n");
u8g2_SetPowerSave(&u8g2, 0); // wake up display
printf( "u8g2_ClearBuffer\r\n");
u8g2_ClearBuffer(&u8g2);
u8g2_ClearDisplay(&u8g2);
delay_ms(1000);
printf("u8g2_DrawBox\r\n");
u8g2_DrawBox(&u8g2, 0, 26, 80,6);
u8g2_DrawFrame(&u8g2, 0,26,100,6);
printf( "u8g2_SetFont\r\n");
u8g2_SetFont(&u8g2, u8g2_font_ncenB14_tr);
printf("u8g2_DrawStr\r\n");
u8g2_DrawStr(&u8g2, 2,17,"Hi nkolban!");
printf( "u8g2_SendBuffer\r\n");
u8g2_SendBuffer(&u8g2);
```