Hi again,
die Zeile in der Initialisierung stimmt nicht
sondern muss wohl so lautenCode:RCC->AHB1ENR |= RCC_APB1ENR_SPI2EN; //Takt für SPI2 aktivieren
Gruss bottyCode:RCC->APB1ENR |= RCC_APB1ENR_SPI2EN; //Takt für SPI2 aktivieren
Hi again,
die Zeile in der Initialisierung stimmt nicht
sondern muss wohl so lautenCode:RCC->AHB1ENR |= RCC_APB1ENR_SPI2EN; //Takt für SPI2 aktivieren
Gruss bottyCode:RCC->APB1ENR |= RCC_APB1ENR_SPI2EN; //Takt für SPI2 aktivieren
Hätt ich schreiben sollen..die hab ich am Freitag schon gefunden (und behoben). Ich hatte gehofft das wäre es bereits gewesen, aber irgend so ein kleiner verfluchter Fehlerteufel muß da noch drin sein. Ich hab den Rechner mit dem Projekt grad nicht an, ich stell morgen nochmal die letzte Codeversion rein.
Du hast zwei Probleme und die solltest du getrennt lösen. Das erste ist dein SPI Controler, das zweite das Display. Ich hab, wie ich gerade rausgefunden hab, auch mal was mit diesem Display gemacht. Bei für mich neuen Bausteinen mit simplem synchronen seriellen Protokoll, fange ich mit Bitbanging an. Ich programmiere einfach direkt das Timingdiagramm nach. Wenn der Baustein dann zuckt, kann man ja immer noch die HW im µC einsetzen. Meist bleibt es aber bei dieser Lösung, so auch bei diesem Display.
Ich kann meine Sachen im Augenblick nicht nachvollziehen, hab keine HW lauffähig. Ich pack aber trotzdem hier mal den wesentlichen Teil des Codes rein. Passt natürlich nicht für deinen Prozessor, ist aber plain C. Mein Prozessor ist ein PIC24 mit 16MHz Befehlstakt,
Ist schon eine Weile her, daß ich das geschrieben hab, daher weiß ich nicht mehr, was der Unterschied der beiden Initialisierungssquenzen am Anfang ist. Da sind auch noch zusätzliche Zeichen drin, die auf die freien Plätze programmiert werden können und ein paar #defines, die das besser "lesbar" machen. Das Backlight hatte ich wohl an einem PWM Ausgang.Code://uint8_t LCD_InitTab[] = {0x39,0x14,0x55,0x6d,0x78,0x38,0x0f,0x06,0x01}; const uint8_t LCD_InitTab[] = {0x29,0x14,0x56,0x6d,0x70,0x38,0x0f}; #define _____ 0x00 #define ____X 0x01 #define ___X_ 0x02 #define ___XX 0x03 #define __X__ 0x04 #define __X_X 0x05 #define __XX_ 0x06 #define __XXX 0x07 #define _X___ 0x08 #define _X__X 0x09 #define _X_X_ 0x0A #define _X_XX 0x0B #define _XX__ 0x0C #define _XX_X 0x0D #define _XXX_ 0x0E #define _XXXX 0x0F #define X____ 0x10 #define X___X 0x11 #define X__X_ 0x12 #define X__XX 0x13 #define X_X__ 0x14 #define X_X_X 0x15 #define X_XX_ 0x16 #define X_XXX 0x17 #define XX___ 0x18 #define XX__X 0x19 #define XX_X_ 0x1A #define XX_XX 0x1B #define XXX__ 0x1C #define XXX_X 0x1D #define XXXX_ 0x1E #define XXXXX 0x1F const uint8_t Chargen[] = { #ifdef ARROWS // left arrow _____, __X__, _X___, XXXXX, _X___, __X__, _____, _____, // top left arrow XXX__, XX___, X_X__, ___X_, ____X, _____, _____, _____, // up arrow __X__, _XXX_, X_X_X, __X__, __X__, __X__, _____, _____, // top right arrow __XXX, ___XX, __X_X, _X___, X____, _____, _____, _____, // right arrow _____, __X__, ___X_, XXXXX, ___X_, __X__, _____, _____, // bottom right arrow _____, _____, _____, X____, _X___, __X_X, ___XX, __XXX, // down arrow _____, _____, __X__, __X__, __X__, X_X_X, _XXX_, __X__, // bottom left arrow _____, _____, _____, ____X, ___X_, X_X__, XX___, XXX__, #else // bottom row _____, _____, _____, _____, _____, _____, _____, XXXXX, // two rows _____, _____, _____, _____, _____, _____, XXXXX, XXXXX, // three rows _____, _____, _____, _____, _____, XXXXX, XXXXX, XXXXX, // four rows _____, _____, _____, _____, XXXXX, XXXXX, XXXXX, XXXXX, // five rows _____, _____, _____, XXXXX, XXXXX, XXXXX, XXXXX, XXXXX, // six rows _____, _____, XXXXX, XXXXX, XXXXX, XXXXX, XXXXX, XXXXX, // seven rows _____, XXXXX, XXXXX, XXXXX, XXXXX, XXXXX, XXXXX, XXXXX, // full block XXXXX, XXXXX, XXXXX, XXXXX, XXXXX, XXXXX, XXXXX, XXXXX, #endif }; void SPI_WriteByte(uint8_t data) { uint8_t mask = 0x80; while (mask) { SCKout = 0; if (data & mask) { SDOout = 1; } else { SDOout = 0; } SCKout = 1; mask >>= 1; } } void LCD_SendCMD(uint8_t command){ RSout = 0; CSBout = 0; SPI_WriteByte(command); CSBout = 1; __delay_us(28); } void LCD_SendData(uint8_t data){ RSout = 1; CSBout = 0; SPI_WriteByte(data); CSBout = 1; __delay_us(28); } void LCD_SendCMDBlock(const uint8_t* commands, int length) { while (length) { LCD_SendCMD(*commands++); length--; } } void LCD_SendDataBlock(const uint8_t* data, int length) { RSout = 1; CSBout = 0; while (length) { LCD_SendData(*data++); length--; } CSBout = 1; } void LCD_ClearDisplay(void){ LCD_SendCMD(0x01); __delay_us(1500); } void LCD_SetCursor(int mode){ LCD_SendCMD(0b00001100 | (mode & 0b00000011)); } void LCD_SetDisplayAddress(int address){ LCD_SendCMD(0b10000000 | (address & 0b01111111)); } void LCD_SetCharGenAddress(int address){ LCD_SendCMD(0b01000000 | (address & 0b00111111)); } void LCD_Init(void){ LCD_SendCMDBlock(LCD_InitTab, sizeof(LCD_InitTab)); LCD_ClearDisplay(); } int LCD_SetExtraChars(const uint8_t* BitPattern, int length) { if(*BitPattern == 0xFF){ // unprogrammed EEPROM data return -1; } if(length > 64){ length = 64; } LCD_SetCharGenAddress(0); LCD_SendDataBlock((uint8_t*) BitPattern, length); return 0; } void LCD_SetBacklight(int intensity) { int tmp; if (intensity > 15) { intensity = 15; } tmp = 0x01 << intensity; OC2R = tmp; }
Achso noch was:
RSout = 0;
CSBout = 0;
hier werden Portbits PIC-typisch (auf 0) gesetzt, da gibts irgendwo an anderer Stelle die #defines dazu, es gibt noch SCKout und SDOout, also 4 Ports.
Ich hoffe, es hilft dir etwas
MfG Klebwax
Strom fließt auch durch krumme Drähte !
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