stm32f405通过SPI控制24bitsDAC芯片的代码

最近使用到DAC芯片,目的是通过stm32f4控制板控制该芯片输出想要的电压,芯片的通信接口是SPI,一次需要发送24bits的数据才行,但是stm32f4的SPI硬件只有8bits和16bits两种选择,所以没法用硬件来实现,只能通过软件SPI模拟口来实现。

SPI通信接口主要包括4根引线,即MOSI,MISO,SCLK,CS。MOSI是主设备输出从设备输入,MISO是从设备输出主设备输入,SCLK是时钟线,用于同步时钟,而CS是片选信号,用于选择通讯设备。SPI通信中必须包含至少一台主设备,且只有主设备才能发起通讯,而允许存在多台从设备,对于存在多台从设备的情况,可通过从设备的CS引脚选择从设备。

                   stm32f405通过SPI控制24bitsDAC芯片的代码_第1张图片

SPI通讯是由时钟线发起的,且只有主设备才能控制时钟线电平的高低,在STM32F4中,当设置CPOL=1时,表示时钟线处于高电平时是空闲状态;CPOL=0时,表示时钟线处于低电平时为空闲状态。当设置CPHA=0时,表示在时钟第一个跳变沿的时候开始采样,而当CPHA=1时,表示在时钟第二个跳变沿时才开始采样。

总的来说,SPI的通讯过程是这样的,以低电平为空闲状态为例,且在第一个跳变沿开始采样(硬件SPI需要设置这两个设定,但软件SPI就不需要,软件SPI的话,主要是看你从设备,也就是DAC芯片是什么样设置,DAC芯片手册如何要求就如何写即可)。我使用的芯片就是低电平空闲,且在第一个跳变沿开始采样。

我的SPI任意使用了PB10,PB11,PB12,PB13四个接口,于是

PB15 ——推挽上拉电阻输出, 对应MOSI

PB14 ——开漏输入, 对应MISO

PB13 ——推挽上拉电阻输出,   对应SCLK

PB12 ——推挽上拉电阻输出, 对应CS

主设备和从设备之间是通过SCLK线来同步消息的,在SCLK线低电平时表示空闲,而在高电平时,从设备会检测MOSI线路上的电平,高低电平表示要发送的数据,因此在SCLK变为高电平时,需要MOSI线上的电平保持稳定。而MOSI的电平由主设备来控制。因此,假设我们要发一个24bits的数据,例如0xffffff,则第一步需要将SCLK拉低,stm32f4中用函数GPIO_ResetBits(GPIOB,GPIO_Pin_13),第二步查看要发送的首位数据是1还是0,0xffffff最高位是1,因此接下来要发送的是高电平,可用GPIO_SetBits(GPIOB,GPIO_Pin_15),将MOSI置高,第三步,拉高SCLK线,从设备接收数据,就是GPIO_SetBits(GPIOB,GPIO_Pin_13),延迟2us,再将SCLK线拉低,这样就实现了一位数据的传输。下面给一个具体的代码。

void SPI2_Init(void)   //IO口设置
{     
  GPIO_InitTypeDef  GPIO_InitStructure;
  GPIO_InitTypeDef  GPIO_InitStructure1;
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);//使能GPIOB时钟
 
    GPIO_InitStructure1.GPIO_Pin = GPIO_Pin_14;//PB14输入     
  GPIO_InitStructure1.GPIO_Mode = GPIO_Mode_IN;//普通输入功能
  GPIO_InitStructure1.GPIO_OType = GPIO_OType_OD;//开漏
  GPIO_InitStructure1.GPIO_Speed = GPIO_Speed_100MHz;//100MHz
  GPIO_InitStructure1.GPIO_PuPd = GPIO_PuPd_NOPULL;
  GPIO_Init(GPIOB, &GPIO_InitStructure1);//初始化

  //GPIOFB13,12,15初始化设置
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13|GPIO_Pin_12|GPIO_Pin_15;//PB12,13,15复用功能输出    
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//输出
  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);//初始化

}

 

 

void SPI_Send(u32 data)                                              //与DAC通信,dac发送数据是固定24bits的
{
    int i=0;
    GPIO_ResetBits(GPIOB,GPIO_Pin_12);                 //CS线,拉低选中从设备
    for(i=0;i<24;i++)
    {        
        if(data&0x00800000)                                           //取数据的最高位,一般是从最高位开始发
        {
            GPIO_SetBits(GPIOB,GPIO_Pin_15);             //如果是1,将MOSI拉高
        }
        else 
        {
            GPIO_ResetBits(GPIOB,GPIO_Pin_15);          //如果是0,将MOSI拉低
        }
        GPIO_SetBits(GPIOB,GPIO_Pin_13);                  //拉高SCLK线
        delay_us(2);
        GPIO_ResetBits(GPIOB,GPIO_Pin_13);               //拉低SCLK线
        data=data<<1;                                                       //向左移位,发送下一位数据
    }
     GPIO_SetBits(GPIOB,GPIO_Pin_12);                      //CS线拉高,结束传输
}

 

你可能感兴趣的:(stm32f405通过SPI控制24bitsDAC芯片的代码)