Перейти к содержанию
    

SPI между STM32L152 и STM32F100

Добрый день!

Помогите разобраться с SPI!

Имеем 2 платы одна STM32F100 DISCOVERY Будет отпавлять На STM32L152 DISCOVERY Число.

Отправка вроде происходит, подключался логическим анализатором там есть движение, не могу разобраться с приемом.

То что пришло, по задумке выведет это в прерывании на встроенный дисплей и зажжет светодиод, а там только непонятное мерцание первого сегмента...

Код передатчика:

#include "stm32f10x_gpio.h"
#include "stm32f10x_rcc.h"
#include "stm32f10x.h"
#include <stm32f10x_exti.h>
#include "misc.h"
#include "stm32f10x_spi.h"

#define SCK_Pin  GPIO_Pin_5
#define SCK_Pin_Port GPIOA

#define MOSI_Pin GPIO_Pin_7
#define MOSI_Pin_Port GPIOA

#define MISO_Pin  GPIO_Pin_6
#define MISO_Pin_Port GPIOA

#define SS_Pin  GPIO_Pin_4
#define SS_Pin_Port GPIOA

void init_periph()
{
   GPIO_InitTypeDef  GPIO_LED;
   RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
   GPIO_LED.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_14;
   GPIO_LED.GPIO_Mode = GPIO_Mode_Out_PP;
   GPIO_LED.GPIO_Speed = GPIO_Speed_50MHz;
   GPIO_Init(GPIOC, &GPIO_LED);

   GPIO_InitTypeDef  GPIO_BUT;
   RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA , ENABLE);
   RCC_APB2PeriphClockCmd(RCC_APB2ENR_AFIOEN , ENABLE);
   GPIO_BUT.GPIO_Pin = GPIO_Pin_0;
   GPIO_BUT.GPIO_Mode = GPIO_Mode_IN_FLOATING;
   GPIO_BUT.GPIO_Speed = GPIO_Speed_2MHz;
   GPIO_Init(GPIOA, &GPIO_BUT);
}
void init_spi()
{
   // включаем тактирование (=питание) на порты A, B и железный SPI1
   RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_SPI1, ENABLE);
   GPIO_InitTypeDef PORT;
   // выбрали ноги для настройки
   PORT.GPIO_Pin   = SCK_Pin | MOSI_Pin | MISO_Pin;;
   // установили наименьшую скорость (максимальная скорость контроллера 4 Мбита в секунду)
   PORT.GPIO_Speed = GPIO_Speed_2MHz;
   // (важно!) определяем предназначение ног. здесь - выбор "альтернативной функции" ног
   PORT.GPIO_Mode  = GPIO_Mode_AF_PP;
   // настроили ноги в порту А
   GPIO_Init(GPIOA, &PORT);

   // выбрали ноги для настройки
   PORT.GPIO_Pin   = SS_Pin;
   // установили скорость (тут - без разницы)
   PORT.GPIO_Speed = GPIO_Speed_2MHz;
   // предназначение - общее, выход
   PORT.GPIO_Mode  = GPIO_Mode_Out_PP;
   // настроили ноги в порту B
   GPIO_Init(GPIOA, &PORT);

   SPI_InitTypeDef SPIConf;
       // указываем, что используем мы только передачу данных
       SPIConf.SPI_Direction = SPI_Direction_1Line_Tx;
       // указываем, что наше устройство - Master
       SPIConf.SPI_Mode = SPI_Mode_Master;
       // передавать будем по 8 бит (=1 байт)
       SPIConf.SPI_DataSize = SPI_DataSize_8b;
       // режим 00
       SPIConf.SPI_CPOL = SPI_CPOL_Low;
       SPIConf.SPI_CPHA = SPI_CPHA_1Edge;
       SPIConf.SPI_NSS = SPI_NSS_Soft;
       // установим скорость передачи (опытным путём выяснили, что разницы от изменения этого параметра нет)
       SPIConf.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2;
       // передаём данные старшим битом вперёд (т.е. слева направо)
       SPIConf.SPI_FirstBit = SPI_FirstBit_MSB;
       // внесём настройки в SPI
       SPI_Init(SPI1, &SPIConf);
       // включим  SPI1
       SPI_Cmd(SPI1, ENABLE);
       // SS = 1
       SPI_NSSInternalSoftwareConfig(SPI1, SPI_NSSInternalSoft_Set);

}

void SPISend(uint16_t data) {
   SPI_I2S_SendData(SPI1, data);  // отправили данные
   while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET); // ждём, пока данные не отправятся
}
int main(void)
{
init_periph();
init_spi();
int i;
uint16_t data = 1;
GPIO_ResetBits(GPIOC, GPIO_Pin_4); // чип селект выбор

while(1)
{
for (i=0; i<1000000; i++){GPIO_SetBits(GPIOC, GPIO_Pin_8);}
SPISend(data);
for (i=0; i<1000000; i++){GPIO_ResetBits(GPIOC, GPIO_Pin_8);}
data++;
}
return 0;

}

 

 

Код приемника:

#include "stm32l1xx_gpio.h"
#include "stm32l1xx_rcc.h"
#include "stm32l1xx.h"
#include "stm32l1xx_exti.h"
#include "misc.h"
#include "lcd_gpio_init.h"
#include "stm32l_discovery_lcd_new.h"
#include "stm32l1xx_spi.h"

#define SCK_Pin  GPIO_Pin_13
#define SCK_Pin_Port GPIOB

#define MOSI_Pin GPIO_Pin_15
#define MOSI_Pin_Port GPIOB

#define MISO_Pin  GPIO_Pin_14
#define MISO_Pin_Port GPIOB

#define SS_Pin  GPIO_Pin_5
#define SS_Pin_Port GPIOA

void RCC_Configuration(void)
{
 SystemInit(); // Сброс по умолчанию
 GPIO_DeInit(GPIOA);
 GPIO_DeInit(GPIOB);
 GPIO_DeInit(GPIOC);
 GPIO_DeInit(GPIOD);
 GPIO_DeInit(GPIOE);

 RCC_AHBPeriphClockCmd( RCC_AHBPeriph_GPIOA | RCC_AHBPeriph_GPIOB |
                        RCC_AHBPeriph_GPIOC | RCC_AHBPeriph_GPIOD |
                        RCC_AHBPeriph_GPIOE, ENABLE);

 RCC_AHBPeriphClockCmd(RCC_AHBENR_GPIOAEN, ENABLE);
 RCC_AHBPeriphClockCmd(RCC_AHBENR_GPIODEN, ENABLE);
 RCC_AHBPeriphClockCmd(RCC_AHBENR_GPIOBEN, ENABLE);
}

void init_led()
{
GPIO_InitTypeDef PORT;
PORT.GPIO_Pin = (GPIO_Pin_7 | GPIO_Pin_6);
PORT.GPIO_Mode = GPIO_Mode_OUT;
PORT.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_Init( GPIOB , &PORT);
}

void init_but()
{
GPIO_InitTypeDef BUTA;
BUTA.GPIO_Pin = GPIO_Pin_0;
BUTA.GPIO_Mode = GPIO_Mode_IN;
BUTA.GPIO_Mode = GPIO_PuPd_NOPULL; // Хардварная кнопка и так подтянута
BUTA.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_Init( GPIOA , &BUTA);

GPIO_InitTypeDef BUTD;
BUTD.GPIO_Pin = GPIO_Pin_2;
BUTD.GPIO_Mode = GPIO_Mode_IN;
BUTD.GPIO_Mode = GPIO_PuPd_UP;
BUTD.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_Init( GPIOD , &BUTD);
}

void spi()
{
 // включаем тактирование железный SPI2
    RCC_APB1PeriphClockCmd(RCC_APB1ENR_SPI2EN , ENABLE);

    GPIO_InitTypeDef PORT;
    // выбрали ноги для настройки
    PORT.GPIO_Pin   = SCK_Pin | MOSI_Pin | MISO_Pin;;
    // установили наименьшую скорость (максимальная скорость контроллера 4 Мбита в секунду)
    PORT.GPIO_Speed = GPIO_Speed_2MHz;
    // (важно!) определяем предназначение ног. здесь - выбор "альтернативной функции" ног
    PORT.GPIO_Mode  = GPIO_Mode_AF;
    // настроили ноги в порту B
    GPIO_Init(GPIOB, &PORT);

    // выбрали ноги для настройки
    PORT.GPIO_Pin   = SS_Pin;
    // установили скорость (тут - без разницы)
    PORT.GPIO_Speed = GPIO_Speed_2MHz;
    // предназначение - общее, выход
    PORT.GPIO_Mode  = GPIO_Mode_IN;
    // настроили ноги в порту A
    GPIO_Init(GPIOA, &PORT);


    SPI_I2S_DeInit(SPI2);

    SPI_InitTypeDef SPIConf;
        // указываем, что используем мы только передачу данных
        SPIConf.SPI_Direction = SPI_Direction_1Line_Rx;
        // указываем, что наше устройство - Прием
        SPIConf.SPI_Mode = SPI_Mode_Slave;
        // передавать будем по 8 бит (=1 байт)
        SPIConf.SPI_DataSize = SPI_DataSize_8b;
        // режим 00
        SPIConf.SPI_CPOL = SPI_CPOL_Low;
        SPIConf.SPI_CPHA = SPI_CPHA_1Edge;
        SPIConf.SPI_NSS = SPI_NSS_Hard;
        // установим скорость передачи (опытным путём выяснили, что разницы от изменения этого параметра нет)
        SPIConf.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2;
        // передаём данные старшим битом вперёд (т.е. слева направо)
        SPIConf.SPI_FirstBit = SPI_FirstBit_MSB;
        // внесём настройки в SPI
        SPI_Init(SPI2, &SPIConf);
        // включим  SPI2
        SPI_Cmd(SPI2, ENABLE);
        // SS = 1
        SPI_NSSInternalSoftwareConfig(SPI2, SPI_NSSInternalSoft_Set);

SPI_I2S_ITConfig(SPI2,SPI_I2S_IT_RXNE,ENABLE); //Включаем прерывание по приему байта
SPI_Cmd(SPI2, ENABLE); // Включаем модуль SPI2....

NVIC_EnableIRQ(SPI2_IRQn); //Разрешаем прерывания от SPI2
}

void SPI2_IRQHandler (void)
{
if (SPI_I2S_GetFlagStatus(SPI2,SPI_I2S_FLAG_RXNE)==SET) // Прерывание вызвано приемом байта ?
{
uint8_t data = SPI2->DR; //Читаем то что пришло
LCD_GLASS_Clear();
LCD_GLASS_DisplayString(data);
GPIO_SetBits(GPIOB, GPIO_Pin_6);
}
}
int main(void)
{
RCC_Configuration();
init_led();
init_but();
exiti();
gpio_init();
lcd_init();
spi();
}

Изменено пользователем Dele

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

У меня SPI на F205 не заработал, пока порты дополнительно к AF не настроил в Push-Pull с подтяжкой к нулю, в соответствии с библиотечными примерами.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Разобрался:

1. Если одна плата питалась от usb ноута другая от зарядки телефона, если соеденить у обоих плат минусы связь стабильней.

2. Не хватало строк

GPIO_PinAFConfig(GPIOB, GPIO_PinSource13, GPIO_AF_SPI2); // Обозначение Альт. функций на пины

GPIO_PinAFConfig(GPIOB, GPIO_PinSource15, GPIO_AF_SPI2);

GPIO_PinAFConfig(GPIOB, GPIO_PinSource14, GPIO_AF_SPI2);

 

SPI_SSOutputCmd(SPI2, ENABLE); // Включение CS

 

Тему можно закрыть

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...