stm32c8t6、oled屏幕、stlink即可实现点亮屏幕
本文基于该教程【STM32入门教程-2024】第14集 如何在OLED屏幕上挥毫_哔哩哔哩_bilibili
大家记得一键三连!!!
1.可以简单了解下OLED模块的硬件底层构造及其原理
OLED(Organic Light-Emitting Diode),有机发光二极管/半导体
是一种有可发光特性的有机分子聚合物
优点:功耗低、体积小、成本低
OLED通信采用I2C协议,详细可见上一篇文章
2.memset()函数
格式:memset(GRAM,0,sizeof(GRAM));
作用:该函数可以将内存都设置成同一个数
参数:数组、设置的值、长度
!!!记得——#include "string.h"
3.(实验)将OLED模块与STM32设置的打开I2C的GPIO口相连,并将写好的代码通过stlink烧录进STM32中,实现点亮OLED屏幕
3.1 器材
硬件:STM32F103C8T6、OLED屏幕、面包板、STLink、若干杜邦线
软件:CubeMX、keil5
3.2 结果
简单使用OLED
3.3 接线
大家对照相应杜邦线接线即可
将OLED的SDA、SCL口接到你stm32打开I2C的GPIO口上即可
(我这里PB6是SCL口、PB7是SDA口)
总体接线图
OLED屏幕接线图
3.4 CubeMX配置
SYS配置
RCC配置
I2C1设置,下方设置为:Fast Mode
时钟配置,改为72 MHZ
3.5 代码(仅添加修改处)
/*oled.h*/
#ifndef INC_OLED_H_
#define INC_OLED_H_
#include "i2c.h"
void OLED_Init();
void OLED_DisPlay_On();
void OLED_NewFrame();
void OLED_ShowFrame();
void OLED_SetPixel(uint8_t x,uint8_t y);
void OLED_Test();
#endif /* INC_OLED_H_*/
/*oled.c*/
#include "oled.h"
#include "string.h"
#define OLED_ADDRESS 0x78
void OLED_SendCmd(uint8_t cmd){
uint8_t sendBuffer[2];//2字节大小的数组
sendBuffer[0] = 0x00;//代表指令通信
sendBuffer[1] = cmd;//指令
//I2C发送函数,参数:外设句柄的指针、从机地址、发送数据的指针、数据长度、等待超时时间
HAL_I2C_Master_Transmit(&hi2c1,OLED_ADDRESS,sendBuffer,2,HAL_MAX_DELAY);
}
//OLED初始化函数,驱动包里有
void OLED_Init()
{
OLED_SendCmd(0xAE); /*关闭显示 display off*/
OLED_SendCmd(0x20);
OLED_SendCmd(0x10);
OLED_SendCmd(0xB0);
OLED_SendCmd(0xC8);
OLED_SendCmd(0x00);
OLED_SendCmd(0x10);
OLED_SendCmd(0x40);
OLED_SendCmd(0x81);
OLED_SendCmd(0xDF);
OLED_SendCmd(0xA1);
OLED_SendCmd(0xA6);
OLED_SendCmd(0xA8);
OLED_SendCmd(0x3F);
OLED_SendCmd(0xA4);
OLED_SendCmd(0xD3);
OLED_SendCmd(0x00);
OLED_SendCmd(0xD5);
OLED_SendCmd(0xF0);
OLED_SendCmd(0xD9);
OLED_SendCmd(0x22);
OLED_SendCmd(0xDA);
OLED_SendCmd(0x12);
OLED_SendCmd(0xDB);
OLED_SendCmd(0x20);
OLED_SendCmd(0x8D);
OLED_SendCmd(0x14);
OLED_NewFrame();
OLED_ShowFrame();
OLED_SendCmd(0xAF); /*开启显示 display ON*/
}
/**
* @brief 开启OLED显示
*/
void OLED_DisPlay_On()
{
OLED_SendCmd(0x8D); // 电荷泵使能
OLED_SendCmd(0x14); // 开启电荷泵
OLED_SendCmd(0xAF); // 点亮屏幕
}
//设置“显存”
uint8_t GRAM[8][128];//8页*128列,缓存128*64个像素值
//将显存清空为0
void OLED_NewFrame(){
/* for(uint8_t i = 0;i < 8;i++){
for(uint8_t j = 0; j <128;j++){
GRAM[i][j] = 0;
}
}*/
memset(GRAM,0,sizeof(GRAM));//memset函数可以将内存都设置成同一个数,参数:数组、设置的值、长度
}
//将显存显示到屏幕上的函数
void OLED_ShowFrame(){
uint8_t sendBuffer[129];//存储待发送数据的数组
sendBuffer[0] = 0x40;//指令
//总览是,将显存里的一页先显示出来,再+i来增加页数
for(uint8_t i = 0;i < 8; i++){
/*此处列循环可以直接用memcpy来代替*/
for(uint8_t j = 0;j < 128; j++){
//将数组的第j+1字节都赋值为第i页第j列的数据,把二位数组GRAM的值全部压到一位数组(待发送数据的数组)sendBuffer中
sendBuffer[j+1] = GRAM[i][j];//这里加1,是因为[0]存的是0x40
}
OLED_SendCmd(0xB0 + i);//页地址设置为第0页,页数增加,要+i
OLED_SendCmd(0x00);//列地址低四位设置为0
OLED_SendCmd(0x10);//列地址高四位设置为0
HAL_I2C_Master_Transmit(&hi2c1,OLED_ADDRESS,sendBuffer,sizeof(sendBuffer),HAL_MAX_DELAY);
}
}
//设置某个像素亮起
void OLED_SetPixel(uint8_t x,uint8_t y){
if(x >= 128 || y >= 64)return;//防止数组越界
GRAM[y/8][x] |= 0x01 << (y % 8);//像素共是128*64,即6页128列,所以y/8,一列上是8个像素,所以要进行左移操作
}
void OLED_Test(){
OLED_SendCmd(0xB0);//页地址设置为第0页
OLED_SendCmd(0x00);//列地址低四位设置为0
OLED_SendCmd(0x10);//列地址高四位设置为0
uint8_t sendBuffer[] = {0x40,0xAA};//设置发送数据内容
HAL_I2C_Master_Transmit(&hi2c1,OLED_ADDRESS,sendBuffer,sizeof(sendBuffer),HAL_MAX_DELAY);
}
/*main.c内需要include的地方*/
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "i2c.h"
#include "gpio.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "oled.h"
/* USER CODE END Includes */
/*main.c内BEGIN 2和while循环内代码*/
/* USER CODE BEGIN 2 */
HAL_Delay(200);//OLED比stm32启动慢,需要加延时
OLED_DisPlay_On();
OLED_Init();
OLED_NewFrame();
OLED_ShowFrame();
OLED_Test();
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
for(uint8_t i = 0;i < 64;i++){
OLED_NewFrame();
OLED_SetPixel(2*i,i);
OLED_ShowFrame();
}
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
[重点]!!!实验注意:(一些区别、问题以及解决方法)
①视频当中的编译软件是CubeIDE,这里使用keil5软件;视频里使用的是up自己的开发板,我们需要自己连线
②出现中文乱码情况,keil5软件需要将编码规则改为UTF-8
打开扳手
更改编码规则为UTF-8
③注意自己的OLED屏幕地址(从机地址码)
视频里的是0x70,我这里的是0x78(写在OLED屏幕背面)
④main.c里的BEGIN 2中延时设置为200,视频里为20
⑤屏幕还是没有反应,还需要打开OLED显示,
在main.c中的BEGIN 2内写上:OLED_DisPlay_On()
别忘了在oled.c内声明下函数:
OLED_DisPlay_On() 定义
详细见上面3.5代码
⑥OLED_Init()初始化代码,是其驱动包内的,可以直接复制我上方OLED_Init()代码
⑦视频内若有不懂代码,可以见我上方3.5代码详细注释!!!
⑧如果代码部分还是不对,别忘了在.h文件中声明下