[AVR] ATtiny2313 UART geht nur bei einem CPU-Takt

  • C

Es gibt 7 Antworten in diesem Thema. Der letzte Beitrag () ist von gfcwfzkm.

    [AVR] ATtiny2313 UART geht nur bei einem CPU-Takt

    Hallo,

    mein Problem ist, das mein kleiner ATtiny2313 nur bei 8Mhz (intern) funktioniert. Bei 4Mhz kommt nur undefiniertes gedöns.

    Ich möchte mein code verwenden, habe aus verzweifelung schon die Library von Peter Fleury probiert.

    Hier mal mein TinyCode ^^:

    C-Quellcode

    1. #define F_CPU 8000000UL //Systemtakt in Hz
    2. #include <avr/io.h>
    3. #include <util/delay.h>
    4. #include <avr/interrupt.h>
    5. #define BAUD 9800UL //Baudrate
    6. //Berechnungen
    7. #define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1) //clever runden
    8. #define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1))) //Reale Baudrate
    9. #define BAUD_ERROR ((BAUD_REAL*1000)/BAUD) //Fehler in Promille, 1000 = kein Fehler.
    10. #define USE_2X 1
    11. #if ((BAUD_ERROR < 990) | (BAUD_ERROR > 1010)) //Wenn die Baudrate zu unregelmässig ist, einen Fehler auslösen!
    12. #error Systematischer Fehler der Baudrate grösser 1% und damit zu hoch!
    13. #endif
    14. #include <util/setbaud.h> //Muss nach den UART-Definitionen eingeschlossen werden!
    15. void uart_init(void);
    16. int uart_putc(unsigned char c);
    17. void uart_puts(char *s);
    18. uint8_t uart_getc(void);
    19. char *uart_gets(void);
    20. int main(void)
    21. {
    22. char c;
    23. uart_init();
    24. sei();
    25. _delay_ms(10);
    26. uart_puts("\n\rUART - Demoprogramm\n\r");
    27. while(1)
    28. {
    29. c = uart_getc();
    30. if (c==13)
    31. {
    32. uart_puts("\n\r");
    33. }
    34. else if (c=='s')
    35. {
    36. while(1)
    37. {
    38. uart_putc('W');
    39. }
    40. }
    41. else
    42. {
    43. uart_putc(c);
    44. }
    45. }
    46. }
    47. void uart_init(void)
    48. {
    49. UBRRH = UBRR_VAL >> 8; // Wichtig! UBRRH vor UBRRL setzten!
    50. UBRRL = UBRR_VAL & 0xFF;
    51. #if USE_2X
    52. /* U2X-Modus erforderlich */
    53. UCSRA |= (1 << U2X);
    54. #else
    55. /* U2X-Modus nicht erforderlich */
    56. UCSRA &= ~(1 << U2X);
    57. #endif
    58. UCSRB |= (1<<TXEN) | (1<<RXEN); // UART TX einschalten - UART RX einschalten
    59. UCSRC |= (1<<UCSZ1) | (1<<UCSZ0); // Asynchron 8N1
    60. }
    61. /* Zeichen senden */
    62. int uart_putc(unsigned char c)
    63. {
    64. while (!(UCSRA & (1<<UDRE))) { } // warten bis Senden möglich ist
    65. UDR = c; // sende Zeichen
    66. return 0;
    67. }
    68. /* Zeichenkette senden */
    69. void uart_puts(char *s)
    70. {
    71. while (*s)
    72. { // so lange *s != '\0' also ungleich dem "String-Endezeichen(Terminator)"
    73. uart_putc(*s);
    74. s++;
    75. }
    76. }
    77. /* Zeichen empfangen */
    78. uint8_t uart_getc(void)
    79. {
    80. while (!(UCSRA & (1<<RXC))) {}
    81. return UDR;
    82. }


    Kennt jemand die lösung? Der Code ist korrekt, läuft problemlos bei einem ATmega. Bei ATtiny halt nur bei 8Mhz F_CPU.

    mfg & thx

    gfcwfzkm
    Habe die interne Frequenz in den Fuses schon richtig eingestellt ^^.

    Ein externes Quarz ist eine gute Idee, jedoch habe ich wenig Lust, 1 Quarz zu bestellen. Da ist dann das Briefpapier drumherum dann mehr wert ^^. Und ist nur für ein Test. Bei fertigen Sachen verwende ich nie interne Oszillator.

    Also, Fuses richtig eingestellt, F_CPU richtig definiert und eine korrekte Baudrate (habe schon 4800, 2400 und 1200 probiert).

    Wo liegt mein Fehler ?(

    mfg

    gfc
    Hab ich am Anfang schon gemacht. Das #define USE_2X habe ich aus verzweifelung später hinzugefügt. Laut Datenblatt sollte dann die geschwindigkeit höher sein. Aber PuTTy empfängt nur undefiniertes zeugs.
    Benutze mal anstadt:

    Quellcode

    1. #define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1) //clever runden
    2. #define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1))) //Reale Baudrate
    3. #define BAUD_ERROR ((BAUD_REAL*1000)/BAUD) //Fehler in Promille, 1000 = kein Fehler.


    Die funktionen der "util/setbaut.h"

    Quellcode

    1. UBRRL = UBRRL_VALUE; // set baud rate
    2. UBRRH = UBRRH_VALUE;


    Vielleicht hilft das sicher bin ich mir nicht.

    Wenn ich das noch richtig im Kopf habe muss man doch um auf UCSRC zuzugreifen "URSEL" setzen.

    Quellcode

    1. UCSRC =
    2. (1<<URSEL) | // Enable writing to 'UCSRC'
    3. (3<<UCSZ0); // Datasize (8bit)