avr-usb-162_Led.c


1
/*  Test program for Olimex AVR-USB-162 with AT90USB162 processor
2
 *  for application TIC (TimerIncrementClock)
3
 *  Blinks the led using a simple delay loop
4
 *    and add with Balkenanzeige
5
 *  Compile with AVRStudio+WinAVR (gcc V4.3.0, WinAVR20080610, AVR lib 1.6.2)
6
* 
7
*  Gerhard V0.2, 4.10.08
8
*    Erzeugung eines Array für low und high matrix für die Zeiten
9
*       1 bis 30
10
*    Zusätzlich kann dadurch eine oder mehrere LEDs zweimal ein-
11
*       geschaltet werden, für 5-er oder 6-er Markierung
12
*    Highside Matrix (C1-C5 an PB0, PB4-7 wird im ausgeschaltetem Zustand 
13
*       als Eingang und dadurch hochohmig geschaltet
14
*    Matrix umbenannt: A1-A5 (Anode) statt C1-C5 (column) und 
15
*       K1-K5 (Kathode) statt R1-R5 (row),da jetzt
16
*       da jetzt LED-Bargraph statt LED-Matrix
17
*
18
*    WIEDER GELÖSCHT: Const in Flash aus"avr-libc: Frequently Asked Questions"
19
*
20
* Gerhard V0.3  11.10.08
21
*  Lichtmarkierung wieder entfernt bei Matrix_Ax_Ausgang
22
*
23
* Gerhard V0.4  17.10.08
24
*  AF und Shoot ergänzt
25
*
26
* Gerhard V0.5   22.10.08
27
*   Tasterabfrage ergänzt für Start von AF, Shoot und einem LED-Durchlauf
28
*
29
* Gerhard V0.6   01.11.08
30
*  Verzögerungen durch _delay_ms
31
*  increment-timer durch 16bit timer erzeugt
32
*  Flag für AF-delay eingeführt
33
*  Eingebundene Programme von MEGA8 auf USB162 angepasst
34
*    TIMSK1 satt TIMSK
35
*    TIMER1_COMPA_vect statt SIG_OUTPUT_COMPARE1A
36
* Gerhard V0.7   02.11.08
37
*  ISR (Interrupt Sevice Routine) anstatt veraltete Form "SIGNAL" verwendet
38
*  Reset des Counters bei Start (TCNT1=0)
39
*
40
* Gerhard V0.8  03.11.08
41
*    TCCR1B = (1<<CS11) | (1<<WGM12); statt  TCCR1B |= (1<<CS11) | (1<<WGM12);
42
 */
43
44
#define F_CPU  8000000UL
45
46
#include "avr\io.h"
47
#include <stdint.h>
48
#include <util/delay.h>    // definiert _delay_ms() 
49
#include <avr/interrupt.h>  // definiert increment_time
50
51
52
53
void delay_ms(uint16_t);
54
int main (void);
55
56
void Parameter_Init()
57
{
58
}
59
60
void PORT_Init()
61
{
62
  PORTB = 0b11110001; // set A1 to A5 to high (highside to LED-Anode)
63
                      // LEDx on, wenn Ax to output, 
64
            // LEDx off, if Ax to input
65
66
  DDRB =  0b00001110; // set A1 to A5 to input (means tristate and LEDx off)
67
68
  PORTC = 0b00000000; // set PC-port to low
69
            //AF und Shoot (PC7 and PC6=low)
70
  DDRC =  0b11000000; // set PC-port as input, except AF and Shoot
71
72
  PORTD = 0b01101111; // LED (PD4=low) and Kx (PD0-3,PD5-6=high) (means off)
73
            // PD7 no internal pull up for switch BUT)
74
75
  DDRD =  0b01111111;  // set LED (PD4) as output
76
                        // and Kx (PD0-3,PD5-6=high) as output (lowside to LED_Kathode)
77
            // PD7 as input for BUT
78
}
79
80
volatile  uint8_t time_number = 0;
81
volatile  uint8_t Low_LED_Matrix[30];
82
volatile  uint8_t High_LED_Matrix[30];
83
84
85
86
void Matrix_Init()
87
{
88
  uint8_t Matrix_Kx_high= 0b01101111;     //Low_Matrix_LEDx off and LED off
89
  uint8_t Matrix_K1_low = 0b01111110;     //PD0 an K1 direkt an Kathode LEDx
90
  uint8_t Matrix_K2_low = 0b01111101;     //PD1 an K2
91
  uint8_t Matrix_K3_low = 0b01111011;     //PD2 an K3
92
  uint8_t Matrix_K4_low = 0b01110111;     //PD3 an K4
93
  uint8_t Matrix_K5_low = 0b01011111;     //PD5 an K5
94
  uint8_t Matrix_K6_low = 0b00111111;     //PD6 an K6
95
96
  uint8_t Matrix_Ax_Eingang = 0b00000000; //High_Matrix_LEDs off
97
  uint8_t Matrix_A1_Ausgang = 0b00000001; //PB0 an A1 über Rx an Anode LEDx
98
99
  uint8_t Matrix_A2_Ausgang = 0b00010000; //PB4 an A2
100
  uint8_t Matrix_A3_Ausgang = 0b00100000; //PB5 an A3
101
  uint8_t Matrix_A4_Ausgang = 0b01000000; //PB6 an A4
102
  uint8_t Matrix_A5_Ausgang = 0b10000000; //PB7 an A5
103
104
  
105
  Low_LED_Matrix[0]  = Matrix_Kx_high;    // Kx auf high  (=low_Matrix off)
106
  High_LED_Matrix[0] = Matrix_Ax_Eingang; // set Ax to input (=high_matrix off
107
108
  Low_LED_Matrix[1]  = Matrix_K1_low;     // K1 auf low  (Matrix EIN)
109
  High_LED_Matrix[1] = Matrix_A1_Ausgang; // set A1 to output, rest to input
110
                            //   means tristate
111
  Low_LED_Matrix[2]  = Matrix_K1_low;
112
  High_LED_Matrix[2] = Matrix_A2_Ausgang;
113
  Low_LED_Matrix[3]  = Matrix_K1_low;
114
  High_LED_Matrix[3] = Matrix_A3_Ausgang;
115
  Low_LED_Matrix[4]  = Matrix_K1_low;
116
  High_LED_Matrix[4] = Matrix_A4_Ausgang;
117
  Low_LED_Matrix[5]  = Matrix_K1_low;
118
  High_LED_Matrix[5] = Matrix_A5_Ausgang;
119
120
  Low_LED_Matrix[6]  = Matrix_K2_low;    //K2 auf low  (Matrix EIN)
121
  High_LED_Matrix[6] = Matrix_A1_Ausgang;
122
  Low_LED_Matrix[7]  = Matrix_K2_low;
123
  High_LED_Matrix[7] = Matrix_A2_Ausgang;
124
  Low_LED_Matrix[8]  = Matrix_K2_low;
125
  High_LED_Matrix[8] = Matrix_A3_Ausgang;
126
  Low_LED_Matrix[9]  = Matrix_K2_low;
127
  High_LED_Matrix[9] = Matrix_A4_Ausgang;
128
  Low_LED_Matrix[10] = Matrix_K2_low;
129
  High_LED_Matrix[10]= Matrix_A5_Ausgang;
130
131
  Low_LED_Matrix[11]  = Matrix_K3_low;    //K3 auf low  (Matrix EIN)
132
  High_LED_Matrix[11] = Matrix_A1_Ausgang;
133
  Low_LED_Matrix[12]  = Matrix_K3_low;
134
  High_LED_Matrix[12] = Matrix_A2_Ausgang;
135
  Low_LED_Matrix[13]  = Matrix_K3_low;
136
  High_LED_Matrix[13] = Matrix_A3_Ausgang;
137
  Low_LED_Matrix[14]  = Matrix_K3_low;
138
  High_LED_Matrix[14] = Matrix_A4_Ausgang;
139
  Low_LED_Matrix[15]  = Matrix_K3_low;
140
  High_LED_Matrix[15] = Matrix_A5_Ausgang;
141
142
  Low_LED_Matrix[16]  = Matrix_K4_low;    //K4 auf low  (Matrix EIN)
143
  High_LED_Matrix[16] = Matrix_A1_Ausgang;
144
  Low_LED_Matrix[17]  = Matrix_K4_low;
145
  High_LED_Matrix[17] = Matrix_A2_Ausgang;
146
  Low_LED_Matrix[18]  = Matrix_K4_low;
147
  High_LED_Matrix[18] = Matrix_A3_Ausgang;
148
  Low_LED_Matrix[19]  = Matrix_K4_low;
149
  High_LED_Matrix[19] = Matrix_A4_Ausgang;
150
  Low_LED_Matrix[20]  = Matrix_K4_low;
151
  High_LED_Matrix[20] = Matrix_A5_Ausgang;
152
153
  Low_LED_Matrix[21]  = Matrix_K5_low;    //K5 auf low  (Matrix EIN)
154
  High_LED_Matrix[21] = Matrix_A1_Ausgang;
155
  Low_LED_Matrix[22]  = Matrix_K5_low;
156
  High_LED_Matrix[22] = Matrix_A2_Ausgang;
157
  Low_LED_Matrix[23]  = Matrix_K5_low;
158
  High_LED_Matrix[23] = Matrix_A3_Ausgang;
159
  Low_LED_Matrix[24]  = Matrix_K5_low;
160
  High_LED_Matrix[24] = Matrix_A4_Ausgang;
161
  Low_LED_Matrix[25]  = Matrix_K5_low;
162
  High_LED_Matrix[25] = Matrix_A5_Ausgang;
163
164
  Low_LED_Matrix[26]  = Matrix_K6_low;    //K6 auf low  (Matrix EIN)
165
  High_LED_Matrix[26] = Matrix_A1_Ausgang;
166
  Low_LED_Matrix[27]  = Matrix_K6_low;
167
  High_LED_Matrix[27] = Matrix_A2_Ausgang;
168
  Low_LED_Matrix[28]  = Matrix_K6_low;
169
  High_LED_Matrix[28] = Matrix_A3_Ausgang;
170
  Low_LED_Matrix[29]  = Matrix_K6_low;
171
  High_LED_Matrix[29] = Matrix_A4_Ausgang;
172
  Low_LED_Matrix[30]  = Matrix_K6_low;
173
  High_LED_Matrix[30] = Matrix_A5_Ausgang;
174
}
175
176
177
/**
178
  @brief  Wird vom 16 Bit Timer ausgelöst, wenn dieser den Vergleichwert erreicht
179
      Wird in TIC fuer incremental_value verwendet (Gerhard)
180
  @param  none
181
  @return  none
182
*/
183
ISR (TIMER1_COMPA_vect) //ISR (TIMER1_COMPA_vect) statt (SIGNAL) SIG_OUTPUT_COMPARE1A
184
{
185
  /*  time_number stellt den Zeitzeiger von 1 bis 29 dar. 
186
    Die Incremental_value wird durch den 16bit-counter1 erzeugt
187
  */
188
  // bisherige LEDx der Bargraphanzeige wieder ausschalten
189
  PORTD = PORTD | ~Low_LED_Matrix[time_number];
190
  DDRB = DDRB & ~High_LED_Matrix[time_number];
191
  
192
  time_number++;   // nächste LEDx der Bargraphanzeige auswählen
193
  
194
  // naechste LEDx der Bargraphanzeige einschalten
195
  PORTD = PORTD & Low_LED_Matrix[time_number];
196
  DDRB = DDRB | High_LED_Matrix[time_number];
197
198
}
199
200
// wartet ms Millisekunden
201
void delay_ms (uint16_t ms)
202
{
203
  uint16_t t;
204
  for( t=0; t<=ms; t++)
205
    _delay_ms(1); 
206
}
207
208
209
int main(void)
210
{  
211
  PORT_Init();
212
  Parameter_Init();
213
  Matrix_Init();
214
215
  uint16_t increment_value = 3000;  // Wert kann 1 bis 60000 sein
216
                    // entspricht 1 - 60000µs, wenn Teiler auf 8
217
  uint16_t AF_delay_time = 1000;    // in ms
218
  uint8_t AF_delay = 0;        // 0 ist keine AF-Verzögerung
219
220
  uint8_t time_number_max = 29;    // max. Anzahl der LEDs
221
222
223
  asm("WDR");            //Watchdog Timer Reset
224
  MCUSR= ~(1<<WDRF);
225
  WDTCSR = (1<<WDCE) | (1<<WDE);
226
  WDTCSR = 0x00;
227
  WDTCKD = 0x00;
228
229
230
  while (1)
231
  {
232
  PORT_Init();
233
// AF_Verzögerung toogeln
234
//    AF_delay ^= (1<<0);
235
236
237
//LED an PD4 einschalten
238
    PORTD = PORTD | 0b00010000; //LED auf high (EIN)
239
240
241
//Für Entprellung. Taster muß mal losgelassen worden sein (BUT an PD7 nicht gedrückt)
242
    while (!(PIND & (1<<PD7)) )  // solange Taster gedrückt
243
    {
244
    }
245
246
247
//Tasterabfrage für Start (BUT an PD7 gedrückt=low)
248
    while (PIND & (1<<PD7) )  // solange Taster nicht gedrückt
249
    {
250
    }
251
    
252
    // Taster wird gedrückt
253
    PORTD = PORTD & 0b11101111; //LED auf low (aus)
254
255
256
257
//AF an PC7
258
    PORTC = PORTC | 0b10000000; //AF auf high (EIN)
259
    
260
    if (AF_delay != 0)
261
    {  delay_ms(AF_delay_time);  //AF um AF_delay_time ms verzögert
262
    }
263
264
//Shoot an PC6
265
    PORTC = PORTC | 0b01000000; //Shoot auf high (EIN)
266
267
268
269
// Init 16 bit Counter und Freigabe timerinterrupt
270
  OCR1A = (uint16_t)(increment_value);// Vergleichwert mit increment_value laden: 
271
                      // Takt= 8MHz/8
272
  TIMSK1 |= (1<<OCIE1A);           // Interrupt wenn Timer Vergleichswert erreicht
273
274
  TCNT1=0;              // Timer1 zurücksetzen
275
  TCCR1B = 0;    //zusätzlich TCCR1B reseten
276
277
278
  TCCR1B |= (1<<CS11) | (1<<WGM12);  // Timer1 mit Div 8 starten (CS11) und Clear Counter on Compare Match
279
280
  sei();                // IRQ Behandlung ein
281
282
// init time_number
283
  time_number = 1;
284
285
  // LED1 der Bargraphanzeige einschalten
286
  PORTD = PORTD & Low_LED_Matrix[time_number];
287
  DDRB = DDRB | High_LED_Matrix[time_number];
288
289
// solange warten, bis alle LEDs durchlaufen sind und counter und interrupt stoppen
290
  while (time_number <= time_number_max);
291
292
  cli();    //Interrupt löschen
293
294
  PORTC = PORTC & 0b01111111; //AF auf low (aus)
295
  PORTC = PORTC & 0b10111111; //Shoot auf low (aus)
296
297
// Bargraphanzeige ausschalten
298
  time_number = 0;
299
  PORTD = PORTD & Low_LED_Matrix[time_number];
300
  DDRB = DDRB | High_LED_Matrix[time_number];
301
302
303
  }
304
  return 0;
305
}