1 | #include<avr/signal.h>
|
2 | /// Includes //////////
|
3 | #include <avr/io.h>
|
4 | #include "os.h"
|
5 | #include <stdbool.h>
|
6 | #include <avr/interrupt.h>
|
7 | #define LCD_PORT_w PORTC
|
8 | #define LCD_PORT_DDR DDRC
|
9 | #define DISPLAY_RS (1<<3)
|
10 | #define DISPLAY_EN (1<<2)
|
11 |
|
12 | //LCD
|
13 | void _long_delay(void);
|
14 | void _lcd_write_command(unsigned char);
|
15 | void LCD_Write(unsigned char *);
|
16 | void LCD_Init(void);
|
17 | char LCD_Putchar(char);
|
18 | #define LCD_Clear {_lcd_write_command(0x01); _long_delay();_long_delay();}
|
19 | void LCD_Gotoxy(unsigned char , unsigned char );
|
20 | void LCD_Gotoxy2(unsigned char , unsigned char );
|
21 | void LCD_DezAusgabe(unsigned long wert , char stellen , unsigned char punkt);
|
22 | void LCD_Puts(const char *s);
|
23 | bool akku;
|
24 | float realakku;
|
25 | int intakku;
|
26 |
|
27 | //Uservariablen
|
28 |
|
29 | /// Data
|
30 | bool lcd;
|
31 | ///Data Types /////////
|
32 | typedef unsigned char u8;
|
33 | typedef unsigned int u16;
|
34 | typedef struct task
|
35 | {
|
36 | // pointer to a function
|
37 | void (*pfunc) (void);
|
38 | // delay before the first call
|
39 | u16 delay;
|
40 | // interval between subsequent runs
|
41 | u16 period;
|
42 | // flag indicating time to run
|
43 | u8 run;
|
44 | }task;
|
45 |
|
46 | /// Defines ///////////
|
47 | // 25msec period 256-180
|
48 | // 7.3728MHz and /1024 prescaler
|
49 | #define StartFrom 76
|
50 | // maximum number of tasks
|
51 | #define MAXnTASKS 20
|
52 |
|
53 | /// Globals ///////////
|
54 | volatile task TaskArray[MAXnTASKS];
|
55 |
|
56 | /// Prototypes ////////
|
57 | void InitUART (u16 baud);
|
58 | void TransmitByte (u8 data);
|
59 | void InitScheduler (void);
|
60 | void UpdateScheduler(void);
|
61 | void DeleteTask (u8 index);
|
62 | void AddTask (void (*taskfunc)(void), u16 taskdelay, u16 taskperiod);
|
63 | void DispatchTask (void);
|
64 |
|
65 | void SPSTASK (void);
|
66 | void LCDTASK (void);
|
67 | void SERKOMTASK (void);
|
68 |
|
69 | /// Main //////////////
|
70 | int main(void)
|
71 | {
|
72 | InitUART (23);
|
73 | InitScheduler();
|
74 | DDRB=0xFF;
|
75 | // populate task array
|
76 | AddTask (t0, 0, 3);
|
77 | AddTask (t1, 1, 4);
|
78 | AddTask (t2, 4, 0);
|
79 | LCD_Init();
|
80 | LCD_Clear;
|
81 | LCD_Gotoxy(0,0);
|
82 |
|
83 | // enable interrupts
|
84 | sei();
|
85 |
|
86 | while (1)
|
87 | {
|
88 | DispatchTask();
|
89 | }
|
90 | }
|
91 |
|
92 | void InitUART (u16 baud)
|
93 | {
|
94 | unsigned char x;
|
95 | UBRRH = (u8)(baud>>8);
|
96 | UBRRL = (u8)baud;
|
97 | UCSRB = (1<<RXEN)|(1<<TXEN);
|
98 | UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);
|
99 | UART.Betriebsart=true;
|
100 | // UCSRB|=(1<<RXCIE);
|
101 | x=UDR;
|
102 | }
|
103 |
|
104 | void TransmitByte (u8 data)
|
105 | {
|
106 | while ( !( UCSRA & (1<<UDRE)) );
|
107 | UDR = data;
|
108 | }
|
109 |
|
110 | void InitScheduler (void)
|
111 | {
|
112 | u8 i;
|
113 |
|
114 | // timer prescaler clock/1024
|
115 | TCCR0 |= (1<<CS01)|(1<<CS00);
|
116 | // clear pending interrupts
|
117 | TIFR = 1<<TOV0;
|
118 | // enable timer0 overflow interrupt
|
119 | TIMSK |= 1<<TOIE0;
|
120 | // load timer0
|
121 | TCNT0 = StartFrom;
|
122 |
|
123 | // clear task array
|
124 | for (i=0; i<MAXnTASKS; i++) DeleteTask(i);
|
125 | }
|
126 |
|
127 | void DeleteTask (u8 j)
|
128 | {
|
129 | TaskArray[j].pfunc = 0x0000;
|
130 | TaskArray[j].delay = 0;
|
131 | TaskArray[j].period = 0;
|
132 | TaskArray[j].run = 0;
|
133 | }
|
134 |
|
135 | void AddTask (void (*taskfunc)(void), u16 taskdelay, u16 taskperiod)
|
136 | {
|
137 | u8 n=0;
|
138 |
|
139 | // find next available position
|
140 | while ((TaskArray[n].pfunc != 0) && (n < MAXnTASKS)) n++;
|
141 |
|
142 | // place task
|
143 | if (n < MAXnTASKS)
|
144 | {
|
145 | TaskArray[n].pfunc = taskfunc;
|
146 | TaskArray[n].delay = taskdelay;
|
147 | TaskArray[n].period = taskperiod;
|
148 | TaskArray[n].run = 0;
|
149 | }
|
150 | }
|
151 |
|
152 | SIGNAL(SIG_OVERFLOW0)
|
153 | {
|
154 | u8 m;
|
155 |
|
156 | // testing
|
157 | // TransmitByte(45); // (-)
|
158 |
|
159 | // load timer
|
160 | TCNT0 = StartFrom;
|
161 |
|
162 | for (m=0; m<MAXnTASKS; m++)
|
163 | {
|
164 | if (TaskArray[m].pfunc)
|
165 | {
|
166 | if (TaskArray[m].delay == 0)
|
167 | {
|
168 | TaskArray[m].run = 1;
|
169 | TaskArray[m].delay = TaskArray[m].period;
|
170 | }
|
171 | else TaskArray[m].delay--;
|
172 | }
|
173 | }
|
174 | }
|
175 |
|
176 | void DispatchTask (void)
|
177 | {
|
178 | u8 k;
|
179 |
|
180 | for (k=0; k<MAXnTASKS; k++)
|
181 | {
|
182 | if (TaskArray[k].run == 1)
|
183 | {
|
184 | // run task
|
185 | (*TaskArray[k].pfunc)();
|
186 | // clear run flag
|
187 | TaskArray[k].run = 0;
|
188 | }
|
189 | }
|
190 |
|
191 | }
|
192 |
|
193 | void t0(void)
|
194 |
|
195 | { //nicht wichtig für diese Betrachtungen
|
196 |
|
197 | }
|
198 | void t1(void)
|
199 |
|
200 | {
|
201 | //nicht wichtig für diese Betrachtungen
|
202 |
|
203 |
|
204 | }
|
205 |
|
206 |
|
207 | void t2(void){
|
208 | DDRC=0x00; //PORTC EINGANG-UmTasten herauszulesen
|
209 | if(!(PINC&0x80)&&!lcd){LCD_Init();
|
210 | LCD_Gotoxy(0,0);
|
211 | LCD_Write("H");
|
212 | lcd=true;
|
213 | }
|
214 | }
|
215 |
|
216 |
|
217 | void _long_delay(void)
|
218 | {
|
219 | int t = 50000;
|
220 | while (t--);
|
221 | }
|
222 |
|
223 | void _short_delay(void)
|
224 | {
|
225 | int t = 20000;
|
226 | while (t--);
|
227 | }
|
228 |
|
229 |
|
230 | void _lcd_write_command(unsigned char data)
|
231 | {
|
232 | DDRC |= (0x80+0x40+0x20+0x10+0x08);
|
233 | LCD_PORT_w = (data & 0xf0) | DISPLAY_EN;
|
234 | LCD_PORT_w = (data & 0xf0) | DISPLAY_EN;
|
235 | LCD_PORT_w = (data & 0xf0) | DISPLAY_EN;
|
236 | LCD_PORT_w = (data & 0xf0);
|
237 | LCD_PORT_w = (data & 0xf0);
|
238 | LCD_PORT_w = (data & 0xf0);
|
239 | LCD_PORT_w = (data << 4) | DISPLAY_EN;
|
240 | LCD_PORT_w = (data << 4) | DISPLAY_EN;
|
241 | LCD_PORT_w = (data << 4) | DISPLAY_EN;
|
242 | LCD_PORT_w = (data << 4);
|
243 | DDRC &= ~(0x80+0x40+0x20+0x10+0x08);
|
244 | PORTD &= ~0x08;
|
245 |
|
246 | }
|
247 |
|
248 | void _lcd_write_4bit(unsigned char data)
|
249 | {
|
250 | DDRC |= (0x80+0x40+0x20+0x10+0x08);
|
251 | LCD_PORT_w = (data << 4) | DISPLAY_EN;
|
252 | LCD_PORT_w = (data << 4) | DISPLAY_EN;
|
253 | LCD_PORT_w = (data << 4) | DISPLAY_EN;
|
254 | LCD_PORT_w = (data << 4);
|
255 | LCD_PORT_w = (data << 4);
|
256 | DDRC &= ~(0x80+0x40+0x20+0x10+0x08);
|
257 | PORTD &= ~0x08;
|
258 |
|
259 | }
|
260 |
|
261 | void lcd_write_byte(unsigned char data)
|
262 | {
|
263 | DDRC |= (0x80+0x40+0x20+0x10+0x08);
|
264 | LCD_PORT_w = (data & 0xf0) | DISPLAY_EN | DISPLAY_RS;
|
265 | LCD_PORT_w = (data & 0xf0) | DISPLAY_EN | DISPLAY_RS;
|
266 | LCD_PORT_w = (data & 0xf0) | DISPLAY_RS;
|
267 | LCD_PORT_w = (data & 0xf0) | DISPLAY_RS;
|
268 | LCD_PORT_w = (data << 4) | DISPLAY_EN | DISPLAY_RS;
|
269 | LCD_PORT_w = (data << 4) | DISPLAY_EN | DISPLAY_RS;
|
270 | LCD_PORT_w = (data << 4) | DISPLAY_RS;
|
271 | DDRC &= ~(0x80+0x40+0x20+0x10+0x08);
|
272 | PORTD &= ~0x08;
|
273 |
|
274 | }
|
275 |
|
276 |
|
277 | int my_pput(int zeichen)
|
278 | {
|
279 | lcd_write_byte((char) zeichen);
|
280 | return(1);
|
281 | }
|
282 |
|
283 |
|
284 |
|
285 | // getch.c
|
286 | unsigned char getch(void) // warten und Zeichen abholen
|
287 | {
|
288 | loop_until_bit_is_set(UCSRA, RXC); // warte bis Zeichen da
|
289 |
|
290 | return UDR; // Zeichen abholen
|
291 | }
|
292 |
|
293 | // getche.c warten, Zeichen abholen und im Echo senden
|
294 | void getche(void)
|
295 | {
|
296 | unsigned char x;
|
297 | loop_until_bit_is_set(UCSRA, RXC);
|
298 | x = UDR;
|
299 | loop_until_bit_is_set(UCSRA, TXC);
|
300 | UDR = x;
|
301 | }
|
302 | // initialize the LCD controller
|
303 | void LCD_Init(void)
|
304 | {
|
305 |
|
306 | LCD_PORT_DDR = 0xff;// - (0x01 + 0x02) ;//0xf0 | DISPLAY_RS | DISPLAY_EN;
|
307 | _long_delay();
|
308 | _long_delay();
|
309 | _lcd_write_4bit(0x03); // noch 8 Bit
|
310 | _long_delay();
|
311 | _lcd_write_4bit(0x03); // noch 8 Bit
|
312 | _long_delay();
|
313 | _lcd_write_4bit(0x03); // noch 8 Bit
|
314 | _long_delay();
|
315 | _lcd_write_4bit(0x02); // jetzt 4 Bit
|
316 | _long_delay();
|
317 |
|
318 | _lcd_write_command(0x28); // 4 Bit Zweizeilig
|
319 | //-
|
320 | _long_delay();
|
321 | _long_delay();
|
322 | _lcd_write_command(0x1C);
|
323 | _long_delay();
|
324 | _lcd_write_command(0x74);
|
325 | _long_delay();
|
326 | _lcd_write_command(0x52); //
|
327 | _long_delay();
|
328 | _lcd_write_command(0x69); // Contrast
|
329 |
|
330 | // ----------------------------
|
331 | //-
|
332 | _long_delay();
|
333 | _lcd_write_command(0x08); // Display aus
|
334 | _long_delay();
|
335 | _lcd_write_command(0x01); // Clear
|
336 | _long_delay();
|
337 | _lcd_write_command(0x06); //Entry mode
|
338 | _long_delay();
|
339 | _lcd_write_command(0x08 + 4); // Display an
|
340 | _long_delay();
|
341 | }
|
342 |
|
343 |
|
344 | void LCD_Gotoxy(unsigned char x , unsigned char y)
|
345 | {
|
346 | _short_delay();
|
347 | switch(y)
|
348 | { case 0 : _lcd_write_command(x + 0x80); break;
|
349 | case 1 : _lcd_write_command(x + 0xC0); break;
|
350 | case 2 : _lcd_write_command(x + (0x80 + 20)); break;
|
351 | case 3 : _lcd_write_command(x + (0xC0 + 20)); break;
|
352 | }
|
353 |
|
354 | }
|
355 |
|
356 |
|
357 | void LCD_Write(unsigned char *this_text)
|
358 | {
|
359 | unsigned char i = 0;
|
360 |
|
361 | while(this_text[i] != 0)
|
362 | {
|
363 | lcd_write_byte(this_text[i++]);
|
364 | _long_delay();
|
365 |
|
366 | }
|
367 |
|
368 |
|
369 | }
|
370 |
|
371 | char LCD_Putchar(char zeichen)
|
372 | {
|
373 | _short_delay();
|
374 | lcd_write_byte((char) zeichen);
|
375 | return(1);
|
376 | }
|