stm32f103c8t6的4针oled显示屏代码
时间: 2023-08-31 10:05:18 浏览: 163
以下是使用stm32f103c8t6控制4针oled显示屏的基本代码,仅供参考:
```c
#include "stm32f10x.h"
#include "delay.h"
#define SCL_H GPIO_SetBits(GPIOB,GPIO_Pin_6)
#define SCL_L GPIO_ResetBits(GPIOB,GPIO_Pin_6)
#define SDA_H GPIO_SetBits(GPIOB,GPIO_Pin_7)
#define SDA_L GPIO_ResetBits(GPIOB,GPIO_Pin_7)
#define OLED_ADDRESS 0x78 // OLED驱动器的地址
void i2c_init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
SDA_H;
SCL_H;
}
void i2c_start(void)
{
SDA_H;
SCL_H;
delay_us(5);
SDA_L;
delay_us(5);
SCL_L;
}
void i2c_stop(void)
{
SDA_L;
SCL_H;
delay_us(5);
SDA_H;
delay_us(5);
}
void i2c_ack(void)
{
SDA_H;
delay_us(5);
SCL_H;
delay_us(5);
SCL_L;
delay_us(5);
}
void i2c_nack(void)
{
SDA_H;
delay_us(5);
SCL_H;
delay_us(5);
SCL_L;
delay_us(5);
}
void i2c_write_byte(uint8_t byte)
{
uint8_t i;
for(i=0; i<8; i++) {
if(byte & 0x80) {
SDA_H;
} else {
SDA_L;
}
byte <<= 1;
delay_us(5);
SCL_H;
delay_us(5);
SCL_L;
delay_us(5);
}
i2c_ack();
}
void oled_init(void)
{
i2c_start();
i2c_write_byte(OLED_ADDRESS);
i2c_write_byte(0x00); // 控制命令字
i2c_write_byte(0xAE); // 关闭OLED显示
i2c_write_byte(0x00);
i2c_write_byte(0xD5); // 设置时钟分频因子,震荡频率
i2c_write_byte(0x80);
i2c_write_byte(0x00);
i2c_write_byte(0xA8); // 设置驱动路数
i2c_write_byte(0x3F); // 默认值0x3f(1/64)
i2c_write_byte(0x00);
i2c_write_byte(0xD3); // 设置显示偏移
i2c_write_byte(0x00); // 默认值为0
i2c_write_byte(0x00);
i2c_write_byte(0x8D); // 电荷泵设置
i2c_write_byte(0x14); // bit2,开启/关闭
i2c_write_byte(0x00);
i2c_write_byte(0x20); // 设置内存地址模式
i2c_write_byte(0x02); // 垂直寻址模式
i2c_write_byte(0x00);
i2c_write_byte(0xA1); // 段重定向设置
i2c_write_byte(0xC8); // 行扫描方向:从上到下
i2c_write_byte(0x00);
i2c_write_byte(0xDA); // 设置COM硬件引脚配置
i2c_write_byte(0x12); // 默认0x12
i2c_write_byte(0x00);
i2c_write_byte(0x81); // 对比度设置
i2c_write_byte(0xEF); // 默认值0x7f(亮度为最大亮度),范围0x00~0xff
i2c_write_byte(0x00);
i2c_write_byte(0xD9); // 预充电周期
i2c_write_byte(0xF1); // bit[3:0],PHASE 1; bit[7:4],PHASE 2;
i2c_write_byte(0x00);
i2c_write_byte(0xDB); // VCOMH 电压倍率
i2c_write_byte(0x40); // 默认值0x20,范围0x00~0xff
i2c_write_byte(0x00);
i2c_write_byte(0xA4); // 全局显示开启;bit0,1表示开启;0表示关闭
i2c_write_byte(0x00);
i2c_write_byte(0xA6); // 设置显示方式:A6:正显示;A7:反显示
i2c_write_byte(0x00);
i2c_write_byte(0xAF); // 打开OLED显示
i2c_stop();
}
void oled_clear_screen(void)
{
uint8_t i,j;
for(i=0; i<8; i++) {
i2c_start();
i2c_write_byte(OLED_ADDRESS);
i2c_write_byte(0x00);
i2c_write_byte(0xb0+i);
i2c_write_byte(0x00);
i2c_write_byte(0x10);
for(j=0; j<128; j++) {
i2c_write_byte(0x00);
}
i2c_stop();
}
}
void oled_show_string(uint8_t row, uint8_t col, char *str)
{
uint8_t i,j,k;
i2c_start();
i2c_write_byte(OLED_ADDRESS);
i2c_write_byte(0x00);
i2c_write_byte(0xb0+row);
i2c_write_byte(((col & 0xf0) >> 4) | 0x10);
i2c_write_byte(col & 0x0f);
for(k=0; k<strlen(str); k++) {
for(i=0; i<8; i++) {
i2c_write_byte(FontArray[str[k]-32][i]);
}
}
i2c_stop();
}
int main(void)
{
i2c_init();
oled_init();
oled_clear_screen();
oled_show_string(0,0,"Hello World!");
while(1);
}
```
该代码使用GPIOB的第6和第7引脚作为I2C总线SCL和SDA,需要开启GPIOB的时钟,并设置相应的引脚模式和速度。在i2c_init()函数中,先初始化GPIOB,然后将SDA和SCL置高,表示总线空闲状态。
i2c_start()和i2c_stop()函数分别用于发送I2C总线的起始和停止信号。i2c_write_byte()函数用于向I2C总线上写入数据。
在oled_init()函数中,先发送I2C总线的起始信号,然后发送OLED驱动器的地址,接着发送一系列控制命令,将OLED驱动器初始化。具体的控制命令可以参考OLED驱动器的数据手册。
oled_clear_screen()函数用于清空OLED屏幕上的所有像素点,原理是将所有像素点的值设为0。
oled_show_string()函数用于在OLED屏幕上显示字符串,原理是根据字符集数组FontArray的内容,向OLED驱动器写入相应的像素点数据。其中,row表示要显示的行号,col表示要显示的列号,str表示要显示的字符串。由于字符集数组FontArray是自己定义的,因此需要根据具体的OLED显示屏的像素点大小来调整数组元素的值。
最后,在main()函数中,先初始化I2C总线和OLED驱动器,并清空OLED屏幕上的所有像素点。然后,在OLED屏幕的第0行第0列显示字符串"Hello World!"。
阅读全文