Hi Harry, hi workwind,
erstmal feststellen, ob F_CPU auch wirklich 20000000UL ist oder noch auf Standard steht.
Wenn es um eine einzige Baudrate geht..ist vllt. das hier hilfreich
www.nongnu.org/avr-libc/user-manual/group__util__setbaud.html
Weil ich auch mit mehreren (bzw. nachträglich verstellbaren) Baudraten arbeiten möchte, habe ich mal UBRR-Berechnungen für die gängigsten Baudraten mit mehreren Makros in ein Include gepackt.
Die Ergebnisse der Makros weichen teilweise von den Ergebnissen aus den Internet-Tabellen ab, aber funktionieren tun sie auch (besser).
//////////////////////////////////////////////////////////////////////////
//
// BLIB UART BAUDCALC Makros berechnen anhand F_CPU die Werte für das
// UBRR für vorgegebene Standard Baudraten.
//
// (c) Birger Töpelmann toepelmann(A)web.de Version 150407a
//
// Die Makrofunktionen wurden aus dem USART-Tutorial von
// mikrocontroller.net und der GCC AVR Lib util/setbaud.h nachgebildet.
//
// Weil das Baudratenteilerregister nur 12 Bit breit ist, wird im
// #define UBRxxxxx in Bit 15 übergeben, ob das U2X Bit zu setzen ist.
//
// Beispiel:
// uint16_t ubrr = UBR009K6; // Baudrate 9600
// // oder ubrr = UBR038K4; // für 38400 Baud
// uint8_t ucsra = 0;
// if ((ubrr & 0x8000) != 0) { // Bit 15 gesetzt -> U2X aktivieren
// ucsra |= (1<<U2X ); // Doppelte Taktrate -> kleinere Fehler
// }
// ubrr &= 0x0fff; // Das Baudratenregister ist nur 12 Bit breit
//
//
#ifndef BLIB_UART_BAUDCALC_H_
#define BLIB_UART_BAUDCALC_H_
//
// BSD License see "license.h"
//
#include "BSD_license.h"
//
#ifdef __cplusplus
extern "C" {
#endif
//
// UBRR Werte über Makros in uart_baudcalc.h berechnen
// UBRR Wert, Index = Baud error
// UBR000K6, // 0 = 600 0.0%
// UBR001K2, // 1 = 1200 0,0%
// UBR002K4, // 2 = 2400 0,0%
// UBR004K8, // 3 = 4800 0,0%
// UBR009K6, // 4 = 9600 0,2%
// UBR014K4, // 5 = 14400 0,0%
// UBR019K2, // 6 = 19200 0,2%
// UBR028K8, // 7 = 28800 0,6%
// UBR038K4, // 8 = 38400 0,2%
// UBR057K6, // 9 = 57600 0,8% !! Nibo2 Senden geht, Empfangen nicht
// UBR076K8, // A = 76800 0,2%
// UBR250K0, // B =250000 0,0%
////////////////////////////////////////////////////////////////////////// 600 Baud
// Werte für ohne U2X berechnen
#define UBR000K6 ((F_CPU + 600UL * 8UL) / ( 600UL * 16UL) - 1UL)
#define IST000K6 (F_CPU / (16UL * (UBR000K6 + 1UL)))
#define ERR000K6 ((IST000K6 * 1000UL)/ 600UL)
// Wenn Abweichung > 1%, UBRR WERT nochmal mit U2X berechnen
#if ((ERR000K6 < 990) || (ERR000K6 > 1010))
#undef UBR000K6
#undef IST000K6
#undef ERR000K6
// Wert für mit U2X berechnen
#define UBR000K6 ((F_CPU + 600UL * 4UL) / ( 600UL * 8UL) - 1UL) + 0x8000
#define IST000K6 (F_CPU / (8UL * ((UBR000K6 & 0x00000FFF) + 1UL)))
#define ERR000K6 ((IST000K6 * 1000UL)/ 600UL)
// Wenn Abweichung > 1%, Warnung ausgeben
#if ((ERR000K6 < 990) || (ERR000K6 > 1010))
#warning "UBRR für 600 Baud mit zu hoher Toleranz"
#endif
#endif
//
////////////////////////////////////////////////////////////////////////// 1200 Baud
// Wert für ohne U2X berechnen
#define UBR001K2 ((F_CPU + 1200UL * 8UL) / ( 1200UL * 16UL) - 1UL)
#define IST001K2 (F_CPU / (16UL * (UBR001K2 + 1UL)))
#define ERR001K2 ((IST001K2 * 1000UL)/ 1200UL)
// Wenn Abweichung > 1%, UBRR WERT nochmal mit U2X berechnen
#if ((ERR001K2 < 990) || (ERR001K2 > 1010))
#undef UBR001K2
#undef IST001K2
#undef ERR001K2
// Wert für mit U2X berechnen
#define UBR001K2 ((F_CPU + 1200UL * 4UL) / ( 1200UL * 8UL) - 1UL) + 0x8000
#define IST001K2 (F_CPU / (8UL * ((UBR001K2 & 0x00000FFF) + 1UL)))
#define ERR001K2 ((IST001K2 * 1000UL)/ 1200UL)
// Wenn Abweichung > 1%, Warnung ausgeben
#if ((ERR001K2 < 990) || (ERR001K2 > 1010))
#warning "UBRR für 1200 Baud mit zu hoher Toleranz"
#endif
#endif
//
////////////////////////////////////////////////////////////////////////// 2400 Baud
// Wert für ohne U2X berechnen
#define UBR002K4 ((F_CPU + 2400UL * 8UL) / ( 2400UL * 16UL) - 1UL)
#define IST002K4 (F_CPU / (16UL * (UBR002K4 + 1UL)))
#define ERR002K4 ((IST002K4 * 1000UL)/ 2400UL)
// Wenn Abweichung > 1%, UBRR WERT nochmal mit U2X berechnen
#if ((ERR002K4 < 990) || (ERR002K4 > 1010))
#undef UBR002K4
#undef IST002K4
#undef ERR002K4
// Wert für mit U2X berechnen
#define UBR002K4 ((F_CPU + 2400UL * 4UL) / ( 2400UL * 8UL) - 1UL) + 0x8000
#define IST002K4 (F_CPU / (8UL * ((UBR002K4 & 0x00000FFF) + 1UL)))
#define ERR002K4 ((IST002K4 * 1000UL)/ 2400UL)
// Wenn Abweichung > 1%, Warnung ausgeben
#if ((ERR002K4 < 990) || (ERR002K4 > 1010))
#warning "UBRR für 2400 Baud mit zu hoher Toleranz"
#endif
#endif
//
////////////////////////////////////////////////////////////////////////// 4800 Baud
// Wert für ohne U2X berechnen
#define UBR004K8 ((F_CPU + 4800UL * 8UL) / ( 4800UL * 16UL) - 1UL)
#define IST004K8 (F_CPU / (16UL * (UBR004K8 + 1UL)))
#define ERR004K8 ((IST004K8 * 1000UL)/ 4800UL)
// Wenn Abweichung > 1%, UBRR WERT nochmal mit U2X berechnen
#if ((ERR004K8 < 990) || (ERR004K8 > 1010))
#undef UBR004K8
#undef IST004K8
#undef ERR004K8
// Wert für mit U2X berechnen
#define UBR004K8 ((F_CPU + 4800UL * 4UL) / ( 4800UL * 8UL) - 1UL) + 0x8000
#define IST004K8 (F_CPU / (8UL * ((UBR004K8 & 0x00000FFF) + 1UL)))
#define ERR004K8 ((IST004K8 * 1000UL)/ 4800UL)
// Wenn Abweichung > 1%, Warnung ausgeben
#if ((ERR004K8 < 990) || (ERR004K8 > 1010))
#warning "UBRR für 4800 Baud mit zu hoher Toleranz"
#endif
#endif
//
////////////////////////////////////////////////////////////////////////// 9600 Baud
// Wert für ohne U2X berechnen
#define UBR009K6 ((F_CPU + 9600UL * 8UL) / ( 9600UL * 16UL) - 1UL)
#define IST009K6 (F_CPU / (16UL * (UBR009K6 + 1UL)))
#define ERR009K6 ((IST009K6 * 1000UL)/ 9600UL)
// Wenn Abweichung > 1%, UBRR WERT nochmal mit U2X berechnen
#if ((ERR009K6 < 990) || (ERR009K6 > 1010))
#undef UBR009K6
#undef IST009K6
#undef ERR009K6
// Wert für mit U2X berechnen
#define UBR009K6 ((F_CPU + 9600UL * 4UL) / ( 9600UL * 8UL) - 1UL) + 0x8000
#define IST009K6 (F_CPU / (8UL * ((UBR009K6 & 0x00000FFF) + 1UL)))
#define ERR009K6 ((IST009K6 * 1000UL)/ 9600UL)
// Wenn Abweichung > 1%, Warnung ausgeben
#if ((ERR009K6 < 990) || (ERR009K6 > 1010))
#warning "UBRR für 9600 Baud mit zu hoher Toleranz"
#endif
#endif
//
////////////////////////////////////////////////////////////////////////// 19200 Baud
// Wert für ohne U2X berechnen
#define UBR019K2 ((F_CPU + 19200UL * 8UL) / ( 19200UL * 16UL) - 1UL)
#define IST019K2 (F_CPU / (16UL * (UBR019K2 + 1UL)))
#define ERR019K2 ((IST019K2 * 1000UL)/ 19200UL)
// Wenn Abweichung > 1%, UBRR WERT nochmal mit U2X berechnen
#if ((ERR019K2 < 990) || (ERR019K2 > 1010))
#undef UBR019K2
#undef IST019K2
#undef ERR019K2
// Wert für mit U2X berechnen
#define UBR019K2 ((F_CPU + 19200UL * 4UL) / ( 19200UL * 8UL) - 1UL) + 0x8000
#define IST019K2 (F_CPU / (8UL * ((UBR019K2 & 0x00000FFF) + 1UL)))
#define ERR019K2 ((IST019K2 * 1000UL)/ 19200UL)
// Wenn Abweichung > 1%, Warnung ausgeben
#if ((ERR019K2 < 990) || (ERR019K2 > 1010))
#warning "UBRR für 19200 Baud mit zu hoher Toleranz"
#endif
#endif
//
////////////////////////////////////////////////////////////////////////// 14400 Baud
// Wert für ohne U2X berechnen
#define UBR014K4 ((F_CPU + 14400UL * 8UL) / ( 14400UL * 16UL) - 1UL)
#define IST014K4 (F_CPU / (16UL * (UBR014K4 + 1UL)))
#define ERR014K4 ((IST014K4 * 1000UL)/ 14400UL)
// Wenn Abweichung > 1%, UBRR WERT nochmal mit U2X berechnen
#if ((ERR014K4 < 990) || (ERR014K4 > 1010))
#undef UBR014K4
#undef IST014K4
#undef ERR014K4
// Wert für mit U2X berechnen
#define UBR014K4 ((F_CPU + 14400UL * 4UL) / ( 14400UL * 8UL) - 1UL) + 0x8000
#define IST014K4 (F_CPU / (8UL * ((UBR014K4 & 0x00000FFF) + 1UL)))
#define ERR014K4 ((IST014K4 * 1000UL)/ 14400UL)
// Wenn Abweichung > 1%, Warnung ausgeben
#if ((ERR014K4 < 990) || (ERR014K4 > 1010))
#warning "UBRR für 14400 Baud mit zu hoher Toleranz"
#endif
#endif
//
////////////////////////////////////////////////////////////////////////// 28800 Baud
// Wert für ohne U2X berechnen
#define UBR028K8 ((F_CPU + 28800UL * 8UL) / ( 28800UL * 16UL) - 1UL)
#define IST028K8 (F_CPU / (16UL * (UBR028K8 + 1UL)))
#define ERR028K8 ((IST028K8 * 1000UL)/ 28800UL)
// Wenn Abweichung > 1%, UBRR WERT nochmal mit U2X berechnen
#if ((ERR028K8 < 990) || (ERR028K8 > 1010))
#undef UBR028K8
#undef IST028K8
#undef ERR028K8
// Wert für mit U2X berechnen
#define UBR028K8 ((F_CPU + 28800UL * 4UL) / ( 28800UL * 8UL) - 1UL) + 0x8000
#define IST028K8 (F_CPU / (8UL * ((UBR028K8 & 0x00000FFF) + 1UL)))
#define ERR028K8 ((IST028K8 * 1000UL)/ 28800UL)
// Wenn Abweichung > 1%, Warnung ausgeben
#if ((ERR028K8 < 990) || (ERR028K8 > 1010))
#warning "UBRR für 28800 Baud mit zu hoher Toleranz"
#endif
#endif
//
////////////////////////////////////////////////////////////////////////// 38400 Baud
// Wert für ohne U2X berechnen
#define UBR038K4 ((F_CPU + 38400UL * 8UL) / ( 38400UL * 16UL) - 1UL)
#define IST038K4 (F_CPU / (16UL * (UBR038K4 + 1UL)))
#define ERR038K4 ((IST038K4 * 1000UL)/ 38400UL)
// Wenn Abweichung > 1%, UBRR WERT nochmal mit U2X berechnen
#if ((ERR038K4 < 990) || (ERR038K4 > 1010))
#undef UBR038K4
#undef IST038K4
#undef ERR038K4
// Wert für mit U2X berechnen
#define UBR038K4 ((F_CPU + 38400UL * 4UL) / ( 38400UL * 8UL) - 1UL) + 0x8000
#define IST038K4 (F_CPU / (8UL * ((UBR038K4 & 0x00000FFF) + 1UL)))
#define ERR038K4 ((IST038K4 * 1000UL)/ 38400UL)
// Wenn Abweichung > 1%, Warnung ausgeben
#if ((ERR038K4 < 990) || (ERR038K4 > 1010))
#warning "UBRR für 38400 Baud mit zu hoher Toleranz"
#endif
#endif
//
////////////////////////////////////////////////////////////////////////// 57600 Baud
// Wert für ohne U2X berechnen
#define UBR057K6 ((F_CPU + 57600UL * 8UL) / ( 57600UL * 16UL) - 1UL)
#define IST057K6 (F_CPU / (16UL * (UBR057K6 + 1UL)))
#define ERR057K6 ((IST057K6 * 1000UL)/ 57600UL)
// Wenn Abweichung > 1%, UBRR WERT nochmal mit U2X berechnen
#if ((ERR057K6 < 990) || (ERR057K6 > 1010))
#undef UBR057K6
#undef IST057K6
#undef ERR057K6
// Wert für mit U2X berechnen
#define UBR057K6 ((F_CPU + 57600UL * 4UL) / ( 57600UL * 8UL) - 1UL) + 0x8000
#define IST057K6 (F_CPU / (8UL * ((UBR057K6 & 0x00000FFF) + 1UL)))
#define ERR057K6 ((IST057K6 * 1000UL)/ 57600UL)
// Wenn Abweichung > 1%, Warnung ausgeben
#if ((ERR057K6 < 990) || (ERR057K6 > 1010))
#warning "UBRR für 57600 Baud mit zu hoher Toleranz"
#endif
#endif
//
////////////////////////////////////////////////////////////////////////// 76800 Baud
// Wert für ohne U2X berechnen
#define UBR076K8 ((F_CPU + 76800UL * 8UL) / ( 76800UL * 16UL) - 1UL)
#define IST076K8 (F_CPU / (16UL * (UBR076K8 + 1UL)))
#define ERR076K8 ((IST076K8 * 1000UL)/ 76800UL)
// Wenn Abweichung > 1%, UBRR WERT nochmal mit U2X berechnen
#if ((ERR076K8 < 990) || (ERR076K8 > 1010))
#undef UBR076K8
#undef IST076K8
#undef ERR076K8
// Wert für mit U2X berechnen
#define UBR076K8 ((F_CPU + 76800UL * 4UL) / ( 76800UL * 8UL) - 1UL) + 0x8000
#define IST076K8 (F_CPU / (8UL * ((UBR076K8 & 0x00000FFF) + 1UL)))
#define ERR076K8 ((IST076K8 * 1000UL)/ 76800UL)
// Wenn Abweichung > 1%, Warnung ausgeben
#if ((ERR076K8 < 990) || (ERR076K8 > 1010))
#warning "UBRR für 76800 Baud mit zu hoher Toleranz"
#endif
#endif
//
////////////////////////////////////////////////////////////////////////// 250000 Baud
// Wert für ohne U2X berechnen
#define UBR250K0 ((F_CPU + 250000UL * 8UL) / (250000UL * 16UL) - 1UL)
#define IST250K0 (F_CPU / (16UL * (UBR250K0 + 1UL)))
#define ERR250K0 ((IST250K0 * 1000UL)/250000UL)
// Wenn Abweichung > 1%, UBRR WERT nochmal mit U2X berechnen
#if ((ERR250K0 < 990) || (ERR250K0 > 1010))
#undef UBR250K0
#undef IST250K0
#undef ERR250K0
// Wert für mit U2X berechnen
#define UBR250K0 ((F_CPU + 250000UL * 4UL) / (250000UL * 8UL) - 1UL) + 0x8000
#define IST250K0 (F_CPU / (8UL * ((UBR250K0 & 0x00000FFF) + 1UL)))
#define ERR250K0 ((IST250K0 * 1000UL)/250000UL)
// Wenn Abweichung > 1%, Warnung ausgeben
#if ((ERR250K0 < 990) || (ERR250K0 > 1010))
#warning "UBRR für 250000 Baud mit zu hoher Toleranz"
#endif
#endif
//
#endif /* BLIB_UART_BAUDCALC_H_ */