Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: SPI между STM32L152 и STM32F100
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
Dele
Добрый день!
Помогите разобраться с SPI!
Имеем 2 платы одна STM32F100 DISCOVERY Будет отпавлять На STM32L152 DISCOVERY Число.
Отправка вроде происходит, подключался логическим анализатором там есть движение, не могу разобраться с приемом.
То что пришло, по задумке выведет это в прерывании на встроенный дисплей и зажжет светодиод, а там только непонятное мерцание первого сегмента...
Код передатчика:
CODE
#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;

}



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

#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();
}
Existing
У меня SPI на F205 не заработал, пока порты дополнительно к AF не настроил в Push-Pull с подтяжкой к нулю, в соответствии с библиотечными примерами.
Dele
CODE
PORT.GPIO_Pin = SCK_Pin | MOSI_Pin | MISO_Pin;
PORT.GPIO_PuPd = GPIO_PuPd_DOWN;


Добавил в код приемника, так же...(
Dele
Разобрался:
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

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

Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.