Danke für den Codeschnipsel...werd ich mir genauer ansehen wenn die SPI läuft.
Der Code, wie er momentan ist. Momentan versuche ich mich mal an der USART in der Hoffnung, den Fehler eingrenzen zu können. Wenn ich die UART zum Laufen bringe ist die SPI-Init Mist. Wenn die USART auch nicht will hab ich wohl ein grundsätzlicheres Konfiproblem.
Code:#include <stdio.h> #include <stdlib.h> #include <stm32f446xx.h> //Takteinstellungen konfigurieren void TaktInit(){ //APB1: Tim6, SPI2, USART3 //AHB1: PortE, PortB, PortC, PortD //APB2: Tim1 //SysClk 16MHz (interner Oszillator) - Takt für APB1 auf 2MHz setzen RCC->CFGR |= RCC_CFGR_HPRE_DIV1; //AHB-Prescaler /1 => 16NHz RCC->CFGR |= RCC_CFGR_PPRE1_DIV1; //Takt für APB1 = AHB/1 } //Nested Vector Interrupt Controller konfigurieren void NVICInit(){ //NVIC_EnableIRQ(SPI2_IRQn); } //Pins, die als einfache Standard-EAs (Taster/LEDs) verwendet werden,konfigurieren void EAInit(){ //Pins für LEDs initialisieren RCC->AHB1ENR |= RCC_AHB1ENR_GPIOEEN; //Takt für PortE aktivieren //PE0 GPIOE->MODER |= GPIO_MODER_MODER0_0; GPIOE->MODER &= ~GPIO_MODER_MODER0_1; //PE0 -> Ausgang MODER ->01 GPIOE->OTYPER &= ~GPIO_OTYPER_OT_0; //PE0 als Push-Pull-Stufe GPIOE->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR0; //PE0 High-Speed GPIOE->PUPDR &= ~GPIO_PUPDR_PUPDR0_0; GPIOE->PUPDR &= ~GPIO_PUPDR_PUPDR0_1; //Pull-up/-down-Widerstände abschalten GPIOE->BSRR|= GPIO_BSRR_BS_0; //LED abschalten //PE1 GPIOE->MODER |= GPIO_MODER_MODER1_0; GPIOE->MODER &= ~GPIO_MODER_MODER1_1; //PE1 -> Ausgang MODER ->01 GPIOE->OTYPER &= ~GPIO_OTYPER_OT_1; //PE1 als Push-Pull-Stufe GPIOE->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR1; //PE1 High-Speed GPIOE->PUPDR &= ~GPIO_PUPDR_PUPDR1_0; GPIOE->PUPDR &= ~GPIO_PUPDR_PUPDR1_1; //Pull-up/-down-Widerstände abschalten GPIOE->BSRR|= GPIO_BSRR_BS_1; //LED abschalten //PE2 GPIOE->MODER |= GPIO_MODER_MODER2_0; GPIOE->MODER &= ~GPIO_MODER_MODER2_1; //PE2 -> Ausgang MODER ->01 GPIOE->OTYPER &= ~GPIO_OTYPER_OT_2; //PE2 als Push-Pull-Stufe GPIOE->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR2; //PE2 High-Speed GPIOE->PUPDR &= ~GPIO_PUPDR_PUPDR2_0; GPIOE->PUPDR &= ~GPIO_PUPDR_PUPDR2_1; //Pull-up/-down-Widerstände abschalten GPIOE->BSRR|= GPIO_BSRR_BS_2; //LED abschalten //PE3 GPIOE->MODER |= GPIO_MODER_MODER3_0; GPIOE->MODER &= ~GPIO_MODER_MODER3_1; //PE3 -> Ausgang MODER ->01 GPIOE->OTYPER &= ~GPIO_OTYPER_OT_3; //PE3 als Push-Pull-Stufe GPIOE->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR3; //PE3 High-Speed GPIOE->PUPDR &= ~GPIO_PUPDR_PUPDR3_0; GPIOE->PUPDR &= ~GPIO_PUPDR_PUPDR3_1; //Pull-up/-down-Widerstände abschalten GPIOE->BSRR|= GPIO_BSRR_BS_3; //LED abschalten //PE4 GPIOE->MODER |= GPIO_MODER_MODER4_0; GPIOE->MODER &= ~GPIO_MODER_MODER4_1; //PE4 -> Ausgang MODER ->01 GPIOE->OTYPER &= ~GPIO_OTYPER_OT_4; //PE4 als Push-Pull-Stufe GPIOE->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR4; //PE4 High-Speed GPIOE->PUPDR &= ~GPIO_PUPDR_PUPDR4_0; GPIOE->PUPDR &= ~GPIO_PUPDR_PUPDR4_1; //Pull-up/-down-Widerstände abschalten GPIOE->BSRR|= GPIO_BSRR_BS_4; //LED abschalten //PE5 GPIOE->MODER |= GPIO_MODER_MODER5_0; GPIOE->MODER &= ~GPIO_MODER_MODER5_1; //PE5 -> Ausgang MODER ->01 GPIOE->OTYPER &= ~GPIO_OTYPER_OT_5; //PE5 als Push-Pull-Stufe GPIOE->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR5; //PE5 High-Speed GPIOE->PUPDR &= ~GPIO_PUPDR_PUPDR5_0; GPIOE->PUPDR &= ~GPIO_PUPDR_PUPDR5_1; //Pull-up/-down-Widerstände abschalten GPIOE->BSRR|= GPIO_BSRR_BS_5; //LED abschalten //PE6 GPIOE->MODER |= GPIO_MODER_MODER6_0; GPIOE->MODER &= ~GPIO_MODER_MODER6_1; //PE6 -> Ausgang MODER ->01 GPIOE->OTYPER &= ~GPIO_OTYPER_OT_6; //PE6 als Push-Pull-Stufe GPIOE->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR6; //PE6 High-Speed GPIOE->PUPDR &= ~GPIO_PUPDR_PUPDR6_0; GPIOE->PUPDR &= ~GPIO_PUPDR_PUPDR6_1; //Pull-up/-down-Widerstände abschalten GPIOE->BSRR|= GPIO_BSRR_BS_6; //LED abschalten //Pins für Taster initialisieren //PB5 GPIOB->MODER &= ~GPIO_MODER_MODER5_0; GPIOB->MODER &= ~GPIO_MODER_MODER5_1; //PB5 -> Eingang MODER ->00 GPIOB->OTYPER &= ~GPIO_OTYPER_OT_5; GPIOB->OSPEEDR &= ~GPIO_OSPEEDER_OSPEEDR5_0; GPIOB->OSPEEDR &= ~GPIO_OSPEEDER_OSPEEDR5_1; GPIOB->PUPDR |= GPIO_PUPDR_PUPDR5_0; GPIOB->PUPDR &= ~GPIO_PUPDR_PUPDR5_1; //Pull-up-Widerstände einschalten PUPDR ->0 //PB6 GPIOB->MODER &= ~GPIO_MODER_MODER6_0; GPIOB->MODER &= ~GPIO_MODER_MODER6_1; //PB6 -> Eingang MODER ->00 GPIOB->OTYPER &= ~GPIO_OTYPER_OT_6; GPIOB->OSPEEDR &= ~GPIO_OSPEEDER_OSPEEDR6_0; GPIOB->OSPEEDR &= ~GPIO_OSPEEDER_OSPEEDR6_1; GPIOB->PUPDR |= GPIO_PUPDR_PUPDR6_0; GPIOB->PUPDR &= ~GPIO_PUPDR_PUPDR6_1; //Pull-up-Widerstände einschalten PUPDR ->01 //PB7 GPIOB->MODER &= ~GPIO_MODER_MODER7_0; GPIOB->MODER &= ~GPIO_MODER_MODER7_1; //PB7 -> Eingang MODER ->00 GPIOB->OTYPER &= ~GPIO_OTYPER_OT_7; GPIOB->OSPEEDR &= ~GPIO_OSPEEDER_OSPEEDR7_0; GPIOB->OSPEEDR &= ~GPIO_OSPEEDER_OSPEEDR7_1; GPIOB->PUPDR |= GPIO_PUPDR_PUPDR7_0; GPIOB->PUPDR &= ~GPIO_PUPDR_PUPDR7_1; //Pull-up-Widerstände einschalten PUPDR ->01 //PB12 GPIOB->MODER &= ~GPIO_MODER_MODER12_0; GPIOB->MODER &= ~GPIO_MODER_MODER12_1; //PB12 -> Eingang MODER ->00 GPIOB->OTYPER &= ~GPIO_OTYPER_OT_12; GPIOB->OSPEEDR &= ~GPIO_OSPEEDER_OSPEEDR12_0; GPIOB->OSPEEDR &= ~GPIO_OSPEEDER_OSPEEDR12_1; GPIOB->PUPDR |= GPIO_PUPDR_PUPDR12_0; GPIOB->PUPDR &= ~GPIO_PUPDR_PUPDR12_1; //Pull-up-Widerstände einschalten PUPDR ->01 //PB13 GPIOB->MODER &= ~GPIO_MODER_MODER13_0; GPIOB->MODER &= ~GPIO_MODER_MODER13_1; //PB13 -> Eingang MODER ->00 GPIOB->OTYPER &= ~GPIO_OTYPER_OT_13; GPIOB->OSPEEDR &= ~GPIO_OSPEEDER_OSPEEDR13_0; GPIOB->OSPEEDR &= ~GPIO_OSPEEDER_OSPEEDR13_1; GPIOB->PUPDR |= GPIO_PUPDR_PUPDR13_0; GPIOB->PUPDR &= ~GPIO_PUPDR_PUPDR13_1; //Pull-up-Widerstände einschalten PUPDR ->01 } //SPI2 konfigurieren, es wird nur ein LCD damit bedient. void SPIInit(){ //Taktversorgung aktivieren RCC->APB1ENR |= RCC_APB1ENR_SPI2EN; //Takt für SPI2 aktivieren RCC->AHB1ENR |= RCC_AHB1ENR_GPIOBEN; //Takt für PortB aktivieren RCC->AHB1ENR |= RCC_AHB1ENR_GPIOCEN; //Takt für PortC aktivieren RCC->APB1ENR |= RCC_APB1ENR_PWREN; //Pins konfigurieren //PB10 -> SPI2-Clock GPIOB->MODER &= ~GPIO_MODER_MODER10_0; GPIOB->MODER |= GPIO_MODER_MODER10_1; //PB10 -> Alternate Function MODER ->10 GPIOB->OTYPER &= ~GPIO_OTYPER_OT_10; //PB10 als Push-Pull-Stufe GPIOB->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR10_0; GPIOB->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR10_1; //PB10 High-Speed GPIOB->PUPDR &= ~GPIO_PUPDR_PUPDR10_0; GPIOB->PUPDR &= ~GPIO_PUPDR_PUPDR10_1; //Pull-up/-down-Widerstände abschalten GPIOB->AFR[1] |= (0b0110<<8); //SPI2 AF6 //PB15 -> SPI2-MoSi GPIOB->MODER &= ~GPIO_MODER_MODER15_0; GPIOB->MODER |= GPIO_MODER_MODER15_1; //PB15 -> Alternate Function MODER ->10 GPIOB->OTYPER &= ~GPIO_OTYPER_OT_15; //PB15 als Push-Pull-Stufe GPIOB->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR15_0; GPIOB->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR15_1; //PB15 High-Speed GPIOB->PUPDR &= ~GPIO_PUPDR_PUPDR15_0; GPIOB->PUPDR &= ~GPIO_PUPDR_PUPDR15_1; //Pull-up/-down-Widerstände abschalten GPIOB->AFR[1] |= (0b0110<<28); //SPI2 AF6 //PC3 -> SPI2-Select LCD GPIOC->MODER |= GPIO_MODER_MODER3_0; GPIOC->MODER &= ~GPIO_MODER_MODER3_1; //PC3 als Ausgang MODER ->01 GPIOC->OTYPER &= ~GPIO_OTYPER_OT_3; //PC3 als Push-Pull-Stufe GPIOC->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR3_0; GPIOC->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR3_1; //PC3 High-Speed GPIOC->PUPDR &= ~GPIO_PUPDR_PUPDR3_0; GPIOC->PUPDR &= ~GPIO_PUPDR_PUPDR3_1; //Pull-up/-down-Widerstände abschalten //PC2 -> SPI2-R/S GPIOC->MODER |= GPIO_MODER_MODER2_0; GPIOC->MODER |= GPIO_MODER_MODER2_1; //PC2 als Ausgang MODER ->01 GPIOC->OTYPER &= ~GPIO_OTYPER_OT_3; //PC2 als Push-Pull-Stufe GPIOC->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR2_0; GPIOC->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR2_1; //PC2 als High-Speed GPIOC->PUPDR &= ~GPIO_PUPDR_PUPDR2_0; GPIOC->PUPDR &= ~GPIO_PUPDR_PUPDR2_1; //Pull-up/-down-Widerstände abschalten //SPI konfigurieren SPI2->CR1 |= SPI_CR1_BIDIMODE; //Bidirektionaler Modus SPI2->CR1 |= SPI_CR1_BIDIOE; //Nur senden SPI2->CR1 &= ~SPI_CR1_CRCEN; //CRC-Berechnung abschalten SPI2->CR1 &= ~SPI_CR1_CRCNEXT; //Keine CRC-Phase SPI2->CR1 &= ~SPI_CR1_DFF; //8-Bit Frameformat SPI2->CR1 &= ~SPI_CR1_RXONLY; //Receive-Only-Modus abschalten SPI2->CR1 &= ~SPI_CR1_SSM; //Software Slave Management abschalten SPI2->CR1 &= ~SPI_CR1_SSI; //NSS-Pin SPI2->CR1 &= ~SPI_CR1_LSBFIRST; //MSB zuerst übertragen SPI2->CR1 &= ~SPI_CR1_BR_2 & ~SPI_CR1_BR_1 | SPI_CR1_BR_0; //Taktteiler 4 -> 16MHz/4 -> 4MHz SPI2->CR1 |= SPI_CR1_MSTR; //Master configuration SPI2->CR1 |= SPI_CR1_CPOL; //Takt=1 im Leerlauf SPI2->CR1 &= ~SPI_CR1_CPHA; //Clockphase, first clock transistion is first data capture edge SPI2->CR1 |= SPI_CR1_SPE; //SPI aktivieren /* SPI2->CR2 |= SPI_CR2_TXEIE; //Tx-buffer empty interupt aktivieren SPI2->CR2 &= ~SPI_CR2_RXNEIE; //Rx-buffer not empty interrupt deaktivieren SPI2->CR2 &= ~SPI_CR2_ERRIE; //Error Interrupt deaktivieren SPI2->CR2 &= ~SPI_CR2_FRF; //Motorola-Modus (Sandard) SPI2->CR2 &= ~SPI_CR2_SSOE; //SS Output deaktivieren SPI2->CR2 &= ~SPI_CR2_TXDMAEN; //TXE DMA-Request deaktivieren SPI2->CR2 &= ~SPI_CR2_RXDMAEN; //RXNE DMA Request deaktivieren*/ } //UART initialisieren void UARTInit(){ //Taktversorgung aktiviern RCC->APB1ENR |= RCC_APB1ENR_USART3EN; //UART3 mit Takt versorgen RCC->AHB1ENR |= RCC_AHB1ENR_GPIODEN; //PortD mit Takt versorgen //Pins konfigurieren //PD9 -> RX GPIOD->MODER &= ~GPIO_MODER_MODER9_0; GPIOD->MODER |= GPIO_MODER_MODER9_1; //PD9 -> Alternate Function MODER ->10 GPIOD->OTYPER &= ~GPIO_OTYPER_OT_9; //PD9 als Push-Pull-Stufe GPIOD->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR9_0; GPIOD->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR9_1; //PD9 High-Speed GPIOD->PUPDR &= ~GPIO_PUPDR_PUPDR9_0; GPIOD->PUPDR &= ~GPIO_PUPDR_PUPDR9_1; //Pull-up/-down-Widerstände abschalten GPIOD->AFR[1] |= (0b0111<<4); //UART //PD8 -> TX GPIOD->MODER &= ~GPIO_MODER_MODER8_0; GPIOD->MODER |= GPIO_MODER_MODER8_1; //PD8 -> Alternate Function MODER ->10 GPIOD->OTYPER &= ~GPIO_OTYPER_OT_8; //PD8 als Push-Pull-Stufe GPIOD->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR8_0; GPIOD->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR8_1; //PD8 High-Speed GPIOD->PUPDR &= ~GPIO_PUPDR_PUPDR8_0; GPIOD->PUPDR &= ~GPIO_PUPDR_PUPDR8_1; //Pull-up/-down-Widerstände abschalten GPIOD->AFR[1] |= (0b0111<<0); //UART //PD11 -> CTS GPIOD->MODER &= ~GPIO_MODER_MODER11_0; GPIOD->MODER |= GPIO_MODER_MODER11_1; //PD11 -> Alternate Function MODER ->10 GPIOD->OTYPER &= ~GPIO_OTYPER_OT_11; //PD11 als Push-Pull-Stufe GPIOD->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR11_0; GPIOD->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR11_1; //PD11 High-Speed GPIOD->PUPDR &= ~GPIO_PUPDR_PUPDR11_0; GPIOD->PUPDR &= ~GPIO_PUPDR_PUPDR11_1; //Pull-up/-down-Widerstände abschalten GPIOD->AFR[1] |= (0b0111<<16); //UART //PD12 -> RTS GPIOD->MODER &= ~GPIO_MODER_MODER12_0; GPIOD->MODER |= GPIO_MODER_MODER12_1; //PD12 -> Alternate Function MODER ->10 GPIOD->OTYPER &= ~GPIO_OTYPER_OT_12; //PD12 als Push-Pull-Stufe GPIOD->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR12_0; GPIOD->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR12_1; //PD12 High-Speed GPIOD->PUPDR &= ~GPIO_PUPDR_PUPDR12_0; GPIOD->PUPDR &= ~GPIO_PUPDR_PUPDR12_1; //Pull-up/-down-Widerstände abschalten GPIOD->AFR[1] |= (0b0111<<20); //UART //UART konfigurieren USART3->CR3 |= USART_CR3_CTSE; //CTS hardware flow control USART3->CR3 |= USART_CR3_RTSE; //RTS hardware flow control USART3->BRR |= 0b111110100000001; //Baudrate 16MHz/2000 => 8kHz USART3->CR1 &= ~ USART_CR1_M; //8-Bit-Modus USART3->CR1 &= ~USART_CR1_PCE; //Paritätskontrolle deaktivieren //USART3->CR1 &= ~USART_CR1_PS; //Paritätsmodus USART3->CR1 &= ~USART_CR1_PEIE; //PE-Interrupt USART3->CR1 |= USART_CR1_RE; //Receiver Enable USART3->CR1 |= USART_CR1_TE; //Transmitter Enable } void LCDInit(){ SndBfhlLCD(0b00111001); SndBfhlLCD(0b00010101); SndBfhlLCD(0b01010101); SndBfhlLCD(0b01101110); SndBfhlLCD(0b01110010); SndBfhlLCD(0b00111000); SndBfhlLCD(0b00001111); SndBfhlLCD(0b00000001); SndBfhlLCD(0b00000110); printf("Init-Befehle an LCD gesendet\n"); } //Sendet ein Befehlbyte ans LCD void SndBfhlLCD(char byte){ SPI2->CR1 |= SPI_CR1_SPE; //SPI aktivieren GPIOC->BSRR |= GPIO_BSRR_BR_2; //RS-Pin zurücksetzen GPIOC->BSRR |= GPIO_BSRR_BR_3; //CS runterziehen while (!(SPI2->SR & SPI_SR_TXE)){ //Warten bis Transmit-Register frei ist } SPI2->DR = byte; //Byte senden while (!(SPI2->SR & SPI_SR_TXE)){ //Warten bis Transmit-Register frei ist } while (SPI2->SR & SPI_SR_BSY){ //Warten bis laufende Übertragung abgeschlossen ist } GPIOC->BSRR |= GPIO_BSRR_BS_3; //CS high GPIOC->BSRR |= GPIO_BSRR_BS_2; //RS-Pin high SPI2->CR1 &= ~SPI_CR1_SPE; //SPI deaktivieren //RS NICHT toggeln } //Sendet ein Datenbyte ans LCD void SndDtnlLCD(char byte){ SPI2->CR1 |= SPI_CR1_SPE; //SPI aktivieren GPIOC->BSRR |= GPIO_BSRR_BS_2; //RS-Pin setzen GPIOC->BSRR |= GPIO_BSRR_BR_3; //CS runterziehen while (!(SPI2->SR & SPI_SR_TXE)){ //Warten bis Transmit-Register frei ist } SPI2->DR = byte; //Byte senden while (!(SPI2->SR & SPI_SR_TXE)){ //Warten bis Transmit-Register frei ist } while (SPI2->SR & SPI_SR_BSY){ //Warten bis laufende Übertragung abgeschlossen ist } GPIOC->BSRR |= GPIO_BSRR_BS_3; //CS high SPI2->CR1 &= ~SPI_CR1_SPE; //SPI deaktivieren GPIOC->BSRR |= GPIO_BSRR_BS_2; //RS toggeln GPIOC->BSRR |= GPIO_BSRR_BR_2; } //SPI2 Interrupt void SPI2_IRQHandler (void){ GPIOE->BSRR |= GPIO_BSRR_BR_4; //LED an E4 einschalten printf("SPI2 Interrupt Event\n"); } void main(void){ SystemInit(); TaktInit(); NVICInit(); EAInit(); GPIOE->BSRR |= GPIO_BSRR_BR_5; //LED an E5 einschalten UARTInit(); SPIInit(); LCDInit(); while(1){ SndDtnlLCD('T'); SndDtnlLCD('e'); SndDtnlLCD('s'); SndDtnlLCD('t'); SndDtnlLCD(' '); SndDtnlLCD('O'); SndDtnlLCD('K'); GPIOE->BSRR |= GPIO_BSRR_BR_1; //LED an E1 einschalten GPIOE->BSRR |= GPIO_BSRR_BS_1; //LED an E1 ausschalten } }
Lesezeichen