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

Annotation of /trunk/PIC/main.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 31 - (hide annotations) (download)
Wed Jan 31 13:19:36 2007 UTC (17 years, 4 months ago) by torben
File MIME type: text/plain
File size: 11778 byte(s)
Altered format of data displayed on the LCD
1 torben 2 /* H7 -projekt opgave */
2 torben 10
3     ///////////////////////////////////////////////////////////////////////
4     //Includes
5 torben 2 #include <pic18.h>
6 torben 17 #include <string.h>
7 torben 27 #include <stdio.h>
8 torben 17
9 torben 2 #include "delay.h"
10     #include "i2c.h"
11     #include "lcd.h"
12    
13 torben 10 /////////////////////////////////////////////////////////////////////
14     //Defines
15 torben 2 #define TC74 0x9A /* I2C TC74 IC */
16    
17 torben 17 #define SLIP_END 192
18     #define SLIP_ESC 219
19     #define SLIP_ESCAPED_END 220
20     #define SLIP_ESCAPED_ESC 221
21 torben 10
22 torben 17 #define BUFFERLEN 16
23    
24     //////////////////////////////////////////////////////////////////
25     // Enumerations
26    
27 torben 10 enum SlipState{
28     SlipNormal,
29     SlipEscaped,
30     SlipError,
31     SlipStopped
32     };
33    
34 torben 17 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 torben 10 //////////////////////////////////////////////////////////////////
61     //Globale data
62     // Alle globale variabler bruger "global_" som prefix
63 torben 17
64     unsigned char global_comm_buffer[BUFFERLEN];
65 torben 10 unsigned char global_comm_length;
66 torben 17
67 torben 10 bit global_comm_ready;
68 torben 17 bit global_comm_error;
69 torben 10
70 torben 17 unsigned char global_comm_slipstate;
71 torben 26 unsigned char global_comm_baudrate;
72 torben 10
73 torben 27 unsigned char global_lcd_buffer[2][BUFFERLEN];
74 torben 10
75    
76 torben 17 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 torben 10 ///////////////////////////////////////////////////////////////////
87     // Interrupt funktioner
88    
89     void recieve_interrupt(void)
90     {
91 torben 17 unsigned char data = RCREG;
92    
93 torben 26 if (global_comm_length == BUFFERLEN) //avoid buffer overrun
94     global_comm_slipstate == SlipError;
95    
96 torben 17 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 torben 10 }
138    
139 torben 17 /*
140 torben 10 void transmit_interrupt(void)
141     {
142 torben 17 RB2 = !RB2;
143 torben 10 }
144 torben 17 */
145 torben 22 //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 torben 10 void interrupt interrupt_handler(void)
155     {
156     if (RCIF == 1)
157     {
158     recieve_interrupt();
159     RCIF = 0;
160     }
161 torben 17 /*if (TXIF == 1)
162 torben 10 {
163     transmit_interrupt();
164     TXIF = 0;
165     }
166 torben 17 */
167 torben 22
168     if (TMR1IF == 1)
169     {
170     timer1_interrupt();
171     TMR1IF = 0;
172     }
173 torben 10 }
174    
175     ///////////////////////////////////////////////////////////////////
176 torben 17 // Slip funktioner
177 torben 10
178 torben 26
179 torben 17 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 torben 27 global_comm_buffer[1] = !RA4;
227 torben 17 else
228     global_comm_error = 1;
229     break;
230     case TSwitch3:
231     if (cmd == CmdRead)
232 torben 27 global_comm_buffer[1] = !RB0;
233 torben 17 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 torben 26 {
260 torben 17 global_reset_baudrate = 1;
261 torben 26 global_comm_baudrate = data;
262     }
263 torben 17 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 torben 26 // init funktioner
322 torben 17
323 torben 10 void interrupt_init(void)
324     {
325 torben 17 TXIE = 0; //Disable AUX TX interrupt - testes med TXIF;
326 torben 10 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 torben 22
335     TMR1IE = 1; // Timer 1
336 torben 10
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 torben 17
372 torben 10 //config completed
373     SPEN = 1; //Enable Serial port
374     }
375    
376 torben 17 /* 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     TRISA0 = 1;
385     }
386 torben 10
387 torben 17 void ad_init(void)
388     {
389     // AD Conversion clock
390     ADCS0 = 0;
391     ADCS1 = 0;
392     ADCS2 = 0;
393 torben 10
394 torben 17 //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 torben 2 void i2c_init(void)
413     {
414 torben 17 // I2C_MODULE hører hjemme i i2c.h
415 torben 2 #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 torben 22 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 torben 10
437 torben 22 T1OSCEN = 1; //enable oscillator circuit
438     RD16 = 0; //normal 8 bit writes
439     TMR1ON = 1;
440     }
441 torben 10
442 torben 26 ///////////////////////////////////////////////////////////////////
443     // Gennerelle funktioner
444    
445    
446 torben 2 char ReadTemp(void)
447     {
448     char temp;
449 torben 10 i2c_WriteTo(TC74); //write to, will automatically send a start condition
450 torben 2 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 torben 10 }
456    
457 torben 27
458    
459 torben 26 void update_lcd(void)
460     {
461 torben 27 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 torben 31 sprintf(global_lcd_buffer[1], "T=%02d, P=%d ", global_temp, (global_potmeter_hi<<8) | global_potmeter_lo);
474 torben 27 lcd_goto(0x00);
475     current_row = 0;
476     }
477    
478     lcd_putch(global_lcd_buffer[current_row][current_char]);
479     current_char++;
480 torben 26 }
481 torben 10
482 torben 26 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 torben 27 strcpy(global_lcd_buffer[0],"Baud=1200 ");
492 torben 26 break;
493     case Baud2400:
494     SPBRG = 103;
495 torben 27 strcpy(global_lcd_buffer[0],"Baud=2400 ");
496 torben 26 break;
497     case Baud9600:
498     SPBRG = 25;
499 torben 27 strcpy(global_lcd_buffer[0],"Baud=9600 ");
500 torben 26 break;
501     case Baud19200:
502     SPBRG = 12;
503 torben 27 strcpy(global_lcd_buffer[0],"Baud=19200");
504 torben 26 break;
505     default:
506 torben 27 strcpy(global_lcd_buffer[0],"Baud=9600 ");
507 torben 26 SPBRG = 25; // this should not be possible, but default to 9600 anyway
508     }
509     SPEN = 1; // enable the serial port again
510     }
511    
512 torben 10 ///////////////////////////////////////////////////////////////////
513     //Main
514 torben 2
515 torben 10
516 torben 2 void main(void)
517     {
518     lcd_init(0); //init in 4-bit mode
519     i2c_init();
520 torben 10 serial_init(); //9600 8N1
521 torben 17 ad_init();
522     io_init();
523 torben 22 timer_init();
524 torben 10 interrupt_init();
525    
526    
527 torben 17 slip_reset(); //take SLIP FSM into normal state
528 torben 26 global_comm_baudrate = Baud9600; //default baudrate = 9600 (allready set in serial_init)
529 torben 17 global_reset_baudrate = 0;
530 torben 10
531     // initialisation completed and we are ready to recieve commands - enable serial reception
532     CREN = 1;
533    
534 torben 27 strcpy(global_lcd_buffer[0], "Baud=9600 ");
535 torben 2 while (1)
536     {
537 torben 17 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 torben 26 reset_baudrate();
547 torben 27 global_reset_baudrate = 0;
548 torben 17 }
549    
550     RB1 = global_led_0;
551 torben 26 RB2 = global_led_1;
552 torben 17 RB3 = global_led_2;
553    
554     global_temp = ReadTemp();
555    
556     //potmeter
557     if (GODONE ==0 )//hvis A/D-conv er færdig
558     {
559    
560     global_potmeter_hi = ADRESH;//gem AD resultat
561     global_potmeter_lo = ADRESL;
562     GODONE = 1; //start ny konverering
563     }
564 torben 27
565     update_lcd();
566 torben 2 }
567     }

  ViewVC Help
Powered by ViewVC 1.1.20