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

Annotation of /trunk/PIC/main.c

Parent Directory Parent Directory | Revision Log Revision Log


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

  ViewVC Help
Powered by ViewVC 1.1.20