Dele 0 10 апреля, 2014 Опубликовано 10 апреля, 2014 (изменено) · Жалоба Добрый день! Помогите разобраться с 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(); } Изменено 10 апреля, 2014 пользователем Dele Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Existing 0 11 апреля, 2014 Опубликовано 11 апреля, 2014 · Жалоба У меня SPI на F205 не заработал, пока порты дополнительно к AF не настроил в Push-Pull с подтяжкой к нулю, в соответствии с библиотечными примерами. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Dele 0 11 апреля, 2014 Опубликовано 11 апреля, 2014 · Жалоба PORT.GPIO_Pin = SCK_Pin | MOSI_Pin | MISO_Pin; PORT.GPIO_PuPd = GPIO_PuPd_DOWN; Добавил в код приемника, так же...( Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Dele 0 12 апреля, 2014 Опубликовано 12 апреля, 2014 · Жалоба Разобрался: 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 Тему можно закрыть Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться