Moing
Ich "darf" für einen Kollegen ein DMX empfänger bastln, welcher je nach
wert 2 Relay schaltet.
Regler wird nach unten geschoben => Relay 1 wird kurz erregt, fällt
wider ab
Regler wird nach oben geschoben => Relay 2 wird kurz erregt, fällt
wieder ab
Da ich DMX am anfang gar nicht kannte aber sah dass es sich eigentlich
um UART handelt, habe ich zugesagt. Als "orientierung" habe ich diese
Daten hier genommen:
Beitrag "DMX512 Empfänger mit Relaisansteuerung für 20 Kanäle"
Jetzt probiere ich seit letzten Freitag und kriege es nicht hin!
Kann jemand mal bitte meinen Code ansehen? Ich sehe einfach nicht mehr
weiter :(
1 | #define F_CPU 16000000
|
2 |
|
3 | #include <avr/io.h>
|
4 | #include <avr/interrupt.h>
|
5 | #include <avr/sleep.h>
|
6 | #include <util/delay.h>
|
7 |
|
8 |
|
9 |
|
10 | uint8_t dmx_data; // DMX data
|
11 | uint8_t lastState; //Last State of Port
|
12 | uint8_t counter_T; //Count the overflows of Timmer0
|
13 | volatile uint8_t flag; // new data available
|
14 |
|
15 |
|
16 | int main(void) {
|
17 |
|
18 | // init
|
19 |
|
20 | PORTB = 0xFF; // all pull-ups ON
|
21 | DDRD = 0x3F; // PD0..5 outputs
|
22 | PORTD = 0x40; //PullUp PD6
|
23 |
|
24 |
|
25 | UBRRH = 0;
|
26 | UBRRL = 3; //Vorteiler 3 @16Mhz = 250 Kbaud
|
27 | UCSRB = (1<<RXCIE) | (1<<RXEN);
|
28 |
|
29 | TCCR0B |= (1<<CS00)|(1<<CS02); // Prescaler 1024 Timmer
|
30 |
|
31 | //enable global Interrupt
|
32 | sei();
|
33 |
|
34 | // main loop
|
35 | while (1) {
|
36 | if (!flag) {
|
37 | set_sleep_mode(SLEEP_MODE_IDLE);
|
38 | sleep_mode();
|
39 | }
|
40 | else {
|
41 | flag=0;
|
42 | if((dmx_data >= 127)&&(lastState == 0)){
|
43 | PORTD |= 16;
|
44 | lastState = 1;
|
45 | TIMSK |= (1<<TOIE0); //Enable Overflow T0
|
46 |
|
47 | }
|
48 |
|
49 | else if ((dmx_data <= 127) && (lastState == 1)){
|
50 | PORTD |= 8;
|
51 | lastState = 0;
|
52 | TIMSK |= (1<<TOIE0); //Enable Overflow T0
|
53 | }
|
54 | }
|
55 | }
|
56 | }
|
57 |
|
58 | ISR(USART_RX_vect) {
|
59 | static uint16_t dmx_channel, dmx_adress;
|
60 | uint8_t status, data;
|
61 |
|
62 | // read UART data, also clears interrupt flag
|
63 | status = UCSRA;
|
64 | data = UDR;
|
65 |
|
66 | if (status & (1<<FE)) { // frame error
|
67 | if (data==0) { // break -> DMX Reset
|
68 | dmx_channel=0;
|
69 | dmx_adress = (~PINB & 0xFF)+1; // read dip switches which define DMX base address
|
70 | if (~PIND & (1<<PD6)) dmx_adress +=256;
|
71 | flag=1; // trigger update
|
72 | }
|
73 | else // rx error
|
74 | dmx_channel++;
|
75 | }
|
76 | else {
|
77 | if (dmx_channel == dmx_adress){
|
78 | dmx_data = data;
|
79 | }
|
80 | dmx_channel++;
|
81 | }
|
82 | }
|
83 |
|
84 |
|
85 | ISR (TIMER0_OVF_vect)
|
86 | {
|
87 | if(counter_T !=255){
|
88 | counter_T++;
|
89 | }
|
90 | else
|
91 | counter_T = 0;
|
92 | TIMSK &= ~(1<<TOIE0);
|
93 | PORTD &= ~(24);
|
94 | }
|
Ich habe schon mit einem USB UART Converter geschaut ob der MAX485
funktioniert..und der ist OK! Die Relays gehen mit dem entsprechenden
Testprogramm auch... Der Controller läuft dem Timmer 0 zu urteilen auch
korekt auf dem 16 MHz Quarz, ERROR ist mit vorteiler 3 für den UART = 0%
(siehe Datasheet seite 137).
Während des Betriebes zieht NIE ein Relay an. Ich hoffe jemand kann mir
helfen :)