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

Contents of /trunk/PIC/main.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 26 - (show annotations) (download)
Wed Jan 31 10:45:20 2007 UTC (17 years, 3 months ago) by torben
File MIME type: text/plain
File size: 10926 byte(s)
Implemented change of baud rate
1 /* H7 -projekt opgave */
2
3 ///////////////////////////////////////////////////////////////////////
4 //Includes
5 #include <pic18.h>
6 #include <string.h>
7
8 #include "delay.h"
9 #include "i2c.h"
10 #include "lcd.h"
11
12 /////////////////////////////////////////////////////////////////////
13 //Defines
14 #define TC74 0x9A /* I2C TC74 IC */
15
16 #define SLIP_END 192
17 #define SLIP_ESC 219
18 #define SLIP_ESCAPED_END 220
19 #define SLIP_ESCAPED_ESC 221
20
21 #define BUFFERLEN 16
22
23 //////////////////////////////////////////////////////////////////
24 // Enumerations
25
26 enum SlipState{
27 SlipNormal,
28 SlipEscaped,
29 SlipError,
30 SlipStopped
31 };
32
33 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 //////////////////////////////////////////////////////////////////
60 //Globale data
61 // Alle globale variabler bruger "global_" som prefix
62
63 unsigned char global_comm_buffer[BUFFERLEN];
64 unsigned char global_comm_length;
65
66 bit global_comm_ready;
67 bit global_comm_error;
68
69 unsigned char global_comm_slipstate;
70 unsigned char global_comm_baudrate;
71
72 unsigned char global_lcd_buffer[2][20];
73
74
75 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 ///////////////////////////////////////////////////////////////////
86 // Interrupt funktioner
87
88 void recieve_interrupt(void)
89 {
90 unsigned char data = RCREG;
91
92 if (global_comm_length == BUFFERLEN) //avoid buffer overrun
93 global_comm_slipstate == SlipError;
94
95 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 }
137
138 /*
139 void transmit_interrupt(void)
140 {
141 RB2 = !RB2;
142 }
143 */
144 //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 void interrupt interrupt_handler(void)
154 {
155 if (RCIF == 1)
156 {
157 recieve_interrupt();
158 RCIF = 0;
159 }
160 /*if (TXIF == 1)
161 {
162 transmit_interrupt();
163 TXIF = 0;
164 }
165 */
166
167 if (TMR1IF == 1)
168 {
169 timer1_interrupt();
170 TMR1IF = 0;
171 }
172 }
173
174 ///////////////////////////////////////////////////////////////////
175 // Slip funktioner
176
177
178 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 {
259 global_reset_baudrate = 1;
260 global_comm_baudrate = data;
261 }
262 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 // init funktioner
321
322 void interrupt_init(void)
323 {
324 TXIE = 0; //Disable AUX TX interrupt - testes med TXIF;
325 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
334 TMR1IE = 1; // Timer 1
335
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
371 //config completed
372 SPEN = 1; //Enable Serial port
373 }
374
375 /* 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
386 void ad_init(void)
387 {
388 // AD Conversion clock
389 ADCS0 = 0;
390 ADCS1 = 0;
391 ADCS2 = 0;
392
393 //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 void i2c_init(void)
412 {
413 // I2C_MODULE hører hjemme i i2c.h
414 #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 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
436 T1OSCEN = 1; //enable oscillator circuit
437 RD16 = 0; //normal 8 bit writes
438 TMR1ON = 1;
439 }
440
441 ///////////////////////////////////////////////////////////////////
442 // Gennerelle funktioner
443
444
445 char ReadTemp(void)
446 {
447 char temp;
448 i2c_WriteTo(TC74); //write to, will automatically send a start condition
449 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 }
455
456 void update_lcd(void)
457 {
458 }
459
460 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 ///////////////////////////////////////////////////////////////////
486 //Main
487
488
489 void main(void)
490 {
491 lcd_init(0); //init in 4-bit mode
492 i2c_init();
493 serial_init(); //9600 8N1
494 ad_init();
495 io_init();
496 timer_init();
497 interrupt_init();
498
499
500 slip_reset(); //take SLIP FSM into normal state
501 global_comm_baudrate = Baud9600; //default baudrate = 9600 (allready set in serial_init)
502 global_reset_baudrate = 0;
503
504 // initialisation completed and we are ready to recieve commands - enable serial reception
505 CREN = 1;
506
507 while (1)
508 {
509 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 reset_baudrate();
519 }
520
521 RB1 = global_led_0;
522 RB2 = global_led_1;
523 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 }
536 }

  ViewVC Help
Powered by ViewVC 1.1.20