概述
重点来了
这个课程设计中硬件方面一共会有两个重点
其中一个自然就是今天要做的OLCD屏幕的驱动
第二个是RFID标签的读写
由于我买的是野火的I2C OLCD屏幕,自然选择野火自带的例程进行修改,让其能够适配HAL库的开发
当然既然是I2C的OLCD,那必然离不开I2C协议
值得一提的是,在stm32要实现I2C,可以选择两种方式
1.硬件I2C
2.软件模拟I2C
虽然火哥在标准库的视频中说过硬件I2C可能会存在一定的问题,但是既然买了板子,当然要用哇,不用岂不是暴殄天物。
所以,我们还是在cubemx中对硬件进行配置,然后驱动OLCD屏幕
I2C是一种协议,当然其核心还是时序逻辑,软件I2C同样好用,但是对编程稍微较高,未来可能会在b站上录制相应的视频
stm32cubemx
首先还是查找硬件相关的手册
这里就不在截图了
总之,选择PB6、PB7引脚输出I2C,正好对应为I2C1的配置
在cubemx中进行配置
I2C的模式当然就是选择I2C
subus可以自己看看,按照火哥讲的,这个是另一种协议不在考虑范围内
下面就是I2C的详细配置
选择高速模式,这个是由外设决定
OLCD支持高速模式,所以可以这样设置
占空比选择2
延迟Disabled
地址位数7
Disabled
slave地址0(不选用主从模式)
然后生成代码
keil5
好!
工程变得越来越复杂了,我们细心的构建一下工程目录
除了系统自动生成的文件夹外,我们在自己创建一个
user
文件夹,用于存放自己编写的文件
工程目录如下:
其中**.ioc**文件当然就是cubemx文件(存放路径不要有中文名,要全英文)
core就是包含src和inc,即c文件和头文件的地方属于系统配置文件,包括着各种系统外设的初始化
Drivers芯片包文件
MDK-ARM工程文件以及各种Debug生成文件
User文件夹就是自己创建的文件
点进user文件夹中
oled就是所有有关oled的模块文件(OLCD)
bsp_system.h文件中包含着全部的自己创建的头文件
(未来大型工程,每次都要写一遍包含头文件太麻烦了)
codetable.h字模表,可以不用管,这是为了LCD中显示中文而用的,如果不用显示中文可以将这个头文件删除
买外设的时候必然会给你提供一定的例程文件
我这里就不再进行分析了,比较麻烦,有兴趣的自己看就行了
总之你需要在keil中有这几个文件
自己添加的就是这个OLED_I2C.c文件以及相关的头文件
在这个文件里面有所有有关OLED的函数
下面是OLED_I2C.c文件
#include "OLED_I2C.h"
#include "i2c.h"
#include "codetab.h"
#include "stm32f1xx_hal.h"
void WriteCmd(unsigned char I2C_OLED_COMmand)//写命令
{
HAL_I2C_Mem_Write(&hi2c1,OLED_ADD,OLED_COM,I2C_MEMADD_SIZE_8BIT,&I2C_OLED_COMmand,1,100);
}
void WriteOLED_DAT(unsigned char I2C_OLED_DATa)//写数据
{
HAL_I2C_Mem_Write(&hi2c1,OLED_ADD,OLED_DAT,I2C_MEMADD_SIZE_8BIT,&I2C_OLED_DATa,1,100);
}
void OLED_Init(void)
{
HAL_Delay(100); //这里的延时很重要
WriteCmd(0xAE); //display off
WriteCmd(0x20); //Set Memory Addressing Mode
WriteCmd(0x10); //00,Horizontal Addressing Mode;01,Vertical Addressing Mode;10,Page Addressing Mode (RESET);11,Invalid
WriteCmd(0xb0); //Set Page Start Address for Page Addressing Mode,0-7
WriteCmd(0xc8); //Set OLED_COM Output Scan Direction
WriteCmd(0x00); //---set low column address
WriteCmd(0x10); //---set high column address
WriteCmd(0x40); //--set start line address
WriteCmd(0x81); //--set contrast control register
WriteCmd(0xff); //亮度调节 0x00~0xff
WriteCmd(0xa1); //--set segment re-map 0 to 127
WriteCmd(0xa6); //--set normal display
WriteCmd(0xa8); //--set multiplex ratio(1 to 64)
WriteCmd(0x3F); //
WriteCmd(0xa4); //0xa4,Output follows RAM content;0xa5,Output ignores RAM content
WriteCmd(0xd3); //-set display offset
WriteCmd(0x00); //-not offset
WriteCmd(0xd5); //--set display clock divide ratio/oscillator frequency
WriteCmd(0xf0); //--set divide ratio
WriteCmd(0xd9); //--set pre-charge period
WriteCmd(0x22); //
WriteCmd(0xda); //--set OLED_COM pins hardware configuration
WriteCmd(0x12);
WriteCmd(0xdb); //--set vOLED_COMh
WriteCmd(0x20); //0x20,0.77xVcc
WriteCmd(0x8d); //--set DC-DC enable
WriteCmd(0x14); //
WriteCmd(0xaf); //--turn on oled panel
}
void OLED_SetPos(unsigned char x, unsigned char y) //设置起始点坐标
{
WriteCmd(0xb0+y);
WriteCmd(((x&0xf0)>>4)|0x10);
WriteCmd((x&0x0f)|0x01);
}
void OLED_Fill(unsigned char fill_OLED_DATa)//全屏填充
{
unsigned char m,n;
for(m=0;m<8;m++)
{
WriteCmd(0xb0+m); //page0-page1
WriteCmd(0x00); //low column start address
WriteCmd(0x10); //high column start address
for(n=0;n<128;n++)
{
WriteOLED_DAT(fill_OLED_DATa);
}
}
}
void OLED_CLS(void)//清屏
{
OLED_Fill(0x00);
}
void OLED_ON(void)
{
WriteCmd(0X8D); //设置电荷泵
WriteCmd(0X14); //开启电荷泵
WriteCmd(0XAF); //OLED唤醒
}
void OLED_OFF(void)
{
WriteCmd(0X8D); //设置电荷泵
WriteCmd(0X10); //关闭电荷泵
WriteCmd(0XAE); //OLED休眠
}
// Parameters : x,y -- 起始点坐标(x:0~127, y:0~7); ch[] -- 要显示的字符串; TextSize -- 字符大小(1:6*8 ; 2:8*16)
// Description : 显示codetab.h中的ASCII字符,有6*8和8*16可选择
void OLED_ShowStr(unsigned char x, unsigned char y, unsigned char ch[], unsigned char TextSize)
{
unsigned char c = 0,i = 0,j = 0;
switch(TextSize)
{
case 1:
{
while(ch[j] != '