提供新唐M031KG6AE用IIC写的oled的驱动
时间: 2023-09-17 11:07:56 浏览: 34
以下是使用新唐M031KG6AE芯片的IIC接口驱动OLED显示屏的示例代码:
```c
#include "NuMicro.h"
#define OLED_CMD 0x00
#define OLED_DATA 0x40
#define OLED_WIDTH 128
#define OLED_HEIGHT 64
#define OLED_PAGES (OLED_HEIGHT / 8)
#define OLED_I2C_ADDR 0x78
volatile uint8_t u8I2CDataReady;
uint8_t u8I2CData[2];
void I2C0_IRQHandler(void)
{
uint32_t u32Status;
u32Status = I2C_GET_STATUS(I2C0);
if(u32Status == 0x38) /* Arbitration lost */
{
I2C_SET_CONTROL_REG(I2C0, I2C_CTL_STO_SI);
I2C_SET_CONTROL_REG(I2C0, I2C_CTL_STA_SI);
}
else if(u32Status == 0x08) /* START has been transmitted and prepare SLA+W */
{
I2C_SET_DATA(I2C0, OLED_I2C_ADDR << 1);
I2C_SET_CONTROL_REG(I2C0, I2C_CTL_SI);
}
else if(u32Status == 0x18) /* SLA+W has been transmitted and ACK has been received */
{
I2C_SET_DATA(I2C0, u8I2CData[0]);
I2C_SET_CONTROL_REG(I2C0, I2C_CTL_SI);
}
else if(u32Status == 0x20) /* SLA+W has been transmitted and NACK has been received */
{
I2C_SET_CONTROL_REG(I2C0, I2C_CTL_STO_SI);
u8I2CDataReady = 0;
}
else if(u32Status == 0x28) /* DATA has been transmitted and ACK has been received */
{
if(u8I2CDataReady)
{
I2C_SET_DATA(I2C0, u8I2CData[1]);
I2C_SET_CONTROL_REG(I2C0, I2C_CTL_SI);
u8I2CDataReady = 0;
}
else
{
I2C_SET_CONTROL_REG(I2C0, I2C_CTL_STO_SI);
}
}
else if(u32Status == 0x30) /* DATA has been transmitted and NACK has been received */
{
I2C_SET_CONTROL_REG(I2C0, I2C_CTL_STO_SI);
u8I2CDataReady = 0;
}
else if(u32Status == 0x10) /* Repeat START has been transmitted and prepare SLA+R */
{
I2C_SET_DATA(I2C0, (OLED_I2C_ADDR << 1) | 0x01);
I2C_SET_CONTROL_REG(I2C0, I2C_CTL_SI);
}
else if(u32Status == 0x40) /* SLA+R has been transmitted and ACK has been received */
{
I2C_SET_CONTROL_REG(I2C0, I2C_CTL_SI);
}
else if(u32Status == 0x48) /* SLA+R has been transmitted and NACK has been received */
{
I2C_SET_CONTROL_REG(I2C0, I2C_CTL_STO_SI);
}
else if(u32Status == 0x50) /* DATA has been received and ACK has been returned */
{
u8I2CData[0] = I2C_GET_DATA(I2C0);
u8I2CDataReady = 1;
I2C_SET_CONTROL_REG(I2C0, I2C_CTL_SI_AA);
}
else if(u32Status == 0x58) /* DATA has been received and NACK has been returned */
{
u8I2CData[0] = I2C_GET_DATA(I2C0);
u8I2CDataReady = 1;
I2C_SET_CONTROL_REG(I2C0, I2C_CTL_STO_SI);
}
else
{
/* TO DO */
}
}
void I2C0_Init(void)
{
/* Open I2C0 and set clock to 400KHz */
I2C_Open(I2C0, 400000);
/* Enable I2C interrupt */
NVIC_EnableIRQ(I2C0_IRQn);
I2C_EnableInt(I2C0);
}
void OLED_WriteCmd(uint8_t u8Cmd)
{
while(u8I2CDataReady);
u8I2CData[0] = OLED_CMD;
u8I2CData[1] = u8Cmd;
u8I2CDataReady = 1;
I2C_SET_CONTROL_REG(I2C0, I2C_CTL_STA_SI);
while(u8I2CDataReady);
}
void OLED_WriteData(uint8_t u8Data)
{
while(u8I2CDataReady);
u8I2CData[0] = OLED_DATA;
u8I2CData[1] = u8Data;
u8I2CDataReady = 1;
I2C_SET_CONTROL_REG(I2C0, I2C_CTL_STA_SI);
while(u8I2CDataReady);
}
void OLED_Init(void)
{
I2C0_Init();
OLED_WriteCmd(0xAE); /* Display off */
OLED_WriteCmd(0xD5); /* Set display clock divide ratio/oscillator frequency */
OLED_WriteCmd(0xF0);
OLED_WriteCmd(0xA8); /* Set multiplex ratio */
OLED_WriteCmd(0x3F);
OLED_WriteCmd(0xD3); /* Set display offset */
OLED_WriteCmd(0x00);
OLED_WriteCmd(0x40); /* Set display start line */
OLED_WriteCmd(0x8D); /* Set charge pump */
OLED_WriteCmd(0x14);
OLED_WriteCmd(0x20); /* Set memory addressing mode */
OLED_WriteCmd(0x00);
OLED_WriteCmd(0xA0); /* Set segment re-map */
OLED_WriteCmd(0x1F);
OLED_WriteCmd(0xC8); /* Set COM output scan direction */
OLED_WriteCmd(0xDA); /* Set COM pins hardware configuration */
OLED_WriteCmd(0x12);
OLED_WriteCmd(0x81); /* Set contrast control */
OLED_WriteCmd(0xCF);
OLED_WriteCmd(0xD9); /* Set pre-charge period */
OLED_WriteCmd(0xF1);
OLED_WriteCmd(0xDB); /* Set VCOMH deselect level */
OLED_WriteCmd(0x40);
OLED_WriteCmd(0xA4); /* Entire display on */
OLED_WriteCmd(0xA6); /* Set normal display */
OLED_WriteCmd(0xAF); /* Display on */
}
void OLED_Clear(void)
{
uint8_t u8Page, u8Col;
for(u8Page = 0; u8Page < OLED_PAGES; u8Page++)
{
OLED_WriteCmd(0xB0 + u8Page); /* Set page address */
for(u8Col = 0; u8Col < OLED_WIDTH; u8Col++)
{
OLED_WriteData(0x00); /* Clear all columns */
}
}
}
void OLED_SetCursor(uint8_t u8Page, uint8_t u8Col)
{
OLED_WriteCmd(0xB0 + u8Page); /* Set page address */
OLED_WriteCmd(0x00 + ((u8Col & 0xF0) >> 4)); /* Set higher nibble of column address */
OLED_WriteCmd(0x10 + (u8Col & 0x0F)); /* Set lower nibble of column address */
}
void OLED_DrawPixel(uint8_t u8Page, uint8_t u8Col, uint8_t u8Pixel)
{
uint8_t u8Mask = 1 << (u8Pixel % 8);
OLED_SetCursor(u8Page, u8Col);
OLED_WriteData(u8Mask);
}
void OLED_DrawLine(uint8_t u8Page, uint8_t u8ColStart, uint8_t u8ColEnd, uint8_t u8Pixel)
{
uint8_t u8Mask = 1 << (u8Pixel % 8);
uint8_t u8Col;
for(u8Col = u8ColStart; u8Col <= u8ColEnd; u8Col++)
{
OLED_SetCursor(u8Page, u8Col);
OLED_WriteData(u8Mask);
}
}
void OLED_DrawRect(uint8_t u8PageStart, uint8_t u8PageEnd, uint8_t u8ColStart, uint8_t u8ColEnd, uint8_t u8Pixel)
{
uint8_t u8Mask = 1 << (u8Pixel % 8);
uint8_t u8Page, u8Col;
for(u8Page = u8PageStart; u8Page <= u8PageEnd; u8Page++)
{
OLED_SetCursor(u8Page, u8ColStart);
for(u8Col = u8ColStart; u8Col <= u8ColEnd; u8Col++)
{
OLED_WriteData(u8Mask);
}
}
}
void OLED_FillScreen(uint8_t u8Pixel)
{
uint8_t u8Page, u8Col;
for(u8Page = 0; u8Page < OLED_PAGES; u8Page++)
{
OLED_WriteCmd(0xB0 + u8Page); /* Set page address */
for(u8Col = 0; u8Col < OLED_WIDTH; u8Col++)
{
OLED_WriteData(1 << (u8Pixel % 8)); /* Set all columns to specified pixel */
}
}
}
int main()
{
SYS_Init();
OLED_Init();
OLED_Clear();
OLED_DrawPixel(0, 0, 0);
OLED_DrawPixel(0, 1, 0);
OLED_DrawPixel(0, 2, 0);
OLED_DrawPixel(0, 3, 0);
OLED_DrawPixel(0, 4, 0);
OLED_DrawPixel(0, 5, 0);
OLED_DrawPixel(0, 6, 0);
OLED_DrawPixel(0, 7, 0);
while(1);
}
```
需要注意的是,此代码使用了I2C0来驱动OLED显示屏,因此需要适当修改代码来适应你的硬件连接。例如,如果你使用的是I2C1接口,那么需要将代码中所有的 I2C0 改为 I2C1。