stm32f0 spi 8 бит.

Кто любит RISC в жизни, заходим, не стесняемся.
Ответить
Родился
Сообщения: 14
Зарегистрирован: Чт апр 10, 2014 15:33:44

Сообщение link0ln »

Всем добра!
stm32f030f4p6. Keil4.
Проблема в том, чтобы заставить stm32f030f4p6 отправлять по spi ровно 8 бит, ибо как ни крути - шлет 16 и все.
В кейле пишу с использованием cmsis. Связь устанавливается по spi с nrf24l01. nrf24l01 умеет spi только по 8 бит.
пробовал следующие вещи:( отсюда http://electronix.ru/forum/lofiversion/ ... 06624.html )

#define SPI1_DR_8b (*(__IO uint8_t *)((uint32_t)SPI1 + 0x0C))
...
SPI1_DR_8b = 0x00; // шлем (00000000), на что nrf24l01 вернет нам значение данного регистра.
... // ждем пока на spi придет ответный байт.
uint8_t result = SPI1_DR_8b; // получаем какой-то результат, чаще всего либо ничего не приходит, либо приходит чтото наподобие 0E.

и отсюда: ( http://kazus.ru/forums/showthread.php?t=107109 )
#define SPI1_DR_8bit (*(__IO uint8_t *)((uint32_t)&(SPI1->DR)))
результат аналогичный первому.

При использовании стандартных функций из библиотек:
SPI_SendData8 и SPI_ReceiveData8 - результат такой же что и в первом варианте.

В spi cr2 выставляется бит DS = 0x07, FRXTH = 1


При программной реализации на тех же пинах все работает, но получается слишком ресурсоемко.

При чтение и записи 3 и 4 пины прижимаю к земле, как и нужно при общении с nrf24l01. Осцила нет, чтобы проконтролировать работу spi. но пробовал к raspberry pi целпять, она не успевает регистрировать импульсы.

Инициализация такая:

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

void initAll()
{
		SPI_InitTypeDef  SPI_InitStructure;
		GPIO_InitTypeDef GPIO_InitStructure;
	
	        USART_InitTypeDef usart;
	        GPIO_InitTypeDef port;

	  
        RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
		RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
	
		GPIO_PinAFConfig(GPIOA, GPIO_Pin_5,GPIO_AF_0);
		GPIO_PinAFConfig(GPIOA, GPIO_Pin_6,GPIO_AF_0);
		GPIO_PinAFConfig(GPIOA, GPIO_Pin_7,GPIO_AF_0);

		GPIO_InitStructure.GPIO_Pin =   GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
		GPIO_InitStructure.GPIO_Mode =  GPIO_Mode_AF;
		GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
		GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
		GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;
		GPIO_Init(GPIOA, &GPIO_InitStructure);

		

		GPIO_InitStructure.GPIO_Pin =   GPIO_Pin_3|GPIO_Pin_4;
		GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_OUT;
		GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
		GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
		GPIO_InitStructure.GPIO_PuPd =  GPIO_PuPd_DOWN;
		GPIO_Init(GPIOA, &GPIO_InitStructure);

                SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
		SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
		SPI_InitStructure.SPI_DataSize = SPI_DataSize_16b;
		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_InitStructure.SPI_CRCPolynomial = 7;
		SPI_Init(SPI1, &SPI_InitStructure);
		SPI_CalculateCRC(SPI1, DISABLE);

		SPI_Cmd(SPI1, ENABLE);
		
		SPI_RxFIFOThresholdConfig(SPI1, SPI_RxFIFOThreshold_QF);
}
Реклама
Прорезались зубы
Аватара пользователя
Сообщения: 202
Зарегистрирован: Пн сен 26, 2011 13:48:25
Откуда: Харьков

Сообщение slavokhire5 »

У Вас в инициализации написано

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

SPI_InitStructure.SPI_DataSize = SPI_DataSize_16b;
Это не может мешать?
Осилит дорогу идущий
--------------------------
Пишу на Си за еду
Реклама
Родился
Сообщения: 14
Зарегистрирован: Чт апр 10, 2014 15:33:44

Сообщение link0ln »

slavokhire5 писал(а):У Вас в инициализации написано

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

SPI_InitStructure.SPI_DataSize = SPI_DataSize_16b;
Это не может мешать?
Да, в данном случае мешает, но пробовал также менять на 8b.
Когда ставишь 16, то при отправке данных вида 0xFF00 - , где FF - будет первая команда, для nrf24l01 - это NOP, то вторую он проглатывает и отвечает, где на МС прилетает как бы 2 байта, но в первом будет ответ от nrf24l01 на команду 00.
Друг Кота
Аватара пользователя
Сообщения: 3604
Зарегистрирован: Пн июл 28, 2008 22:12:01

Сообщение dosikus »

link0ln, сие вам поможет http://kazus.ru/forums/showpost.php?p=7 ... ostcount=7
Реклама
Эиком - электронные компоненты и радиодетали
Родился
Сообщения: 14
Зарегистрирован: Чт апр 10, 2014 15:33:44

Сообщение link0ln »

dosikus писал(а):link0ln, сие вам поможет http://kazus.ru/forums/showpost.php?p=7 ... ostcount=7
Я в первом посте писал, что пробовал способ из ссылки, но результатов не дало.
Может у кого есть примеры рабочего кода?
Реклама
Друг Кота
Аватара пользователя
Сообщения: 3604
Зарегистрирован: Пн июл 28, 2008 22:12:01

Сообщение dosikus »

Хрен знает что и как ты пробовал .
Здесь полностью рабочий и инит и работа с SPI на F0 :

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

#define SPI1_DR_8bit          (*(__IO uint8_t *)((uint32_t)&(SPI1->DR))) 
///
//CUT
///
  void Spi1_init(void) 
  {
    	
		RCC->APB2ENR |=RCC_APB2ENR_SPI1EN;
			                  
		SPI1->CR1 |= 
						 SPI_CR1_BR_0 |    
						 SPI_CR1_BR_1 |
						 SPI_CR1_MSTR |
						 SPI_CR1_SSI 	|				 
						 SPI_CR1_SSM 
						 ;	
	SPI1->CR2  = 0x700;   //  8 bit
	SPI1->CR2 |= SPI_CR2_FRXTH;
	SPI1->CR1 |= SPI_CR1_SPE;	

  }

    uint8_t Spi1_send (uint8_t data)
      { 
        while (!(SPI1->SR & SPI_SR_TXE));     
        SPI1_DR_8bit = data;                       
        while (!(SPI1->SR & SPI_SR_RXNE));     
        
        return (SPI1_DR_8bit);		        
      }


      uint8_t Spi1_read (void)
      { 
     
        return 	Spi1_send(0xFF);  
 
      }



Реклама
Прорезались зубы
Аватара пользователя
Сообщения: 202
Зарегистрирован: Пн сен 26, 2011 13:48:25
Откуда: Харьков

Сообщение slavokhire5 »

а Вы в функцию передаете число какой разрядности? покажите функцию передачи
Осилит дорогу идущий
--------------------------
Пишу на Си за еду
Родился
Сообщения: 14
Зарегистрирован: Чт апр 10, 2014 15:33:44

Сообщение link0ln »

slavokhire5 писал(а):а Вы в функцию передаете число какой разрядности? покажите функцию передачи
ПРобовал так

#define SPI1_DR_8bit (*(__IO uint8_t *)((uint32_t)&(SPI1->DR)))
SPI1_DR_8bit = 0x00
и так
SPI1_DR_8bit = (uint8_t) 0x00

Разницы нет.
Друг Кота
Аватара пользователя
Сообщения: 3604
Зарегистрирован: Пн июл 28, 2008 22:12:01

Сообщение dosikus »

No comments ...

Изображение
Родился
Сообщения: 14
Зарегистрирован: Чт апр 10, 2014 15:33:44

Сообщение link0ln »

По рекомендации dosikus собрал следующий код в keil4.
Спойлер

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

#include "stm32f0xx.h"
#include "stm32f0xx_rcc.h"
//#include "stm32f0xx_spi.h"

#define SPI1_DR_8bit          (*(__IO uint8_t *)((uint32_t)&(SPI1->DR))) 


uint8_t status0,status1,status2,status3,status4,status5,status6,status7;



void Delay(uint32_t k) {
volatile uint32_t i;
for (i=0; i != 0x200*k; i++);
}



uint8_t Spi1_send (uint8_t data){
	GPIO_ResetBits(GPIOA, GPIO_Pin_4); // off nss
	Delay(1);
	while (!(SPI1->SR & SPI_SR_TXE));     //wait for data
	SPI1_DR_8bit = data;                    //send data   
	while (!(SPI1->SR & SPI_SR_RXNE));    //wait for data 
	Delay(1);
	GPIO_SetBits(GPIOA, GPIO_Pin_4); // en nss
	return (SPI1_DR_8bit);                //return data
}


void initGPIO()
{
		GPIO_InitTypeDef GPIO_InitStructure;
	  
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
		RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
	
		GPIO_PinAFConfig(GPIOA, GPIO_Pin_5,GPIO_AF_0);
		GPIO_PinAFConfig(GPIOA, GPIO_Pin_6,GPIO_AF_0);
		GPIO_PinAFConfig(GPIOA, GPIO_Pin_7,GPIO_AF_0);

		GPIO_InitStructure.GPIO_Pin =   GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
		GPIO_InitStructure.GPIO_Mode =  GPIO_Mode_AF;
		GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
		GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
		GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;
		GPIO_Init(GPIOA, &GPIO_InitStructure);

		GPIO_InitStructure.GPIO_Pin =   GPIO_Pin_3|GPIO_Pin_4;
		GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_OUT;
		GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
		GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
		GPIO_InitStructure.GPIO_PuPd =  GPIO_PuPd_DOWN;
		GPIO_Init(GPIOA, &GPIO_InitStructure);
}

int main() 
{ 
	initGPIO();  
	GPIO_ResetBits(GPIOA, GPIO_Pin_3);
	// the next is configuration for spi
	RCC->APB2ENR |=RCC_APB2ENR_SPI1EN;
  SPI1->CR1 |= 
        SPI_CR1_BR_0 |    
        SPI_CR1_BR_1 |
        SPI_CR1_MSTR |
        SPI_CR1_SSI    |             
        SPI_CR1_SSM;   
	SPI1->CR2  = 0x700;
	SPI1->CR2 |= SPI_CR2_FRXTH;
	SPI1->CR1 |= SPI_CR1_SPE;  	
	// end configuration of spi

	while(1){	
		status0 = Spi1_send(0x00);
		status1 = Spi1_send(0x01);
		status2 = Spi1_send(0x02);
		status3 = Spi1_send(0x03);
		status7 = Spi1_send(0x07);
	}
}
И собственно вот такой не верный результат получаю
http://youtu.be/0u1bNgDMd9A
Друг Кота
Аватара пользователя
Сообщения: 3604
Зарегистрирован: Пн июл 28, 2008 22:12:01

Сообщение dosikus »

link0ln писал(а):По рекомендации dosikus собрал следующий код в keil4.
link0ln писал(а): И собственно вот такой не верный результат получаю
Поставить 5й Keil и вылечить его наконец-то.
Отлаживать наблюдая не DR ( он как был 16бит так и останется )

Изображение

Похоже опыт нулевой? :))) ...
Родился
Сообщения: 14
Зарегистрирован: Чт апр 10, 2014 15:33:44

Сообщение link0ln »

Тему можно закрывать. Разобрался, dosikus, большое спасибо. Проблема больше оказалась в логике общения с nrf24l01.
Суть в чем - шлем байт регистра, которого хотим прочитать, в ответ параллельно, как я понял возвращается 0x0E( вот оно оказывается откуда берется).
Далее нам необходимо еще раз дернуть 8 раз sck, чтобы nrf дал ответ - для этого просто шлем любой байт(в большинстве примеров 0x00), в параллельном ответе будет значение регистра, который мы запрашивали.
Ответить

Вернуться в «ARM»