打印
[STM32F0]

STM32的SPI及IIC

[复制链接]
234|12
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
SPI配置方法
1.SPI简介
SPI 是英语Serial Peripheral interface的缩写,顾名思义就是串行外围设备接口。是Motorola首先在其MC68HCXX系列处理器上定义的。

SPI,是一种高速的,全双工,同步的通信总线,并且在芯片的管脚上只占用四根线,节约了芯片的管脚,同时为PCB的布局上节省空间,提供方便,主要应用在 EEPROM,FLASH,实时时钟,AD转换器,还有数字信号处理器和数字信号解码器之间。

2.SPI工作原理总结
①硬件上为4根线。
②主机和从机都有一个串行移位寄存器,主机通过向它的SPI串行寄存器写入一个字节来发起一次传输。
③串行移位寄存器通过MOSI信号线将字节传送给从机,从机也将自己的串行移位寄存器中的内容通过MISO信号线返回给主机。这样,两个移位寄存器中的内容就被交换。
④外设的写操作和读操作是同步完成的。如果只进行写操作,主机只需忽略接收到的字节;反之,若主机要读取从机的一个字节,就必须发送一个空字节来引发从机的传输。


使用特权

评论回复
沙发
是你的乱码|  楼主 | 2024-3-31 21:44 | 只看该作者
配置方法
1)时钟使能。GPIO时钟使能RCC->APB2ENR,SPI时钟使能RCC->APB2ENR设置。(为什么还要连接GPIO时钟,参见STM32参考手册8.1.4节。手册上这么说的:对于复用输出功能,端口必须配置成复用功能输出模式(推挽或开漏)。)

RCC_AHBxPeriphClockCmd() / RCC_APBxPeriphClockCmd();

使用特权

评论回复
板凳
是你的乱码|  楼主 | 2024-3-31 21:44 | 只看该作者
配置GPIO工作模式。配置GPIO片选,由软件管理(即自定义引脚),推挽输出,上拉;配置SPI引脚SCK、MOSI、MISO所用到的引脚为复用功能;GPIOX->CR1 GPIOX->ODR;

void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct);

使用特权

评论回复
地板
是你的乱码|  楼主 | 2024-3-31 21:44 | 只看该作者
SPI设置工作模式。通过配置SPIx->CR1来设置SPI 的工作模式。配置工作模式为全双工,主机模式,SCK闲时电平为高,第二个时钟沿(上升沿)采样数据,内部从机选择软件管理模式。设置SPI的时钟频率(最大18MHZ),设置数据格式(MSB在前还是LSB在后),内部从机选择设置为主机(置1)。

void SPI_Init(SPI_TypeDef* SPIx, SPI_InitTypeDef* SPI_InitStruct);

使用特权

评论回复
5
是你的乱码|  楼主 | 2024-3-31 21:45 | 只看该作者
使能SPI,启动传输。

void SPI_Cmd(SPI_TypeDef* SPIx, FunctionalState NewState);

使用特权

评论回复
6
是你的乱码|  楼主 | 2024-3-31 21:45 | 只看该作者
SPI传输数据。

void SPI_I2S_SendData(SPI_TypeDef* SPIx, uint16_t Data);
uint16_t SPI_I2S_ReceiveData(SPI_TypeDef* SPIx) ;

使用特权

评论回复
7
是你的乱码|  楼主 | 2024-3-31 21:45 | 只看该作者
查看SPI传输状态。

SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE);

使用特权

评论回复
8
是你的乱码|  楼主 | 2024-3-31 21:45 | 只看该作者
总结
void SPI1_Init(void)
{         
  GPIO_InitTypeDef  GPIO_InitStructure;
  SPI_InitTypeDef  SPI_InitStructure;
       
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);//使能GPIOA时钟
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);//使能SPI1时钟

  //PB3,4,5初始化设置
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5;//PB3~5复用功能输出
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用功能
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
  GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化
       
  GPIO_PinAFConfig(GPIOB,GPIO_PinSource3,GPIO_AF_SPI1); //PB3复用为SPI1
  GPIO_PinAFConfig(GPIOB,GPIO_PinSource4,GPIO_AF_SPI1); //PB4复用为SPI1
  GPIO_PinAFConfig(GPIOB,GPIO_PinSource5,GPIO_AF_SPI1); //PB5复用为SPI1

//这里只针对SPI口初始化
  RCC_APB2PeriphResetCmd(RCC_APB2Periph_SPI1,ENABLE);//复位SPI1
  RCC_APB2PeriphResetCmd(RCC_APB2Periph_SPI1,DISABLE);//停止复位SPI1


  SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;//设置SPI单向或者双向的数据模式:SPI设置为双线双向全双工
  SPI_InitStructure.SPI_Mode = SPI_Mode_Master;                //设置SPI工作模式:设置为主SPI
  SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;                //设置SPI的数据大小:SPI发送接收8位帧
  SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;                //串行同步时钟的空闲状态为高电平
  SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;        //串行同步时钟的第二个跳变沿(上升或下降)数据被采样
  SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;                //NSS信号由硬件(NSS管脚)还是软件(使用SSI位)管理:内部NSS信号由SSI控制
  SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;                //定义波特率预分频的值:波特率预分频值为256
  SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;        //指定数据传输从MSB位还是LSB位开始:数据传输从MSB位开始
  SPI_InitStructure.SPI_CRCPolynomial = 7;        //CRC值计算的多项式
  SPI_Init(SPI1, &SPI_InitStructure);  //根据SPI_InitStruct中指定的参数初始化外设SPIx寄存器

  SPI_Cmd(SPI1, ENABLE); //使能SPI外设

  SPI1_ReadWriteByte(0xff);//启动传输                 
}   
//SPI1速度设置函数
//SPI速度=FAPB2/分频系数
//@ref SPI_BaudRate_Prescaler:SPI_BaudRatePrescaler_2~SPI_BaudRatePrescaler_256  
//fAPB2时钟一般为84Mhz
void SPI1_SetSpeed(u8 SPI_BaudRatePrescaler)
{
  assert_param(IS_SPI_BAUDRATE_PRESCALER(SPI_BaudRatePrescaler));//判断有效性
        SPI1->CR1&=0XFFC7;//位3-5清零,用来设置波特率
        SPI1->CR1|=SPI_BaudRatePrescaler;        //设置SPI1的速度
        SPI_Cmd(SPI1,ENABLE); //使能SPI1
}
//SPI1 读写一个字节
//TxData:要写入的字节
//返回值:读取到的字节
u8 SPI1_ReadWriteByte(u8 TxData)
{                                          

    while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET){}//等待发送区空
       
     SPI_I2S_SendData(SPI1, TxData); //通过外设SPIx发送一个byte数据
               
    while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET){} //等待接收完一个byte

     return SPI_I2S_ReceiveData(SPI1); //返回通过SPIx最近接收的数据
                    
}

使用特权

评论回复
9
是你的乱码|  楼主 | 2024-3-31 21:45 | 只看该作者
IIC配置方法
1.IIC功能

I2C模块接收和发送数据,并将数据从串行转换成并行,或并行转换成串行。可以开启或禁止中断。接口通过数据引脚(SDA)和时钟引脚(SCL)连接到I2C总线。允许连接到标准(高达100kHz)或快速(高达400kHz)的I2C总线。

使用特权

评论回复
10
是你的乱码|  楼主 | 2024-3-31 21:45 | 只看该作者
I2C 总线在传送数据过程中共有三种类型信号, 它们分别是:开始信号、结束信号和应答信号。
开始信号:SCL 为高电平时,SDA 由高电平向低电平跳变,开始传送数据。
结束信号:SCL 为高电平时,SDA 由低电平向高电平跳变,结束传送数据。
应答信号:接收数据的 IC 在接收到 8bit 数据后,向发送数据的 IC 发出特定的低电平脉冲,表示已收到数据。CPU 向受控单元发出一个信号后,等待受控单元发出一个应答信号,CPU 接收到应答信号后,根据实际情况作出是否继续传递信号的判断。若未收到应答信号,由判断为受控单元出现故障。

使用特权

评论回复
11
是你的乱码|  楼主 | 2024-3-31 21:50 | 只看该作者
这些信号中,起始信号是必需的,结束信号和应答信号,都可以不要。

#include "iic.h"

//*****************************************************
// IIC2初始化函数:初始化STM32硬件自带的IIC2
//                 IIC2_SCL对应GPIO.B10
//                 IIC2_SDA对应GPIO.B11
//*****************************************************
void I2C2_Init(void)
{
        /*GPIO与IIC初始化结构体*/
        GPIO_InitTypeDef GPIO_InitStructure;
        I2C_InitTypeDef I2C_InitStructure;
       
        /*GPIO与IIC时钟使能*/
        RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE );                //GPIOB时钟使能
        RCC_APB1PeriphClockCmd( RCC_APB1Periph_I2C2, ENABLE );                //IIC2时钟使能

        /*初始化GPIO*/
        GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_10 | GPIO_Pin_11;        //初始化GPIO.B10(IIC2_SCL),GPIO.B11(IIC2_SDA)
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;                        //最高输出速度50Hz
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;                                //输入输出模式为复用功能开漏输出
        GPIO_Init( GPIOB, &GPIO_InitStructure );                                        //根据GPIO初始化结构体初始化GPIOB
       
        /*初始化IIC2*/
        I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;                                        //设置为IIC模式
        I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;                        //设置IIC的占空比,低电平除以高电平值为2
        I2C_InitStructure.I2C_OwnAddress1 = AT24C02_ADDRESS;                //指定第一个设备的地址为7位地址
        I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;                                        //使能ACK信号
        I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;        //指定7位地址
        I2C_InitStructure.I2C_ClockSpeed = 400000;                                        //时钟频率,必须小于等于400KHz
       
        I2C_Cmd( I2C2, ENABLE );                                                                           //使能IIC2
        I2C_Init( I2C2, &I2C_InitStructure );                                                //根据IIC初始化结构体初始化IIC2
       
        /*允许一字节一应答模式*/
        I2C_AcknowledgeConfig( I2C2, ENABLE );                                          //使能IIC2应答状态  
}


//*****************************************************
// IIC2写函数   :往IIC设备写入一个BYTE的data
// id           :IIC设备的id
// write_address:数据要写入IIC设备的地址
// data         :需要写入的数据
//*****************************************************
void I2C2_WriteByte( u8 id, u8 write_address, u8 data )
{
        while (I2C_GetFlagStatus(I2C2, I2C_FLAG_BUSY));                                                                //当IIC2状态为BUSY时,一直停在这里死循环
       
        /*发送START之后要等待,意味着START条件被正确释放,此时IIC总线上没有其它外设*/
        I2C_GenerateSTART( I2C2, ENABLE );                                                                                        //一旦不为BUSY,跳出循环,产生START条件       
        while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT));                                //如果主机被选中(死循环等待ACK信号)
         
        /*主机发送地址联系从机后,主机要等待从机的ACK,如果主机设置为发射,*/
        /*则收到ACK信号时 I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED 被置1 */
        I2C_Send7bitAddress( I2C2, id, I2C_Direction_Transmitter );                                        //发送从机地址以选择从机,主机为发送模式
        while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));        //如果主机发射模式被选中(死循环等待ACK信号)

        /*通讯建立(生成START过程与从机地址被承认)以后,主机发送数据,*/
        /*如果数据被转移并输出IIC总线,则 I2C_EVENT_MASTER_BYTE_TRANSMITTED 被置1*/
        I2C_SendData( I2C2, write_address );                                                                                //将write_address,即要写的地址通过IIC2发送出去       
        while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED));                        //如果地址已经从IIC2成功发射出去(死循环等待ACK信号)

        /*往寄存器发送数据data*/
        I2C_SendData( I2C2, data );
        while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED));                       

        I2C_GenerateSTOP( I2C2, ENABLE );                                                                                        //IIC2产生STOP条件

        /*循环确保IIC设备与主机的通讯建立*/
        do
        {               
                I2C_GenerateSTART( I2C2, ENABLE );                                                                                //IIC2产生START条件
                I2C_Send7bitAddress( I2C2, AT24C02_ADDRESS, I2C_Direction_Transmitter );//发送EEPROM地址0XA0
        }
        while (!(I2C_ReadRegister(I2C2,I2C_Register_SR1)&0x0002));                                        //读取IIC2->SR1的值,当IIC2->SR1[1] = 1时跳出循环
                                                                                                                                                                //此时地址发送结束

        I2C_ClearFlag( I2C2, I2C_FLAG_AF );                                                                                        //IIC2清除应答错误标志位   
        I2C_GenerateSTOP( I2C2, ENABLE );                                                                                          //IIC2产生STOP条件
}


//*****************************************************
// IIC2读函数   :从IIC设备的指定地址中读出一个BYTE的数据
// id           :IIC设备的id
// read_address :需要读取IIC数据的设备的地址
// 返回值       :读出的数据
//*****************************************************
u8 I2C2_ReadByte( u8 id, u8 read_address )
{  
        u8 data;  
        /***主机发送地址***/
        while (I2C_GetFlagStatus(I2C2, I2C_FLAG_BUSY));                                                                //当IIC2状态为BUSY时,一直停在这里死循环
       
        /*发送START之后要等待,意味着START条件被正确释放,此时IIC总线上没有其它外设*/
        I2C_GenerateSTART( I2C2, ENABLE );                                                                                        //一旦不为BUSY,跳出循环,产生START条件       
        while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT));                                //如果主机被选中(死循环等待ACK信号)

        /*主机发送地址联系从机后,主机要等待从机的ACK,如果主机设置为发射,*/
        /*则收到ACK信号时 I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED 被置1 */
        I2C_Send7bitAddress( I2C2, id, I2C_Direction_Transmitter );                                        //发送从机地址以选择从机,主机为发送模式
        while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));        //如果主机发射模式被选中(死循环等待ACK信号)

        /*通讯建立(生成START过程与从机地址被承认)以后,主机发送数据,*/
        /*如果数据被转移并输出IIC总线,则 I2C_EVENT_MASTER_BYTE_TRANSMITTED 被置1*/
        I2C_Cmd( I2C2, ENABLE );                                                                                                        //使能IIC2
        I2C_SendData( I2C2, read_address );                                                                                  //将write_address,即要读的地址通过IIC2发送出去
        while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED));                        //如果地址已经从IIC2成功发射出去(死循环等待ACK信号?
          
        I2C_GenerateSTART( I2C2, ENABLE );                                                                                        //产生START条件
        while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT));                                //如果主机被选中(死循环等待ACK信号)
       
       
        /***主机接收数据***/
        I2C_Send7bitAddress( I2C2, id, I2C_Direction_Receiver );                                        //主机设置为接收模式
        while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));                //如果主机接收模式被选中(死循环等待ACK信号)

        I2C_AcknowledgeConfig( I2C2, DISABLE );                                                                                //失能IIC2的应答状态
        I2C_GenerateSTOP( I2C2, ENABLE );                                                                                        //产生STOP条件
        while (!(I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_RECEIVED)));                        //如果主机接收数据成功(死循环等待ACK信号)
                  
        data = I2C_ReceiveData(I2C2);                                                                                                //返回IIC2接收的数据,赋给temp
        I2C_AcknowledgeConfig( I2C2, ENABLE );                                                                                //再一次使能IIC2的应答状态

        return data;                                                                                                                                //返回接收到的数据
}

使用特权

评论回复
12
是你的乱码|  楼主 | 2024-3-31 21:50 | 只看该作者
SPI驱动OLED屏幕
#include "OLED.h"
#include "oledfont.h"


void delay(int ms)    //延时毫秒
{
        delay_init(72);
        delay_ms(ms);
}



//SPI时序为在时钟的上升沿把数据写入

void OLED_WR_Byte(unsigned char dat,unsigned char cmd)
{       
        unsigned char i;                          
        if(cmd)                      //判断是写命令还是数据,从而拉低对应的IO引脚
          OLED_DC_Set();
        else
          OLED_DC_Clr();                  
        OLED_CS_Clr();               //拉低片选线
        for(i=0;i<8;i++)
        {                          
                OLED_SCLK_Clr();         //拉低时钟线,数据会在时钟的上升沿把数据写入
                if(dat&0x80)             //从高位开始传送数据
                        {
                                OLED_SDIN_Set();
                        }
                else
                   OLED_SDIN_Clr();
               
                OLED_SCLK_Set();
                dat<<=1;   
        }                                                   
        OLED_CS_Set();
        OLED_DC_Set();             
}



//开启OLED显示   
void OLED_Display_On(void)
{
        OLED_WR_Byte(0X8D,OLED_CMD);  //SET DCDC命令
        OLED_WR_Byte(0X14,OLED_CMD);  //DCDC ON
        OLED_WR_Byte(0XAF,OLED_CMD);  //DISPLAY ON
}



//关闭OLED显示     
void OLED_Display_Off(void)
{
        OLED_WR_Byte(0X8D,OLED_CMD);  //SET DCDC命令
        OLED_WR_Byte(0X10,OLED_CMD);  //DCDC OFF
        OLED_WR_Byte(0XAE,OLED_CMD);  //DISPLAY OFF
}               


//清屏函数,清完屏,整个屏幕是黑色的!和没点亮一样!!!          
void OLED_Clear(void)  
{  
        unsigned char i,n;                    
        for(i=0;i<8;i++)  
        {  
                OLED_WR_Byte (0xb0+i,OLED_CMD);    //设置页地址(0~7)
                OLED_WR_Byte (0x00,OLED_CMD);      //设置显示位置—列低地址
                OLED_WR_Byte (0x10,OLED_CMD);      //设置显示位置—列高地址   
                for(n=0;n<128;n++)
                        OLED_WR_Byte(0,OLED_DATA);     //每一页有128列,8行,每写入一个字节会一次性写入8行,每写入一列后再写入的时候会自动写入下一位
        } //更新显示
}


//设置要在那一列的哪一列画点,所谓的画点就是让屏幕上某一个位置的点亮或者不亮,因为每次至少写入一个字节,所以一次点亮或关闭的至少是竖着的8个点
void OLED_Set_Pos(unsigned char x, unsigned char y)
{
        OLED_WR_Byte(0xb0+y,OLED_CMD);                 //设置页地址
        OLED_WR_Byte(((x&0xf0)>>4)|0x10,OLED_CMD);     //设置列地址高4位
        OLED_WR_Byte((x&0x0f)|0x01,OLED_CMD);          //设置列地址低4位
}             


//在指定位置显示一个字符,包括部分字符
//x:0~127
//y:0~7
//mode:0,反白显示;1,正常显示                                 
//size:选择字体 16/12
//char为要显示的字符,这个字符要是ASCII码中的字符

//下面这个函数是在指定位置显示ASCII码的函数
//每一个ASCII码占16*8个点
//x, y指的是要写入的字符左上角是在哪一列,哪一页,x对应列,y对应页
void OLED_ShowChar(unsigned char x,unsigned char y,unsigned char chr)
{             
                unsigned char c=0,i=0;       
                c=chr-' ';                            //得到偏移后的值                       
                if(x>Max_Column-1)
                {
                        x=0;
                        y=y+2;
                }
               
                if(SIZE ==16)
                        {
                                OLED_Set_Pos(x,y);        //在第y页,第x列开始写字符
                               
                                for(i=0;i<8;i++)    //从第y页,第x列开始写第一个字符,连续写8列
                                        OLED_WR_Byte(F8X16[c*16+i],OLED_DATA);
                               
                                OLED_Set_Pos(x,y+1); //因为字体垂直方向为16,水平方向为8,所以每写一个字符要设计到两页
                               
                                for(i=0;i<8;i++)
                                        OLED_WR_Byte(F8X16[c*16+i+8],OLED_DATA);
                        }
                else
                {       
                        OLED_Set_Pos(x,y+1);
                       
                        for(i=0;i<6;i++)
                                OLED_WR_Byte(F6x8[c][i],OLED_DATA);               
                }
}

使用特权

评论回复
13
是你的乱码|  楼主 | 2024-3-31 21:50 | 只看该作者
IIC驱动mpu6050

#include "mpu6050.h"

uint8_t buffer[14];

void MPU6050_setClockSource(uint8_t source){
    MPU_IICwriteBits(0x68, 0x6B, 2, 3, source);
}

void MPU6050_setFullScaleGyroRange(uint8_t range) {
    MPU_IICwriteBits(0x68, 0x1B, 4, 2, range);
}

void MPU6050_setFullScaleAccelRange(uint8_t range) {
    MPU_IICwriteBits(0x68, 0x1C, 4, 2, range);
}


void MPU6050_resetEnabled(uint8_t enabled) {
    MPU_IICwriteBit(0x68, 0x6B, 7, enabled);
        Delay_ms(100);
}


void MPU6050_set_Gyro_Accel_outRange(uint8_t range) {
    MPU_IICwriteBits(0x68, 0x6C, 5, 6, range);
}

void MPU6050_set_SMPRT_DIV(uint8_t range) {
          MPU_IICwriteByte(0x68,0x19,range);
}

void MPU6050_set_Gyro_DLPF_outRange(uint8_t range) {
    MPU_IICwriteBits(0x68, 0x1A, 2, 3, range);
}


void MPU6050_INT_Disabled(uint8_t enabled) {
    MPU_IICwriteBit(0x68, 0x38, 0, enabled);
}


void MPU6050_setSleepEnabled(uint8_t enabled) {
    MPU_IICwriteBit(0x68, 0x6B, 6, enabled);
}


void MPU6050_testConnection(void) {
       
   while(buffer[0] != 0x68){
                        MPU_IICreadBytes(0x68, 0x75, 1, buffer);
         };  
}

void MPU6050_setI2CMasterModeEnabled(uint8_t enabled) {
    MPU_IICwriteBit(0x68, 0x6A, 5, enabled);
}

void MPU6050_setI2CBypassEnabled(uint8_t enabled) {
    MPU_IICwriteBit(0x68, 0x37, 1, enabled);
}


void MPU6050_initialize(void) {
        MPU_IIC_Init();             //IIC初始化
        MPU6050_testConnection();     //检测MPU6050 是否已经连接
        MPU6050_resetEnabled(1);   //复位mpu6050  需延时100ms
    MPU6050_setClockSource(2); //设置时钟
        MPU6050_set_Gyro_Accel_outRange(0);  // 设置输出三轴陀螺仪和三轴加速度数据
        MPU6050_INT_Disabled(0);    //禁止中断
        MPU6050_set_SMPRT_DIV(0);   //采样分频
    MPU6050_setFullScaleGyroRange(3);//陀螺仪最大量程 +-1000度每秒
    MPU6050_setFullScaleAccelRange(0);        //加速度度最大量程 +-2G
          MPU6050_set_Gyro_DLPF_outRange(2);  //设置陀螺仪和加速度计的低通滤波器
    MPU6050_setSleepEnabled(0); //进入工作状态
        MPU6050_setI2CMasterModeEnabled(0);         //不让MPU6050 控制AUXI2C
        MPU6050_setI2CBypassEnabled(1);         //主控制器的I2C与        MPU6050的AUXI2C        直通。控制器可以直接访问HMC5883L
}

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

19

主题

263

帖子

1

粉丝