#define G431_USART2 /* 2020-12-10 Michael Nowak http://www.mino-elektronik.de Alle Angaben ohne Gewaehr ! */ #include "system_G431.h" #define BIT(x) (1<BRR = SystemCoreClock/APB1_TEILER/baud; return(0); } void USART2_IRQHandler(void) { uint32_t temp, sr_temp; uint32_t temp_zeiger; sr_temp = USART2->ISR; if(sr_temp & USART_ISR_TXE_TXFNF) { // Tx-Flag testen if(usart2_tx_schreib_zeiger != usart2_tx_lese_zeiger) { // noch zeichen im puffer USART2->TDR = usart2_tx_puffer[usart2_tx_lese_zeiger++]; // Zeichen ausgeben usart2_tx_lese_zeiger &= TX2_BUF_MASK; } else { USART2->CR1 &= ~USART_CR1_TXEIE; // sonst weitere Interrupts sperren */ __ISB(); // Ausführung abwarten } } if(sr_temp & USART_ISR_RXNE_RXFNE) { // Rx-Flag testen temp = USART2->RDR; // Zeichen lesen USART2->ICR = USART_ICR_ORECF; // OVE-Bit immer loeschen temp_zeiger = (usart2_rx_schreib_zeiger + 1) & RX2_BUF_MASK; if( temp_zeiger != usart2_rx_lese_zeiger) { usart2_rx_puffer[usart2_rx_schreib_zeiger] = temp; usart2_rx_schreib_zeiger = temp_zeiger; } } if(sr_temp & USART_ISR_ORE) { // Ueberlauf-Flag testen USART2->ICR = USART_ICR_ORECF; // OVE-Bit immer loeschen } } void clr_tx2_buf() { USART2->CR1 &= ~(USART_CR1_TXEIE); // TXIE abschalten __ISB(); usart2_tx_lese_zeiger = 0; usart2_tx_schreib_zeiger = 0; } void clr_rx2_buf() { USART2->CR1 &= ~(USART_CR1_RXNEIE); // RXIE abschalten __ISB(); usart2_rx_lese_zeiger = 0; usart2_rx_schreib_zeiger = 0; USART2->CR1 |= (USART_CR1_RXNEIE); // RXIE einschalten } void init_usart2(void) { uint32_t tmp; RCC->AHB2ENR |= RCC_AHB2ENR_GPIOAEN; // PortA aktivieren RCC->APB1ENR1 |= RCC_APB1ENR1_USART2EN; __ISB(); // AF2 für USART2 tmp = GPIOA->MODER & ~(CLR_MODER << (TxD2_Pin * 2) | CLR_MODER << (RxD2_Pin * 2)); GPIOA->MODER = tmp | (AF << (TxD2_Pin * 2) | AF << (RxD2_Pin * 2)); // PA2+PA3 USART2 alternative Funktionen mit den IO-Pins verbinden GPIOA->AFR[0] |= (AFR_USART2 << ((TxD2_Pin) * 4) | AFR_USART2 << ((RxD2_Pin) * 4)); // alle weiteren Einstellungen default 8N1 set_baudrate2(DEF_BAUDRATE); // enable UART Interrupt-Vector NVIC_SetPriority(USART2_IRQn,PRIO_USART2); NVIC_EnableIRQ(USART2_IRQn); clr_rx2_buf(); clr_tx2_buf(); // RXIE und Rx + Tx einschalten USART2->CR1 |= USART_CR1_RXNEIE | USART_CR1_UE | USART_CR1_RE | USART_CR1_TE; ser_status = 1; // USART2 ist initialisiert } void write_tx2_buf(char c) { uint32_t temp_zeiger; if(!ser_status) init_usart2() ; do { temp_zeiger = (usart2_tx_schreib_zeiger + 1) & TX2_BUF_MASK; } while( temp_zeiger == usart2_tx_lese_zeiger); // warten, bis wieder platz ist usart2_tx_puffer[usart2_tx_schreib_zeiger] = c; usart2_tx_schreib_zeiger = temp_zeiger; USART2->CR1 |= USART_CR1_TXEIE; // per Interrupt ausgeben } char read_rx2_buf() { int32_t temp = 0; // default bei leerem Puffer if(!ser_status) init_usart2() ; if(usart2_rx_lese_zeiger != usart2_rx_schreib_zeiger) { temp = usart2_rx_puffer[usart2_rx_lese_zeiger++]; usart2_rx_lese_zeiger &= RX2_BUF_MASK; } return(temp); } uint32_t read_rx2_buf_count() { return((usart2_rx_schreib_zeiger - usart2_rx_lese_zeiger) & RX2_BUF_MASK); } // Ausgabekanal für printf() int putchar(int x) { if((uint8_t)x == 10) write_tx2_buf(13); write_tx2_buf((uint8_t)x); return(x); } void sende_string(char *s) { while(*s) putchar(*(s++)); putchar(10); }