Перейти к содержанию
    

Всё это, конечно... очень интересно... :rolleyes:

"А был ли мальчик?"(С)

А глюк то... где??? Неужто самоликвидировался???

 

если коротко ТС взял другую плату дискавери, и залил туда проект с одним лишь СПИ, без прочей периферии, и глюк пропал.

 

Предложение по одному добавлять остальную периферию и найти какой модуль рушит СПИ одобрения не встретило. Потому до конца не ясно что же является причиной плата или остальная периферия.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Пишу с опозданием надобыло кое какие проекты сдавать и платы делать.

 

Во первых я не заявлял что нашел глюк, тема четко говорит "проблемы с СПИ", а проблемы могут быть по разым причинам, в том числе и по причине моей ошибки.

 

Сделал вот что:

 

1) После того как убедился что на новой голой плате проект СПИ заработал, я переписал старый проект по новому, и прогнал его тоже на новой плате - Заработало.

 

2) Старую платуполностью отсоеденил от всего что было соеденено, прогнал тот же епределанный проект - Заработало.

 

3) Начал присоеденять по очереди остальную перферию - Заработало с присоединенной всей периферией (Uart,PWM,I2C)

 

4) После того как СПИ проект с подсоединенной но не активизированной программно периферией заработал, я ее начал по очереди активизировать, в итоге проект был доведен до "оригиального" состояния, и тоже заработал

 

под "заработал" я имею ввиду что сразу при включении не надо долго ждать и я вижу свои байты на осциллографе.

 

 

Единственное что я заметил в результате всего этого это задержка SCK на примерно 1500нс когда все нижеприведенные функции не заккоментированны.

Когда закомментированны две последние функции включения i2c и usart3 то задержка подтянутого SCK не более 400нс

Когда закомментирован только usart3 то задержка SCk перед его переключением и посылкой байта 900нс

Когда все нижеприведенные функции включены (не закомментированны) то задержка SCK перед его переключением и посылкой байта 1500нс

 

При этом: Если включить всеэти функции (не комментировать их) и включить цикл задержки длинной после включения платы, а потом подать через тот же Usart3 команду на посылку байта по SPI, то байт отсылается сразу и SCK не задерживается (сразу начинает пиерелючатся)

 

Вот моя последовательность включения программно периферии:

config_gpio_all(); // configure all GPIOs
config_pwm_io(); // configure Input and Output PWM channels
config_spi_all(); // config all peripherals using SPI
config_i2c_all(); // config all peripherals using I2C
config_usart3(); // configure USART3

 

А вот код каждой функции:

uint32_t config_gpio_all(void)
{

//=============================================================================
// GPIOB configuration
//=============================================================================

// enable GPIOB clock
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOBEN;

// Alternate Function
GPIOB->MODER = 0; // clear moder register
GPIOB->MODER |=
(
GPIO_MODER_MODER12_1 | // Alternate Function, SPI2 NSS
GPIO_MODER_MODER13_1 | // Alternate Function, SPI2 SCK
GPIO_MODER_MODER14_1 | // Alternate Function, SPI2 MISO
GPIO_MODER_MODER15_1 | // Alternate Function, SPI2 MOSI

GPIO_MODER_MODER9_1  | // Alternate Function,  I2C1, SDA
GPIO_MODER_MODER8_1  | // Alternate Function,  I2C1, SCL

GPIO_MODER_MODER4_1 | // AF, PWM_OUT1, TIM3_CH1
GPIO_MODER_MODER5_1 | // AF, PWM_OUT2, TIM3_CH2
GPIO_MODER_MODER0_1 | // AF, PWM_OUT3, TIM3_CH3
GPIO_MODER_MODER1_1 | // AF, PWM_OUT4, TIM3_CH4
GPIO_MODER_MODER6_1 | // AF, PWM_IN5, TIM4_CH1
GPIO_MODER_MODER7_1   // AF, PWM_IN6, TIM4_CH2
);

// Output type
GPIOB->OTYPER = 0; // clear otype register 
GPIOB->OTYPER |=  // push-pull if 0
(
GPIO_OTYPER_OT_8 | // Open-Drain, I2C1, SCL
GPIO_OTYPER_OT_9   // OPen-Drain, I2C1, SDA
);

// Speed type
GPIOB->OSPEEDR = 0; // clear ospeedr register 
GPIOB->OSPEEDR |=
(
GPIO_OSPEEDER_OSPEEDR12_1 |  // SPI2 NSS 50MH
GPIO_OSPEEDER_OSPEEDR13_1 |  // SPI2 SCK, 50MHz
GPIO_OSPEEDER_OSPEEDR14_1 |  // SPI2 MISO 50MH
GPIO_OSPEEDER_OSPEEDR15_1 |  // SPI2 MOSI 50MH

GPIO_OSPEEDER_OSPEEDR4_1 | // PWM_OUT1, TIM3_CH1, 50MHz
GPIO_OSPEEDER_OSPEEDR5_1 | // PWM_OUT2, TIM3_CH2, 50MHz
GPIO_OSPEEDER_OSPEEDR0_1 | // PWM_OUT3, TIM3_CH3, 50MHz
GPIO_OSPEEDER_OSPEEDR1_1 | // PWM_OUT4, TIM3_CH4, 50MHz
GPIO_OSPEEDER_OSPEEDR6_1 | // PWM_IN5, TIM4_CH1, 50MHz
GPIO_OSPEEDER_OSPEEDR7_1   // PWM_IN6, TIM4_CH2, 50MHz
);

// Push/Pull
GPIOB->PUPDR = 0; // clear pupdr register  
GPIOB->PUPDR |=
(
GPIO_PUPDR_PUPDR8_0 |  // Pull-Up, I2C1, SCL
GPIO_PUPDR_PUPDR9_0 |  // Pull-Up, I2C1, SDA
GPIO_PUPDR_PUPDR4_0 |  // Pull-Up, PWM_OUT1, TIM3_CH1
GPIO_PUPDR_PUPDR5_0 |  // Pull-Up, PWM_OUT2, TIM3_CH2
GPIO_PUPDR_PUPDR0_0 |  // Pull-Up, PWM_OUT3, TIM3_CH3
GPIO_PUPDR_PUPDR1_0 |  // Pull-Up, PWM_OUT4, TIM3_CH4
GPIO_PUPDR_PUPDR6_0 |  // Pull-Up, PWM_IN5, TIM4_CH1
GPIO_PUPDR_PUPDR7_0    // Pull-Up, PWM_IN6, TIM4_CH2
);


// Alternate Function pins
GPIOB->AFR[1] = 0; // clear AFR_H register
GPIOB->AFR[1] |=
(
(4 << ((8 - 8) << 2)) |  // I2C1 SCL, AF4
(4 << ((9 - 8) << 2)) |   // I2C1 SDA, AF4

(5 << ((12 - 8) << 2)) |  // SPI2 NSS, AF5
(5 << ((13 - 8) << 2)) |  // SPI2 SCK, AF5
(5 << ((14 - 8) << 2)) |  // SPI2 MISO, AF5
(5 << ((15 - 8) << 2))   // SPI2 MOSI, AF5

);

GPIOB->AFR[0] = 0; // clear AFR_L register
GPIOB->AFR[0] |=
(
(2 << ((4 - 0) << 2)) |  // PWM_OUT1, TIM3_CH1, AF2
(2 << ((5 - 0) << 2)) |  // PWM_OUT2, TIM3_CH2, AF2
(2 << ((0 - 0) << 2)) |  // PWM_OUT3, TIM3_CH3, AF2
(2 << ((1 - 0) << 2)) |  // PWM_OUT4, TIM3_CH4, AF2
(2 << ((6 - 0) << 2)) |  //  TIM4_CH1, AF2
(2 << ((7 - 0) << 2))    //  TIM4_CH2, AF2
);







//=============================================================================
// GPIOD configuration
//=============================================================================
// enable GPIOD clock
((RCC_TypeDef *)(RCC_BASE))->AHB1ENR |= RCC_AHB1ENR_GPIODEN;


// Alternate Function
((GPIO_TypeDef *)(GPIOD_BASE))->MODER |=
(GPIO_MODER_MODER9_1  | // Alternate Function,  USART3_RX
GPIO_MODER_MODER8_1  ); // Alternate Function,  USART3_TX

// Output type
((GPIO_TypeDef *)(GPIOD_BASE))->OTYPER |=  0;// push-pull if 0
//(GPIO_OTYPER_OT_8 | // Open-Drain, I2C1, SCL
//GPIO_OTYPER_OT_9); // OPen-Drain, I2C1, SDA



// Speed type
((GPIO_TypeDef *)(GPIOD))->OSPEEDR |=
(GPIO_OSPEEDER_OSPEEDR8_1 | // USART3 TX 50 MHz
GPIO_OSPEEDER_OSPEEDR9_1);  // USART3 RX 50 MHz


// Push/Pull for USART3
((GPIO_TypeDef *)(GPIOD_BASE))->PUPDR |=
(
GPIO_PUPDR_PUPDR8_0 |  // Pull-Up, USART3 TX
GPIO_PUPDR_PUPDR9_0    // Pull-Up, USART3 RX
);


((GPIO_TypeDef *)(GPIOD_BASE))->AFR[1] |= (
(7 << ((8 - 8) << 2)) |  // USART3 TX, AF7
(7 << ((9 - 8) << 2)) );  // USART3 RX, AF7







return 0;
}

 

uint32_t config_pwm_io(void)
{
//=============================================================================
// set up PWM Output on TIM3 channels
//=============================================================================

// enable TIM3 clock
RCC->APB1ENR |= RCC_APB1ENR_TIM3EN;


// set the prescaler for 2MHz clock count
// fpclk = 42MHz, TIM3_clk = 2*fpclk = 84MHz
// CK_CNT = TIM3_clk / (PSC + 1)
// PSC = TIM3_clk / CK_CNT - 1
TIM3->PSC = 41; // 84MHz/2MHz - 1 = 41

// set the Auto Reload Register
// Needed period = (1/CK_CNT) * ARR
TIM3->ARR = 30000; // PWM_period = 15ms / (1/2MHz)

// clear CR2
TIM3->CR2 = 0;


TIM3->CCR1 = 3000; // 10% duty cycle, for CH1
TIM3->CCR2 = 3000; // 10% duty cycle, for CH2
TIM3->CCR3 = 3000; // 10% duty cycle, for CH3
TIM3->CCR4 = 3000; // 10% duty cycle, for CH4

// set output compare mode 1.
TIM3->CCMR1 |=
	TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_1  | // CH1
	TIM_CCMR1_OC2M_2 | TIM_CCMR1_OC2M_1;   // CH2

TIM3->CCMR2 |=
	TIM_CCMR2_OC3M_2 | TIM_CCMR2_OC3M_1  | // CH3
	TIM_CCMR2_OC4M_2 | TIM_CCMR2_OC4M_1;   // CH4


// enable Output compare
TIM3->CCER |= TIM_CCER_CC1E; //CH1
TIM3->CCER |= TIM_CCER_CC2E; //CH2
TIM3->CCER |= TIM_CCER_CC3E; //CH3
TIM3->CCER |= TIM_CCER_CC4E; //CH4

// enable TIM3
TIM3->CR1 |= TIM_CR1_CEN;


return 0;
}

 

uint32_t config_spi_all(void)
{

//=============================================================================
// SPI1 Related configuration
//=============================================================================
// enable SPI2 clock
RCC->APB1ENR |= RCC_APB1ENR_SPI2EN;


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


//SPI2->CR2 |= (SPI_CR2_SSOE);



return 0;
}

 

 

uint32_t config_i2c_all(void)
{

//=============================================================================
// I2C1 Related configuration
//=============================================================================
// enable I2C1 clock
((RCC_TypeDef *) (RCC_BASE))->APB1ENR |= RCC_APB1ENR_I2C1EN;





// 1) configure I2C_CR2
I2C1 -> CR2 |= (I2C_CR2_FREQ_5 | I2C_CR2_FREQ_3 |
I2C_CR2_FREQ_1); // APB1 clock is 42MHz

// 2) Configure Clock Control Register, I2C_CCR
// For 100KHz, APB1clk=42MHz, T_high = T_low = (1/42MHz)*210 = 5us
// For Fast mode, T_high = 9*(1/42MHz)*CCR = 0.8us,
//                T_low = 16*(1/42MHz)*CCR = 1.5us,
//                CCR = 4, F/S = 1, DUTY = 1, I2C_CCR = 0xc004
I2C1 -> CCR = 0xc004; // 0xd2, d210 for 100KHz,

// 3) Configure I2C_TRISE, Rise Time register
I2C1 -> TRISE = 0x2b; // 0x2b, d42 (42 + 1)

// 4) enable I2C1 peripheral
I2C1 -> CR1 |= (I2C_CR1_PE);


return 0;
}

 

 

uint32_t config_usart3(void)
{

//=============================================================================
// USART3 Related configuration
//=============================================================================
// enable I2C1 clock
RCC->APB1ENR |= RCC_APB1ENR_USART3EN;


// 1) Setting UE, amd M bits
USART3-> CR1 |= 0x2000; // UE = 1

// 2) Programming number of stop bits if needed


// 3) Enable DMA if needed


// 4) set the Baud Rate
// BAUD = fck / ( 8 * (2 - OVER8) * USARTDIV )
// fck = 42MHz,
// OVER8 = 0
// Choose BAUD = 115200
// then: USARTDIV = fck / ( 8 * (2  -OVER8) * BAUD = 22.75
// BRR = (22 << 4) | ( 0.75 * 16) = 364,
// or: BRR = fck / BAUD = 42MHz / 115200 = 364
USART3->BRR = 364;


// enable transmitter
USART3->CR1 |= USART_CR1_TE;

// enable receiver
USART3->CR1 |= USART_CR1_RE;

return 0;
}

 

Короче вывод такой что если сразу после включения всей периферии в приведенном коде посылать байт по SPI то буден задержкав 1500нс, но байт по любому отсылается.

 

 

p.s. задача поднятия пина SS после передачи байта тоже решена программным путем. Никакие эксперименты с битами SSOE SSI SSM ни следование мануалу не привело к тому чтобыstm32 сам поднимал пин SS вверх после успешной отправки байта. (как я уже написал...после отправки читаю прием а потом уже BSY и вручную поднимаю его сам)

(почти тоже самое что в теме приведенной Viko)

 

а так вобщем работает все.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...