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

Что не так с инициализацией SPI на stm32vldiscovery?


Гость bobjen

Рекомендуемые сообщения

Не получается заставить работать spi на stm32vldiscovery. 

Инициализирую SPI1 как master и SPI2 как slave на одной и той же плате. Соединил соответстующие их выводы проводами. Идея такая что SPI1 шлет строку SPI2, тот ее зеркалит назад, и обработчик прерывания SPI1 передает то что получил от SPI1 в USART1 (который настроен и работает - он исправно выдает строку "Application started"). А вот вместо байт строки "oh well this is it" он выдает набор байт 0xff, причем на один меньше чем длина строки.

Что не так с инициализацией SPI?

 

int main() {
    initializeUsart1();


    //Initializing SPI1 as master
    //SPI1 SS(PA4), SCK(PA5), MISO(PA6), MOSI(PA7)

#define SPI1_SS GPIO_Pin_4
#define SPI1_SCK GPIO_Pin_5
#define SPI1_MISO GPIO_Pin_6
#define SPI1_MOSI GPIO_Pin_7

    //Clock
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

    //GPIO (for SPI1)
    GPIO_InitTypeDef spiGpioInitStruct;
    spiGpioInitStruct.GPIO_Pin = SPI1_SCK | SPI1_MOSI | SPI1_SS;
    spiGpioInitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    spiGpioInitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_Init(GPIOA, &spiGpioInitStruct);
    spiGpioInitStruct.GPIO_Pin = SPI1_MISO;
    spiGpioInitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    spiGpioInitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOA, &spiGpioInitStruct);

    //Initializing SPI itself
    SPI_InitTypeDef spiInitStruct;
    spiInitStruct.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
    spiInitStruct.SPI_DataSize = SPI_DataSize_8b;
    spiInitStruct.SPI_CPOL = SPI_CPOL_Low;
    spiInitStruct.SPI_CPHA = SPI_CPHA_1Edge;
    spiInitStruct.SPI_NSS = SPI_NSS_Hard;
    spiInitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_32;
    spiInitStruct.SPI_FirstBit = SPI_FirstBit_MSB;
    spiInitStruct.SPI_Mode = SPI_Mode_Master;
    SPI_Init(SPI1, &spiInitStruct);
    SPI_I2S_ITConfig(SPI1, SPI_I2S_IT_RXNE, ENABLE);
    SPI_Cmd(SPI1, ENABLE);
    NVIC_EnableIRQ(SPI1_IRQn);

    //Initializing SPI2 as slave
    //SPI2 SS(PB12), SCK(PB13), MISO(PB14), MOSI(PB15)

#define SPI2_SS GPIO_Pin_12
#define SPI2_SCK GPIO_Pin_13
#define SPI2_MISO GPIO_Pin_14
#define SPI2_MOSI GPIO_Pin_15

    //Clock
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
    //GPIO (for SPI2)
    GPIO_InitTypeDef spi2GpioInitStruct;
    spi2GpioInitStruct.GPIO_Pin = SPI2_MISO | SPI2_SS;
    spi2GpioInitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    spi2GpioInitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_Init(GPIOB, &spi2GpioInitStruct);
    spi2GpioInitStruct.GPIO_Pin = SPI2_SCK | SPI2_MOSI;
    spi2GpioInitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    spi2GpioInitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOB, &spi2GpioInitStruct);

    //Initializing SPI itself
    SPI_InitTypeDef spi2InitStruct;
    spi2InitStruct.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
    spi2InitStruct.SPI_DataSize = SPI_DataSize_8b;
    spi2InitStruct.SPI_CPOL = SPI_CPOL_Low;
    spi2InitStruct.SPI_CPHA = SPI_CPHA_1Edge;
    spi2InitStruct.SPI_NSS = SPI_NSS_Hard;
    spi2InitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_32;
    spi2InitStruct.SPI_FirstBit = SPI_FirstBit_MSB;
    spi2InitStruct.SPI_Mode = SPI_Mode_Slave;
    SPI_Init(SPI2, &spi2InitStruct);
    SPI_I2S_ITConfig(SPI2, SPI_I2S_IT_RXNE, ENABLE);
    SPI_Cmd(SPI2, ENABLE);
    NVIC_EnableIRQ(SPI2_IRQn);


    sendStringToUart("Application started\n");

    char *buf = "oh well this is it";

    while(1) {
        //delayMs(300);
        //blinkBlueLed();

        //while(*buf) {
        if(*buf) {
            while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) != SET);
            SPI_I2S_SendData(SPI1, (uint16_t)*buf);
            buf++;
        } else {
            blinkBlueLed();
        }
        //}

        processUsartRxBuffer();
    }
}

//char i=0;
//Master SPI
void SPI1_IRQHandler() {
    if(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == SET) { //this is RX not empty (i.e., byte received)
        uint8_t receivedByte = SPI1->DR;
        //... do something with the received byte
        sendBufToUart(&receivedByte, 1); //lets send it to UART and print in terminal
        //i++;
    }
}

//Slave SPI
void SPI2_IRQHandler() {
    if(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == SET) { //this is RX not empty (i.e., byte received)
        uint8_t receivedByte = SPI_I2S_ReceiveData(SPI2);
        //... do something with the received byte
        while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) != SET); //wait for previous transmission to be completed
        SPI_I2S_SendData(SPI2, receivedByte); //just echo what slave has received from master
        //SPI2->DR = receivedByte;

    }
}
 

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

Реклама: ООО ТД Промэлектроника, ИНН: 6659197470, Тел: 8 (800) 1000-321

20% скидка на весь каталог электронных компонентов в ТМ Электроникс!

Акция "Лето ближе - цены ниже", успей сделать выгодные покупки!

Плюс весь апрель действует скидка 10% по промокоду APREL24 + 15% кэшбэк и бесплатная доставка!

Перейти на страницу акции

Реклама: ООО ТМ ЭЛЕКТРОНИКС, ИНН: 7806548420, info@tmelectronics.ru, +7(812)4094849

16 minutes ago, Yurkin2015 said:

Выход SS у мастера активирован?


SPI_SSOutputCmd(SPI1, ENABLE);

Что логический анализатор на линии SS показывает?

Спасибо! Именно в этом и была проблема (еще была выставлена слишком большая скорость SPI, UART не поспевал за ним, но с этим разобрался).

А для чего нужен вывод SS? Slave select, как я понимаю, можно сделать через GPIO, и перед отправкой/принятием данных выставлять его в 0, а потом после обмена данными, выставлять его в 1, а в 0 выставлять другой GPIO, который назначили Slave Select для другого устройства (если хочется несколько девайсов поцепить на один и тот же SPI). А так имеется только один вывод SS, который автоматически выставляется в 0 перед передачей (это функция SPI_SSOutputCmd(SPI1, ENABLE) его в 0 опускает?), и так и остается в 0 (судя по лог.анализатору), получается он ничего выбрать не может, кроме этого конкретного slave девайса, к которому он подключен.

Как применяется эта нога и зачем она нужна?

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

Выбираем схему BMS для корректной работы литий-железофосфатных (LiFePO4) аккумуляторов

 Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ, также как и для других, очень важен контроль процесса заряда и разряда, а специализированных микросхем для этого вида аккумуляторов не так много. Инженеры КОМПЭЛ подготовили список имеющихся микросхем и возможных решений от разных производителей. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

Если несколько слейвов сидят на SPI, то для выбора с кем конкретно общаться в данный момент, конечно, нужно использовать несколько GPIO и в программе опускать нужную ногу перед началом общения. А стандартный SS не использовать вовсе.

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

1 hour ago, Yurkin2015 said:

 

Спасибо за ответы!

Хм не понимаю. Почему-то часть символов не приходит в уарт, а часть - просто дубликаты, вместо реальных символов, которые отправляю в SPI.

уменьшил скорость до минимума:

    spiInitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;
    spi2InitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;

отсылаю в SPI текст

"this is an spi string!\n"

а получаю мусор вроде 

"this is  n spi s "

или еще что-нибудь.

Перед каждой отправкой в SPI или UART, я проверяю, готов ли передатчик, в бесконечном цикле:

while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET) {}; 

while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) != SET);

но почему-то возникают проблемы...

Код тот же что в стартовом посте, только изменил spi_paudrateprescaler.

USART1 настроен правильно, скорости 115200  и в прошивке stm, и в программе-терминале, если просто отослать текст в uart, он правильно отобразиться в терминале. А через spi байты теряются/дублируются.

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

 

Чего я не учел?

 

Capture.PNG

Изменено пользователем bobbjenkins
Ссылка на комментарий
Поделиться на другие сайты

Видимо обмен байтом по SPI происходит быстрее, чем выдача байта по USART. То есть ещё не успел вытолкнуться предыдущий байт USART из Tx на выход в сдвиговый регистр, ещё он сидит и ждёт отправки, а уже SPI прокрутилось и затолкнуло новый байт в Tx USART.

Вот, что эта процедура processUsartRxBuffer() делает? По уму, надо бы дожидаться конца передачи USART, а потом уже продолжать основной цикл while().

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

20 minutes ago, Yurkin2015 said:

Видимо обмен байтом по SPI происходит быстрее, чем выдача байта по USART. То есть ещё не успел вытолкнуться предыдущий байт USART из Tx на выход в сдвиговый регистр, ещё он сидит и ждёт отправки, а уже SPI прокрутилось и затолкнуло новый байт в Tx USART.

Вот, что эта процедура processUsartRxBuffer() делает? По уму, надо бы дожидаться конца передачи USART, а потом уже продолжать основной цикл while().

я дожидаюсь в обработчике прерывания RXNE SPI. Немного неправильно, но должно же работать точно так же, как если бы дожидался в цикле while() функции main()?Процедура processUsartRxBuffer() проверяет флаг "uartRxBufferHasDataToBeProcessed", и если он 1, то просто отсылает данные обратно. В коде пока не используется (потому что данные из uart в stm32 я не отсылаю, только из stm32 в uart). Перед каждой отправкой (в uart или в SPI) я жду в циклах ожидания, когда передатчик будет "готов".

Пока нет отладчика нормального (в coocox так и не понял как его завести, а printf() не работает потому что в vldiscovery устаревший stlink-1), приходится гадать по лог. анализатору.

Непонятно почему данные не до конца отсылаются по SPI (на картинке лог анализатора видно что только часть текста отправляется), и почему принимается на 2 байта меньше, чем было отослано (а первые принятые 2 байта - вообще нули). Я так понимаю, первые два байта всегда нужно игнорировать, они там в результате сдвига пустого двухбайтного регистра-отправителя?

Вот полный код прошивки:

#include <stm32f10x.h>
#include <stm32f10x_rcc.h>
#include <stm32f10x_gpio.h>
#include <stm32f10x_flash.h>
#include <stm32f10x_tim.h>
#include <stm32f10x_spi.h>
#include <stdint.h>


//Data Watchpoint and Trace Register
#define    DWT_CYCCNT    *(volatile unsigned long *)0xE0001004
#define    DWT_CONTROL   *(volatile unsigned long *)0xE0001000
#define    SCB_DEMCR     *(volatile unsigned long *)0xE000EDFC
void delayTimerInit() {
	SCB_DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
	DWT_CYCCNT = 0;
	DWT_CONTROL |= DWT_CTRL_CYCCNTENA_Msk;
}

static __inline uint32_t delta(uint32_t t0, uint32_t t1)
{
    return (t1 - t0);
}
void delayUs(uint32_t us)
{
      uint32_t t0 =  DWT->CYCCNT;
      uint32_t us_count_tic =  us * (SystemCoreClock/1000000);
      while (delta(t0, DWT->CYCCNT) < us_count_tic) ;
}

void delayMs(uint32_t us)
{
      uint32_t t0 =  DWT->CYCCNT;
      uint32_t us_count_tic =  us * (SystemCoreClock/1000);
      while (delta(t0, DWT->CYCCNT) < us_count_tic) ;
}



void blinkGreenLed() {
	GPIO_SetBits(GPIOC, GPIO_Pin_9);
	delayMs(1);
	GPIO_ResetBits(GPIOC, GPIO_Pin_9);
}

void blinkBlueLed() {
	GPIO_SetBits(GPIOC, GPIO_Pin_8);
	delayMs(1);
	GPIO_ResetBits(GPIOC, GPIO_Pin_8);
}

volatile int counter = 0;

int main() {
	initSystemClockWith24MHz();
	delayTimerInit();

	initializeUsart1();


	//Initializing the onboard LEDs
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
	GPIO_InitTypeDef ledPortInitStruct;
	ledPortInitStruct.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9;
	ledPortInitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
	ledPortInitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOC, &ledPortInitStruct);





	//Initializing SPI1 as master
	//SPI1 SS(PA4), SCK(PA5), MISO(PA6), MOSI(PA7)

#define SPI1_SS GPIO_Pin_4
#define SPI1_SCK GPIO_Pin_5
#define SPI1_MISO GPIO_Pin_6
#define SPI1_MOSI GPIO_Pin_7

	//Clock
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

	//GPIO (for SPI1)
	GPIO_InitTypeDef spiGpioInitStruct;
	spiGpioInitStruct.GPIO_Pin = SPI1_SCK | SPI1_MOSI | SPI1_SS;
	spiGpioInitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	spiGpioInitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_Init(GPIOA, &spiGpioInitStruct);
	spiGpioInitStruct.GPIO_Pin = SPI1_MISO;
	spiGpioInitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	spiGpioInitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	GPIO_Init(GPIOA, &spiGpioInitStruct);

	//Initializing SPI itself
	SPI_InitTypeDef spiInitStruct;
	spiInitStruct.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
	spiInitStruct.SPI_DataSize = SPI_DataSize_8b;
	spiInitStruct.SPI_CPOL = SPI_CPOL_Low;
	spiInitStruct.SPI_CPHA = SPI_CPHA_1Edge;
	spiInitStruct.SPI_NSS = SPI_NSS_Hard;
	spiInitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;
	spiInitStruct.SPI_FirstBit = SPI_FirstBit_MSB;
	spiInitStruct.SPI_Mode = SPI_Mode_Master;
	SPI_Init(SPI1, &spiInitStruct);
	SPI_I2S_ITConfig(SPI1, SPI_I2S_IT_RXNE, ENABLE);
	SPI_Cmd(SPI1, ENABLE);
	NVIC_EnableIRQ(SPI1_IRQn);
	SPI_SSOutputCmd(SPI1, ENABLE);


	//Initializing SPI2 as slave
	//SPI2 SS(PB12), SCK(PB13), MISO(PB14), MOSI(PB15)

#define SPI2_SS GPIO_Pin_12
#define SPI2_SCK GPIO_Pin_13
#define SPI2_MISO GPIO_Pin_14
#define SPI2_MOSI GPIO_Pin_15

	//Clock
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
	//GPIO (for SPI2)
	GPIO_InitTypeDef spi2GpioInitStruct;
	spi2GpioInitStruct.GPIO_Pin = SPI2_MISO;
	spi2GpioInitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	spi2GpioInitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_Init(GPIOB, &spi2GpioInitStruct);
	spi2GpioInitStruct.GPIO_Pin = SPI2_SCK | SPI2_MOSI | SPI2_SS;
	spi2GpioInitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	spi2GpioInitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	GPIO_Init(GPIOB, &spi2GpioInitStruct);

	//Initializing SPI itself
	SPI_InitTypeDef spi2InitStruct;
	spi2InitStruct.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
	spi2InitStruct.SPI_DataSize = SPI_DataSize_8b;
	spi2InitStruct.SPI_CPOL = SPI_CPOL_Low;
	spi2InitStruct.SPI_CPHA = SPI_CPHA_1Edge;
	spi2InitStruct.SPI_NSS = SPI_NSS_Hard;
	spi2InitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;
	spi2InitStruct.SPI_FirstBit = SPI_FirstBit_MSB;
	spi2InitStruct.SPI_Mode = SPI_Mode_Slave;
	SPI_Init(SPI2, &spi2InitStruct);
	SPI_I2S_ITConfig(SPI2, SPI_I2S_IT_RXNE, ENABLE);
	SPI_Cmd(SPI2, ENABLE);
	NVIC_EnableIRQ(SPI2_IRQn);

	//SPI_


	sendStringToUart("Application started\n");

	char *buf = "1234567890";

	while(1) {
		//delayMs(300);
		//blinkBlueLed();

		//while(*buf) {
		if(*buf) {
			while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) != SET);
			SPI_I2S_SendData(SPI1, (uint16_t)*buf);
			buf++;
		} else {
			blinkBlueLed();
			//char thebuf[100];
			//sprintf(thebuf, "Counter: %d\n", counter);
			//sendStringToUart(thebuf);
			//delayMs(1000);
		}
		//}

		processUsartRxBuffer();
		//delayMs(50);
	}
}


//char i=0;
//Master SPI
void SPI1_IRQHandler() {
	if(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == SET) { //this is RX not empty (i.e., byte received)
		counter++;
		uint8_t receivedByte = SPI1->DR;
		//... do something with the received byte
		sendBufToUart(&receivedByte, 1); //lets send it to UART and print in terminal
		//i++;
	}
}

//Slave SPI
void SPI2_IRQHandler() {
	if(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == SET) { //this is RX not empty (i.e., byte received)
		uint8_t receivedByte = SPI_I2S_ReceiveData(SPI2);
		//... do something with the received byte
		while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) != SET); //wait for previous transmission to be completed
		SPI_I2S_SendData(SPI2, receivedByte); //just echo what slave has received from master
		//SPI2->DR = receivedByte;

	}
}



#define UARTRXBUFFERSIZE 0xff
unsigned int uartRxBufferPointer = 0;
char uartRxBuffer[UARTRXBUFFERSIZE];
FlagStatus uartRxBufferHasDataToBeProcessed = RESET;

void initializeUsart1() {
	//USART1 pins: TX(PA10), RX(PA10)
	//USART2 pins: TX(PA2), RX(PA3)
	//USART3 pins: TX(B10), RX(B11)

	//Initializing USART
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //Usart1 uses PA9 and PA10
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);

	//Initializing USART interrupt
	NVIC_InitTypeDef usartNvicInitStruct;
	usartNvicInitStruct.NVIC_IRQChannel = USART1_IRQn;
	usartNvicInitStruct.NVIC_IRQChannelPreemptionPriority = 0;
	usartNvicInitStruct.NVIC_IRQChannelSubPriority = 0;
	usartNvicInitStruct.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&usartNvicInitStruct);

	//Initializing GPIO (USART1 TX)
	GPIO_InitTypeDef usartGpioInitStruct;
	usartGpioInitStruct.GPIO_Pin = GPIO_Pin_9;
	usartGpioInitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
	usartGpioInitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &usartGpioInitStruct);

	//Initializing GPIO (USART1 RX)
	usartGpioInitStruct.GPIO_Pin = GPIO_Pin_10;
	usartGpioInitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	GPIO_Init(GPIOA, &usartGpioInitStruct);

	//Configuring USART itself
	USART_InitTypeDef usartInitStruct;
	usartInitStruct.USART_BaudRate = 115200;
	usartInitStruct.USART_WordLength = USART_WordLength_8b;
	usartInitStruct.USART_StopBits = USART_StopBits_1;
	usartInitStruct.USART_Parity = USART_Parity_No;
	usartInitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	usartInitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
	USART_Init(USART1, &usartInitStruct);
	USART_Cmd(USART1, ENABLE);
	USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
}

//Called when received 1 byte
void USART1_IRQHandler() {
	//if((USART2->SR & USART_FLAG_RXNE) != (u16)RESET) { //Checking if receiving buffer is not empty
	if(USART_GetITStatus(USART1, USART_IT_RXNE)) {
		uint8_t receivedByte = USART_ReceiveData(USART1);
		uartRxBuffer[uartRxBufferPointer++] = receivedByte;
		if(receivedByte == 0x0d) { //The received byte is "\n"
			uartRxBufferHasDataToBeProcessed = SET;
			blinkGreenLed();
		} else { //Any other byte
			if(uartRxBufferPointer >= UARTRXBUFFERSIZE) {
				uartRxBufferPointer = 0;
			}
		}

	}
}

void processUsartRxBuffer() {
	if(uartRxBufferHasDataToBeProcessed == SET) {
		sendBufToUart(uartRxBuffer, uartRxBufferPointer);
		sendBufToUart("\n", 1);
		uartRxBufferHasDataToBeProcessed = RESET;
		uartRxBufferPointer = 0;
	}
}

void sendStringToUart(char *string) {
	while(*string) {
		while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET) {}; //Spinning until Transmission Complete flag becomes SET
		USART_SendData(USART1, *string);
		string++;
	}
}

void sendBufToUart(uint8_t *buf, unsigned int bufSize) {
	for(unsigned int i=0; i<bufSize; i++) {
		while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET) {}; //Spinning until Transmission Complete flag becomes SET
		USART_SendData(USART1, buf[i]);
	}
}




void initSystemClockWith24MHz() {
	RCC_DeInit();

	RCC_HSEConfig(RCC_HSE_ON); //hse clock = 8 mhz

	ErrorStatus hseStatus = RCC_WaitForHSEStartUp();
	if(hseStatus == SUCCESS) {

		//FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
		FLASH_SetLatency(FLASH_Latency_0);

		//Div1 means "divided by 1", so no actual division
		RCC_HCLKConfig(RCC_SYSCLK_Div1); //AHB Prescaler //ahb = sysclock
		RCC_PCLK2Config(RCC_HCLK_Div1); //APB2 Prescaler //apb2 = sysclock
		RCC_PCLK1Config(RCC_HCLK_Div1); //APB1 Prescaler //abp1 = sysclock



		//PLL - is a multiplier of the clock
		RCC_PREDIV1Config(RCC_PREDIV1_Source_HSE, RCC_PREDIV1_Div2);
		RCC_PLLConfig(RCC_PLLSource_PREDIV1, RCC_PLLMul_6); //PLL = HSE*6/2 = 6*8/2 = 48/2 = 24 MHz   HSE*9 = 8MHz * 9 = 72/2 = 36 MHz
		RCC_PLLCmd(ENABLE);

		//wait while PLL is ready
		while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET) {}



		RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);

		//wait while sys clock is switched to PLL
		while(RCC_GetSYSCLKSource()!=0x08) {}
	} else {
		//problems with HSE
	}
}

 

Изменено пользователем bobbjenkins
Ссылка на комментарий
Поделиться на другие сайты

Можно, это два независимых блока.

Если есть два процесса передачи данных SPI и USART, то я бы сделал по-простому.

Сначала передал байт по SPI, дождался окончания передачи байта, при этом одновременно бы закончился приём нового байта по SPI.

Затем проверил, можно ли записывать новый байт в Tx по USART, и послал байт по USART.

Затем инкрементируем указатель buf, и возвращаемся на новый круг.

Прерывание SPI1 не нужно совсем.

В прерывании SPI2 проверял бы только флаг приёма нового байта.

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

uint8_t receivedByte;
.....
if(*buf) {
    SPI_I2S_SendData(SPI1, *buf);
    while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) != SET);// Ожидаем окончания передачи/приёма байта по SPI
    receivedByte = SPI1->DR;
    while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) != SET) {}; // Ожидаем освобождения регистра Tx по USART
    USART_SendData(USART1, receivedByte);
    buf++;
    } 
	else{
        blinkBlueLed();
    }
....
void SPI2_IRQHandler() {
    if(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == SET) //this is RX not empty (i.e., byte received)
	{
        SPI2->DR = SPI2->DR;
    }
}

 

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

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

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

Гость
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Ответить в этой теме...

×   Вставлено с форматированием.   Восстановить форматирование

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

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

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

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

Загрузка...
  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
×
×
  • Создать...