二十四.OLED编程
1.介绍
OLED是一种使用LED发光的显示设备,尺寸0.96存,分辨率128X64,使用IIC接口进行通信,OLED厂家除了提供说明手册以外,也提供参考代码,参考代码使用IIC控制器来实现的。
硬件连接:
2.IIC控制器编程
添加IIC库函数代码
(1)开始时钟
RCC_xxx
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
(2)将GPIO配置为IIC功能
GPIO_Init(...);
GPIO_AFPinConfig(...);
(3)IIC初始化
void I2C_Init(I2C_TypeDef* I2Cx, I2C_InitTypeDef* I2C_InitStruct);
参数:
I2Cx - 哪个IIC
I2C_InitStruct - IIC初始化结构
typedef struct
{
uint32_t I2C_ClockSpeed; /*!< 时钟速度 100K ~ 400K */
uint16_t I2C_Mode; /*!< IIC模式 @ref I2C_mode */
uint16_t I2C_DutyCycle; /*!< 高低电平的比例 @ref I2C_duty_cycle_in_fast_mode */
uint16_t I2C_OwnAddress1; /*!< 自己的地址 */
uint16_t I2C_Ack; /*!< ACK使能 @ref I2C_acknowledgement */
uint16_t I2C_AcknowledgedAddress; /*!< 从设备地址位数 @ref I2C_acknowledged_address */
}I2C_InitTypeDef;
(4)如果需要读取IIC数据开启应答使能
I2C_AcknowledgeConfig(I2C_TypeDef* I2Cx, FunctionalState NewState);
(5)使能IIC
I2C_Cmd(I2C1,ENABLE);
(6)进行IIC通信
1)查询总线是否繁忙
I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY);
2)起始信号
void I2C_GenerateSTART(I2C_TypeDef* I2Cx, FunctionalState NewState);
3)设置好对应的模式
I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT);
4)设置从设备从设备地址和读写信号
I2C_Send7bitAddress(I2C1, /*从设备地址*/, I2C_Direction_Transmitter);
I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED);//主设备发送模式
5)发送和接收数据
void I2C_SendData(I2C_TypeDef* I2Cx, uint8_t Data);
I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED);//等待发送完成
I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED);//确认有数据收到
uint8_t I2C_ReceiveData(I2C_TypeDef* I2Cx);
6)停止信号
void I2C_GenerateSTOP(I2C_TypeDef* I2Cx, FunctionalState NewState);
3.移植OLED
(1)初始化
I2C_Configuration();//初始化IIC控制器
OLED_Init();//OLED初始化
(2)显示
void OLED_Fill(unsigned char fill_Data);//全屏填充
//显示ascii字符
void OLED_ShowStr(unsigned char x, unsigned char y, unsigned char ch[], unsigned char TextSize);
//显示汉字
void OLED_ShowCN(unsigned char x, unsigned char y, unsigned char N);
练习:
完成OLED的移植,将超声波距离读出来显示到OLED上
4.制作字模
(1)打开字模软件并配置
(2)生成字模
(3)将生成的字模拷贝到代码中使用
(4)制作图片
图片大小128X64,必须设置为黑白图片,最后就和制作字模一样制作图片的数据。
二十五.Flash
1.概念
Flash是嵌入式设备中最常用的辅助存储器,相当于PC中的硬盘,其数据掉电不丢失。Flash读数据就是直接读,但是写之前必须先擦除,原因是写数据只能把1变为0,不能把0变为1,所以在写之前必须把写的区域进行擦除,使数据全变为1。
2.stm32f407的内置Flash
具有写保护的功能
读操作就是直接通过指针获取对应flash地址上的数据,像内存一样访问。
3.使用库函数实现对内置Flash的访问
添加Flash代码到工程
(1)解除写保护/恢复写保护
void FLASH_Unlock(void);
void FLASH_Lock(void);
(2)查询状态
FLASH_Status FLASH_GetStatus(void);
//返回FLASH_COMPLETE表示空闲且正常
(3)擦除扇区
FLASH_Status FLASH_EraseSector(uint32_t FLASH_Sector, uint8_t VoltageRange);
参数:
FLASH_Sector - 哪个扇区
VoltageRange - 电压范围 VoltageRange_3
//返回FLASH_COMPLETE表示擦除成功
(4)写操作
FLASH_Status FLASH_ProgramWord(uint32_t Address, uint32_t Data);
参数:
Address - 写的地址
Data - 写的数据
//返回FLASH_COMPLETE表示写成功
(5)清除标志 ---------- 开始操作前
void FLASH_ClearFlag(uint32_t FLASH_FLAG);
参数:
@arg FLASH_FLAG_EOP: FLASH End of Operation flag
@arg FLASH_FLAG_OPERR: FLASH operation Error flag
@arg FLASH_FLAG_WRPERR: FLASH Write protected error flag
@arg FLASH_FLAG_PGAERR: FLASH Programming Alignment error flag
@arg FLASH_FLAG_PGPERR: FLASH Programming Parallelism error flag
@arg FLASH_FLAG_PGSERR: FLASH Programming Sequence error flag
注意:
1.读操作就是直接将Flash地址当做内存使用
2.擦除和写之前必须解除写保护,操作完成后恢复写保护
3.不要去操作存储程序的扇区(0~3)
练习:
通过蓝牙命令读取温湿度并存储到Flash
也可以通过蓝牙命令将存储的温湿度读出来
二十六.spi flash
1.原理图
spi接口的CS,SCLK,MISO,MOSI分别连接到了PB14,PB3,PB4,PB5,这些引脚具有SPI的复用功能。
2.spi协议
spi是摩托罗拉公司发明的用于板间的串行通信方式,应用场景类似于IIC,速度高于IIC。
spi属于高速,全双工,同步的通信总线,和设备连接占用4根线,相对比较占用引脚,速度可高达40Mbps。
硬件连接:
CS(chip select):片选信号,主设备控制,用于选择要通信的从设备
SCLK:时钟信号,主设备控制
MISO(Master input Slave output):主设备输入,从设备输出
MOSI(Master output Slave input):主设备输出,从设备输入
spi协议:
spi每一位数据的发送和接收都是在时钟信号的上升沿/下降沿完成,根据选择上升沿/下降沿和时钟信号的高低电平顺序,一共有四种情形。
CPOL表示极性,CPHA表示相位
3.spi的库函数编程实现(控制器)
添加spi的库函数文件
(1)开启时钟
GPIOB时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
(2)将GPIO配置为SPI的复用功能
GPIO_Init(...);
GPIO_AFPinConfig(...);
(3)初始化SPI
void SPI_Init(SPI_TypeDef* SPIx, SPI_InitTypeDef* SPI_InitStruct);
参数:
SPIx - 哪路SPI
SPI_InitStruct - SPI初始化结构
typedef struct
{
uint16_t SPI_Direction; /*!< 传输方向 单向/双向 @ref SPI_data_direction */
uint16_t SPI_Mode; /*!< 主/从设备选择 @ref SPI_mode */
uint16_t SPI_DataSize; /*!< 一次传输数据位长度 @ref SPI_data_size */
uint16_t SPI_CPOL; /*!< 时钟信号极性选择 高/低 @ref SPI_Clock_Polarity */
uint16_t SPI_CPHA; /*!< 相位,选择采样的边沿 @ref SPI_Clock_Phase */
uint16_t SPI_NSS; /*!< 片选信号选择 软件/硬件 @ref SPI_Slave_Select_management */
uint16_t SPI_BaudRatePrescaler; /*!< 参考时钟的分频系数 10M左右 */
uint16_t SPI_FirstBit; /*!< 传输位顺序 高位/低位 @ref SPI_MSB_LSB_transmission */
uint16_t SPI_CRCPolynomial; /*!< CRC校验,无需设置 */
}SPI_InitTypeDef;
(4)使能SPI
SPI_Cmd(...);
(5)使用SPI传输数据
//发送和接收同时进行,先发送
void SPI_I2S_SendData(SPI_TypeDef* SPIx, uint16_t Data);
uint16_t SPI_I2S_ReceiveData(SPI_TypeDef* SPIx);
(6)查询SPI传输状态
FlagStatus SPI_I2S_GetFlagStatus(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLAG);
//SPI_I2S_FLAG_TXE ----- 发送完成标志
作业:
实现蓝牙读取距离,温湿度,可燃气体状态时
将数据显示到OLED(汉字)