Forum: Mikrocontroller und Digitale Elektronik Empfangsprobleme mit DMX ( attiny2313A )


von Steve (Gast)


Lesenswert?

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

von Dödel (Gast)


Lesenswert?

In Zeile 42 muss du den Wert der Variable anpassen.

von Steve (Gast)


Lesenswert?

daraus schließe ich dass du den code haben willst ?

von Dödel (Gast)


Lesenswert?

Wie soll man den sonst helfen können?

von Steve (Gast)


Lesenswert?

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
}

von oszi40 (Gast)


Lesenswert?

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?

von Steve (Gast)


Lesenswert?

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

von R. M. (rmax)


Lesenswert?

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
Noch kein Account? Hier anmelden.