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

Diff of /trunk/PIC/main.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 2 by torben, Mon Jan 29 09:45:25 2007 UTC revision 26 by torben, Wed Jan 31 10:45:20 2007 UTC
# Line 1  Line 1 
1  /* H7 -projekt opgave */  /* H7 -projekt opgave */
2    
3    ///////////////////////////////////////////////////////////////////////
4    //Includes
5  #include <pic18.h>  #include <pic18.h>
6    #include <string.h>
7    
8  #include "delay.h"  #include "delay.h"
9  #include "i2c.h"  #include "i2c.h"
10  #include "lcd.h"  #include "lcd.h"
11    
12    /////////////////////////////////////////////////////////////////////
13    //Defines
14  #define TC74 0x9A /* I2C TC74 IC */  #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)  void i2c_init(void)
412  {  {
413    // I2C_MODULE hører hjemme i i2c.h
414  #ifdef I2C_MODULE  #ifdef I2C_MODULE
415      SSPMode(MASTER_MODE);      SSPMode(MASTER_MODE);
416      SSPEN = 1;      SSPEN = 1;
# Line 22  void i2c_init(void) Line 423  void i2c_init(void)
423  #endif  #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)  char ReadTemp(void)
446  {  {
447          char temp;          char temp;
448          i2c_WriteTo(TC74);          i2c_WriteTo(TC74); //write to, will automatically send a start condition
449          i2c_PutByte(0x00); //tell TC74 we want to read          i2c_PutByte(0x00); //tell TC74 we want to read
450          i2c_ReadFrom(TC74);          i2c_ReadFrom(TC74);
451          temp = i2c_GetByte(I2C_LAST);          temp = i2c_GetByte(I2C_LAST);
452          i2c_Stop(); //assert a stop condition on SDA & SCL          i2c_Stop(); //assert a stop condition on SDA & SCL
453          return temp;          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)  void main(void)
490  {  {
491          lcd_init(0); //init in 4-bit mode          lcd_init(0); //init in 4-bit mode
492          i2c_init();          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)          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  }  }
537    

Legend:
Removed from v.2  
changed lines
  Added in v.26

  ViewVC Help
Powered by ViewVC 1.1.20