Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: STM32F100 SPI no SCK
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > ARM, 32bit
P4R4N014C
Здравствуйте. Пытаюсь связать LIS3DH и STM32F100 по SPI. Использую Software режим, fullduplex. Проблема в том, что на выходе SCK нет такта - все время висит высокий или низкий уровень в зависимости от CPOL. Не выставляются флаги Busy и RXNE, не сбрасывается флаг TXE. Ниже приведен код, проект собран в Keil. Проект испытывал на собранной плате, на STM32F0 DISCOVERY. Также пробовал загружать пример от STM на плату STM32F4 (MEMS акселерометр). Везде одна и та же проблема - SPI мертв. Видимо упускаю что-то системное, что то общее для всех 3х плат, но у меня уже нет идей, что это может быть. Прошу помощи.

#include "stm32f10x.h"
#include "stm32f10x_spi.h"

void init();
void spi();


void main()
{
init();
while(1)
{
spi();

}
}

void init()
{

RCC->APB2ENR^=(1<<0 | 1<<2 | 1<<3 | 1<<5 | 1<<12 ); // spi1, GPIO clock enable
GPIOA->CRL&=0x000000ff; // port A config to spi
GPIOA->CRL^=0xb4b34b00;

SPI1->CR1=(1<<0|1<<1|1<<5|1<<8|1<<9); // spi config

}



void spi()
{
unsigned char ax=0;
unsigned char ay=0;
unsigned char az=0;
unsigned char temp;
temp=0xE8;

SPI1->CR1^=(1<<2|1<<6); // SPI enable


while (!(SPI1->SR & SPI_SR_TXE)); // if tx empty then transfer
SPI1->DR = temp;


while (!(SPI1->SR & SPI_SR_RXNE));
ax= SPI1->DR;

SPI1->DR = temp;
while (!(SPI1->SR & SPI_SR_RXNE)); // wait before reiceve ends
ay = SPI1->DR;

SPI1->DR = temp;
while (!(SPI1->SR & SPI_SR_RXNE)); // wait before reiceve ends
az= SPI1->DR;


SPI1->CR1^=(1<<6); // SPI disable

}
A.Lex
Могу предложить для сравнения работающий код инициализации SPI
P4R4N014C
Спасибо что откликнулись. С вашим исходником у меня проект не собрался, но на его основе я написал следующее:


#include "stm32f10x.h"
#include "stm32f10x_spi.h"
SPI_InitTypeDef SPI_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;


void init();
void delay();
void spi();
void uart();

void main()
{
init();
while(1)
{
spi();

}
}

void init()
{

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //GPIO A clock enable
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE); // SPI 1 clock enable

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_7; // PA5(SCK),PA7(MOSI)- out AF PP
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin =GPIO_Pin_6; //PA5(MISO)- AF Input pullup,
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOA, &GPIO_InitStructure);



SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; // spi config
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_2Edge;
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_64;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_LSB;
SPI_InitStructure.SPI_CRCPolynomial = 7;
SPI_Init(SPI1, &SPI_InitStructure);
SPI_Cmd(SPI1, ENABLE);



}



void spi()
{
unsigned char ax=0;
unsigned char ay=0;
unsigned char az=0;
unsigned char temp;
temp=0xE8;


while (!(SPI1->SR & SPI_SR_TXE)); // if tx empty then transfer
SPI1->DR = temp;


while (!(SPI1->SR & SPI_SR_RXNE));
ax= SPI1->DR;

SPI1->DR = temp;
while (!(SPI1->SR & SPI_SR_RXNE)); // wait before reiceve ends
ay = SPI1->DR;

SPI1->DR = temp;
while (!(SPI1->SR & SPI_SR_RXNE)); // wait before reiceve ends
az= SPI1->DR;


SPI1->CR1^=(1<<6); // SPI disable

}


Результат тот же - такта нет. Может есть идеи? Ну и еще вопрос вдогонку: по умолчанию используется HSI в связке с PLL в качестве источника тактового сигнала, я ради интереса выводил сигнал с выхода HSI, с выхода PLL, а также с HSE на вывод MCO. Во всех 3 случаях сигнал на выводе MCO был похож на синус на основной частоте + 2-я, может быть 3-я гармоника. Это нормально?
A.Lex
Должен перед Вами извиниться: перед разрешением SPI д.б. разрешение генерации флагов

SPI_I2S_ITConfig(SPI1, SPI_I2S_IT_RXNE|SPI_I2S_IT_TXE, ENABLE);



По поводу сигнала на MCO - не пробовал.

P4R4N014C
Такт и данные на выводе MOSI появляются при запуске программы на свободное выполнение, но глухо в пошаговом режиме. Я так понимаю платы вроде STM32 DISCOVERY плохо подходят для отладки интерфейсов?
toweroff
Цитата(P4R4N014C @ Apr 20 2014, 20:31) *
Здравствуйте



Цитата(P4R4N014C @ Apr 21 2014, 21:18) *
я написал следующее:


а в теги [ codebox ] завернуть не судьба?
P4R4N014C
Опыт общения на форумах почти нулевой, так что некоторые вещи, которые де факто являются здесь правилами хорошего тона, мне могут быть просто не известны. Прошу прощения за былые и будущие промахи.
Сергей Борщ
Цитата(P4R4N014C @ Apr 23 2014, 08:53) *
Опыт общения на форумах почти нулевой,
А думать лень... Ведь уже по первому сообщению видно было, что оно отличается от остальных сообщений с кодом на форуме.
P4R4N014C
Позовите еще кого-нибудь, пусть тоже напишут об ошибках оформления и о не желании думать, а на описываемую проблему не обращайте внимания.
toweroff
Цитата(P4R4N014C @ Apr 23 2014, 15:32) *
Позовите еще кого-нибудь, пусть тоже напишут об ошибках оформления и о не желании думать, а на описываемую проблему не обращайте внимания.

хороший тон взяли с самого начала
ViKo
Пока не залезете в Reference Manual и не изучите регистры SPI, не догадаетесь, в чем ошибка.
У меня было так, для STM32F207. Такты включались раньше.
CODE
/* SPI1 -- связь с SFM M25PE40
8-bit, MSB first, SPEn, Fpclk2 / 4 (15 MHz), Master, CPOL=0, CPHA=0
Раньше разрешал SPI позже! */
SPI1->CR1 =
SPI_CR1_CPHA * 0 | // Clock Phase
SPI_CR1_CPOL * 0 | // Clock Polarity
SPI_CR1_MSTR * 1 | // Master Selection
SPI_CR1_BR_0 * 1 | // Baud Rate Control - fpclk2 / 4 = 15 MHz
SPI_CR1_BR_1 * 0 | //
SPI_CR1_BR_2 * 0 | //
SPI_CR1_SPE * 1 | // SPI Enable
SPI_CR1_LSBFIRST * 0 | // Frame Format
SPI_CR1_SSI * 1 | // Internal slave select
SPI_CR1_SSM * 1 | // Software slave management
SPI_CR1_RXONLY * 0 | // Receive only
SPI_CR1_DFF * 0 | // Data Frame Format
SPI_CR1_CRCNEXT * 0 | // Transmit CRC next
SPI_CR1_CRCEN * 0 | // Hardware CRC calculation enable
SPI_CR1_BIDIOE * 0 | // Output enable in bidirectional mode
SPI_CR1_BIDIMODE * 0; // Bidirectional data mode enable
SPI1->CR2 =
SPI_CR2_RXDMAEN * 0 | // Rx Buffer DMA Enable
SPI_CR2_TXDMAEN * 0 | // Tx Buffer DMA Enable
SPI_CR2_SSOE * 0 | // SS Output Enable
SPI_CR2_FRF * 0 | // Protocol format - 0: SPI Motorola mode, 1: SPI TI mode
SPI_CR2_ERRIE * 0 | // Error Interrupt Enable
SPI_CR2_RXNEIE * 0 | // RX buffer Not Empty Interrupt Enable
SPI_CR2_TXEIE * 0; // Tx buffer Empty Interrupt Enable
// SPI1->CR1 |= SPI_CR1_MSTR | SPI_CR1_SPE; // Разрешить, Мастер

/* SPI2 -- конфигурирование EP3C5
CONF_N (NSS) переключается программно */
SPI2->CR1 =
SPI_CR1_CPHA * 0 | // Clock Phase
SPI_CR1_CPOL * 0 | // Clock Polarity
SPI_CR1_MSTR * 1 | // Master Selection
SPI_CR1_BR_0 * 0 | // Baud Rate Control - fpclk1 / 2 = 15 MHz
SPI_CR1_BR_1 * 0 | //
SPI_CR1_BR_2 * 0 | //
SPI_CR1_SPE * 1 | // SPI Enable (раньше включалось позже!)
SPI_CR1_LSBFIRST * 1 | // Frame Format
SPI_CR1_SSI * 1 | // Internal slave select (раньше задавалось!)
SPI_CR1_SSM * 1 | // Software slave management
SPI_CR1_RXONLY * 0 | // Receive only
SPI_CR1_DFF * 0 | // Data Frame Format - 8 bit
SPI_CR1_CRCNEXT * 0 | // Transmit CRC next
SPI_CR1_CRCEN * 0 | // Hardware CRC calculation enable
SPI_CR1_BIDIOE * 0 | // Output enable in bidirectional mode
SPI_CR1_BIDIMODE * 0; // Bidirectional data mode enable
SPI2->CR2 =
SPI_CR2_RXDMAEN * 0 | // Rx Buffer DMA Enable
SPI_CR2_TXDMAEN * 0 | // Tx Buffer DMA Enable
SPI_CR2_SSOE * 0 | // SS Output Enable (все равно используется GPIO?)
SPI_CR2_FRF * 0 | // Protocol format - 0: SPI Motorola mode, 1: SPI TI mode
SPI_CR2_ERRIE * 0 | // Error Interrupt Enable
SPI_CR2_RXNEIE * 0 | // RX buffer Not Empty Interrupt Enable
SPI_CR2_TXEIE * 0; // Tx buffer Empty Interrupt Enable
// SPI2->CR1 |= SPI_CR1_SPE;

/* SPI3 -- регистр управления аналоговыми узлами
8-bit, MSB first, SPEn, Fpclk1 / 2 (15MHz), Master, CPOL=0, CPHA=0
74HC595 SCK - Pos, AD5314 SCK - Neg (изменить CPOL) */
SPI3->CR1 =
SPI_CR1_CPHA * 0 | // Clock Phase
SPI_CR1_CPOL * 0 | // Clock Polarity HC595
SPI_CR1_MSTR * 1 | // Master Selection
SPI_CR1_BR_0 * 0 | // Baud Rate Control - fpclk1 / 2 = 15 MHz
SPI_CR1_BR_1 * 0 | //
SPI_CR1_BR_2 * 0 | //
SPI_CR1_SPE * 1 | // SPI Enable
SPI_CR1_LSBFIRST * 0 | // Frame Format
SPI_CR1_SSI * 1 | // Internal slave select
SPI_CR1_SSM * 1 | // Software slave management
SPI_CR1_RXONLY * 0 | // Receive only
SPI_CR1_DFF * 0 | // Data Frame Format (8 bit)
SPI_CR1_CRCNEXT * 0 | // Transmit CRC next
SPI_CR1_CRCEN * 0 | // Hardware CRC calculation enable
SPI_CR1_BIDIOE * 0 | // Output enable in bidirectional mode
SPI_CR1_BIDIMODE * 0; // Bidirectional data mode enable
SPI3->CR2 =
SPI_CR2_RXDMAEN * 0 | // Rx Buffer DMA Enable
SPI_CR2_TXDMAEN * 0 | // Tx Buffer DMA Enable
SPI_CR2_SSOE * 0 | // SS Output Enable
SPI_CR2_FRF * 0 | // Protocol format - 0: SPI Motorola mode, 1: SPI TI mode
SPI_CR2_ERRIE * 0 | // Error Interrupt Enable
SPI_CR2_RXNEIE * 0 | // RX buffer Not Empty Interrupt Enable
SPI_CR2_TXEIE * 0; // Tx buffer Empty Interrupt Enable
P4R4N014C
Viko, спасибо за ответ!

Цитата(toweroff @ Apr 23 2014, 15:59) *
хороший тон взяли с самого начала

Мне сделали замечание и я учту его в будущем, но вот зачем мне его еще раз делает другой человек, да еще и записывает вот так сразу в лентяи? Это хороший тон,да?
toweroff
Цитата(P4R4N014C @ Apr 23 2014, 19:10) *
Мне сделали замечание и я учту его в будущем, но вот зачем мне его еще раз делает другой человек, да еще и записывает вот так сразу в лентяи? Это хороший тон,да?

хороший тон - это сначала разобраться с даташитом.
Не скажу, что сам всегда сразу "втыкаю" что и где, но ведь есть куча примеров с разными средами разработки, да и на сайте производителя много примеров. Если уж совсем затык - тогда сюда
P4R4N014C
Цитата(toweroff @ Apr 23 2014, 20:02) *
хороший тон - это сначала разобраться с даташитом.
Не скажу, что сам всегда сразу "втыкаю" что и где, но ведь есть куча примеров с разными средами разработки, да и на сайте производителя много примеров. Если уж совсем затык - тогда сюда

Пишете так, будто уверены, что всего этого я не делал. Собственно откуда такая уверенность? Сюда обратился, потому что зашел в тупик, потому что исчерпал для себя другие способы решения проблемы, но с таким отношением - лучше бы и не писал.
toweroff
В инициализации много ума нет. Сложно было проверить шагам что происходит в рабочем варианте и в нерабочем?
P4R4N014C
Цитата(toweroff @ Apr 23 2014, 22:26) *
В инициализации много ума нет. Сложно было проверить шагам что происходит в рабочем варианте и в нерабочем?

А вам не приходило в голову, что именно из-за того, что рабочий пример у меня при отладке не отличается от нерабочего я сюда и написал?Прямо не покидает ощущение, что держите за идиота...
Сергей Борщ
Цитата(P4R4N014C @ Apr 22 2014, 19:10) *
Такт и данные на выводе MOSI появляются при запуске программы на свободное выполнение, но глухо в пошаговом режиме.
Странно это. Не должно быть отличий. Возможно посылка происходит слишком быстро и вы не успеваете ее заметить?

Цитата(P4R4N014C @ Apr 22 2014, 19:10) *
Я так понимаю платы вроде STM32 DISCOVERY плохо подходят для отладки интерфейсов?
Да прекрасно все отлаживается. Просто надо помнить, что хоть программа и исполняется пошагово, но периферия продолжает работать на полной скорости. Из-за этого вы можете наблюдать установку некоторых флагов, которые никогда не успеют выставиться на всем скаку или наоборот, не успеете засечь сброшенное состояние других.

Вообще подобные вещи удобно наблюдать осциллографом в динамике, зацикливая в программе необходимый участок обмена.
toweroff
Еще один вариант - что при отладке отображаются регистры, флаги которых сбрасываются при чтении. Старые грабли
При обычном проходе содержимое регистра куда-то сохраняются, флаги сбрасываются автоматом аппаратно. А при отладке этот регистр вычитывает сам дебагер, после чего его уже читает программа со сброшенными флагами
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.