DAY9-OLED,Flash和SPI通信

279 阅读5分钟

二十四.OLED编程

1.介绍

OLED是一种使用LED发光的显示设备,尺寸0.96存,分辨率128X64,使用IIC接口进行通信,OLED厂家除了提供说明手册以外,也提供参考代码,参考代码使用IIC控制器来实现的。

硬件连接:

0

0

2.IIC控制器编程

添加IIC库函数代码

0

(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)打开字模软件并配置

0

(2)生成字模

0

(3)将生成的字模拷贝到代码中使用

0

(4)制作图片

图片大小128X64,必须设置为黑白图片,最后就和制作字模一样制作图片的数据。

二十五.Flash

1.概念

Flash是嵌入式设备中最常用的辅助存储器,相当于PC中的硬盘,其数据掉电不丢失。Flash读数据就是直接读,但是写之前必须先擦除,原因是写数据只能把1变为0,不能把0变为1,所以在写之前必须把写的区域进行擦除,使数据全变为1。

2.stm32f407的内置Flash

具有写保护的功能

0

0

读操作就是直接通过指针获取对应flash地址上的数据,像内存一样访问。

0

0

3.使用库函数实现对内置Flash的访问

添加Flash代码到工程

0

(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.原理图

0

0

0

spi接口的CS,SCLK,MISO,MOSI分别连接到了PB14,PB3,PB4,PB5,这些引脚具有SPI的复用功能。

2.spi协议

spi是摩托罗拉公司发明的用于板间的串行通信方式,应用场景类似于IIC,速度高于IIC。

spi属于高速,全双工,同步的通信总线,和设备连接占用4根线,相对比较占用引脚,速度可高达40Mbps。

硬件连接:

0

CS(chip select):片选信号,主设备控制,用于选择要通信的从设备
SCLK:时钟信号,主设备控制
MISO(Master input Slave output):主设备输入,从设备输出
MOSI(Master output Slave input):主设备输出,从设备输入

0

spi协议:

spi每一位数据的发送和接收都是在时钟信号的上升沿/下降沿完成,根据选择上升沿/下降沿和时钟信号的高低电平顺序,一共有四种情形。

CPOL表示极性,CPHA表示相位

0

0

3.spi的库函数编程实现(控制器)

添加spi的库函数文件

0

(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(汉字)