Forum: Mikrocontroller und Digitale Elektronik NEC Beamersteuerung mit Atmega8U2


von Jonas W. (jonaschr)


Lesenswert?

Guten Tag,
nachdem ich nunmehr eine Woche lang das ganze Internet durchforstet 
habe, und mich in einer gedanklichen Sackgasse befinde, möchte ich das 
Forum nutzen, um nach Hilfe zu suchen.

Mein Ziel ist es einen NEC M311W Beamer über die RS 232 Schnittstelle 
von einem Atmega 8U2 aus Ein zu schalten. Dazu hätte der Beamer gerne 
den HEX Code 02H 00H 00H 00H 00H 02H mit der Baudrate 9600Bd. Vom PC aus 
habe ich das getestet mit Hterm -> funktioniert.

Auf dem Atmega habe ich die Lib von Peter Fleury etwas 
angepasst,(||defined(_AVR_ATmega8U2_) habe ich dazu geschrieben) 
sodass sie den Atmega 8u2 auch unterstützt. Meines erachtens nach 
entspricht der 8U2 der Kategorie AT90USBxx. Ich kann mich aber auch 
irren.
1
#elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB647__) || defined(__AVR_AT90USB1287__)||defined(__AVR_ATmega8U2__)
2
3
 /* AT90USBxx with one USART */
4
 #define AT90USB_USART
5
 #define UART0_RECEIVE_INTERRUPT   USART1_RX_vect
6
 #define UART0_TRANSMIT_INTERRUPT  USART1_UDRE_vect
7
 #define UART0_STATUS   UCSR1A
8
 #define UART0_CONTROL  UCSR1B
9
 #define UART0_DATA     UDR1
10
 #define UART0_UDRIE    UDRIE1

Initialisiert wird der USART im Hauptprogramm so
1
  uart_init( UART_BAUD_SELECT(9600,F_CPU) ); 
2
  sei();

Und die uart_init ruft das auf:
1
   /* set baud rate */
2
    if ( baudrate & 0x8000 ) 
3
    {
4
      UART0_STATUS = (1<<U2X1 );  //Enable 2x speed 
5
      baudrate &= ~0x8000;
6
    }
7
    UBRR1H = (unsigned char)(baudrate>>8);
8
    UBRR1L = (unsigned char) baudrate;
9
10
    /* Enable UART receiver and transmitter and receive complete interrupt*/
11
    UART0_CONTROL = _BV(RXCIE1)|(1<<RXEN1)|(1<<TXEN1);
12
    
13
    /* Set frame format: asynchronous, 8data, no parity, 1stop bit */
14
    UCSR1C = (1<<UCSZ11)|(1<<UCSZ10);

Wenn ich nun versuche den Hex Code an meinen PC zu senden,
1
uart_putc(0x02);
2
uart_putc(0x00);
3
uart_putc(0x00);
4
uart_putc(0x00);
5
uart_putc(0x00);
6
uart_putc(0x02);

empfängt mein PC mit Hterm 00 00 00 00 00 00 00 00 rot hinterlegt also 
Fehler. Und komischerweise auch mehr als er eigentlich sollte nämlich 8 
Byte statt 6.

Am Beamer direkt funktioniert es natürlich auch nicht.

Kann mir irgendjemand weiterhelfen?

Ich danke jetzt schon einmal für die Antworten:-)

: Bearbeitet durch User
von Beamer (Gast)


Lesenswert?

Jonas,
poste bitte den ganzen Code dann kann man dir besser Helfen.

von Jonas W. (jonaschr)


Lesenswert?

Ok, der Code ist aber schon ziemlich aufgebläht:-) und nicht die tollste 
Programmierart (blutiger Anfänger)

Interessant ist eigentlich nur in starts.c die Funktion "startvid" und 
der code von Peter Fleury. Der Rest (Relaisansteuerung für die 
Musikanlage) funktioniert soweit (Den Code zur Entprellung usw. habe ich 
weggelassen. Tut ja nichts zur Sache.


main.c
1
#define F_CPU 16000000UL     /* 16MHz */
2
 
3
#include <avr/io.h>
4
#include <util/delay.h>
5
#include <avr/interrupt.h>
6
#include "header.h"
7
#include "uart.h" 
8
 
9
// Defines:
10
#define DELAY      5000        // Einschalt/Ausschaltdelay für Audiogeräte
11
#define LED_PORT    PORTC        // Port an dem LEDS liegen
12
#define LED1      (1<<PC2)      // LED 1 Ein/Aus System
13
#define LED2      (1<<PC4)      // LED 2 EIN/AUS Audio
14
#define LED3      (1<<PC5)      // LED 3 EIN/AUS Subwoofer
15
#define LED4      (1<<PC6)      // LED 4 EIN/AUS Foyer
16
#define LED5      (1<<PC7)      // LED 5 EIN/AUS Video
17
#define RELAIS_PORT    PORTB        // Port an dem Relais liegen
18
#define RELAIS1      (1<<PB7)      // RELAIS  EIN/AUS System
19
#define RELAIS2      (1<<PB6)      // RELAIS  EIN/AUS Audio1
20
#define RELAIS3      (1<<PB5)      // RELAIS  EIN/AUS Audio2
21
#define RELAIS5      (1<<PB4)      // RELAIS  EIN/AUS Audio3
22
#define RELAIS6      (1<<PB3)      // RELAIS  EIN/AUS Beamer
23
#define RELAIS7      (1<<PB2)      // RELAIS  EIN/AUS AUDIO Subwoofer
24
#define RELAIS8      (1<<PB1)      // RELAIS  EIN/AUS AUDIO Foyer                      //!!!!! PC3 und PC7 sind unterschiedlich bei 8a und 8u2!!!!!//
25
#define TAST_PORT1    PORTB        // Port an dem Taster1 liegt
26
#define TAST_PIN1    PINB        // PIN an dem Taster1 liegt
27
#define TASTE1      (1<<PB0)      // Taste 1 Ein/Aus System nicht auf Tastport sondern auf LED_Port
28
#define TAST_PORT    PORTD        // Port an dem Taster liegen
29
#define TAST_PIN    PIND        // PIN an dem Taster liegen
30
#define TASTE2      (1<<PD0)      // Taste 2 EIN/AUS Audio
31
#define TASTE3      (1<<PD1)      // Taste 3 EIN/AUS Subwoofer
32
#define TASTE4      (1<<PD4)      // Taste 4 EIN/AUS Foyer
33
#define TASTE5      (1<<PD5)      // Taste 5 EIN/AUS Video
34
#define RXD        PD2          // RXD Port
35
#define TXD        PD3          // TXD Port
36
#define RTS        !PD6        // RTS Port
37
#define CTS        !PD7        // CTS Port
38
39
40
41
42
///////////////////////////////////////////////////////////////////////////////////
43
///////     Hauptprogramm
44
45
int main()
46
{  
47
  //////////////////////////////////////////////////////////////////////////////
48
  ////////  Initialisierung
49
  
50
  ////////////////////////////////
51
  // Ausgänge initialisieren
52
  
53
  // für LEDs
54
  DDRC  |= LED1|LED2|LED3|LED4|LED5 ;
55
  
56
  // für Relais
57
  DDRB |= RELAIS1|RELAIS2|RELAIS3|RELAIS5|RELAIS6|RELAIS7|RELAIS8;
58
  
59
  // Ausgänge auf 0 setzen
60
  LED_PORT  = 0x00;
61
  RELAIS_PORT  = 0xFF;
62
  ////////////////////////////////
63
  // Eingänge initialisieren
64
  
65
  // Pullups der Tasten einschalten
66
  TAST_PORT  |= TASTE2| TASTE3 | TASTE4 | TASTE5;
67
  TAST_PORT1 |= TASTE1;      
68
69
  
70
  /////////////////////////////////////////////////////////////////////////////////
71
  ///////  Arbeitsvariablen
72
  ///////
73
  char stat=0,stataud=0,statvid=0,statsub=0,statfoy=0;    //stat als Statusmerker des System EIN/AUS
74
                                //stataud als Statusmerker des AUDIO EIN/AUS
75
                                //statvid als Statusmerker des VIDEO EIN/AUS
76
  /////////////////////////////////////////////////////////////////////////////////
77
  ///////  UART Initialisieren, Interrupts einschalten
78
  ///////
79
                                
80
  uart_init( UART_BAUD_SELECT(9600,F_CPU) ); 
81
  sei();
82
                                
83
  /////////////////////////////////////////////////////////////////////////////////
84
  ///////  Systemstart bei Bootup
85
  ///////                              
86
  startsystem();
87
  stat=1;
88
                      
89
                      
90
  /////////////////////////////////////////////////////////////////////////////////
91
  ///////  Hauptschleife
92
  ///////
93
  while(1)
94
  {
95
  ///////////////////////////////////////////////
96
  // EIN/AUS System
97
  
98
  if (taster1(TASTE1,TAST_PIN1))              
99
  {
100
    
101
    if (stat)
102
    {
103
      mainshutdown(stat,stataud,statvid);          // Befehl komplettes System herunterfahren
104
      stat=0;
105
      stataud=0;
106
      statvid=0;
107
      statfoy=0;
108
      statsub=0;                      // Statusmerker zurücksetzen
109
    } 
110
        
111
    
112
    
113
  
114
  }    
115
  
116
  
117
  
118
    
119
  ///////////////////////////////////////////////
120
  // EIN/AUS AUDIO
121
  
122
  if (stat&&(taster2(TASTE2,TAST_PIN)))          
123
  {
124
 
125
    if (stataud)                // Statusmerker zurücksetzen - Befehl AUDIO System herunterfahren
126
    {
127
      audioshutdown();
128
      stataud = 0;
129
      statfoy = 0;
130
      statsub = 0;
131
    }
132
    else 
133
    {  
134
      LED_PORT    |=  LED2;        // LED2 EIN
135
      RELAIS_PORT    &= ~RELAIS2;      // Schleife EIN
136
      long_delay(20);
137
      RELAIS_PORT    &= ~RELAIS3;      // Sonstiges EIN
138
      long_delay(20);
139
      RELAIS_PORT    &= ~RELAIS5;      // Endstufe EIN
140
      stataud=1;
141
    }
142
  }
143
  
144
  
145
  
146
  
147
  ///////////////////////////////////////////////
148
  // EIN/AUS Subwoofer
149
  
150
  if (stataud&&(taster3(TASTE3,TAST_PIN))) 
151
  {
152
    if(!statsub)
153
    {
154
      RELAIS_PORT  &= ~ RELAIS8;
155
      LED_PORT  |= LED3;
156
      statsub=1;
157
    }
158
    else
159
    {
160
      RELAIS_PORT  |=RELAIS8;
161
      LED_PORT  &= ~LED3;
162
      statsub=0;
163
    }
164
  }
165
    
166
  
167
  
168
  
169
    
170
  
171
  ///////////////////////////////////////////////
172
  // EIN/AUS Foyer
173
  
174
  if (stataud&&(taster4(TASTE4,TAST_PIN))) 
175
  {
176
    if(!statfoy)
177
    {
178
      RELAIS_PORT  &= ~ RELAIS7;
179
      LED_PORT  |= LED4;
180
      statfoy=1;
181
    }
182
    else
183
    {
184
      RELAIS_PORT  |= RELAIS7;
185
      LED_PORT  &= ~LED4;
186
      statfoy=0;
187
    }
188
  }
189
  
190
  
191
      
192
  ///////////////////////////////////////////////
193
  // EIN/AUS Video
194
  
195
  if (stat&&(taster5(TASTE5,TAST_PIN)))              
196
  {
197
              
198
    if (statvid==1) 
199
    {
200
      if (videoshutdown())
201
      {
202
        statvid=0;
203
      }
204
    }
205
    else
206
    { 
207
      if (vidstart())
208
      {
209
        statvid=1;
210
      }
211
      
212
    }
213
214
  }
215
  
216
  
217
  }
218
 
219
  return 0;
220
}

starts.c
1
#define F_CPU 16000000UL     /* 16MHz */
2
3
#include <avr/io.h>
4
#include <util/delay.h>
5
#include <avr/interrupt.h>
6
#include "header.h"
7
#include "uart.h"
8
9
// Defines:
10
#define LED_PORT    PORTC        // Port an dem LEDS liegen
11
#define LED1      (1<<PC2)      // LED 1 Ein/Aus System
12
#define LED2      (1<<PC4)      // LED 2 EIN/AUS Audio
13
#define LED3      (1<<PC5)      // LED 3 EIN/AUS Subwoofer
14
#define LED4      (1<<PC6)      // LED 4 EIN/AUS Foyer
15
#define LED5      (1<<PC7)      // LED 5 EIN/AUS Video
16
#define RELAIS_PORT    PORTB        // Port an dem Relais liegen
17
#define RELAIS1      (1<<PB7)      // RELAIS  EIN/AUS System
18
#define RELAIS2      (1<<PB6)      // RELAIS  EIN/AUS Audio1
19
#define RELAIS3      (1<<PB5)      // RELAIS  EIN/AUS Audio2
20
#define RELAIS5      (1<<PB4)      // RELAIS  EIN/AUS Audio3
21
#define RELAIS6      (1<<PB3)      // RELAIS  EIN/AUS Beamer
22
#define RELAIS7      (1<<PB2)      // RELAIS  EIN/AUS AUDIO Subwoofer
23
#define RELAIS8      (1<<PB1)      // RELAIS  EIN/AUS AUDIO Foyer                  
24
#define TAST_PORT1    PORTB        // Port an dem Taster1 liegt
25
#define TAST_PIN1    PINB        // PIN an dem Taster1 liegt
26
#define TASTE1      (1<<PB0)      // Taste 1 Ein/Aus System nicht auf Tastport sondern auf LED_Port
27
#define TAST_PORT    PORTD        // Port an dem Taster liegen
28
#define TAST_PIN    PIND        // PIN an dem Taster liegen
29
#define TASTE2      (1<<PD0)      // Taste 2 EIN/AUS Audio
30
#define TASTE3      (1<<PD1)      // Taste 3 EIN/AUS Subwoofer
31
#define TASTE4      (1<<PD4)      // Taste 4 EIN/AUS Foyer
32
#define TASTE5      (1<<PD5)      // Taste 5 EIN/AUS Video
33
#define RXD        PD2          // RXD Port
34
#define TXD        PD3          // TXD Port
35
#define RTS        !PD6        // RTS Port
36
#define CTS        !PD7        // CTS Port
37
///////////////////////////////////////////////////////
38
// Starts
39
char vidstart(void)
40
{
41
  RELAIS_PORT    &=~ RELAIS6;
42
  LED_PORT    |= LED5;
43
44
          
45
46
47
    uart_putc(0x02);
48
    uart_putc(0x00);
49
    uart_putc(0x00);
50
    uart_putc(0x00);
51
    uart_putc(0x00);
52
    uart_putc(0x02);
53
54
55
56
  
57
58
59
60
  return 1;
61
  
62
}
63
64
char startsystem(void)
65
{
66
  
67
    LED_PORT |= LED1;
68
    long_delay(20);
69
    LED_PORT &= ~LED1;
70
    
71
    LED_PORT |= LED2;
72
    long_delay(20);
73
    LED_PORT &= ~LED2;
74
    
75
    LED_PORT |= LED3;
76
    long_delay(20);
77
    LED_PORT &= ~LED3;
78
    
79
    LED_PORT |= LED4;
80
    long_delay(20);
81
    LED_PORT &= ~LED4;  
82
      
83
    LED_PORT |= LED5;
84
    long_delay(25);
85
    LED_PORT &= ~LED5;
86
87
    LED_PORT |= LED4;
88
    long_delay(20);
89
    LED_PORT &= ~LED4;    
90
    
91
    LED_PORT |= LED3;
92
    long_delay(20);
93
    LED_PORT &= ~LED3;
94
    
95
    LED_PORT |= LED2;
96
    long_delay(20);
97
    LED_PORT &= ~LED2;  
98
    
99
  
100
  LED_PORT   |= LED1;
101
  RELAIS_PORT  |= RELAIS1;
102
  return 1;
103
    
104
}

uart.c
1
/*************************************************************************
2
Title:    Interrupt UART library with receive/transmit circular buffers
3
Author:   Peter Fleury <pfleury@gmx.ch>   http://jump.to/fleury
4
File:     $Id: uart.c,v 1.12 2014/01/08 21:58:12 peter Exp $
5
Software: AVR-GCC 4.1, AVR Libc 1.4.6 or higher
6
Hardware: any AVR with built-in UART, 
7
License:  GNU General Public License 
8
          
9
DESCRIPTION:
10
    An interrupt is generated when the UART has finished transmitting or
11
    receiving a byte. The interrupt handling routines use circular buffers
12
    for buffering received and transmitted data.
13
    
14
    The UART_RX_BUFFER_SIZE and UART_TX_BUFFER_SIZE variables define
15
    the buffer size in bytes. Note that these variables must be a 
16
    power of 2.
17
    
18
USAGE:
19
    Refere to the header file uart.h for a description of the routines. 
20
    See also example test_uart.c.
21
22
NOTES:
23
    Based on Atmel Application Note AVR306
24
                    
25
LICENSE:
26
    Copyright (C) 2006 Peter Fleury
27
28
    This program is free software; you can redistribute it and/or modify
29
    it under the terms of the GNU General Public License as published by
30
    the Free Software Foundation; either version 2 of the License, or
31
    any later version.
32
33
    This program is distributed in the hope that it will be useful,
34
    but WITHOUT ANY WARRANTY; without even the implied warranty of
35
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
36
    GNU General Public License for more details.
37
                        
38
*************************************************************************/
39
#include <avr/io.h>
40
#include <avr/interrupt.h>
41
#include <avr/pgmspace.h>
42
#include "uart.h"
43
44
45
/*
46
 *  constants and macros
47
 */
48
49
/* size of RX/TX buffers */
50
#define UART_RX_BUFFER_MASK ( UART_RX_BUFFER_SIZE - 1)
51
#define UART_TX_BUFFER_MASK ( UART_TX_BUFFER_SIZE - 1)
52
53
#if ( UART_RX_BUFFER_SIZE & UART_RX_BUFFER_MASK )
54
#error RX buffer size is not a power of 2
55
#endif
56
#if ( UART_TX_BUFFER_SIZE & UART_TX_BUFFER_MASK )
57
#error TX buffer size is not a power of 2
58
#endif
59
60
#if defined(__AVR_AT90S2313__) \
61
 || defined(__AVR_AT90S4414__) || defined(__AVR_AT90S4434__) \
62
 || defined(__AVR_AT90S8515__) || defined(__AVR_AT90S8535__) \
63
 || defined(__AVR_ATmega103__)
64
 /* old AVR classic or ATmega103 with one UART */
65
 #define AT90_UART
66
 #define UART0_RECEIVE_INTERRUPT   UART_RX_vect 
67
 #define UART0_TRANSMIT_INTERRUPT  UART_UDRE_vect
68
 #define UART0_STATUS   USR
69
 #define UART0_CONTROL  UCR
70
 #define UART0_DATA     UDR  
71
 #define UART0_UDRIE    UDRIE
72
#elif defined(__AVR_AT90S2333__) || defined(__AVR_AT90S4433__)
73
 /* old AVR classic with one UART */
74
 #define AT90_UART
75
 #define UART0_RECEIVE_INTERRUPT   UART_RX_vect 
76
 #define UART0_TRANSMIT_INTERRUPT  UART_UDRE_vect
77
 #define UART0_STATUS   UCSRA
78
 #define UART0_CONTROL  UCSRB
79
 #define UART0_DATA     UDR 
80
 #define UART0_UDRIE    UDRIE
81
#elif  defined(__AVR_ATmega8__) || defined(__AVR_ATmega16__) || defined(__AVR_ATmega32__) \
82
  || defined(__AVR_ATmega323__)
83
  /* ATmega with one USART */
84
 #define ATMEGA_USART
85
 #define UART0_RECEIVE_INTERRUPT   USART_RXC_vect
86
 #define UART0_TRANSMIT_INTERRUPT  USART_UDRE_vect
87
 #define UART0_STATUS   UCSRA
88
 #define UART0_CONTROL  UCSRB
89
 #define UART0_DATA     UDR
90
 #define UART0_UDRIE    UDRIE
91
#elif defined (__AVR_ATmega8515__) || defined(__AVR_ATmega8535__)
92
 #define ATMEGA_USART
93
 #define UART0_RECEIVE_INTERRUPT   USART_RX_vect
94
 #define UART0_TRANSMIT_INTERRUPT  USART_UDRE_vect
95
 #define UART0_STATUS   UCSRA
96
 #define UART0_CONTROL  UCSRB
97
 #define UART0_DATA     UDR
98
 #define UART0_UDRIE    UDRIE
99
#elif defined(__AVR_ATmega163__)
100
  /* ATmega163 with one UART */
101
 #define ATMEGA_UART
102
 #define UART0_RECEIVE_INTERRUPT   UART_RX_vect
103
 #define UART0_TRANSMIT_INTERRUPT  UART_UDRE_vect
104
 #define UART0_STATUS   UCSRA
105
 #define UART0_CONTROL  UCSRB
106
 #define UART0_DATA     UDR
107
 #define UART0_UDRIE    UDRIE
108
#elif defined(__AVR_ATmega162__) 
109
 /* ATmega with two USART */
110
 #define ATMEGA_USART0
111
 #define ATMEGA_USART1
112
 #define UART0_RECEIVE_INTERRUPT   USART0_RXC_vect
113
 #define UART1_RECEIVE_INTERRUPT   USART1_RXC_vect
114
 #define UART0_TRANSMIT_INTERRUPT  USART0_UDRE_vect
115
 #define UART1_TRANSMIT_INTERRUPT  USART1_UDRE_vect
116
 #define UART0_STATUS   UCSR0A
117
 #define UART0_CONTROL  UCSR0B
118
 #define UART0_DATA     UDR0
119
 #define UART0_UDRIE    UDRIE0
120
 #define UART1_STATUS   UCSR1A
121
 #define UART1_CONTROL  UCSR1B
122
 #define UART1_DATA     UDR1
123
 #define UART1_UDRIE    UDRIE1
124
#elif defined(__AVR_ATmega64__) || defined(__AVR_ATmega128__) 
125
 /* ATmega with two USART */
126
 #define ATMEGA_USART0
127
 #define ATMEGA_USART1
128
 #define UART0_RECEIVE_INTERRUPT   USART0_RX_vect
129
 #define UART1_RECEIVE_INTERRUPT   USART1_RX_vect
130
 #define UART0_TRANSMIT_INTERRUPT  USART0_UDRE_vect
131
 #define UART1_TRANSMIT_INTERRUPT  USART1_UDRE_vect
132
 #define UART0_STATUS   UCSR0A
133
 #define UART0_CONTROL  UCSR0B
134
 #define UART0_DATA     UDR0
135
 #define UART0_UDRIE    UDRIE0
136
 #define UART1_STATUS   UCSR1A
137
 #define UART1_CONTROL  UCSR1B
138
 #define UART1_DATA     UDR1
139
 #define UART1_UDRIE    UDRIE1
140
#elif defined(__AVR_ATmega161__)
141
 /* ATmega with UART */
142
 #error "AVR ATmega161 currently not supported by this libaray !"
143
#elif defined(__AVR_ATmega169__) 
144
 /* ATmega with one USART */
145
 #define ATMEGA_USART
146
 #define UART0_RECEIVE_INTERRUPT   USART0_RX_vect
147
 #define UART0_TRANSMIT_INTERRUPT  USART0_UDRE_vect
148
 #define UART0_STATUS   UCSRA
149
 #define UART0_CONTROL  UCSRB
150
 #define UART0_DATA     UDR
151
 #define UART0_UDRIE    UDRIE
152
#elif defined(__AVR_ATmega48__) || defined(__AVR_ATmega88__) || defined(__AVR_ATmega168__) || defined(__AVR_ATmega48P__) || defined(__AVR_ATmega88P__) || defined(__AVR_ATmega168P__) || defined(__AVR_ATmega328P__) \
153
 || defined(__AVR_ATmega3250__) || defined(__AVR_ATmega3290__) ||defined(__AVR_ATmega6450__) || defined(__AVR_ATmega6490__)
154
 /* ATmega with one USART */
155
 #define ATMEGA_USART0
156
 #define UART0_RECEIVE_INTERRUPT   USART_RX_vect
157
 #define UART0_TRANSMIT_INTERRUPT  USART_UDRE_vect
158
 #define UART0_STATUS   UCSR0A
159
 #define UART0_CONTROL  UCSR0B
160
 #define UART0_DATA     UDR0
161
 #define UART0_UDRIE    UDRIE0
162
#elif defined(__AVR_ATtiny2313__) 
163
 #define ATMEGA_USART
164
 #define UART0_RECEIVE_INTERRUPT   USART_RX_vect
165
 #define UART0_TRANSMIT_INTERRUPT  USART_UDRE_vect
166
 #define UART0_STATUS   UCSRA
167
 #define UART0_CONTROL  UCSRB
168
 #define UART0_DATA     UDR
169
 #define UART0_UDRIE    UDRIE
170
#elif defined(__AVR_ATmega329__) || \
171
      defined(__AVR_ATmega649__) || \
172
      defined(__AVR_ATmega325__) || \
173
      defined(__AVR_ATmega645__) 
174
  /* ATmega with one USART */
175
  #define ATMEGA_USART0
176
  #define UART0_RECEIVE_INTERRUPT   USART0_RX_vect
177
  #define UART0_TRANSMIT_INTERRUPT  USART0_UDRE_vect
178
  #define UART0_STATUS   UCSR0A
179
  #define UART0_CONTROL  UCSR0B
180
  #define UART0_DATA     UDR0
181
  #define UART0_UDRIE    UDRIE0
182
#elif defined(__AVR_ATmega2560__) || defined(__AVR_ATmega2561__) || defined(__AVR_ATmega1280__)  || defined(__AVR_ATmega1281__) || defined(__AVR_ATmega640__)
183
/* ATmega with two USART */
184
  #define ATMEGA_USART0
185
  #define ATMEGA_USART1
186
  #define UART0_RECEIVE_INTERRUPT   USART0_RX_vect
187
  #define UART1_RECEIVE_INTERRUPT   USART1_RX_vect
188
  #define UART0_TRANSMIT_INTERRUPT  USART0_UDRE_vect
189
  #define UART1_TRANSMIT_INTERRUPT  USART1_UDRE_vect
190
  #define UART0_STATUS   UCSR0A
191
  #define UART0_CONTROL  UCSR0B
192
  #define UART0_DATA     UDR0
193
  #define UART0_UDRIE    UDRIE0
194
  #define UART1_STATUS   UCSR1A
195
  #define UART1_CONTROL  UCSR1B
196
  #define UART1_DATA     UDR1
197
  #define UART1_UDRIE    UDRIE1  
198
#elif defined(__AVR_ATmega644__)
199
 /* ATmega with one USART */
200
 #define ATMEGA_USART0
201
 #define UART0_RECEIVE_INTERRUPT   USART1_RX_vect
202
 #define UART0_TRANSMIT_INTERRUPT  USART1_UDRE_vect
203
 #define UART0_STATUS   UCSR1A
204
 #define UART0_CONTROL  UCSR1B
205
 #define UART0_DATA     UDR1
206
 #define UART0_UDRIE    UDRIE1
207
#elif defined(__AVR_ATmega164P__) || defined(__AVR_ATmega324P__) || defined(__AVR_ATmega644P__)
208
 /* ATmega with two USART */
209
 #define ATMEGA_USART0
210
 #define ATMEGA_USART1
211
 #define UART0_RECEIVE_INTERRUPT   USART0_RX_vect
212
 #define UART1_RECEIVE_INTERRUPT   USART1_RX_vect
213
 #define UART0_TRANSMIT_INTERRUPT  USART0_UDRE_vect
214
 #define UART1_TRANSMIT_INTERRUPT  USART1_UDRE_vect
215
 #define UART0_STATUS   UCSR0A
216
 #define UART0_CONTROL  UCSR0B
217
 #define UART0_DATA     UDR0
218
 #define UART0_UDRIE    UDRIE0
219
 #define UART1_STATUS   UCSR1A
220
 #define UART1_CONTROL  UCSR1B
221
 #define UART1_DATA     UDR1
222
 #define UART1_UDRIE    UDRIE1
223
#elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB647__) || defined(__AVR_AT90USB1287__)||defined(__AVR_ATmega8U2__)
224
 /* AT90USBxx with one USART */
225
 #define AT90USB_USART
226
 #define UART0_RECEIVE_INTERRUPT   USART1_RX_vect
227
 #define UART0_TRANSMIT_INTERRUPT  USART1_UDRE_vect
228
 #define UART0_STATUS   UCSR1A
229
 #define UART0_CONTROL  UCSR1B
230
 #define UART0_DATA     UDR1
231
 #define UART0_UDRIE    UDRIE1
232
 
233
#else
234
 #error "no UART definition for MCU available"
235
#endif
236
237
238
/*
239
 *  module global variables
240
 */
241
static volatile unsigned char UART_TxBuf[UART_TX_BUFFER_SIZE];
242
static volatile unsigned char UART_RxBuf[UART_RX_BUFFER_SIZE];
243
static volatile unsigned char UART_TxHead;
244
static volatile unsigned char UART_TxTail;
245
static volatile unsigned char UART_RxHead;
246
static volatile unsigned char UART_RxTail;
247
static volatile unsigned char UART_LastRxError;
248
249
#if defined( ATMEGA_USART1 )
250
static volatile unsigned char UART1_TxBuf[UART_TX_BUFFER_SIZE];
251
static volatile unsigned char UART1_RxBuf[UART_RX_BUFFER_SIZE];
252
static volatile unsigned char UART1_TxHead;
253
static volatile unsigned char UART1_TxTail;
254
static volatile unsigned char UART1_RxHead;
255
static volatile unsigned char UART1_RxTail;
256
static volatile unsigned char UART1_LastRxError;
257
#endif
258
259
260
261
ISR (UART0_RECEIVE_INTERRUPT)  
262
/*************************************************************************
263
Function: UART Receive Complete interrupt
264
Purpose:  called when the UART has received a character
265
**************************************************************************/
266
{
267
    unsigned char tmphead;
268
    unsigned char data;
269
    unsigned char usr;
270
    unsigned char lastRxError;
271
 
272
 
273
    /* read UART status register and UART data register */ 
274
    usr  = UART0_STATUS;
275
    data = UART0_DATA;
276
    
277
    /* */
278
#if defined( AT90_UART )
279
    lastRxError = (usr & (_BV(FE)|_BV(DOR)) );
280
#elif defined( ATMEGA_USART )
281
    lastRxError = (usr & (_BV(FE)|_BV(DOR)) );
282
#elif defined( ATMEGA_USART0 )
283
    lastRxError = (usr & (_BV(FE0)|_BV(DOR0)) );
284
#elif defined ( ATMEGA_UART )
285
    lastRxError = (usr & (_BV(FE)|_BV(DOR)) );
286
#elif defined( AT90USB_USART )
287
    lastRxError = (usr & (_BV(FE1)|_BV(DOR1)) );
288
#endif
289
        
290
    /* calculate buffer index */ 
291
    tmphead = ( UART_RxHead + 1) & UART_RX_BUFFER_MASK;
292
    
293
    if ( tmphead == UART_RxTail ) {
294
        /* error: receive buffer overflow */
295
        lastRxError = UART_BUFFER_OVERFLOW >> 8;
296
    }else{
297
        /* store new index */
298
        UART_RxHead = tmphead;
299
        /* store received data in buffer */
300
        UART_RxBuf[tmphead] = data;
301
    }
302
    UART_LastRxError |= lastRxError;   
303
}
304
305
306
ISR (UART0_TRANSMIT_INTERRUPT)
307
/*************************************************************************
308
Function: UART Data Register Empty interrupt
309
Purpose:  called when the UART is ready to transmit the next byte
310
**************************************************************************/
311
{
312
    unsigned char tmptail;
313
314
    
315
    if ( UART_TxHead != UART_TxTail) {
316
        /* calculate and store new buffer index */
317
        tmptail = (UART_TxTail + 1) & UART_TX_BUFFER_MASK;
318
        UART_TxTail = tmptail;
319
        /* get one byte from buffer and write it to UART */
320
        UART0_DATA = UART_TxBuf[tmptail];  /* start transmission */
321
    }else{
322
        /* tx buffer empty, disable UDRE interrupt */
323
        UART0_CONTROL &= ~_BV(UART0_UDRIE);
324
    }
325
}
326
327
328
/*************************************************************************
329
Function: uart_init()
330
Purpose:  initialize UART and set baudrate
331
Input:    baudrate using macro UART_BAUD_SELECT()
332
Returns:  none
333
**************************************************************************/
334
void uart_init(unsigned int baudrate)
335
{
336
    UART_TxHead = 0;
337
    UART_TxTail = 0;
338
    UART_RxHead = 0;
339
    UART_RxTail = 0;
340
    
341
#if defined( AT90_UART )
342
    /* set baud rate */
343
    UBRR = (unsigned char)baudrate; 
344
345
    /* enable UART receiver and transmmitter and receive complete interrupt */
346
    UART0_CONTROL = _BV(RXCIE)|_BV(RXEN)|_BV(TXEN);
347
348
#elif defined (ATMEGA_USART)
349
    /* Set baud rate */
350
    if ( baudrate & 0x8000 )
351
    {
352
       UART0_STATUS = (1<<U2X);  //Enable 2x speed 
353
       baudrate &= ~0x8000;
354
    }
355
    UBRRH = (unsigned char)(baudrate>>8);
356
    UBRRL = (unsigned char) baudrate;
357
   
358
    /* Enable USART receiver and transmitter and receive complete interrupt */
359
    UART0_CONTROL = _BV(RXCIE)|(1<<RXEN)|(1<<TXEN);
360
    
361
    /* Set frame format: asynchronous, 8data, no parity, 1stop bit */
362
    #ifdef URSEL
363
    UCSRC = (1<<URSEL)|(3<<UCSZ0);
364
    #else
365
    UCSRC = (3<<UCSZ0);
366
    #endif 
367
    
368
#elif defined (ATMEGA_USART0 )
369
    /* Set baud rate */
370
    if ( baudrate & 0x8000 ) 
371
    {
372
       UART0_STATUS = (1<<U2X0);  //Enable 2x speed 
373
       baudrate &= ~0x8000;
374
     }
375
    UBRR0H = (unsigned char)(baudrate>>8);
376
    UBRR0L = (unsigned char) baudrate;
377
378
    /* Enable USART receiver and transmitter and receive complete interrupt */
379
    UART0_CONTROL = _BV(RXCIE0)|(1<<RXEN0)|(1<<TXEN0);
380
    
381
    /* Set frame format: asynchronous, 8data, no parity, 1stop bit */
382
    #ifdef URSEL0
383
    UCSR0C = (1<<URSEL0)|(3<<UCSZ00);
384
    #else
385
    UCSR0C = (3<<UCSZ00);
386
    #endif 
387
388
#elif defined ( ATMEGA_UART )
389
    /* set baud rate */
390
    if ( baudrate & 0x8000 ) 
391
    {
392
      UART0_STATUS = (1<<U2X);  //Enable 2x speed 
393
      baudrate &= ~0x8000;
394
    }
395
    UBRRHI = (unsigned char)(baudrate>>8);
396
    UBRR   = (unsigned char) baudrate;
397
398
    /* Enable UART receiver and transmitter and receive complete interrupt */
399
    UART0_CONTROL = _BV(RXCIE)|(1<<RXEN)|(1<<TXEN);
400
401
#elif defined ( AT90USB_USART )
402
   /* set baud rate */
403
    if ( baudrate & 0x8000 ) 
404
    {
405
      UART0_STATUS = (1<<U2X1 );  //Enable 2x speed 
406
      baudrate &= ~0x8000;
407
    }
408
    UBRR1H = (unsigned char)(baudrate>>8);
409
    UBRR1L = (unsigned char) baudrate;
410
411
    /* Enable UART receiver and transmitter and receive complete interrupt */
412
    UART0_CONTROL = _BV(RXCIE1)|(1<<RXEN1)|(1<<TXEN1);
413
    
414
    /* Set frame format: asynchronous, 8data, no parity, 1stop bit */
415
    UCSR1C = (1<<UCSZ11)|(1<<UCSZ10);
416
#endif
417
418
}/* uart_init */
419
420
421
/*************************************************************************
422
Function: uart_getc()
423
Purpose:  return byte from ringbuffer  
424
Returns:  lower byte:  received byte from ringbuffer
425
          higher byte: last receive error
426
**************************************************************************/
427
unsigned int uart_getc(void)
428
{    
429
    unsigned char tmptail;
430
    unsigned char data;
431
432
433
    if ( UART_RxHead == UART_RxTail ) {
434
        return UART_NO_DATA;   /* no data available */
435
    }
436
    
437
    /* calculate /store buffer index */
438
    tmptail = (UART_RxTail + 1) & UART_RX_BUFFER_MASK;
439
    UART_RxTail = tmptail; 
440
    
441
    /* get data from receive buffer */
442
    data = UART_RxBuf[tmptail];
443
    
444
    data = (UART_LastRxError << 8) + data;
445
    UART_LastRxError = 0;
446
    return data;
447
448
}/* uart_getc */
449
450
451
/*************************************************************************
452
Function: uart_putc()
453
Purpose:  write byte to ringbuffer for transmitting via UART
454
Input:    byte to be transmitted
455
Returns:  none          
456
**************************************************************************/
457
void uart_putc(unsigned char data)
458
{
459
    unsigned char tmphead;
460
461
    
462
    tmphead  = (UART_TxHead + 1) & UART_TX_BUFFER_MASK;
463
    
464
    while ( tmphead == UART_TxTail ){
465
        ;/* wait for free space in buffer */
466
    }
467
    
468
    UART_TxBuf[tmphead] = data;
469
    UART_TxHead = tmphead;
470
471
    /* enable UDRE interrupt */
472
    UART0_CONTROL    |= _BV(UART0_UDRIE);
473
474
}/* uart_putc */
475
476
477
/*************************************************************************
478
Function: uart_puts()
479
Purpose:  transmit string to UART
480
Input:    string to be transmitted
481
Returns:  none          
482
**************************************************************************/
483
void uart_puts(const char *s )
484
{
485
    while (*s) 
486
      uart_putc(*s++);
487
488
}/* uart_puts */
489
490
491
/*************************************************************************
492
Function: uart_puts_p()
493
Purpose:  transmit string from program memory to UART
494
Input:    program memory string to be transmitted
495
Returns:  none
496
**************************************************************************/
497
void uart_puts_p(const char *progmem_s )
498
{
499
    register char c;
500
    
501
    while ( (c = pgm_read_byte(progmem_s++)) ) 
502
      uart_putc(c);
503
504
}/* uart_puts_p */
505
506
507
/*
508
 * these functions are only for ATmegas with two USART
509
 */
510
#if defined( ATMEGA_USART1 )
511
512
ISR(UART1_RECEIVE_INTERRUPT)
513
/*************************************************************************
514
Function: UART1 Receive Complete interrupt
515
Purpose:  called when the UART1 has received a character
516
**************************************************************************/
517
{
518
    unsigned char tmphead;
519
    unsigned char data;
520
    unsigned char usr;
521
    unsigned char lastRxError;
522
 
523
 
524
    /* read UART status register and UART data register */ 
525
    usr  = UART1_STATUS;
526
    data = UART1_DATA;
527
    
528
    /* */
529
    lastRxError = (usr & (_BV(FE1)|_BV(DOR1)) );
530
        
531
    /* calculate buffer index */ 
532
    tmphead = ( UART1_RxHead + 1) & UART_RX_BUFFER_MASK;
533
    
534
    if ( tmphead == UART1_RxTail ) {
535
        /* error: receive buffer overflow */
536
        lastRxError = UART_BUFFER_OVERFLOW >> 8;
537
    }else{
538
        /* store new index */
539
        UART1_RxHead = tmphead;
540
        /* store received data in buffer */
541
        UART1_RxBuf[tmphead] = data;
542
    }
543
    UART1_LastRxError |= lastRxError;   
544
}
545
546
547
ISR(UART1_TRANSMIT_INTERRUPT)
548
/*************************************************************************
549
Function: UART1 Data Register Empty interrupt
550
Purpose:  called when the UART1 is ready to transmit the next byte
551
**************************************************************************/
552
{
553
    unsigned char tmptail;
554
555
    
556
    if ( UART1_TxHead != UART1_TxTail) {
557
        /* calculate and store new buffer index */
558
        tmptail = (UART1_TxTail + 1) & UART_TX_BUFFER_MASK;
559
        UART1_TxTail = tmptail;
560
        /* get one byte from buffer and write it to UART */
561
        UART1_DATA = UART1_TxBuf[tmptail];  /* start transmission */
562
    }else{
563
        /* tx buffer empty, disable UDRE interrupt */
564
        UART1_CONTROL &= ~_BV(UART1_UDRIE);
565
    }
566
}
567
568
569
/*************************************************************************
570
Function: uart1_init()
571
Purpose:  initialize UART1 and set baudrate
572
Input:    baudrate using macro UART_BAUD_SELECT()
573
Returns:  none
574
**************************************************************************/
575
void uart1_init(unsigned int baudrate)
576
{
577
    UART1_TxHead = 0;
578
    UART1_TxTail = 0;
579
    UART1_RxHead = 0;
580
    UART1_RxTail = 0;
581
    
582
583
    /* Set baud rate */
584
    if ( baudrate & 0x8000 ) 
585
    {
586
      UART1_STATUS = (1<<U2X1);  //Enable 2x speed 
587
      baudrate &= ~0x8000;
588
    }
589
    UBRR1H = (unsigned char)(baudrate>>8);
590
    UBRR1L = (unsigned char) baudrate;
591
592
    /* Enable USART receiver and transmitter and receive complete interrupt */
593
    UART1_CONTROL = _BV(RXCIE1)|(1<<RXEN1)|(1<<TXEN1);
594
    
595
    /* Set frame format: asynchronous, 8data, no parity, 1stop bit */   
596
    #ifdef URSEL1
597
    UCSR1C = (1<<URSEL1)|(3<<UCSZ10);
598
    #else
599
    UCSR1C = (3<<UCSZ10);
600
    #endif 
601
}/* uart_init */
602
603
604
/*************************************************************************
605
Function: uart1_getc()
606
Purpose:  return byte from ringbuffer  
607
Returns:  lower byte:  received byte from ringbuffer
608
          higher byte: last receive error
609
**************************************************************************/
610
unsigned int uart1_getc(void)
611
{    
612
    unsigned char tmptail;
613
    unsigned char data;
614
615
616
    if ( UART1_RxHead == UART1_RxTail ) {
617
        return UART_NO_DATA;   /* no data available */
618
    }
619
    
620
    /* calculate /store buffer index */
621
    tmptail = (UART1_RxTail + 1) & UART_RX_BUFFER_MASK;
622
    UART1_RxTail = tmptail; 
623
    
624
    /* get data from receive buffer */
625
    data = UART1_RxBuf[tmptail];
626
    
627
    data = (UART1_LastRxError << 8) + data;
628
    UART1_LastRxError = 0;
629
    return data;
630
631
}/* uart1_getc */
632
633
634
/*************************************************************************
635
Function: uart1_putc()
636
Purpose:  write byte to ringbuffer for transmitting via UART
637
Input:    byte to be transmitted
638
Returns:  none          
639
**************************************************************************/
640
void uart1_putc(unsigned char data)
641
{
642
    unsigned char tmphead;
643
644
    
645
    tmphead  = (UART1_TxHead + 1) & UART_TX_BUFFER_MASK;
646
    
647
    while ( tmphead == UART1_TxTail ){
648
        ;/* wait for free space in buffer */
649
    }
650
    
651
    UART1_TxBuf[tmphead] = data;
652
    UART1_TxHead = tmphead;
653
654
    /* enable UDRE interrupt */
655
    UART1_CONTROL    |= _BV(UART1_UDRIE);
656
657
}/* uart1_putc */
658
659
660
/*************************************************************************
661
Function: uart1_puts()
662
Purpose:  transmit string to UART1
663
Input:    string to be transmitted
664
Returns:  none          
665
**************************************************************************/
666
void uart1_puts(const char *s )
667
{
668
    while (*s) 
669
      uart1_putc(*s++);
670
671
}/* uart1_puts */
672
673
674
/*************************************************************************
675
Function: uart1_puts_p()
676
Purpose:  transmit string from program memory to UART1
677
Input:    program memory string to be transmitted
678
Returns:  none
679
**************************************************************************/
680
void uart1_puts_p(const char *progmem_s )
681
{
682
    register char c;
683
    
684
    while ( (c = pgm_read_byte(progmem_s++)) ) 
685
      uart1_putc(c);
686
687
}/* uart1_puts_p */
688
689
690
#endif

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Wenn du einen Simulator in deiner IDE hast, wirf ihn doch bitte mal an 
und schau, welche Baudrate und welche Eigenschaften nach der 
Initialisierung in den UART Registern stehen. Nützlich ist dazu die 
Tabelle 18-2 im Datenblatt des Mega8U2 auf Seite 175.
Schau, ob dann wirklich eine 207 in UBRR1L steht; UBRR1H sollte 0 sein. 
Wenn du schon dabei bist, kontrolliere auch gleich die anderen Register.

von Jonas W. (jonaschr)


Lesenswert?

Erstmal danke für die schnellen Antworten hier:-) das hätte ich ja 
garnicht gedacht.

Ich Programmiere mit Atmel Studio direkt auf ein 8U2 Breakout board von 
eHaJo.de leider wird mir keine Simulation angeboten. Ich könnte aber
1
/*Set baud rate*/
2
UBRR1H = 0x00;
3
UBRR1L = 103;
direkt setzen. Dann müsste es ja auch wirklich im Register stehen oder?

Habe ich einmal ausprobiert, gleiches Problem.

103 oder 207 ist ja eigentlich egal, der Fehler ist immer bei 0.2% 
soweit ich das dem Datenblatt entnehmen kann. Solange U2Xn entsprechend 
gesetzt ist.

von Jonas W. (jonaschr)


Angehängte Dateien:

Lesenswert?

Wobei der PC jetzt manchmal ein paar Bytes ohne Fehler erkennt.
Auf dem 2ten Bild sieht man Hterm mit 4800bd Einstellung. Den Code vom 
uC habe ich nicht geändert sollte also immernoch 9600bd sein. Der PC 
empfängt immer 8Byte statt 6Byte woran kann das liegen.
Ich werde mir jetzt mal einen anderen Quarz besorgen vllt. mit 
18,432Mhz.

So wie ich das lese liegt es an der Baudrate, der Code passt soweit 
oder?

von Schorschi (Gast)


Lesenswert?

Hi,

bist du sicher daß dein µC mit dem ext. Takt läuft?
Für mich sieht es so aus als ob du von einem Takt ausgehst der µC
aber mit einem aneren läuft. Dadurch kommt dann auch die falsche 
Baudrate
zustande. Wird wahrscheinlich etwas krummes sein. Könnte man auch mit 
einem
Oszi schnell prüfen.

Gruß,
Schorschi.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.