Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Как заставить SPI работать (stm32f4Discovery)
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
BlackOps
конфигурирую пины PB13 - SPI2_SCK, PB15 - SPI2_MOSI: в режиме SPI только посылаю.

вот код:
CODE
int main(void)
{
/*!< At this stage the microcontroller clock setting is already configured,
this is done through SystemInit() function which is called from startup
file (startup_stm32f4xx.s) before to branch to application main.
To reconfigure the default setting of SystemInit() function, refer to
system_stm32f4xx.c file
*/
uint8_t d0 = 0xd9; // 11011001, test data0




// declare SPI init data structure
SPI_InitTypeDef spi2;

// declare GPIO init data structure
GPIO_InitTypeDef gpiob;

// enable SPI2 clock
RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);

// enable SPI2 pins
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);

// connecting Alternate Functions to GPIOB pins
GPIO_PinAFConfig(GPIOB, GPIO_PinSource13, GPIO_AF_SPI2);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource15, GPIO_AF_SPI2);


// GPIOB configuration
gpiob.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_15;
gpiob.GPIO_Mode = GPIO_Mode_AF;
gpiob.GPIO_OType = GPIO_OType_PP;
gpiob.GPIO_Speed = GPIO_Speed_50MHz;
gpiob.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOB, &gpiob);

// initializing the SPI2
SPI_I2S_DeInit(SPI2);
spi2.SPI_Direction = SPI_Direction_1Line_Tx;
spi2.SPI_DataSize = SPI_DataSize_8b;
spi2.SPI_CPOL = SPI_CPOL_High;
spi2.SPI_CPHA = SPI_CPHA_1Edge;
spi2.SPI_FirstBit = SPI_FirstBit_LSB;
spi2.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8;
spi2.SPI_Mode = SPI_Mode_Master;

SPI_Init(SPI2, &spi2);


// enable the SPI2
SPI_Cmd(SPI2, ENABLE);

// sending the data
while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET);
SPI_I2S_SendData(SPI2, (uint8_t)d0);



while (1)
{}
}



проблема такая, когда проверяю ножку пина PB15, то вижу клок в 5.25МГц, что вобщемто и должно быть т.к. я прескалер поставил _8.
Но на ножке PB15, с момента запуска платы никаких данных не постыпает.
SPIМне кажется сам модуль SPI вроде как сконфигурирован, но какая то проблема с посыланием данных, я сам взял это с какого то примера. Сам код отвечающий за посылку данных выделен.
// sending the data
while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET);
SPI_I2S_SendData(SPI2, (uint8_t)d0);



я просто жду пока Тх буффер будет свободен, и заливаю туда байт.

Но в чем же причина, почему я не вижу активности на пине MOSI? (PB15)
adnega
Может битик SYSCFGEN в RCC_APB2ENR взвести?
AHTOXA
Цитата(BlackOps @ Jun 8 2012, 10:13) *
Но в чем же причина, почему я не вижу активности на пине MOSI? (PB15)

Вы забыли включить тактирование AFIO.
adnega
Цитата(AHTOXA @ Jun 8 2012, 09:14) *
Вы забыли включить тактирование AFIO.


Для F4 это SYSCFGEN?
BlackOps
Цитата(AHTOXA @ Jun 8 2012, 10:14) *
Вы забыли включить тактирование AFIO.

а поподробнее?

не это разве?
gpiob.GPIO_Speed = GPIO_Speed_50MHz;

указана тактовая частота, или чтото другое подразумеваете?
AHTOXA
Пардон, я не разглядел, что речь идёт о F4. Там этого нет.
BlackOps
ну тогда в чем же еще может там быть проблема?
я строго следую инструкциям описанными в самой библиотеки, ну и походу сравниваю с некоторыми другими аналогичными примерами.


и еще, тот факт что я на осциллографе вижу пин SPI2_SCK (PB13) дергается на частоте примерно 5.25МГц мне говорит о том что вроде как сам модуль SPI настроен и вроде как работает.

но вот почему данные не могу переслать в буфер? что там еще может быть?
AHTOXA
Да вроде нормально всё. Попробуйте задать spi2.SPI_Mode = SPI_NSS_Soft.

Цитата(adnega @ Jun 8 2012, 11:20) *
Для F4 это SYSCFGEN?

Не, это совсем другое. SYSCFGEN включает тактирование System configuration controller (глава 7 из RM0090).
BlackOps
попробовал. не помогло. мало того да и пин PB13 даже перестал клок подавать.
BlackOps
что еще может быть?
может данные как то по другому надо пересылать?
AHTOXA
Данные вы отправляете правильно.
Попробуйте ещё поставить вызовы GPIO_PinAFConfig() после вызова GPIO_Init(). Мне думается, что так логичнее - сначала сконфигурировать пин, а затем подключить его к периферии.
Gunner
QUOTE (BlackOps @ Jun 8 2012, 07:13) *
конфигурирую пины PB13 - SPI2_SCK, PB15 - SPI2_MOSI: в режиме SPI только посылаю.

Попробуйте еще сконфигурировать пин SPI2_NSS и после SPI_Init() поставить SPI_SSOutputCmd(SPI2, ENABLE).

"When configured in master mode with NSS configured as an input (MSTR=1 and SSOE=0) and if NSS is pulled low, the SPI enters the master mode fault state: the MSTR bit is automatically cleared and the device is configured in slave mode"
BlackOps
т.е. сконфигурировать NSS и подать на него Vdd?
Gunner
QUOTE (BlackOps @ Jun 8 2012, 12:05) *
т.е. сконфигурировать NSS и подать на него Vdd?

Пока подавать ничего не надо. Просто сконфигурите SPI2_NSS и командой SPI_SSOutputCmd(SPI2, ENABLE) подключите его на выход. При этом spi2.SPI_NSS = SPI_NSS_Hard.
У меня в такой конфигурации все работает (STM32F207).
BlackOps
сделал. не сработало. вот что получаю:

пин MOSI поднимается сейчас вверх, и через 0.2мкс примерно опять спускается на уровень 0, а пин SCK стартует и остается на уровне Vdd.


кстати, я обнаружил что в моем случае надо ставить направление в режиме spi2.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
в таком случае коммуникация идет по двум пинам, но т.к. я использую только отправку а не принятие, то в таком режиме я использую пин MOSI.
правильно?


вот обновленный код, я установил НСС как вы сказали:
CODE

int main(void)
{
/*!< At this stage the microcontroller clock setting is already configured,
this is done through SystemInit() function which is called from startup
file (startup_stm32f4xx.s) before to branch to application main.
To reconfigure the default setting of SystemInit() function, refer to
system_stm32f4xx.c file
*/
uint8_t d0 = 0xd9; // 11011001, test data0



// declare SPI init data structure
SPI_InitTypeDef spi2;

// declare GPIO init data structure
GPIO_InitTypeDef gpiob;

// enable SPI2 clock
RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);

// enable SPI2 pins
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);




// GPIOB configuration
gpiob.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_15 | GPIO_Pin_12;
gpiob.GPIO_Mode = GPIO_Mode_AF;
gpiob.GPIO_OType = GPIO_OType_PP;
gpiob.GPIO_Speed = GPIO_Speed_50MHz;
gpiob.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOB, &gpiob);


// connecting Alternate Functions to GPIOB pins
GPIO_PinAFConfig(GPIOB, GPIO_PinSource13, GPIO_AF_SPI2);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource15, GPIO_AF_SPI2);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource12, GPIO_AF_SPI2);



// initializing the SPI2
SPI_I2S_DeInit(SPI2);
spi2.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
spi2.SPI_DataSize = SPI_DataSize_8b;
spi2.SPI_CPOL = SPI_CPOL_High;
spi2.SPI_CPHA = SPI_CPHA_1Edge;
spi2.SPI_FirstBit = SPI_FirstBit_LSB;
spi2.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8;
spi2.SPI_Mode = SPI_Mode_Master;
spi2.SPI_NSS = SPI_NSS_Hard;
SPI_Init(SPI2, &spi2);
SPI_SSOutputCmd(SPI2, ENABLE);

// enable the SPI2
SPI_Cmd(SPI2, ENABLE);

// sending the data
while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET)
{
}
SPI_I2S_SendData(SPI2, (uint8_t)d0);

// make sure the transmit buffer is free
// while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET);
// SPI_I2S_SendData(SPI2, d0);
// we are not reading data so be sure that the character goes to the shift register
//while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET);
// and then be sure it has been sent over the wire
// while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_BSY) == SET);


while (1)
{}
}
adnega
У меня работает в режиме Мастер при такой конфигурации.
Правда, без использования стандартной библиотеки.

Код
//-----------------------------------------------------------------------------
//    void init_SPI2(void)
//-----------------------------------------------------------------------------
void init_SPI2(void)
{
    SPI2->CR1 =
            SPI_CR1_SSM
        | SPI_CR1_SSI
        | SPI_CR1_MSTR
        | SPI_CR1_BR_2 | SPI_CR1_BR_1 | SPI_CR1_BR_0;

    SPI2->CR2 =
            SPI_CR2_SSOE;

    SPI2->CR1 =
            SPI_CR1_SPE
        | SPI_CR1_SSM
        | SPI_CR1_SSI
        | SPI_CR1_MSTR
        | SPI_CR1_BR_2 | SPI_CR1_BR_1 | SPI_CR1_BR_0;
}

//-----------------------------------------------------------------------------
//    void __inline init_SYSTEM(void)
//-----------------------------------------------------------------------------
void __inline init_SYSTEM(void)
{
    RCC->AHB1ENR = RCC_AHB1ENR_GPIOBEN;
    RCC->APB1ENR = RCC_APB1ENR_SPI2EN;
}

//-----------------------------------------------------------------------------
//    void __inline init_GPIO(void)
//-----------------------------------------------------------------------------
void __inline init_GPIO(void)
{
    GPIOB->MODER = GPIO_MODER_MODER13_1  | GPIO_MODER_MODER14_1  | GPIO_MODER_MODER15_1
    GPIOB->AFR[1] = (5 << ((13 - 8) << 2)) | (5 << ((14 - 8) << 2)) | (5 << ((15 - 8) << 2));
}
BlackOps
ну хоть дернулся пин PB15! какой то сдвиг, гдето еще чегото не хватает.. читаю даташит:
NSS output enabled (SSM = 0, SSOE = 1)
This configuration is used only when the device operates in master mode. The
NSS signal is driven low when the master starts the communication and is kept
low until the SPI is disabled.



теперь понятно почему надо было делать: SPI_SSOutputCmd(SPI2, ENABLE); это и включает SSOE = 1

и почему надо было: spi2.SPI_NSS = SPI_NSS_Hard; а это ставит бит SSM = 0

ну тогда же у меня все правильно, что там еще может быть?

напомню еще раз: клок идет вверх на Вдд и стоит там, а МОСИ идет на Вдд и опускается на ноль.
BlackOps
Вобщем получилось наконец-то завести SPI2.

Кстати, этот NSS пин вообще не нужен если мне не надо явно выбирать другой чип. использовал только MOSI и SCK.
вот код если еще кому надо:
CODE
int main(void)
{
/*!< At this stage the microcontroller clock setting is already configured,
this is done through SystemInit() function which is called from startup
file (startup_stm32f4xx.s) before to branch to application main.
To reconfigure the default setting of SystemInit() function, refer to
system_stm32f4xx.c file
*/
uint8_t d0 = 0xd9; // 11011001, test data0



// enable SPI2 clock
((RCC_TypeDef *) (RCC_BASE))->APB1ENR |= RCC_APB1ENR_SPI2EN;

// enable GPIOB clock
((RCC_TypeDef *)(RCC_BASE))->AHB1ENR |= RCC_AHB1ENR_GPIOBEN;


// GPIOB configuration
((GPIO_TypeDef *)(GPIOB_BASE))->MODER |= (GPIO_MODER_MODER13_1 |
GPIO_MODER_MODER15_1 );
((GPIO_TypeDef *)(GPIOB_BASE))->OTYPER |= 0x00;
((GPIO_TypeDef *)(GPIOB_BASE))->OSPEEDR |= (GPIO_OSPEEDER_OSPEEDR13_1 |
GPIO_OSPEEDER_OSPEEDR15_1 );
((GPIO_TypeDef *)(GPIOB_BASE))->PUPDR |= 0x00;
//((GPIO_TypeDef *)(GPIOB_BASE))->IDR |= RCC_AHB1ENR_GPIOBEN;
//((GPIO_TypeDef *)(GPIOB_BASE))->ODR |= RCC_AHB1ENR_GPIOBEN;
//((GPIO_TypeDef *)(GPIOB_BASE))->BSRRL |= RCC_AHB1ENR_GPIOBEN;
//((GPIO_TypeDef *)(GPIOB_BASE))->BSRRH |= RCC_AHB1ENR_GPIOBEN;
//((GPIO_TypeDef *)(GPIOB_BASE))->LCKR |= RCC_AHB1ENR_GPIOBEN;
((GPIO_TypeDef *)(GPIOB_BASE))->AFR[1] |= (0x500000 | 0x50000000);

// configure SPI2
((SPI_TypeDef *) (SPI2_BASE)) -> CR1 |= (SPI_CR1_SPE | SPI_CR1_CPOL |
SPI_CR1_CPHA | SPI_CR1_MSTR |
SPI_CR1_BR_1 | SPI_CR1_SSM | SPI_CR1_SSI);



// transmit the test data
while ( ( (((SPI_TypeDef *) (SPI2_BASE)) -> SR) & 0x2 ) == RESET)
{
// wait until TXE bit is 1
}
((SPI_TypeDef*)(SPI2_BASE)) -> DR = d0;

while (1)
{}
}
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.