SPI
Модераторы: ea, dav, bkolbov, Alis, pip, _sva_
Re: SPI
И у меня и у blessedit речь идет именно о коротких посылках. У меня вообще 24 бита.
Re: SPI
Ну да, DMA, конечно, не для этого придумали, но за время обмена, 240 тактов из 5000 можно делать рутинные операции.
Re: SPI
Добрый день!
А возможна непрерывная работа SPI (без отпускания CS и пропусков тактирования)?
А возможна непрерывная работа SPI (без отпускания CS и пропусков тактирования)?
- Вложения
-
- SPI.png (8.64 КБ) 2533 просмотра
Re: SPI
Да, перешел на программное управление CS, но последняя посылка отправляется позже чем я отпускаю CS, видимо из за сдвигового регистра.
Необходимо городить временную задержку.
Но интересен SCLK, он прерывается после каждого байта отправленных данных.
Работаю с SD картой.
Необходимо городить временную задержку.
Но интересен SCLK, он прерывается после каждого байта отправленных данных.
Работаю с SD картой.
Re: SPI
Да, возможно принимать необходимое количество слов от 1 до 1024х.Доброго времени суток, товарищи!
А есть какая-то возможность заставить SPI выдавать прерывания при приеме/передаче каждого 16-битного слова?
Заполнять буфер четырьмя словами по 4 бита не предлагать ))
Сделать это можно настроив ДМА (на 1 -1024 слово), по завершению приема ДМА выдаст вам прерывание.
Еще можно настроить ДМА на передачу и прием (но вкл перерывание только на прием), тогда по завершению передачи в режиме мастера вы получите прерывание от принимающего буфера (не забудьте вычитать 8 раз буфер приема перед включением ДМА).
Re: SPI
Столкнулся с проблемой, загадкой...
Есть 2 платы с МК1921 один в режиме мастера другой в слейве.
Когда отправляю значения 0, 1, 7 слейв все принимает сигнализируя на шине MISO значением (0xfe, так контролирую прием).
Когда отправляю 2, 4, 5... и т.д слейв может принять данные, а может и не принять, как ему захочется (закономерности не установил).
Работаю в режиме ДМА.
Привожу несколько рисунков обмена, прошу помощи весь мозг сломал.
Есть 2 платы с МК1921 один в режиме мастера другой в слейве.
Когда отправляю значения 0, 1, 7 слейв все принимает сигнализируя на шине MISO значением (0xfe, так контролирую прием).
Когда отправляю 2, 4, 5... и т.д слейв может принять данные, а может и не принять, как ему захочется (закономерности не установил).
Работаю в режиме ДМА.
Привожу несколько рисунков обмена, прошу помощи весь мозг сломал.
- Вложения
-
- Значение 0х01
- Screenshot_3.png (34.67 КБ) 1414 просмотров
-
- Значение 0х41
- Screenshot_2.png (36.99 КБ) 1414 просмотров
Re: SPI
Почему-то в режиме слейва происходит потеря данных при включении запрета на передачу SOD.
Сделал циклический буфер, по прерыванию складываю туда принятые значения, одновременно хочу отвечать происходит потеря данных как на прием так и на передачу.
Так же в какой то момент SPI сам по себе начинает отсылать последнее значение записанное в буфер.
Просто в режиме приема все работает корректно.
Подскажите что может быть не так?
Сделал циклический буфер, по прерыванию складываю туда принятые значения, одновременно хочу отвечать происходит потеря данных как на прием так и на передачу.
Так же в какой то момент SPI сам по себе начинает отсылать последнее значение записанное в буфер.
Просто в режиме приема все работает корректно.
Подскажите что может быть не так?
Re: SPI
Простой пример работы в режиме слейва.
Принимаю данные, на каждый 20 принятый символ хочу ответить.
По факту непрерывно отправляется значение ответа.
При данных настройках потерь данных нет.
Что я делаю не так?
Инициализация
Основной код
Принимаю данные, на каждый 20 принятый символ хочу ответить.
По факту непрерывно отправляется значение ответа.
При данных настройках потерь данных нет.
Что я делаю не так?
Код: Выделить всё
if(Cnt > 20){
NT_SPI1->SPI_DR = 0x80;
while(!SPI_GetITStatus(NT_SPI1, SPI_Flag_TFE));
while(SPI_GetITStatus(NT_SPI1, SPI_Flag_BSY));
}
Код: Выделить всё
#include "K1921VK01T.h"
#include "niietcm4.h"
#include "system_K1921VK01T.h"
void GPIO_Ph_Init() {
GPIO_Init_TypeDef GPIOInit_SPI;
// SPI1 MOSI
GPIO_StructInit(&GPIOInit_SPI);
GPIOInit_SPI.GPIO_Pin = GPIO_Pin_0;
GPIOInit_SPI.GPIO_Mode = GPIO_Mode_AltFunc;
GPIOInit_SPI.GPIO_AltFunc = GPIO_AltFunc_3;
GPIOInit_SPI.GPIO_Out = GPIO_Out_En;
GPIOInit_SPI.GPIO_PullUp = GPIO_PullUp_En;
GPIO_Init(NT_GPIOF, &GPIOInit_SPI);
// SPI1 MISO
GPIO_StructInit(&GPIOInit_SPI);
GPIOInit_SPI.GPIO_Pin = GPIO_Pin_2;
GPIOInit_SPI.GPIO_Mode = GPIO_Mode_AltFunc;
GPIOInit_SPI.GPIO_AltFunc = GPIO_AltFunc_3;
GPIOInit_SPI.GPIO_Out = GPIO_Out_En;
GPIOInit_SPI.GPIO_PullUp = GPIO_PullUp_En;
GPIO_Init(NT_GPIOG, &GPIOInit_SPI);
// SPI1 SCLK
GPIO_StructInit(&GPIOInit_SPI);
GPIOInit_SPI.GPIO_Pin = GPIO_Pin_9;
GPIOInit_SPI.GPIO_Mode = GPIO_Mode_AltFunc;
GPIOInit_SPI.GPIO_AltFunc = GPIO_AltFunc_3;
GPIOInit_SPI.GPIO_Out = GPIO_Out_En;
GPIOInit_SPI.GPIO_PullUp = GPIO_PullUp_En;
GPIO_Init(NT_GPIOE, &GPIOInit_SPI);
// SPI1 CS
GPIO_StructInit(&GPIOInit_SPI);
GPIOInit_SPI.GPIO_Pin = GPIO_Pin_8;
GPIOInit_SPI.GPIO_Mode = GPIO_Mode_AltFunc;
GPIOInit_SPI.GPIO_AltFunc = GPIO_AltFunc_3;
GPIOInit_SPI.GPIO_Out = GPIO_Out_En;
//GPIOInit_SPI.GPIO_PullUp = GPIO_PullUp_En;
GPIO_Init(NT_GPIOE, &GPIOInit_SPI);
}
//! SPI_DIV_SPI OFF FQspi = Fsys/(CPSDVSR*(SCR+1))
//! SPI_DIV_SPI ON FQspi = Fsys/(CPSDVSR*(SCR+1)*2*(DIV_SPI+1))
void SPI_Ph_Init() {
// настройка тактирования и сброса SPI
RCC_PeriphRstCmd(RCC_PeriphRst_SPI1, ENABLE);
SPI_ClkInit_TypeDef SPI_ClkInitStruct1;
SPI_ClkInitStruct1.SPI_SelectClk = SPI_Select_SystemClock;
SPI_ClkInitStruct1.SPI_ClkDiv = SPI_SysClkDiv_SysClk;
SPI_ClkInitStruct1.SPI_SysClkStatus = SPI_Clk_Enable;
SPI_ClkInitStruct1.SPI_DIV_SPI = 0; // max 63
SPI_ClkInit(NT_SPI1, &SPI_ClkInitStruct1);
// настройка блока SPI
SPI_Init_TypeDef SPI_InitStruct1;
SPI_StructInit(&SPI_InitStruct1);
SPI_InitStruct1.SPI_SCR = 0;
SPI_InitStruct1.SPI_CPSDVSR = 2;
SPI_InitStruct1.SPI_Mode = SPI_ModeSlave;
SPI_InitStruct1.SPI_WordLength = SPI_WordLength8b;
SPI_InitStruct1.SPI_SPH = SPI_SPH_1Edge;
SPI_InitStruct1.SPI_SPO = SPI_SPO_Low;
SPI_InitStruct1.SPI_FRF = SPI_FRF_SPI_Motorola;
SPI_InitStruct1.SPI_TX_Slave = 0;
SPI_Init(NT_SPI1, &SPI_InitStruct1);
Энвик_EnableIRQ(SPI1_IRQn);
SPI_ITConfig(NT_SPI1, SPI_IT_RX, ENABLE);
SPI_Cmd(NT_SPI1, ENABLE);
}
#define SYSTEM_CLK 72000000
#define DataLength 100
uint16_t Cnt = 0;
uint8_t SPI1_RXData[DataLength] = { 0 };
Код: Выделить всё
void main() {
RCC_PLLAutoConfig(RCC_PLLRef_XI_OSC, SYSTEM_CLK);
GPIO_Ph_Init();
SPI_Ph_Init();
while (1) {
if(Cnt > 20){
NT_SPI1->SPI_DR = 0x80;
while(!NT_SPI1->SPI_SR_bit.TFE);
while(NT_SPI1->SPI_SR_bit.BSY);
}
if(Cnt > DataLength){
Cnt = 0;
}
}
}
void SPI1_IRQHandler() {
while(NT_SPI1->SPI_SR_bit.BSY);
while(NT_SPI1->SPI_SR_bit.RNE){
SPI1_RXData[Cnt++] = (uint8_t) (NT_SPI1->SPI_DR);
}
SPI_ClearITPendingBit(NT_SPI1, SPI_IT_MASK);
}
- Вложения
-
- Screenshot_1.png (47.16 КБ) 1025 просмотров