Hallo ich habe eine ganz einfach platine mit nem attiny2313a und zwei leds aufgebaut um dmx zu empfangen. das passende dmx treiber IC ist auch vorhanden. Ich habe meinen standart uart empfangs interrupt verwendet der auf anderen controllern ( atmega8,atmega32 ) immer fehlerfrei lief. mein problem ist jetzt dass es so scheint als ob der controller an einer bestimmten stelle aufhört das zu tun was er soll. zu anfang ist die led aus. wenn der empfangene wert größer als 127 wird soll die led angemacht werden. das funktioniert zuverlässig. aber wenn der wert wieder kleiner wird soll auch die led wieder ausgehen. das läuft nicht. CPU takt 12Mhz externer Quarz CKDIV8 Bit nicht gesetzt UBRR = 2 Danke für eure antworten
1 | /*
|
2 | * strobecontrol_beta.c
|
3 | *
|
4 | * Created: 30.07.2013 14:18:08
|
5 | * Author: Steve
|
6 | */
|
7 | |
8 | #define F_CPU 1200000
|
9 | #include <avr/io.h> |
10 | |
11 | #include <avr/io.h> |
12 | #include <avr/interrupt.h> |
13 | #include <stdlib.h> |
14 | #include <string.h> |
15 | #include <util/delay.h> |
16 | #include <util/twi.h> |
17 | #include "E:\AVR\ATtiny2313\Includes\BitUtilities.h" |
18 | |
19 | |
20 | uint16_t dmx_pos = 0x0FFF; |
21 | uint16_t dmx_addr; |
22 | volatile uint8_t dmx_byte[6]; |
23 | |
24 | |
25 | int main(void) |
26 | {
|
27 | DDRD = 0x0C; // D2=gruen, D3=rot |
28 | |
29 | |
30 | |
31 | // DMX UART: 8-N-2, 250kBAUD
|
32 | UCSRA = 0; |
33 | UCSRB = (1<<RXEN) | (1<<RXCIE); |
34 | UCSRC = (1<<USBS) | (1<<UCSZ1) | (1<<UCSZ0); |
35 | UBRRL = 2; // 8Mhz : 1 12Mhz : 2 |
36 | UBRRH = 0; |
37 | |
38 | |
39 | sei(); |
40 | |
41 | while(1) |
42 | {
|
43 | if (dmx_byte[1]>127) |
44 | {
|
45 | sbi(PORTD,2); |
46 | }
|
47 | else
|
48 | {
|
49 | cbi(PORTD,2); |
50 | }
|
51 | |
52 | }
|
53 | return 0; |
54 | }
|
55 | |
56 | |
57 | ISR(USART_RX_vect) |
58 | {
|
59 | uint8_t uart_st = UCSRA; |
60 | |
61 | uint8_t uart_da = UDR; |
62 | if (uart_st & (1<<FE)) |
63 | {
|
64 | dmx_pos = 0; |
65 | }
|
66 | else
|
67 | {
|
68 | if (dmx_pos == 0) |
69 | {
|
70 | if (uart_da != 0) |
71 | {
|
72 | dmx_pos = 0x0FFF; |
73 | }
|
74 | }
|
75 | else if (dmx_pos >= dmx_addr && dmx_pos <= 0x0200) |
76 | {
|
77 | uint16_t ofs = dmx_pos-dmx_addr; |
78 | if (ofs > sizeof(dmx_byte)) |
79 | {
|
80 | dmx_pos = 0x0FFF; |
81 | } else { |
82 | dmx_byte[ofs] = uart_da; |
83 | |
84 | }
|
85 | }
|
86 | }
|
87 | if (dmx_pos <= 0x0200) dmx_pos++; |
88 | dmx_addr = 1; |
89 | }
|
Steve schrieb: > aber wenn der Wert wieder kleiner wird soll auch die led wieder > ausgehen. Das läuft nicht. Dann kommt Dein Programm wohl nie an dem Schritt vorbei wo das geprüft wird?
oszi40 schrieb: > Dann kommt Dein Programm wohl nie an dem Schritt vorbei wo das geprüft > wird? doch sollte es aber da es in der while(1) schleife steht
Auf den ersten, zweiten und dritten Blick konnte ich keinen Fehler finden. Allerdings finde ich die ISR etwas unübersichtlich, deshalb hier ein (ungetesteter) Vorschlag für eine weniger verschachtelte Variante:
1 | #define DMX_START 1
|
2 | #define DMX_SIZE 6
|
3 | #define DMX_END (DMX_START + DMX_SIZE)
|
4 | #define DMX_MAX 512
|
5 | #define DMX_SKIP (DMX_MAX + 1)
|
6 | #if DMX_END > DMX_MAX
|
7 | # error "DMX only has 512 channels."
|
8 | #endif
|
9 | |
10 | uint16_t dmx_pos = DMX_SKIP; |
11 | volatile uint8_t dmx_byte[DMX_SIZE]; |
12 | |
13 | ISR(USART_RX_vect) |
14 | {
|
15 | uint8_t uart_st = UCSRA; |
16 | uint8_t uart_da = UDR; |
17 | |
18 | if (uart_st & (1 << FE)) |
19 | {
|
20 | // BREAK, start a new frame.
|
21 | dmx_pos = 0; |
22 | }
|
23 | else if (dmx_pos == 0 && uart_da != 0) |
24 | {
|
25 | // Invalid start byte, skip this frame.
|
26 | dmx_pos = DMX_SKIP; |
27 | }
|
28 | else if (dmx_pos >= DMX_START && dmx_pos < DMX_END) |
29 | {
|
30 | // Store the values of the channels we are interested in.
|
31 | dmx_byte[dmx_pos - DMX_START] = uart_da; |
32 | }
|
33 | if (dmx_pos <= DMX_MAX) dmx_pos++; |
34 | }
|
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.