[Atria AT32A403A automotive MCU development board] + I2C communication and OLED display
[Copy link]
This post was last edited by dmzdmz666666 on 2024-1-27 16:40
Part 4: I2C communication and OLED display
This article will evaluate the hardware I2C of AT32A403A and use I2C to drive OLED.
The OLED I chose is the common 0.96-inch OLED on the market. It supports I2C and SPI interfaces. The common driving method is to use software I2C or SPI. Here I will use AT32's hardware I2C to drive it.
First of all, because there are many people using 0.96-inch OLEDs on the market, some developers or merchants have written universal drivers for them. In order to improve development efficiency and avoid reinventing the wheel, I chose a driver from a certain park, which provides a lot of routines, and I modified them based on it.
First, create C files such as I2C.c, 0_96_OLED.c and their corresponding h header files in the hardware folder.
The second step is to configure the hardware I2C of AT32A403A through WorkBench, select I2C1, and select PB6 and PB7 by default for GPIO. I use the default parameters here. Please note that PB6 and PB7 can be connected to the onboard SPI Flash at the same time, but they are not connected by default. Switch them through JP8.
The newly created I2C.C file is derived from the official I2C application layer library function, located in AT32A403A_Firmware_Library_V2.0.1\middlewares\i2c_application_library , which includes the selection of I2C GPIO and initialization of multiplexing functions, enabling I2C clock, configuring I2C division coefficient, transmission rate, sending data, receiving data, etc.
Port the I2C1 initialization code generated by WorkBench into the I2C_Init() function.
Then remember to enable the clock of the corresponding peripheral
The third step is to copy the I2C driver of a certain park's OLED to 0_96_OLED.c. When facing different MCUs, only the driver layer needs to be transplanted, including the OLED instruction sending function and the OLED data sending function. The application layer is separated from the specific hardware and does not need to be transplanted.
The OLED command sending function Write_IIC_Command() is similar to the OLED data sending function Write_IIC_Data(). First, the first 8-bit data is sent: 7-bit slave address + read/write bit. Because they are all sent to OLED, the read/write bit is 0; the second 8-bit data is the control byte. If the next one is a command, it is 0x00, if it is data, it is 0x40; the third 8-bit data is the specific command or data. The details are as follows. It should be noted here that I redefined a static I2C structure, and designated the write data and write command of the above OLED as I2C1. If it is not added, it will not affect the microcontroller when only one I2C is enabled, but if several are enabled, it is easy to conflict, because the program for the I2C structure to specify a certain I2C channel is in the I2C_Init() function, such as I2C1 and I2C2 are initialized through hi2cx.i2cx = I2C1 and I2C_Init(&hi2cx);/hi2cx.i2cx = I2C2 and I2C_Init(&hi2cx);, but when it comes to communication, I don’t know which channel is used. The structure is a global variable and has a global impact. So it is best to re-specify an I2C structure to specify which I2C channel to use (of course, it needs to be verified).
Here I will say a little more. Pay attention to the slave address. The slave address is 0x78. In fact, this 0x78 contains the last read-write bit 0. The actual address should be 0x78>>1 (although the address is a write operation). The HC32F448 of Xiaohua Semiconductor used before uses I2C_Master_Transmit() to fill in the slave address. The real address 0x3C (0x78>>1) is required, because it will call I2C_TransAddr() to send the address and I2C_TransData() to send data. The internal I2C_TransAddr() is sent through I2C_WriteData(I2Cx, (uint8_t)(u16Addr << 1U) | u8Dir);. You can see that it will automatically shift the slave address right by one bit and add the read-write bit. After it is processed, it is 0x78, so the slave address you fill in must be the slave address shifted left by one bit. I stepped on the pit for a few days at that time, woo woo woo! ! !
The AT32A403A library function will not shift the slave address you fill in left or right. If it is currently in send mode, it will force the last position of the address to be 0, which is write mode. This is logical. The final value passed to i2c_x->dt is 0x78, and i2c_x->dt is the I2C data register.
After porting these core functions, there will be no problem with other functions. Then you can call related functions in the main function.
Finally, write the corresponding API to display the corresponding effect.
|