main.c


1
//*****************************************************************************
2
//*
3
//*  LED fading test
4
//*  uses exponential PWM settings to achive visual linear brightness
5
//*
6
//*  ATmega32 @ 8 MHz
7
//*
8
//*
9
//*****************************************************************************
10
#ifndef F_CPU
11
/* In neueren Version der WinAVR/Mfile Makefile-Vorlage kann
12
   F_CPU im Makefile definiert werden, eine nochmalige Definition
13
   hier wuerde zu einer Compilerwarnung fuehren. Daher "Schutz" durch
14
   #ifndef/#endif
15
16
   Dieser "Schutz" kann zu Debugsessions führen, wenn AVRStudio
17
   verwendet wird und dort eine andere, nicht zur Hardware passende
18
   Taktrate eingestellt ist: Dann wird die folgende Definition
19
   nicht verwendet, sondern stattdessen der Defaultwert (8 MHz?)
20
   von AVRStudio - daher Ausgabe einer Warnung falls F_CPU
21
   noch nicht definiert: */
22
#warning "F_CPU war noch nicht definiert, wird nun nachgeholt mit 16000000"
23
#define F_CPU 16000000UL    // Systemtakt in Hz - Definition als unsigned long beachten >> Ohne ergeben Fehler in der Berechnung
24
#endif
25
26
#define BAUD 9600UL          // Baudrate
27
28
// Berechnungen
29
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)   // clever runden
30
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1)))     // Reale Baudrate
31
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD) // Fehler in Promille, 1000 = kein Fehler.
32
33
#if ((BAUD_ERROR<990) || (BAUD_ERROR>1010))
34
  #error Systematischer Fehler der Baudrate grösser 1% und damit zu hoch!
35
#endif
36
37
38
39
#include <inttypes.h>
40
#include <avr/io.h>
41
#include <util/delay.h>
42
#include <avr/pgmspace.h>
43
44
// global variables
45
46
uint16_t pwmtable_16[256] PROGMEM = {0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2,
47
                                     2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3,
48
                                     4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6,
49
                                     6, 7, 7, 7, 8, 8, 8, 9, 9, 10, 10, 10, 11,
50
                                     11, 12, 12, 13, 13, 14, 15, 15, 16, 17, 17,
51
                                     18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28,
52
                                     29, 31, 32, 33, 35, 36, 38, 40, 41, 43, 45,
53
                                     47, 49, 52, 54, 56, 59, 61, 64, 67, 70, 73,
54
                                     76, 79, 83, 87, 91, 95, 99, 103, 108, 112,
55
                                     117, 123, 128, 134, 140, 146, 152, 159, 166,
56
                                     173, 181, 189, 197, 206, 215, 225, 235, 245,
57
                                     256, 267, 279, 292, 304, 318, 332, 347, 362,
58
                                     378, 395, 412, 431, 450, 470, 490, 512, 535,
59
                                     558, 583, 609, 636, 664, 693, 724, 756, 790,
60
                                     825, 861, 899, 939, 981, 1024, 1069, 1117,
61
                                     1166, 1218, 1272, 1328, 1387, 1448, 1512,
62
                                     1579, 1649, 1722, 1798, 1878, 1961, 2048,
63
                                     2139, 2233, 2332, 2435, 2543, 2656, 2773,
64
                                     2896, 3025, 3158, 3298, 3444, 3597, 3756,
65
                                     3922, 4096, 4277, 4467, 4664, 4871, 5087,
66
                                     5312, 5547, 5793, 6049, 6317, 6596, 6889,
67
                                     7194, 7512, 7845, 8192, 8555, 8933, 9329,
68
                                     9742, 10173, 10624, 11094, 11585, 12098,
69
                                     12634, 13193, 13777, 14387, 15024, 15689,
70
                                     16384, 17109, 17867, 18658, 19484, 20346,
71
                                     21247, 22188, 23170, 24196, 25267, 26386,
72
                                     27554, 28774, 30048, 31378, 32768, 34218,
73
                                     35733, 37315, 38967, 40693, 42494, 44376,
74
                                     46340, 48392, 50534, 52772, 55108, 57548,
75
                                     60096, 62757, 65535};
76
77
78
/*
79
 * Timer0 starten.
80
 *
81
 */
82
void init_pwm_timer0 (){
83
  PORTD = (0 << PD6) | (1 << PD7);
84
  TCCR0  =    (1 << WGM01)|(1 << WGM00)   //Fast PWM
85
        |(1 << COM01)|(0 << COM00)  //Set OC0 on compare match, clear OC0 at BOTTOM,
86
        |(0 << CS02) |(0 << CS01) |(1 << CS00); //clkI/O/(No prescaling)
87
88
}
89
90
/*
91
 * Time1 (16Bit) starten
92
 */
93
void init_pwm_timer1 (){
94
    TCCR1A = _BV(COM1A1)   | !_BV(COM1A0)        //  Both PWM outputs set at TOP,
95
             | _BV(COM1B1) | !_BV(COM1B0)    //    clear on compare match
96
             | !_BV(FOC1A) | !_BV(FOC1B)        //  PWM mode, can't force output
97
             | _BV(WGM11)  | !_BV(WGM10);       //  Fast PWM, TOP = ICR1
98
99
    TCCR1B = !_BV(ICNC1) | !_BV(ICES1)          //  Disable input capture noise canceler,
100
                                                //  edge select to negative.
101
                | _BV(WGM13) | _BV(WGM12)       //  Fast PWM, TOP = ICR1
102
                | !_BV(CS12) | _BV(CS11) | _BV(CS10);   //  clk(i/o) / 1024
103
104
    ICR1 = 0xFFFF;          // TOP for PWM, full 16 Bit
105
106
    TCCR1B &= ~0x7;         // clear clk setting
107
    TCCR1B |= 1;            // precaler 1 -> ~122 Hz PWM frequency
108
109
}
110
111
112
/*
113
 * Timer2 starten
114
 */
115
void init_pwm_timer2 (){
116
  TCCR2  =    (1 << WGM21)|(1 << WGM20)   //Fast PWM
117
        |(1 << COM21)|(0 << COM20)  //Set OC0 on compare match, clear OC0 at BOTTOM,
118
        |(0 << CS22) |(0 << CS21) |(1 << CS20); //clkI/O/(No prescaling)
119
120
}
121
122
/*
123
 * Initialisieren der Timer des ATMega32
124
 */
125
void INIT_Timer () {
126
  init_pwm_timer0();
127
  init_pwm_timer1();
128
  init_pwm_timer2();
129
}
130
131
/*
132
 * Einfaches Steuern der 3 PWMs
133
 */
134
void DIM_Leds(uint16_t delay){
135
    int i;
136
    PORTD |= (1 << PD6);
137
  for(i=0; i<=255; i++){
138
      OCR0=i;
139
      OCR2=i;
140
      OCR1A = pgm_read_word(pwmtable_16+i);
141
      _delay_loop_2(delay);
142
    }
143
    PORTD &= (0 << PD6);
144
145
    for (i=255; i>=0; i--){
146
      OCR0=i;
147
      OCR2=i;
148
      OCR1A = pgm_read_word(pwmtable_16+i);
149
      _delay_loop_2(delay);
150
    }
151
152
}
153
/*
154
 * USART aktivieren.
155
 * Baudrate wird über defines ermittelt
156
 */
157
void USART_Init()
158
{
159
  UCSRB = 0x00;// Stop USART
160
  /* Set baud rate */
161
    UBRRH = UBRR_VAL >> 8;
162
    UBRRL = UBRR_VAL & 0xFF;
163
    /* Enable receiver and transmitter */
164
  UCSRB = (1<<TXEN);  // Zum Empfangen (1<<RXEN) |
165
  /* Set frame format: 8data, 1stop bit */
166
  UCSRC |=
167
    (1<<URSEL)|     //muss gesetzt sein
168
    (0<<UMSEL)|     //Asynchrone Schnittstelle
169
    (0<<UPM1)|      //no parity
170
    (0<<UPM0)|      //no parity
171
    (0<<USBS)|      //one stop bit only
172
    (1<<UCSZ1)|     //8-bit mode
173
    (1<<UCSZ0)|     //8-bit mode
174
    (0<<UCPOL);     //Write this to zero in asynchronous mode
175
176
177
}
178
179
180
181
void USART_Transmit(unsigned char data )
182
{
183
  /* Wait for empty transmit buffer */
184
  while ( !( UCSRA & (1<<UDRE)) );
185
  /* Put data into buffer, sends the data */
186
  UDR = data;
187
}
188
189
/* puts ist unabhaengig vom Controllertyp */
190
void USART_Puts (char *s)
191
{
192
    while (*s)
193
    {   /* so lange *s != '\0' also ungleich dem "String-Endezeichen" */
194
      USART_Transmit(*s);
195
        s++;
196
    }
197
}
198
199
/*
200
 *  Testen der Ports.
201
 *  Alle LEDs an
202
 *
203
 */
204
void CHECK_Ports(){
205
  int i;
206
207
    PORTD |= (1 << PD5) | (1 << PD6) | (1 << PD7);
208
    PORTB |= (1 << PB3);
209
    for (i = 0; i < 256; i++ ){
210
      _delay_loop_2(30000);
211
    }
212
}
213
214
int main(void)
215
{
216
    int16_t step_time=8000;      // delay in millisecond for one fading step
217
218
    DDRD = (1 << PD5) | (1 << PD6) | (1 << PD7) ;   // LED uses OC1A  OC1A
219
    DDRB = (1 << PB3);
220
221
    CHECK_Ports();
222
    INIT_Timer();
223
    // Testausgabe auf dem Terminal
224
    USART_Init();
225
    _delay_loop_2(64000);
226
    USART_Puts("Yeah!! It Works");
227
    USART_Puts(" -- Aber was ist falsch");
228
    // test all fading routines
229
    while(1) {
230
      DIM_Leds(step_time);
231
    };
232
233
    return 0;
234
}