/[H7]/trunk/PIC/main.c
ViewVC logotype

Contents of /trunk/PIC/main.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 66 - (show annotations) (download)
Tue Feb 6 21:47:56 2007 UTC (17 years, 3 months ago) by torben
File MIME type: text/plain
File size: 11829 byte(s)
Hmmm maybe we should set the state of the right port ??
1 /* H7 -projekt opgave */
2
3 ///////////////////////////////////////////////////////////////////////
4 //Includes
5 #include <pic18.h>
6 #include <string.h>
7 #include <stdio.h>
8
9 #include "delay.h"
10 #include "i2c.h"
11 #include "lcd.h"
12
13 /////////////////////////////////////////////////////////////////////
14 //Defines
15 #define TC74 0x9A /* I2C TC74 IC */
16
17 #define SLIP_END 192
18 #define SLIP_ESC 219
19 #define SLIP_ESCAPED_END 220
20 #define SLIP_ESCAPED_ESC 221
21
22 #define BUFFERLEN 16
23
24 //////////////////////////////////////////////////////////////////
25 // Enumerations
26
27 enum SlipState{
28 SlipNormal,
29 SlipEscaped,
30 SlipError,
31 SlipStopped
32 };
33
34 enum BaudRates{
35 Baud1200,
36 Baud2400,
37 Baud4800,
38 Baud9600,
39 Baud19200
40 };
41
42 enum Commands{
43 CmdRead,
44 CmdWrite,
45 CmdAck,
46 CmdNAck
47 };
48
49 enum Targets {
50 TLed3, //0
51 TLed4,
52 TLed5,
53 TSwitch2,
54 TSwitch3,
55 TPotmeter,
56 TTemp,
57 TBaud = 10
58 };
59
60 //////////////////////////////////////////////////////////////////
61 //Globale data
62 // Alle globale variabler bruger "global_" som prefix
63
64 unsigned char global_comm_buffer[BUFFERLEN];
65 unsigned char global_comm_length;
66
67 bit global_comm_ready;
68 bit global_comm_error;
69
70 unsigned char global_comm_slipstate;
71 unsigned char global_comm_baudrate;
72
73 unsigned char global_lcd_buffer[2][BUFFERLEN];
74
75
76 bit global_led_0;
77 bit global_led_1;
78 bit global_led_2;
79
80 bit global_reset_baudrate;
81
82 char global_temp;
83 unsigned char global_potmeter_hi;
84 unsigned char global_potmeter_lo;
85
86 ///////////////////////////////////////////////////////////////////
87 // Interrupt funktioner
88
89 void recieve_interrupt(void)
90 {
91 unsigned char data = RCREG;
92
93 if (global_comm_length == BUFFERLEN) //avoid buffer overrun
94 global_comm_slipstate == SlipError;
95
96 switch (global_comm_slipstate)
97 {
98 case SlipNormal:
99 if (data == SLIP_END)
100 {
101 global_comm_ready = 1;
102 global_comm_slipstate = SlipStopped;
103 }
104 else if (data == SLIP_ESC)
105 {
106 global_comm_slipstate = SlipEscaped;
107 }
108 else
109 global_comm_buffer[ global_comm_length++ ] = data;
110 break;
111
112 case SlipEscaped:
113 if (data == SLIP_ESCAPED_ESC)
114 {
115 global_comm_buffer[ global_comm_length++ ] = SLIP_ESC;
116 global_comm_slipstate = SlipNormal;
117 }
118 else if (data ==SLIP_ESCAPED_END)
119 {
120 global_comm_buffer[ global_comm_length++ ] = SLIP_END;
121 global_comm_slipstate = SlipNormal;
122 }
123 else
124 {
125 global_comm_slipstate = SlipError;
126 }
127 case SlipError:
128 if (data == SLIP_END)
129 {
130 global_comm_error = 1;
131 global_comm_slipstate = SlipStopped;
132 global_comm_ready = 1;
133 }
134 case SlipStopped: //vi var ikke klar til at modtage data
135 global_comm_error = 1;
136 }
137 }
138
139 /*
140 void transmit_interrupt(void)
141 {
142 RB2 = !RB2;
143 }
144 */
145 //Timer1 er en 16 bit timer, der kører med en 1:8 prescaler,
146 // og er styret fra en ekstern 32768 Hz krystal
147 //Når at registrene preloades med 0xEFFF vil det resultere i en
148 //timer overflow ca hvert sekund
149 void timer1_interrupt(void)
150 {
151 TMR1H = 0xEF;
152 TMR1L = 0xFF;
153 }
154 void interrupt interrupt_handler(void)
155 {
156 if (RCIF == 1)
157 {
158 recieve_interrupt();
159 RCIF = 0;
160 }
161 /*if (TXIF == 1)
162 {
163 transmit_interrupt();
164 TXIF = 0;
165 }
166 */
167
168 if (TMR1IF == 1)
169 {
170 timer1_interrupt();
171 TMR1IF = 0;
172 }
173 }
174
175 ///////////////////////////////////////////////////////////////////
176 // Slip funktioner
177
178
179 void slip_reset(void)
180 {
181 global_comm_error = 0;
182 global_comm_slipstate = SlipNormal;
183 global_comm_ready = 0;
184 global_comm_length = 0;
185 memset(global_comm_buffer, 0, BUFFERLEN);
186 }
187
188 void slip_highlevel_protocol(void)
189 {
190 unsigned char cmd,target,data;
191
192 cmd = global_comm_buffer[0] & 0x0F;
193 target = ( global_comm_buffer[0] >> 4 ) & 0x0F;
194 data = global_comm_buffer[1];
195
196 if (cmd == CmdRead || cmd == CmdWrite)
197 {
198 //sæt standart længde - da længden kun varierer ved læsning af potmeter
199 if (cmd == CmdRead)
200 global_comm_length = 2;
201 else
202 global_comm_length = 1;
203
204 switch(target)
205 {
206 case TLed3:
207 if (cmd == CmdRead)
208 global_comm_buffer[1] = global_led_0;
209 else
210 global_led_0 = data;
211 break;
212 case TLed4:
213 if(cmd == CmdRead)
214 global_comm_buffer[1] = global_led_1;
215 else
216 global_led_1 = data;
217 break;
218 case TLed5:
219 if (cmd == CmdRead)
220 global_comm_buffer[1] = global_led_2;
221 else
222 global_led_2 = data;
223 break;
224 case TSwitch2:
225 if (cmd == CmdRead)
226 global_comm_buffer[1] = !RA4;
227 else
228 global_comm_error = 1;
229 break;
230 case TSwitch3:
231 if (cmd == CmdRead)
232 global_comm_buffer[1] = !RB0;
233 else
234 global_comm_error = 1;
235 break;
236 case TPotmeter:
237 if (cmd == CmdRead)
238 {
239 global_comm_buffer[1] = global_potmeter_hi;
240 global_comm_buffer[2] = global_potmeter_lo;
241 global_comm_length = 3;
242 }
243 else
244 global_comm_error = 1;
245 break;
246 case TTemp:
247 if (cmd == CmdRead)
248 global_comm_buffer[1] = global_temp;
249 else
250 global_comm_error = 1;
251 break;
252 case TBaud:
253 if (cmd == CmdRead)
254 global_comm_error = 1;
255 else
256 {
257 //we can only handle 1200,2400,9600,19200
258 if (data == 0 || data == 1 || data == 3 || data == 4)
259 {
260 global_reset_baudrate = 1;
261 global_comm_baudrate = data;
262 }
263 else
264 global_comm_error = 1;
265 }
266 break;
267 default:
268 global_comm_error = 1;
269
270 }
271 }
272 else //kommandoen var noget andet end read/write
273 {
274 global_comm_error = 1;
275 }
276
277
278 if (global_comm_error == 1) //we saw an error
279 {
280 global_comm_buffer[0] = CmdNAck | target<<4;
281 global_comm_length = 1;
282 }
283 else
284 {
285 global_comm_buffer[0] = CmdAck | target<<4; //skriv acknowledge feltet
286 }
287 }
288
289 void slip_send_byte(char data)
290 {
291 TXREG = data;
292 while (TRMT==0) ;
293 DelayUs(20);
294 }
295
296 void slip_send_response(void)
297 {
298 int i;
299 for (i=0; i< global_comm_length;i++)
300 {
301 if ( global_comm_buffer[i] == SLIP_ESC)
302 {
303 slip_send_byte(SLIP_ESC);
304 slip_send_byte(SLIP_ESCAPED_ESC);
305 }
306 else if (global_comm_buffer[i] == SLIP_END)
307 {
308 slip_send_byte(SLIP_ESC);
309 slip_send_byte(SLIP_ESCAPED_END);
310 }
311 else
312 {
313 slip_send_byte( global_comm_buffer[i]);
314 }
315 }
316
317 slip_send_byte(SLIP_END);
318 }
319
320 ///////////////////////////////////////////////////////////////////
321 // init funktioner
322
323 void interrupt_init(void)
324 {
325 TXIE = 0; //Disable AUX TX interrupt - testes med TXIF;
326 RCIE = 1; //Enable AUX Recieve interrupt - testes med RCIF;
327
328 IPEN = 0; // IPEN=Interrupt Priority ENable bit - her bruges ingen prioritet
329
330 PEIE = 1; // PEIE = PEriphal Interrupt Enable
331
332 TXIF = 0; //nulstil intterupt flag
333 RCIF = 0;
334
335 TMR1IE = 1; // Timer 1
336
337 GIE = 1; //Global interrupt enable bit
338 }
339
340 void serial_init(void)
341 {
342 SPEN = 0; //Make sure serial port is disabled
343
344 // snupset fra Kim H Pedersens serialmain.c
345 // Set Port C bit 6 output (TxD) and bit 7 input (RxD)
346 TRISC6 = 0;
347 TRISC7 = 1;
348
349 SPBRG = 25; // x = Fosc/(16 * Baud Rate) - 1
350 // x = 4000000/(16 * 9600) - 1
351 // x = 25.0417 ~ 25
352 // Baud Rate = Fosc/(16 * (x+1))
353 // Baud Rate = 4000000/(16 * (25+1))
354 // Baud Rate = 9615
355 TXSTA = 0x24; // TXSTA7 = 0 Don't care in asynchronous
356 // TXSTA6 = 0 8-bit transmission
357 // TXSTA5 = 1 Transmit enabled
358 // TXSTA4 = 0 Asynchronous mode
359 // TXSTA3 = 0 Unimplemented
360 // TXSTA2 = 1 High speed
361 // TXSTA1 = 0 TSR empty
362 // TXSTA0 = 0 9th bit */
363 RCSTA = 0x90; // RCSTA7 = 0 Serial port disabled
364 // RCSTA6 = 0 8-bit reception
365 // RCSTA5 = 0 Don't care in asynchronous
366 // RCSTA4 = 1 Receiver enabled
367 // RCSTA3 = 0 Don't care (8-bit operation)
368 // RCSTA2 = 0 No framing error
369 // RCSTA1 = 0 Overrun error bit
370 // RCSTA0 = 0 9th bit */
371
372 //config completed
373 SPEN = 1; //Enable Serial port
374 }
375
376 /* basic I/O ports */
377 void io_init(void)
378 {
379 TRISB3 = 0; //LED ports = output
380 TRISB2 = 0;
381 TRISB1 = 0;
382
383 TRISB0 = 1; //Switch porte = input
384 TRISA4 = 1;
385 }
386
387 void ad_init(void)
388 {
389 // AD Conversion clock
390 ADCS0 = 0;
391 ADCS1 = 0;
392 ADCS2 = 0;
393
394 //Select AN0/RA0 for AD source
395 CHS0=0;
396 CHS1=0;
397 CHS2=0;
398
399 //Only AN0 is selected for AD and with Vdd/Vss as limits
400 PCFG0=0;
401 PCFG1=1;
402 PCFG2=1;
403 PCFG3=1;
404
405 //Result is right justified
406 ADFM=1;
407
408 //Fire up for A/D converter module
409 ADON=1;
410 }
411
412 void i2c_init(void)
413 {
414 // I2C_MODULE hører hjemme i i2c.h
415 #ifdef I2C_MODULE
416 SSPMode(MASTER_MODE);
417 SSPEN = 1;
418 CKP = 1;
419 #else
420 SCL_DIR = I2C_OUTPUT;
421 SDA_DIR = I2C_OUTPUT;
422 SDA = 0;
423 SCL = 0;
424 #endif
425 }
426
427 void timer_init(void)
428 {
429 TMR1CS = 1; //use external clock
430
431 T1CKPS1 = 1; //1:8 prescale
432 T1CKPS0 = 1;
433
434 TMR1H = 0xEF;
435 TMR1L = 0xFF;
436
437 T1OSCEN = 1; //enable oscillator circuit
438 RD16 = 0; //normal 8 bit writes
439 TMR1ON = 1;
440 }
441
442 ///////////////////////////////////////////////////////////////////
443 // Gennerelle funktioner
444
445
446 char ReadTemp(void)
447 {
448 char temp;
449 i2c_WriteTo(TC74); //write to, will automatically send a start condition
450 i2c_PutByte(0x00); //tell TC74 we want to read
451 i2c_ReadFrom(TC74);
452 temp = i2c_GetByte(I2C_LAST);
453 i2c_Stop(); //assert a stop condition on SDA & SCL
454 return temp;
455 }
456
457
458
459 void update_lcd(void)
460 {
461 static char current_row = 0;
462 static char current_char = 0;
463
464 if ( current_char >= BUFFERLEN || global_lcd_buffer[current_row][current_char] == 0 )
465 {
466 current_row++;
467 current_char = 0;
468 lcd_goto(0x40);
469 }
470
471 if (current_row >= 2)
472 {
473 sprintf(global_lcd_buffer[1], "T=%02d, P=%d ", global_temp, (global_potmeter_hi<<8) | global_potmeter_lo);
474 lcd_goto(0x00);
475 current_row = 0;
476 }
477
478 lcd_putch(global_lcd_buffer[current_row][current_char]);
479 current_char++;
480 }
481
482 void reset_baudrate(void)
483 {
484 SPEN = 0; //disable serial port
485
486 //set baudrate generator, i henhold til side 171 af PIC18F452 dokumentationen
487 switch (global_comm_baudrate)
488 {
489 case Baud1200:
490 SPBRG = 207;
491 strcpy(global_lcd_buffer[0],"Baud=1200 ");
492 break;
493 case Baud2400:
494 SPBRG = 103;
495 strcpy(global_lcd_buffer[0],"Baud=2400 ");
496 break;
497 case Baud9600:
498 SPBRG = 25;
499 strcpy(global_lcd_buffer[0],"Baud=9600 ");
500 break;
501 case Baud19200:
502 SPBRG = 12;
503 strcpy(global_lcd_buffer[0],"Baud=19200");
504 break;
505 default:
506 strcpy(global_lcd_buffer[0],"Baud=9600 ");
507 SPBRG = 25; // this should not be possible, but default to 9600 anyway
508 }
509 SPEN = 1; // enable the serial port again
510 }
511
512 ///////////////////////////////////////////////////////////////////
513 //Main
514
515
516 void main(void)
517 {
518 lcd_init(0); //init in 4-bit mode
519 i2c_init();
520 serial_init(); //9600 8N1
521 ad_init();
522 io_init();
523 timer_init();
524 interrupt_init();
525
526
527 slip_reset(); //take SLIP FSM into normal state
528 global_comm_baudrate = Baud9600; //default baudrate = 9600 (allready set in serial_init)
529 global_reset_baudrate = 0;
530
531 // initialisation completed and we are ready to recieve commands - enable serial reception
532 CREN = 1;
533
534 strcpy(global_lcd_buffer[0], "Baud=9600 ");
535 while (1)
536 {
537 if (global_comm_ready == 1)
538 {
539 slip_highlevel_protocol(); //parse the slip frame recieved & generate response
540 slip_send_response();
541 slip_reset();
542 }
543
544 if ( global_reset_baudrate == 1)
545 {
546 reset_baudrate();
547 global_reset_baudrate = 0;
548 }
549
550 //sæt status på dioder ud fra styre variablerne
551 RB1 = global_led_0;
552 RB2 = global_led_1;
553 RB3 = global_led_2;
554
555 global_temp = ReadTemp();
556
557 //potmeter
558 if (GODONE ==0 )//hvis A/D-conv er færdig
559 {
560
561 global_potmeter_hi = ADRESH;//gem AD resultat
562 global_potmeter_lo = ADRESL;
563 GODONE = 1; //start ny konverering
564 }
565
566 update_lcd();
567 }
568 }

  ViewVC Help
Powered by ViewVC 1.1.20