Golikov 0 24 апреля, 2013 Опубликовано 24 апреля, 2013 · Жалоба Всё это, конечно... очень интересно... :rolleyes: "А был ли мальчик?"(С) А глюк то... где??? Неужто самоликвидировался??? если коротко ТС взял другую плату дискавери, и залил туда проект с одним лишь СПИ, без прочей периферии, и глюк пропал. Предложение по одному добавлять остальную периферию и найти какой модуль рушит СПИ одобрения не встретило. Потому до конца не ясно что же является причиной плата или остальная периферия. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
BlackOps 0 2 мая, 2013 Опубликовано 2 мая, 2013 · Жалоба Пишу с опозданием надобыло кое какие проекты сдавать и платы делать. Во первых я не заявлял что нашел глюк, тема четко говорит "проблемы с СПИ", а проблемы могут быть по разым причинам, в том числе и по причине моей ошибки. Сделал вот что: 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) а так вобщем работает все. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться