一、SPI配置方法
1、配置相关引脚的复用功能,使能SPI2时钟。
假设我们要使用SPI2,第一步SPI2时钟使能,第二步相关引脚的输出模式
2、初始化SPI2,设置SPI2工作模式
3、使能SPI2
初始化完成之后我们就要使能SPI2通信了。
SPI_Cmd(SPI2,ENABLE);//使能SPI外设
4.SPI传输数据
传输数据时,就需要有发送数据和接收数据的函数
发送数据函数为:void SPI_I2S_SendData(SPI_TypeDef* SPIx, uint16_t Data);
接收数据函数为:uint16_t SPI_I2S_ReceiveData(SPI_TypeDef* SPIx) ;
5、查看SPI传输状态
判断数据是否传输完成
SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE);
二、IIC配置方法
1)引脚配置
SCL,SDA可以配置成推挽输出、开漏输出(上拉电阻输出1)
SCL,SDA也可以配置成开漏输出、开漏输出(开漏输出为防止多个器件存在短路)
注意:必须器件内部自带上拉电阻 或者外界接上拉电阻 或者软件设置上拉电阻
SCL,SDA也可以配置成推挽输出、推挽输出与浮空输入(通过切换模式)
2)开漏输出和线与
硬件IIC:会自动配置为开漏输出,(不推荐不稳定)
软件IIC:
推挽输出:输出0,N-MOS激活。 输出1,P-MOS激活
开漏输出(不带上拉电阻):输出0,N-MOS激活。 输出1,P-MOS不会激活,不会输出高电平
开漏输出(带上拉电阻):输出0,N-MOS激活。 输出1,P-MOS激活
简言之:开漏输出必须有上拉电阻才能输出高电平。目前单片机GPIO口可以通过软件设置配置上下拉
三、SPI驱动OLED屏幕
需要的工具:
1.CubeMX:
2.MDK5(Keil 5):
以STM32F103C8xx芯片配置为例:
步骤:
1.打开软件CubeMX(不同版本的软件内部不太一样)
2.进入选择芯片
3.选择芯片(以STM32F103C8Tx系列举例)
4.配置时钟需要用的的选项
5.配置硬件SPI选项
6.配置OLED的部分接口
7.配置相对应的时钟数
8.在最后进行最终的配置
四、IIC驱动mpu6050
MPU6050 的内部框图
通过IIC对MPU6050寄存器进行读写
//IIC写一个字节
//reg: 寄存器地址
//data: 数据
//返回值: 0,正常
// 其他,错误代码
u8 IIC_Write_Byte(u8 reg,u8 data)
{
IIC_Start();
IIC_Send_Byte((MPU_ADDR<<1)|0);//发送器件地址+写命令
if(IIC_Wait_Ack()) //等待应答
{
IIC_Stop();
return 1;
}
IIC_Send_Byte(reg); //写寄存器地址
IIC_Wait_Ack(); //等待应答
IIC_Send_Byte(data);//发送数据
if(IIC_Wait_Ack()) //等待ACK
{
IIC_Stop();
return 1;
}
IIC_Stop();
return 0;
}
//IIC读一个字节
//reg:寄存器地址
//返回值:读到的数据
u8 IIC_Read_Byte(u8 reg)
{
u8 res;
IIC_Start();
IIC_Send_Byte((MPU_ADDR<<1)|0);//发送器件地址+写命令
IIC_Wait_Ack();//等待应答
IIC_Send_Byte(reg);//写寄存器地址
IIC_Wait_Ack();//等待应答
IIC_Start();
IIC_Send_Byte((MPU_ADDR<<1)|1);//发送期间地址+读命令
IIC_Wait_Ack();//等待应答
res=IIC_Read_Byte(0);//读取数据,发送nACK
IIC_Stop();//产生一个停止条件
return res;
}
//IIC连续写
//addr:器件地址
//reg: 寄存器地址
//len: 写入长度
//buf: 数据区
//返回值: 0,正常
// 其他,错误代码
u8 IIC_Write_Len(u8 addr,u8 reg,u8 len,u8 *buf)
{
u8 i;
IIC_Start();
IIC_Send_Byte((addr<<1)|0);//发送器件地址+写命令
if(IIC_Wait_Ack())//等待应答
{
IIC_Stop();
return 1;
}
IIC_Send_Byte(reg);//写寄存器地址
IIC_Wait_Ack();//等待应答
for(i=0;i {
IIC_Send_Byte(buf[i]);//发送数据
if(IIC_Wait_Ack())//等待ACK
{
IIC_Stop();
return 1;
}
}
IIC_Stop();
return 0;
}
//IIC连续读
//addr:器件地址
//reg:要读取的寄存器地址
//len:要读取得长度
//buf:读取到的数据存储区
//返回值: 0,正常
// 其他,错误代码
u8 IIC_Read_Len(u8 addr,u8 reg,u8 len,u8 *buf)
{
IIC_Start();