Страница 1 из 1

STM32 SPI

Добавлено: Вс дек 06, 2020 12:53:21
Cheeseman
Приветствую. При пересылке нескольких байт данных по SPI логический анализатор выдает следующую картинку (прикрепил).
не могу понять почему spi не работает (на анализаторе какая-то фигня). Также имеется вопрос. Настроил ногу PA4 (CS пин) с подтяжкой к +, а подтяжки почему-то нет.
Код проекта:

Код: Выделить всё

#include "stm32f4xx_hal.h"

void init_SPI(void);
void init_port(void);
void send_frame(int frame);

#define CS_LOW  do { GPIOA->BSRR |= GPIO_BSRR_BR4; } while (0)
#define CS_HIGH do { GPIOA->BSRR |= GPIO_BSRR_BS4; } while (0)

void mymain(void) {
	init_port();
	init_SPI();
	while (1) {
		send_frame(0x02);
		send_frame(0x0F);
		send_frame(0x54);
		send_frame(0x8D);
		send_frame(0x56);
		send_frame(0x3E);
		send_frame(0x5A);
		send_frame(0x1E);
		send_frame(0x58);
		send_frame(0x0);
		send_frame(0x4C);
		send_frame(0x70);
		send_frame(0x2A);
		send_frame(0x40);
		send_frame(0x22);
		send_frame(0x3D);

	}
}

void init_port(void) {
	//PA4 - CS ; PA5 -  SCK ; PA6 - MISO ; PA7 - MOSI
	RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN; // вкл тактирование порта А

	GPIOA->MODER |= GPIO_MODER_MODER4_0; // PA4 - не имеет альтернативной функции
	GPIOA->MODER |= GPIO_MODER_MODER5_1 | GPIO_MODER_MODER6_1 | GPIO_MODER_MODER7_1; // 5_1 - альтерн функция
	GPIOA->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR4_0| GPIO_OSPEEDER_OSPEEDR5_0
			| GPIO_OSPEEDER_OSPEEDR6_0 | GPIO_OSPEEDER_OSPEEDR7_0; //  high_speed
	GPIOA->PUPDR |=  GPIO_PUPDR_PUPD5_1| GPIO_PUPDR_PUPD6_1 | GPIO_PUPDR_PUPD7_1; // pull-down
	GPIOA->PUPDR |=  GPIO_PUPDR_PUPD4_0; // pull-up
	//назначаем выводам необходимые альтернативные ф-ции
	GPIOA->AFR[0] |= (0x05<<5*4);
	GPIOA->AFR[0] |= (0x05<<6*4);
	GPIOA->AFR[0] |= (0x05<<7*4);
}

void init_SPI(void) {
	RCC->APB2ENR |= RCC_APB2ENR_SPI1EN; // вкл тактирование SPI
/*
 * двухпроводный режим (BIDIMODE  = 0)
 * CRC отсутствуует (CRCEN = 0)
 * данные - 8 бит (DFF = 0)
 * MSB - первый бит
 */
	SPI1->CR1 |= SPI_CR1_BR;                //Baud rate = Fpclk/256
	SPI1->CR1 |= SPI_CR1_MSTR;              //Mode Master
	SPI1->CR1 &= ~SPI_CR1_CPOL;             //Polarity signal CPOL = 0;
	SPI1->CR1 &= ~SPI_CR1_CPHA;             //Phase signal    CPHA = 0;
	SPI1->CR1 |= SPI_CR1_SSM | SPI_CR1_SSI; // включаем так как режим мастер. Nss актуальна только для слейва
	SPI1->CR1 |= SPI_CR1_SPE;                //Enable SPI1
}

void send_frame(int frame) {
	CS_LOW; //активируем Chip Select
	while(!(SPI1->SR & SPI_SR_TXE));
		SPI1->DR = frame; //отправляем данные
	CS_HIGH;
}

Re: STM32 SPI

Добавлено: Вс дек 06, 2020 13:08:32
Reflector
Ты проверил TXE, записал байт и сразу CS подымаешь, а в это время может только первый бит передается. Нужно ждать окончания передачи, на разных версиях SPI это делается по-разному...

Re: STM32 SPI

Добавлено: Вт дек 08, 2020 17:28:22
Myp3ik
В простейшем случае подождать пока установится флаг BUSY, затем подымать CS.

Re: STM32 SPI

Добавлено: Ср июн 02, 2021 15:30:58
boris911
Подскажите, пожалуйста, по правильной настройке SPI2 STM32F103C8T6. В авр уровень SCK низкий с импульсами вверх, уровень MOSI высокий с импульсами вниз. В то же время у меня на bluepill оба сигнала с низким уровнем и импульсами вверх. Так и должно быть или неправильная инициализация?

Код: Выделить всё

void InitSpi2() {
volatile u32 tmp=0;

	RCC->APB2ENR |=  RCC_APB2ENR_AFIOEN;     //включить тактирование альтернативных функций        
	RCC->APB2ENR |=  RCC_APB2ENR_IOPBEN;     //включить тактирование порта B

	tmp=RCC->APB2ENR;	//delay

	RCC->APB1ENR |= RCC_APB1ENR_SPI2EN; //подать тактирование
	tmp=RCC->APB1ENR;	//delay
	SPI2->CR1     = 0x0000;             //очистить первый управляющий регистр
	SPI2->CR2     = 0x0000;             //очистить второй управляющий регистр
	SPI2->CR1    |= SPI_CR1_MSTR;       //контроллер должен быть мастером
	SPI2->CR1    |= 0b10<<3;                   //задаем скорость
	SPI2->CR1    |= SPI_CR1_SSI;        //обеспечить высокий уровень программного NSS
	SPI2->CR1    |= SPI_CR1_SSM;        //разрешить программное формирование NSS
	SPI2->CR1    |= SPI_CR1_SPE;        //разрешить работу модуля SPI

	//вывод SCK: выход двухтактный, альтернативная функция, 50MHz
	GPIOB->CRH   |=  GPIO_CRH_MODE13;    //
	GPIOB->CRH   &= ~GPIO_CRH_CNF13;     //
	GPIOB->CRH   |=  GPIO_CRH_CNF13_1;   //

	//вывод MOSI: выход двухтактный, альтернативная функция, 50MHz
	GPIOB->CRH   |=  GPIO_CRH_MODE15;    //
	GPIOB->CRH   &= ~GPIO_CRH_CNF15;     //
	GPIOB->CRH   |=  GPIO_CRH_CNF15_1;   //
}

Re: STM32 SPI

Добавлено: Чт июн 03, 2021 16:17:14
Myp3ik
Полярность и фаза сигналов задаётся регистрами CPOL и CPHA.

Re: STM32 SPI

Добавлено: Чт июн 03, 2021 16:31:44
Reflector
На MOSI должно быть то, что собственно выводится, разве что инверсия включена, чего для F1 не предусмотрено. Если в DR записали 0, то и на MOSI будет 0, не важно что там творится на SCK...