2015-02-09 148 views
0

我可以使用下面的代碼給init SPI和加速度計STM32F4發現SPI LIS3DSH

SPI_InitTypeDef SPI_InitTypeDefStruct; 
    GPIO_InitTypeDef GPIO_InitTypeDefStruct; 

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE); 
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); 
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE , ENABLE); 

    SPI_InitTypeDefStruct.SPI_Direction   = SPI_Direction_2Lines_FullDuplex; 
    SPI_InitTypeDefStruct.SPI_Mode    = SPI_Mode_Master; 
    SPI_InitTypeDefStruct.SPI_DataSize   = SPI_DataSize_8b; 
    SPI_InitTypeDefStruct.SPI_CPOL    = SPI_CPOL_High; 
    SPI_InitTypeDefStruct.SPI_CPHA    = SPI_CPHA_2Edge; 
    SPI_InitTypeDefStruct.SPI_NSS    = SPI_NSS_Soft | SPI_NSSInternalSoft_Set; 
    SPI_InitTypeDefStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;  //seems like it was here causing trouble 
    SPI_InitTypeDefStruct.SPI_FirstBit   = SPI_FirstBit_MSB; 
    SPI_Init(SPI1, &SPI_InitTypeDefStruct); 

    GPIO_InitTypeDefStruct.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_7 | GPIO_Pin_6; 
    GPIO_InitTypeDefStruct.GPIO_Mode = GPIO_Mode_AF; 
    GPIO_InitTypeDefStruct.GPIO_Speed = GPIO_Speed_50MHz; 
    GPIO_InitTypeDefStruct.GPIO_OType = GPIO_OType_PP; 
    GPIO_InitTypeDefStruct.GPIO_PuPd = GPIO_PuPd_NOPULL; 
    GPIO_Init(GPIOA, &GPIO_InitTypeDefStruct); 

    GPIO_InitTypeDefStruct.GPIO_Pin = GPIO_Pin_3; 
    GPIO_InitTypeDefStruct.GPIO_Mode = GPIO_Mode_OUT; 
    GPIO_InitTypeDefStruct.GPIO_Speed = GPIO_Speed_50MHz; 
    GPIO_InitTypeDefStruct.GPIO_PuPd = GPIO_PuPd_UP; 
    GPIO_InitTypeDefStruct.GPIO_OType = GPIO_OType_PP; 
    GPIO_Init(GPIOE, &GPIO_InitTypeDefStruct); 

    GPIO_PinAFConfig(GPIOA, GPIO_PinSource5, GPIO_AF_SPI1); 
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_SPI1); 
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_SPI1); 

    GPIO_SetBits(GPIOE, GPIO_Pin_3); 
    SPI_Cmd(SPI1, ENABLE); 

    SPI_send(0x23, 0xc9);       // resetting the accelerometer internal circuit 
    //SPI_send(0x20, 0x67);       // 100Hz data update rate, block data update disable, x/y/z enabled 
    SPI_send(0x20, 0x97); 
    //SPI_send(0x24, 0x20);       // Anti aliasing filter bandwidth 800Hz, 16G (very sensitive), no self-test, 4-wire interface 
    SPI_send(0x24, 0x00);       // Anti aliasing filter bandwidth 800Hz, 2G (sensitive ??), no self-test, 4-wire interface 
    SPI_send(0x10, 0x00);       // Output(X) = Measurement(X) - OFFSET(X) * 32; 
    SPI_send(0x11, 0x00);       // Output(Y) = Measurement(Y) - OFFSET(Y) * 32; 
    SPI_send(0x12, 0x00);       // Output(Z) = Measurement(Z) - OFFSET(Z) * 32; 

void SPI_send(uint8_t address, uint8_t data) 
{ 
    GPIO_ResetBits(GPIOE, GPIO_Pin_3); 

    while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET); 
    SPI_I2S_SendData(SPI1, address); 
    while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET); 
    SPI_I2S_ReceiveData(SPI1); 

    while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET); 
    SPI_I2S_SendData(SPI1, data); 
    while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET); 
    SPI_I2S_ReceiveData(SPI1); 

    GPIO_SetBits(GPIOE, GPIO_Pin_3); 

} 



uint8_t SPI_read(uint8_t address) 
{ 
    GPIO_ResetBits(GPIOE, GPIO_Pin_3); 
    address = 0x80 | address;       // 0b10 - reading and clearing status 

    while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET); 
    SPI_I2S_SendData(SPI1, address); 
    while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET); 
    SPI_I2S_ReceiveData(SPI1); 

    while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET); 
    SPI_I2S_SendData(SPI1, 0x00); 
    while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET); 

    GPIO_SetBits(GPIOE, GPIO_Pin_3); 

    return SPI_I2S_ReceiveData(SPI1); 
} 

讀出值然後,我結合這些代碼與我的項目,它有一個500Hz的中斷。 它始終工作,但如果我拔掉電路板然後再插入它,即使LIS3DSH仍然有讀數(我用示波器檢查過它),SPI將只讀取零。我不得不下載較短版本的項目代碼(取出中斷中的大部分代碼)以使SPI再次正常工作。 我使用的是Kickstart,大小有限的IAR ewarm,我認爲這是因爲我的代碼超出了限制。但我沒有得到警告,我的代碼不超過32kb。

我只是困惑,因爲它的工作,直到我拔掉它。有人能給我一些建議嗎? 謝謝

回答

0

我決定在SPI_Init(...)之前添加SPI_DeInit(...)。這似乎解決了這個問題。我仍然不明白爲什麼它不會重置自己。