基于stm32的标准库函数写一个iic协议的0.96寸oled的驱动程序
时间: 2023-10-01 08:10:16 浏览: 138
以下是一个基于STM32标准库函数的IIC协议的0.96寸OLED驱动程序:
```
#include "stm32f10x.h"
#define OLED_ADDR 0x78
#define OLED_CMD 0x00
#define OLED_DATA 0x40
void delay_ms(uint16_t ms) {
while (ms--) {
volatile uint32_t x = 1000;
while (x--);
}
}
void IIC_Start(void) {
GPIOB->BSRR = GPIO_BSRR_BR6;
GPIOB->BSRR = GPIO_BSRR_BS7;
delay_ms(1);
}
void IIC_Stop(void) {
GPIOB->BSRR = GPIO_BSRR_BR7;
GPIOB->BSRR = GPIO_BSRR_BS6;
delay_ms(1);
}
void IIC_SendByte(uint8_t data) {
uint8_t i;
for (i = 0; i < 8; i++) {
if ((data << i) & 0x80) {
GPIOB->BSRR = GPIO_BSRR_BS7;
} else {
GPIOB->BSRR = GPIO_BSRR_BR7;
}
GPIOB->BSRR = GPIO_BSRR_BS6;
delay_ms(1);
GPIOB->BSRR = GPIO_BSRR_BR6;
}
GPIOB->BSRR = GPIO_BSRR_BS7;
GPIOB->BSRR = GPIO_BSRR_BS6;
delay_ms(1);
}
void OLED_Init(void) {
IIC_Start();
IIC_SendByte(OLED_ADDR << 1);
IIC_SendByte(OLED_CMD);
IIC_SendByte(0xae); //turn off oled panel
IIC_SendByte(0xd5);
IIC_SendByte(0x80); //set display clock divide ratio/oscillator frequency
IIC_SendByte(0xa8); //set multiplex ratio
IIC_SendByte(0x3f); //1/64 duty
IIC_SendByte(0xd3); //set display offset
IIC_SendByte(0x00);
IIC_SendByte(0x40); //set start line
IIC_SendByte(0x8d); //charge pump
IIC_SendByte(0x14);
IIC_SendByte(0x20); //set memory mode
IIC_SendByte(0x00);
IIC_SendByte(0xa1); //set segment remap
IIC_SendByte(0xc8); //set com output scan direction
IIC_SendByte(0xda); //set com pins hardware configuration
IIC_SendByte(0x12);
IIC_SendByte(0x81); //set contrast control
IIC_SendByte(0xcf);
IIC_SendByte(0xd9); //set pre-charge period
IIC_SendByte(0xf1);
IIC_SendByte(0xdb); //set vcomh
IIC_SendByte(0x40);
IIC_SendByte(0xa4); //disable entire display on
IIC_SendByte(0xa6); //set normal display
IIC_SendByte(0xaf); //turn on oled panel
IIC_Stop();
}
void OLED_SetPos(uint8_t x, uint8_t y) {
IIC_Start();
IIC_SendByte(OLED_ADDR << 1);
IIC_SendByte(OLED_CMD);
IIC_SendByte(0xb0 + y);
IIC_SendByte(((x & 0xf0) >> 4) | 0x10);
IIC_SendByte((x & 0x0f) | 0x01);
IIC_Stop();
}
void OLED_Fill(uint8_t dat) {
uint8_t i, j;
IIC_Start();
IIC_SendByte(OLED_ADDR << 1);
IIC_SendByte(OLED_CMD);
for (i = 0; i < 8; i++) {
OLED_SetPos(0, i);
for (j = 0; j < 128; j++) {
IIC_SendByte(dat);
}
}
IIC_Stop();
}
void OLED_ShowChar(uint8_t x, uint8_t y, uint8_t chr) {
uint8_t i;
uint8_t c = chr - 32;
if (x > 120 || y > 7) {
return;
}
IIC_Start();
IIC_SendByte(OLED_ADDR << 1);
IIC_SendByte(OLED_CMD);
OLED_SetPos(x, y);
for (i = 0; i < 6; i++) {
IIC_SendByte(F6x8[c][i]);
}
IIC_Stop();
}
void OLED_ShowString(uint8_t x, uint8_t y, uint8_t *str) {
uint8_t i = 0;
while (str[i] != '\0') {
OLED_ShowChar(x, y, str[i]);
x += 6;
if (x > 122) {
x = 0;
y++;
}
if (y > 7) {
break;
}
i++;
}
}
int main(void) {
RCC->APB2ENR |= RCC_APB2ENR_IOPBEN;
GPIOB->CRL &= ~GPIO_CRL_CNF6;
GPIOB->CRL |= GPIO_CRL_MODE6_0;
GPIOB->CRL &= ~GPIO_CRL_CNF7;
GPIOB->CRL |= GPIO_CRL_MODE7_0;
OLED_Init();
OLED_Fill(0x00);
OLED_ShowString(0, 0, "Hello World!");
while (1);
}
```
这个驱动程序使用了STM32F10x的标准库函数来实现IIC协议的通信,并且可以在0.96寸OLED屏幕上显示字符和字符串。需要注意的是,这个程序中的OLED屏幕地址是0x78,如果你使用的是其他OLED屏幕,可能需要修改这个地址。同时,这个程序中的字符和字符串显示使用了一个6x8的字体,如果你需要显示其他字体,可能需要修改对应的字模表。
阅读全文