Полная версия этой страницы:
STM32F100 SPI no SCK
P4R4N014C
Apr 20 2014, 16:31
Здравствуйте. Пытаюсь связать 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
}
Могу предложить для сравнения работающий код инициализации SPI
P4R4N014C
Apr 21 2014, 17:18
Спасибо что откликнулись. С вашим исходником у меня проект не собрался, но на его основе я написал следующее:
#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-я гармоника. Это нормально?
Должен перед Вами извиниться: перед разрешением SPI д.б. разрешение генерации флагов
SPI_I2S_ITConfig(SPI1, SPI_I2S_IT_RXNE|SPI_I2S_IT_TXE, ENABLE);
По поводу сигнала на MCO - не пробовал.
P4R4N014C
Apr 22 2014, 16:10
Такт и данные на выводе MOSI появляются при запуске программы на свободное выполнение, но глухо в пошаговом режиме. Я так понимаю платы вроде STM32 DISCOVERY плохо подходят для отладки интерфейсов?
toweroff
Apr 22 2014, 16:35
Цитата(P4R4N014C @ Apr 20 2014, 20:31)

Здравствуйте
Цитата(P4R4N014C @ Apr 21 2014, 21:18)

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

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

Позовите еще кого-нибудь, пусть тоже напишут об ошибках оформления и о не желании думать, а на описываемую проблему не обращайте внимания.
хороший тон взяли с самого начала
Пока не залезете в 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
Apr 23 2014, 15:10
Viko, спасибо за ответ!
Цитата(toweroff @ Apr 23 2014, 15:59)

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

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

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

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

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

Я так понимаю платы вроде STM32 DISCOVERY плохо подходят для отладки интерфейсов?
Да прекрасно все отлаживается. Просто надо помнить, что хоть программа и исполняется пошагово, но периферия продолжает работать на полной скорости. Из-за этого вы можете наблюдать установку некоторых флагов, которые никогда не успеют выставиться на всем скаку или наоборот, не успеете засечь сброшенное состояние других.
Вообще подобные вещи удобно наблюдать осциллографом в динамике, зацикливая в программе необходимый участок обмена.
toweroff
Apr 24 2014, 08:06
Еще один вариант - что при отладке отображаются регистры, флаги которых сбрасываются при чтении. Старые грабли
При обычном проходе содержимое регистра куда-то сохраняются, флаги сбрасываются автоматом аппаратно. А при отладке этот регистр вычитывает сам дебагер, после чего его уже читает программа со сброшенными флагами
Для просмотра полной версии этой страницы, пожалуйста,
пройдите по ссылке.