2015-04-23 2 views
1

Я застрял с этим на некоторое время. Я следил за несколькими примерами в Интернете, но без успеха. Я не могу заставить его работать с моим STM32F4Discovery. У меня есть внешний чип (SX1272 от Semtech, чтобы быть более конкретным), с которым я пытаюсь получить SPI-связь. Это все детские игры, когда вы делаете это через Arduino, но не повезло с продуктом ST. Я использовал осциллограф, и он показал, что команда MOSI отправлена, но MISO не выходит. (С Ардуино это хорошо). Вот мой код:Почему SPI не работает с моим STM32f4DISCOVERY?

#include "main.h" 

void init_SPI1(void){ 


    GPIO_InitTypeDef GPIO_InitStruct; 
    SPI_InitTypeDef SPI_InitStruct; 

    // enable clock for used IO pins 
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); 

    /* configure pins used by SPI1 
    * PA5 = SCK 
    * PA6 = MISO 
    * PA7 = MOSI 
    */ 
    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_6 | GPIO_Pin_5; 
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; 
    GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; 
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; 
    GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL; 
    GPIO_Init(GPIOA, &GPIO_InitStruct); 

    // connect SPI1 pins to SPI alternate function 
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource5, GPIO_AF_SPI1); 
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_SPI1); 
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_SPI1); 

    // enable clock for used IO pins 
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE); 

    /* Configure the chip select pin 
    in this case we will use PE7 */ 
    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_7; 
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT; 
    GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; 
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; 
    GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP; 
    GPIO_Init(GPIOE, &GPIO_InitStruct); 

    GPIO_SetBits(GPIOE, GPIO_Pin_7); // set PE7 high 

    // enable peripheral clock 
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE); 

    /* configure SPI1 in Mode 0 
    * CPOL = 0 --> clock is low when idle 
    * CPHA = 0 --> data is sampled at the first edge 
    */ 
    SPI_InitStruct.SPI_Direction =    SPI_Direction_2Lines_FullDuplex;  // set to full duplex mode, seperate MOSI and MISO lines 
    SPI_InitStruct.SPI_Mode =      SPI_Mode_Master;      // transmit in master mode, NSS pin has to be always high 
    SPI_InitStruct.SPI_DataSize =     SPI_DataSize_8b;      // one packet of data is 8 bits wide 
    SPI_InitStruct.SPI_CPOL =      SPI_CPOL_High;       // clock is low when idle 
    SPI_InitStruct.SPI_CPHA =      SPI_CPHA_1Edge;       // data sampled at first edge 
    SPI_InitStruct.SPI_NSS =      SPI_NSS_Soft | SPI_NSSInternalSoft_Set; // set the NSS management to internal and pull internal NSS high 
    SPI_InitStruct.SPI_BaudRatePrescaler =  SPI_BaudRatePrescaler_64;    // SPI frequency is APB2 frequency/4 
    SPI_InitStruct.SPI_FirstBit =     SPI_FirstBit_MSB;      // data is transmitted MSB first 
    SPI_Init(SPI1, &SPI_InitStruct); 

    SPI_Cmd(SPI1, ENABLE); // enable SPI1 
} 


/* This funtion is used to transmit and receive data 
* with SPI1 
*   data --> data to be transmitted 
*   returns received value 
*/ 
uint8_t SPI1_read(uint8_t data){ 
    GPIO_ResetBits(GPIOE, GPIO_Pin_7); // set PE7 (CS) low 

    SPI1->DR = data; // write data to be transmitted to the SPI data register 
    while(!(SPI1->SR & SPI_I2S_FLAG_TXE)); // wait until transmit complete 
    while(SPI1->SR & SPI_I2S_FLAG_BSY); // wait until SPI is not busy anymore 

    GPIO_SetBits(GPIOE, GPIO_Pin_7); // set PE7 (CS) high 
    uint8_t ret = SPI1->DR; 
    return ret; // return received data from SPI data register 
} 


void SPI1_write(uint8_t address, uint8_t data){ 

    uint16_t comb = (address << 8) | data; 
    GPIO_ResetBits(GPIOE, GPIO_Pin_7); // set PE7 (CS) low 

    SPI1->DR = address; // write data to be transmitted to the SPI data register 
    while(!(SPI1->SR & SPI_I2S_FLAG_TXE)); // wait until transmit complete 
    //while(SPI1->SR & SPI_I2S_FLAG_BSY); // wait until SPI is not busy anymore 

    SPI1->DR = data; // write data to be transmitted to the SPI data register 
    while(!(SPI1->SR & SPI_I2S_FLAG_TXE)); // wait until transmit complete 
    while(SPI1->SR & SPI_I2S_FLAG_BSY); // wait until SPI is not busy anymore 

    GPIO_SetBits(GPIOE, GPIO_Pin_7); // set PE7 (CS) high 
} 

int main(void){ 

    init_SPI1(); 

    while(1){ 
    SPI1_read(0x01); 
    } 
} 

Все, что я получаю от MOSI является случайным ~ 1.5V пик, который находится вне синхронизации.

+0

Обновите это кодом, который, как вы говорите, попробовал, который устанавливает контакт MISO в качестве входа. –

+0

Царапины, что я сказал о связи. На MISO нет ответа. Чип не интерпретирует команды из MOSI. Что-то не так с протоколом связи SPI ... С Arduino все еще работает отлично. Я вижу (на осциллографе) четкий ответ, и все работает так, как ожидалось. –

+0

Сделайте программу SPI транзакциями несколько раз, чтобы вы могли получить стабильное изображение даже в аналоговой области, а также сделать снимок выбора чипа и часы, затем еще один из часов и первого байта данных MOSI. –

ответ

1
/* configure pins used by SPI1 
* PA5 = SCK 
* PA6 = MISO 
* PA7 = MOSI 
*/ 

Это говорит о том, что ваш MISO (мастер в, подчиненный выход) сигнал на ПА6

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

Но это настраивает PA6 как выхода.

Настройте PA6 в качестве входа и повторите попытку. Если он все еще не работает, попробуйте ввести уровень там через резистор 1K или около того, и посмотрите, можете ли вы изменить напряжение на область действия и полученное значение, чтобы отразить это вообще.

+0

Почему бы не заменить функцию Function? Разве это не должно быть, поскольку SPI1 настроен из регистров? –

+0

И нет, он все еще не работает –

+0

Вам все еще нужно настроить направление драйверов ввода-вывода, и вы настраиваете входной контакт в качестве выхода. Что случилось, когда вы пытались ввести уровень со слабым источником? Изменилось ли напряжение? Получили ли полученные данные? –

0

Вы пытались использовать инструмент конфигурации ST STM32Cube для генерации кода инициализации и интерфейса связи. Я использовал его для генерации синхронизации часов. USART, I2C и SPI связывают интерфейсы, используя DMA-передачи примерно через час. Он включает в себя предопределенную конфигурацию для платы обнаружения F4. Все, что мне нужно было сделать, это очистить линию CS, когда передача была загружена в DMA, и снова установить ее в функции обратного вызова прерывания передачи.

+0

Нет, не знаю. Попытаюсь –

Смежные вопросы