Кто любит RISC в жизни, заходим, не стесняемся.
Ответить

Помогите совсем начинающему разобраться с SPI

Пт мар 10, 2017 13:26:45

Привет всем.
Раньше как тоигрался с ардуино, а теперь вот решил немного освоить STM32.
Чип у меня STM32F103C8T6. Работать пытаюсь в COOCOX. Знаю что не лучшая система, но Кейл не осилил пока.

Проблема такая:

Создал новый проект. добавил SPI. Автоматом добавились GPIO, RCC и CMSIS.
Почитав много всего в сети, написал такую прогу.
Код:
#include "stm32f10x.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_rcc.h"
#include "stm32f10x_spi.h"



int main(void)
{
   //************************************************************************************
         RCC_DeInit();
         RCC_HSEConfig(RCC_HSE_ON);
         RCC_HCLKConfig(RCC_SYSCLK_Div1);
          RCC_PCLK2Config(RCC_HCLK_Div1);
          RCC_PCLK1Config(RCC_HCLK_Div2);
          RCC_ADCCLKConfig(RCC_PCLK2_Div4);
          RCC_PLLConfig(0x00010000, RCC_PLLMul_9);
          RCC_PLLCmd(ENABLE);
          while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
          {
          }
          RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
          while(RCC_GetSYSCLKSource() != 0x08)
          {
          }
   //************************************************************************************
         SPI_InitTypeDef  SPI_InitStructure;
         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
         RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);

         GPIO_InitTypeDef GPIO_InitStructure;
         GPIO_InitStructure.GPIO_Pin   = (GPIO_Pin_13 | GPIO_Pin_15);
         GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_PP;
         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
         GPIO_Init(GPIOB, &GPIO_InitStructure);

         SPI_InitStructure.SPI_Direction = SPI_Direction_1Line_Tx;
         SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
         SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
         SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
         SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
         SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
         SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2;
         SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
         SPI_Init(SPI2, &SPI_InitStructure);

         SPI_CalculateCRC(SPI2, DISABLE);

         SPI_Cmd(SPI2, ENABLE);
   //************************************************************************************

    while(1)
    {
       while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET) { ; }
       SPI_I2S_SendData(SPI2, 0x00);
    }
}


По сути циклически отправляет в SPI код "0".
Теоретически ожидалось что байты будут передаваться подряд без промежутков. Ну или с минимальным промежутком в 1 бит. Но на деле получилось что между байтами промежуток еще в пару байт. Соответственно в несколько раз падает скорость SPI.
IMG_20170310_101111.jpg
(34.81 KiB) Скачиваний: 458

Подозреваю что где то не правильно настроил модуль SPI, но не могу понять где.
Буду рад подсказкам.

Re: Помогите совсем начинающему разобраться с SPI

Пт мар 10, 2017 20:31:07

Возможно тупят функции. Может вот так попробовать?
Код:
while (!(SPI2->SR&SPI_SR_TXE));
SPI2->DR=0x00;


Может чего напутал конечно.
---
В кокосе вроде по умолчанию оптимизация выключена.

Re: Помогите совсем начинающему разобраться с SPI

Сб мар 11, 2017 11:00:10

Z_h_e писал(а):Возможно тупят функции. Может вот так попробовать?
Код:
while (!(SPI2->SR&SPI_SR_TXE));
SPI2->DR=0x00;


Может чего напутал конечно.
---
В кокосе вроде по умолчанию оптимизация выключена.


Да действительно функции подтормаживают. Сделал как Вы предложили, стало значительно быстрее. Но все же есть еще не большой промежуток между байтами. Думаю быстрее полингом уже не получится. Дальше только DMA.

Re: Помогите совсем начинающему разобраться с SPI

Сб мар 11, 2017 21:05:25

ksgroup писал(а):Дальше только DMA.
У Вас SPI работает на максимальной частоте, да? Поглядите ДШ, если в SPI нет буферного регистра данных, то все равно промежуток будет.

Если хотите чтобы было красиво на осциллограмме, просто понизьте частоту SPI. Можно еще код из ОЗУ выполнять, будет быстрее работать.

Re: Помогите совсем начинающему разобраться с SPI

Вс мар 12, 2017 10:21:44

Z_h_e писал(а):если в SPI нет буферного регистра данных, то все равно промежуток будет.

Буферный регистр как раз есть и данные следующего байта в него можно писать после передачи SPI первого бита данных, так что тут все в порядке. Просто ядро не успевает это сделать вовремя из за тормозных функций Си. Нужно наверное на ассемблере попробовать.
Z_h_e писал(а):просто понизьте частоту SPI.

И? Смысл? Естественно на меньшей скорости все будет ОК, но, если вы конечно читали весь топик, нужно то на максимуме!
Ответить