stm32oled屏幕显示程序
时间: 2023-10-07 09:11:29 浏览: 52
以下是一个简单的STM32 OLED屏幕显示程序,使用了I2C通信协议:
首先,在main.c文件中添加以下代码:
```
#include "stm32f10x.h"
#include "ssd1306.h"
int main(void)
{
// 初始化OLED屏幕
ssd1306_Init();
// 清空屏幕
ssd1306_Fill(Black);
// 设置字体大小
ssd1306_SetCursor(0,0);
ssd1306_WriteString("Hello World!", Font_11x18, White);
// 更新显示
ssd1306_UpdateScreen();
while(1)
{
}
}
```
然后,在ssd1306.h文件中添加以下代码:
```
#ifndef SSD1306_H
#define SSD1306_H
#include "stm32f10x.h"
#define SSD1306_I2C_ADDR 0x78
#define SSD1306_WIDTH 128
#define SSD1306_HEIGHT 64
typedef enum {
Black = 0x00, /*!< Black color, no pixel */
White = 0x01 /*!< Pixel is set. Color depends on LCD */
} SSD1306_COLOR;
void ssd1306_Init(void);
void ssd1306_Fill(SSD1306_COLOR color);
void ssd1306_UpdateScreen(void);
void ssd1306_DrawPixel(uint8_t x, uint8_t y, SSD1306_COLOR color);
char ssd1306_WriteChar(char ch, FontDef Font, SSD1306_COLOR color);
void ssd1306_SetCursor(uint8_t x, uint8_t y);
void ssd1306_WriteString(char* str, FontDef Font, SSD1306_COLOR color);
#endif /* SSD1306_H */
```
最后,在ssd1306.c文件中添加以下代码:
```
#include "ssd1306.h"
#include "fonts.h"
#include "stm32f10x_i2c.h"
static uint8_t SSD1306_Buffer[SSD1306_WIDTH * SSD1306_HEIGHT / 8];
static uint8_t SSD1306_Commands[] = {
0xAE, // display off
0xD5, 0x80, // set display clock div
0xA8, 0x3F, // set multiplex
0xD3, 0x00, // set display offset
0x40, // set start line
0x8D, 0x14, // charge pump
0x20, 0x00, // memory mode
0xA1, // segment remap
0xC8, // com scan dir
0xDA, 0x12, // com pin config
0x81, 0xCF, // contrast
0xD9, 0xF1, // precharge
0xDB, 0x40, // vcomh
0xA4, // all pixels off
0xA6, // display on
};
void ssd1306_I2C_WriteCommand(uint8_t command)
{
I2C_GenerateSTART(I2C1, ENABLE);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
I2C_Send7bitAddress(I2C1, SSD1306_I2C_ADDR, I2C_Direction_Transmitter);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
I2C_SendData(I2C1, 0x00);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
I2C_SendData(I2C1, command);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
I2C_GenerateSTOP(I2C1, ENABLE);
}
void ssd1306_Init(void)
{
I2C_InitTypeDef I2C_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
I2C_DeInit(I2C1);
I2C_Cmd(I2C1, ENABLE);
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
I2C_InitStructure.I2C_OwnAddress1 = 0x00;
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_InitStructure.I2C_ClockSpeed = 400000;
I2C_Init(I2C1, &I2C_InitStructure);
for(uint8_t i = 0; i < sizeof(SSD1306_Commands); i++)
{
ssd1306_I2C_WriteCommand(SSD1306_Commands[i]);
}
ssd1306_Fill(Black);
ssd1306_UpdateScreen();
}
void ssd1306_Fill(SSD1306_COLOR color)
{
memset(SSD1306_Buffer, (color == Black) ? 0x00 : 0xFF, sizeof(SSD1306_Buffer));
}
void ssd1306_UpdateScreen(void)
{
for(uint8_t page = 0; page < SSD1306_HEIGHT / 8; page++)
{
ssd1306_I2C_WriteCommand(0xB0 + page);
ssd1306_I2C_WriteCommand(0x00);
ssd1306_I2C_WriteCommand(0x10);
for(uint8_t column = 0; column < SSD1306_WIDTH; column++)
{
ssd1306_I2C_WriteCommand(SSD1306_Buffer[column + page * SSD1306_WIDTH]);
}
}
}
void ssd1306_DrawPixel(uint8_t x, uint8_t y, SSD1306_COLOR color)
{
if(x >= SSD1306_WIDTH || y >= SSD1306_HEIGHT)
{
return;
}
if(color == White)
{
SSD1306_Buffer[x + (y / 8) * SSD1306_WIDTH] |= 1 << (y % 8);
}
else
{
SSD1306_Buffer[x + (y / 8) * SSD1306_WIDTH] &= ~(1 << (y % 8));
}
}
char ssd1306_WriteChar(char ch, FontDef Font, SSD1306_COLOR color)
{
uint32_t i, b, j;
// 判断字符是否在字体范围内
if((ch < 32) || (ch > 126))
{
return 0;
}
// 遍历字体数据
for(i = 0; i < Font.FontHeight; i++)
{
b = Font.data[(ch - 32) * Font.FontHeight + i];
for(j = 0; j < Font.FontWidth; j++)
{
if((b << j) & 0x8000)
{
ssd1306_DrawPixel(Font.CurrentX + j, (Font.CurrentY + i), (SSD1306_COLOR)color);
}
else
{
ssd1306_DrawPixel(Font.CurrentX + j, (Font.CurrentY + i), (SSD1306_COLOR)!color);
}
}
}
// 移动光标
Font.CurrentX += Font.FontWidth;
// 返回字符宽度
return Font.FontWidth;
}
void ssd1306_SetCursor(uint8_t x, uint8_t y)
{
Font.CurrentX = x;
Font.CurrentY = y;
}
void ssd1306_WriteString(char* str, FontDef Font, SSD1306_COLOR color)
{
while(*str)
{
ssd1306_WriteChar(*str, Font, color);
str++;
}
}
```
以上代码实现了一些基本的功能,例如初始化OLED屏幕、清空屏幕、设置字体大小、打印字符串等。你可以根据自己的需要添加更多的功能。