1 | // Defines an den Controller und die Anwendung anpassen
|
2 |
|
3 | #define F_CPU 2000000L // Systemtakt in Hz
|
4 | #define F_PWM 70 // PWM-Frequenz in Hz
|
5 | #define PWM_STEPS 256 // PWM-Schritte pro Zyklus(1..256)
|
6 | #define PWM_PORT PORTB // Port für PWM
|
7 | #define PWM_DDR DDRB // Datenrichtungsregister für PWM
|
8 |
|
9 | // ab hier nichts ändern, wird alles berechnet
|
10 |
|
11 | #define T_PWM (F_CPU/(F_PWM*PWM_STEPS)) // Systemtakte pro PWM-Takt
|
12 |
|
13 | #if (T_PWM<(93+5))
|
14 | #error T_PWM zu klein, F_CPU muss vergrösst werden oder F_PWM oder PWM_STEPS verkleinert werden
|
15 | #endif
|
16 |
|
17 | // includes
|
18 |
|
19 | #include <stdint.h>
|
20 | #include <string.h>
|
21 | #include <avr/io.h>
|
22 | #include <avr/interrupt.h>
|
23 |
|
24 | void uart_puts (char *s);
|
25 | void uart_putc(unsigned char c);
|
26 | int uart_getc(void);
|
27 | void uart_clear(void);
|
28 | void uart_gets( char* Buffer, uint8_t MaxLen );
|
29 |
|
30 | // globale Variablen
|
31 |
|
32 | volatile uint8_t pwm_setting[8]; // Einstellungen für die einzelnen PWM-Kanäle
|
33 |
|
34 | char empfangen[10];
|
35 |
|
36 |
|
37 | // Timer 1 Output COMPARE A Interrupt
|
38 |
|
39 | ISR(TIMER1_COMPA_vect)
|
40 | {
|
41 | static uint8_t pwm_cnt=0;
|
42 | uint8_t tmp=0;
|
43 |
|
44 | OCR1A += (uint16_t)T_PWM;
|
45 |
|
46 | if (pwm_setting[0] > pwm_cnt) tmp |= (1<<0);
|
47 | if (pwm_setting[1] > pwm_cnt) tmp |= (1<<1);
|
48 | if (pwm_setting[2] > pwm_cnt) tmp |= (1<<2);
|
49 | if (pwm_setting[3] > pwm_cnt) tmp |= (1<<3);
|
50 | if (pwm_setting[4] > pwm_cnt) tmp |= (1<<4);
|
51 | if (pwm_setting[5] > pwm_cnt) tmp |= (1<<5);
|
52 | if (pwm_setting[6] > pwm_cnt) tmp |= (1<<6);
|
53 | if (pwm_setting[7] > pwm_cnt) tmp |= (1<<7);
|
54 | PWM_PORT = tmp; // PWMs aktualisieren
|
55 | if (pwm_cnt==(uint8_t)(PWM_STEPS-1))
|
56 | pwm_cnt=0;
|
57 | else
|
58 | pwm_cnt++;
|
59 | }
|
60 |
|
61 |
|
62 | int main(void) {
|
63 |
|
64 | //uint8_t kommando, geraet, kanal, wert;
|
65 | // PWM einstellen
|
66 |
|
67 | PWM_DDR = 0xFF; // Port als Ausgang
|
68 |
|
69 | // Timer 1 OCRA1, als variablem Timer nutzen
|
70 |
|
71 | TCCR1B = 1; // Timer läuft mit vollem Systemtakt
|
72 | TIMSK |= (1<<OCIE1A); // Interrupt freischalten
|
73 |
|
74 | // USART Initialisierung
|
75 | UBRRH=0;
|
76 | UBRRL=12;
|
77 | UCSRA|=(1<<U2X);
|
78 | UCSRB|=(1 << TXEN)|(1<<RXEN)|(1<<RXCIE);
|
79 | uart_putc('N');
|
80 |
|
81 | sei(); // Interrupts gloabl einschalten
|
82 | while(1)
|
83 | {
|
84 | if( (UCSRA & (1<<RXC)) )
|
85 | {
|
86 | cli();
|
87 | //PORTB &=~(1<<PB4);
|
88 | uart_gets(empfangen, sizeof(empfangen));
|
89 | uart_puts(empfangen);
|
90 | pwm_setting[empfangen[2]-'0']=(empfangen[3]-'0')*25;
|
91 | for(int i=0; i<=7; i++)
|
92 | {
|
93 | uart_putc((char)pwm_setting[i]);
|
94 | }
|
95 | sei();
|
96 | }
|
97 |
|
98 |
|
99 | return 0;
|
100 | }
|