【极海APM32M3514电机通用评估板】 硬件I2C驱动OLED显示屏
[复制链接]
测试APM32M3514板卡硬件I2C方式驱动OLED显示屏。
一、硬件部分
测试使用PB8和PB9端口
需要将上面的电阻去掉,将PB8和PB9分别连接OLED显示的SCL和SDA引脚,PB8和PB9引脚服复用功能如下表。
二、程序部分
2.1、i2c.c
-
-
- /* Waiting TIMEOUT */
-
-
- /*Debug Information output*/
-
-
-
- static volatile uint32_t I2CTimeout = I2CT_LONG_TIMEOUT;
-
-
- void init_i2c(void)
- {
- GPIO_Config_T gpioConfigStruct;
- I2C_Config_T i2cConfigStruct;
-
- /* Enable I2C related Clock */
- RCM_EnableAHBPeriphClock(RCM_AHB_PERIPH_GPIOB);
- RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_I2C);
- RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_SYSCFG);
-
-
- /* Free I2C_SCL and I2C_SDA */
- gpioConfigStruct.mode = GPIO_MODE_OUT;
- gpioConfigStruct.speed = GPIO_SPEED_50MHz;
- gpioConfigStruct.outtype = GPIO_OUT_TYPE_PP;
- gpioConfigStruct.pupd = GPIO_PUPD_NO;
- gpioConfigStruct.pin = GPIO_PIN_8;
- GPIO_Config(GPIOB, &gpioConfigStruct);
-
- gpioConfigStruct.pin = GPIO_PIN_9;
- GPIO_Config(GPIOB, &gpioConfigStruct);
-
- GPIO_SetBit(GPIOB, GPIO_PIN_8);
- GPIO_SetBit(GPIOB, GPIO_PIN_9);
-
- /* Connect I2C to SCL */
- GPIO_ConfigPinAF(GPIOB, GPIO_PIN_SOURCE_8, GPIO_AF_PIN1);
- /* Connect I2C to SDA */
- GPIO_ConfigPinAF(GPIOB, GPIO_PIN_SOURCE_9, GPIO_AF_PIN1);
- /* Config I2C GPIO */
- gpioConfigStruct.mode = GPIO_MODE_AF;
- gpioConfigStruct.speed = GPIO_SPEED_50MHz;
- gpioConfigStruct.outtype = GPIO_OUT_TYPE_OD;
- gpioConfigStruct.pupd = GPIO_PUPD_NO;
- gpioConfigStruct.pin = GPIO_PIN_8;
- GPIO_Config(GPIOB, &gpioConfigStruct);
-
- gpioConfigStruct.pin = GPIO_PIN_9;
- GPIO_Config(GPIOB, &gpioConfigStruct);
-
- /* Config I2C */
- I2C_Reset();
- RCM_ConfigI2CCLK(RCM_I2CCLK_SYSCLK);
- i2cConfigStruct.ack = I2C_ACK_ENABLE;
- i2cConfigStruct.ackaddress = I2C_ACK_ADDRESS_7BIT;
- i2cConfigStruct.address1 = 0x30;
- i2cConfigStruct.analogfilter = I2C_ANALOG_FILTER_ENABLE;
- i2cConfigStruct.digitalfilter = I2C_DIGITAL_FILTER_0;
- i2cConfigStruct.mode = I2C_MODE_I2C;
- i2cConfigStruct.timing = 0x1042F013;
- I2C_Config(&i2cConfigStruct);
-
- /* Enable the I2C Interrupt */
- I2C_EnableInterrupt(I2C_INT_RXIE | I2C_INT_ADDRIE | I2C_INT_STOPIE);
-
- /* NVIC configuration */
- NVIC_EnableIRQRequest(I2C_IRQn, 1);
-
- /* slave configuration*/
- I2C_EnableSlaveByteControl();
- I2C_EnableReload();
- I2C_EnableStretchClock();
-
- /* Enable I2C */
- I2C_Enable();
- }
-
- void I2C_Isr(void)
- {
- uint8_t dat;
-
- if (I2C_ReadIntFlag(I2C_INT_FLAG_ADDR) == SET)
- {
- I2C_ConfigNumberOfBytes(1);
- I2C_ClearIntFlag(I2C_INT_FLAG_ADDR);
- }
-
- if (I2C_ReadStatusFlag(I2C_FLAG_RXBNE) == SET)
- {
- /* I2C_ConfigNumberOfBytes is necessary*/
- I2C_ConfigNumberOfBytes(1);
- dat = (uint8_t)I2C_RxData();
- printf("%c", dat);
- }
-
- if (I2C_ReadIntFlag(I2C_INT_FLAG_STOP) == SET)
- {
- I2C_ClearIntFlag(I2C_INT_FLAG_STOP);
- }
- }
-
- uint32_t I2C_TIMEOUT_UserCallback(uint8_t errorCode)
- {
- if (I2C_DEBUG_ON)
- {
- I2C_ERROR("I2C Wait TIMEOUT! errorCode = %d\r\n", errorCode);
- }
-
- return 0;
- }
-
- uint32_t I2C_WriteDat(uint8_t DevAddr, uint8_t* pBuffer, uint8_t NByte)
- {
- uint8_t wNum;
- I2CTimeout = I2CT_LONG_TIMEOUT;
-
- /* Wait until I2C is idle */
- while (I2C_ReadStatusFlag(I2C_FLAG_BUSY) == SET)
- {
- init_i2c();
- if ((I2CTimeout--) == 0)
- {
- return I2C_TIMEOUT_UserCallback(1);
- }
- }
-
- /* Disable I2C interrupt */
- I2C_DisableInterrupt(I2C_INT_RXIE | I2C_INT_ADDRIE | I2C_INT_STOPIE);
- I2C_DisableReload();
- /* I2C Send Configuration*/
- I2C_HandlingTransfer(DevAddr, NByte, I2C_RELOAD_MODE_AUTOEND, I2C_GENERATE_START_WRITE);
-
- for(wNum = 0;wNum < NByte;wNum++)
- {
- I2C_TxData(pBuffer[wNum]);
- I2CTimeout = I2CT_LONG_TIMEOUT;
-
- while (I2C_ReadStatusFlag(I2C_FLAG_TXBE) == RESET)
- {
- if ((I2CTimeout--) == 0)
- {
- return I2C_TIMEOUT_UserCallback(2);
- }
- }
- }
-
- /* I2C Generate Stop signal */
- I2C_EnableGenerateStop();
-
- I2CTimeout = I2CT_LONG_TIMEOUT;
- while (I2C_ReadStatusFlag(I2C_FLAG_STOP) == RESET)
- {
- if ((I2CTimeout--) == 0)
- {
- return I2C_TIMEOUT_UserCallback(3);
- }
- }
-
- /* I2C Clear Stop Flag */
- I2C_ClearIntFlag(I2C_INT_FLAG_STOP);
- return 0;
- }
-
-
-
2.2、i2c.h
- #ifndef _I2C_H
- #define _I2C_H
-
- void init_i2c(void);
- void I2C_Isr(void);
- uint32_t I2C_WriteDat(uint8_t DevAddr, uint8_t* pBuffer, uint8_t NByte);
-
- #endif
-
2.3、oled.c
使用的OLED显示屏驱动芯片是SSD1306
- #include "main.h"
- #include "oled/codetab.h"
- #include "i2c/i2c.h"
-
- void oled_WriteByte(uint8_t addr, uint8_t dat)
- {
- i2c_Start();
- i2c_SendByte(0x78);
- i2c_WaitAck();
- i2c_SendByte(addr);
- i2c_WaitAck();
- i2c_SendByte(dat);
- i2c_WaitAck();
- i2c_Stop();
- }
-
- void I2C_WriteByte(uint8_t addr, uint8_t dat)
- {
- uint8_t temp[2];
- temp[0] = addr;
- temp[1] = dat;
- I2C_WriteDat(0x78, temp, 2);
- }
-
-
- void WriteCmd(unsigned char I2C_Command)
- {
- I2C_WriteByte(0x00, I2C_Command);
- }
-
- void WriteDat(unsigned char I2C_Data)
- {
- I2C_WriteByte(0x40, I2C_Data);
- }
-
- void OLED_WrCmd(unsigned char IIC_Command)
- {
- WriteCmd(IIC_Command);
- }
-
- void OLED_Init(void)
- {
-
- APM_DelayMs(100);
- WriteCmd(0xAE);
- WriteCmd(0x20);
- WriteCmd(0x10);
- WriteCmd(0xb0);
- WriteCmd(0xc8);
- WriteCmd(0x00);
- WriteCmd(0x10);
- WriteCmd(0x40);
- WriteCmd(0x81);
- WriteCmd(0xff);
- WriteCmd(0xa1);
- WriteCmd(0xa6);
- WriteCmd(0xa8);
- WriteCmd(0x3F);
- WriteCmd(0xa4);
- WriteCmd(0xd3);
- WriteCmd(0x00);
- WriteCmd(0xd5);
- WriteCmd(0xf0);
- WriteCmd(0xd9);
- WriteCmd(0x22);
- WriteCmd(0xda);
- WriteCmd(0x12);
- WriteCmd(0xdb);
- WriteCmd(0x40);
- WriteCmd(0x8d);
- WriteCmd(0x14);
- WriteCmd(0xaf);
- }
-
- void OLED_SetPos(unsigned char x, unsigned char y)
- {
- WriteCmd(0xb0+y);
- WriteCmd(((x&0xf0)>>4)|0x10);
- WriteCmd((x&0x0f)|0x01);
- }
-
- void OLED_Fill(unsigned char fill_Data)
- {
- unsigned char m,n;
- for(m=0;m<8;m++)
- {
- WriteCmd(0xb0+m);
- WriteCmd(0x00);
- WriteCmd(0x10);
- for(n=0;n<128;n++)
- {
- WriteDat(fill_Data);
- }
- }
- }
-
- void OLED_CLS(void)
- {
- OLED_Fill(0xff);
- }
-
- void OLED_ON(void)
- {
- WriteCmd(0X8D);
- WriteCmd(0X14);
- WriteCmd(0XAF);
- }
-
- void OLED_OFF(void)
- {
- WriteCmd(0X8D);
- WriteCmd(0X10);
- WriteCmd(0XAE);
- }
-
- void OLED_ShowStr(unsigned char x, unsigned char y, unsigned char ch[], unsigned char TextSize)
- {
- unsigned char 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++)
- WriteDat(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++)
- WriteDat(F8X16[c*16+i]);
- OLED_SetPos(x,y+1);
- for(i=0;i<8;i++)
- WriteDat(F8X16[c*16+i+8]);
- x += 8;
- j++;
- }
- }break;
- }
- }
-
- void OLED_ShowCN(unsigned char x, unsigned char y, unsigned char N)
- {
- unsigned char wm=0;
- unsigned int adder=32*N;
- OLED_SetPos(x , y);
- for(wm = 0;wm < 16;wm++)
- {
- WriteDat(F16x16[adder]);
- adder += 1;
- }
- OLED_SetPos(x,y + 1);
- for(wm = 0;wm < 16;wm++)
- {
- WriteDat(F16x16[adder]);
- adder += 1;
- }
- }
-
- 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++)
- {
- WriteDat(BMP[j++]);
- }
- }
- }
-
- void oled_test(void)
- {
- OLED_Init();
- OLED_Fill(0x00);
- OLED_ShowStr(0,0,"APM32M3514 BOARD",2);
- OLED_ShowStr(0,2,"I2C OLED TEST",2);
- }
-
2.4、main.c
- int main(void)
- {
- APM_DelayInit();
- APM_DelayMs(5000);
-
- init_usart();
- init_led();
- init_i2c();
- OLED_Init();
- oled_test();
-
- while (1)
- {
- led_on();
- APM_DelayMs(200);
- led_off();
- APM_DelayMs(200);
- }
- }
三、运行结果
下载程序后,OLED显示屏显示
|