/* H7 -projekt opgave */ /////////////////////////////////////////////////////////////////////// //Includes #include #include #include "delay.h" #include "i2c.h" #include "lcd.h" ///////////////////////////////////////////////////////////////////// //Defines #define TC74 0x9A /* I2C TC74 IC */ #define SLIP_END 192 #define SLIP_ESC 219 #define SLIP_ESCAPED_END 220 #define SLIP_ESCAPED_ESC 221 #define BUFFERLEN 16 ////////////////////////////////////////////////////////////////// // Enumerations enum SlipState{ SlipNormal, SlipEscaped, SlipError, SlipStopped }; enum BaudRates{ Baud1200, Baud2400, Baud4800, Baud9600, Baud19200 }; enum Commands{ CmdRead, CmdWrite, CmdAck, CmdNAck }; enum Targets { TLed3, //0 TLed4, TLed5, TSwitch2, TSwitch3, TPotmeter, TTemp, TBaud = 10 }; ////////////////////////////////////////////////////////////////// //Globale data // Alle globale variabler bruger "global_" som prefix unsigned char global_comm_buffer[BUFFERLEN]; unsigned char global_comm_length; unsigned char global_comm_index; bit global_comm_ready; bit global_comm_error; unsigned char global_comm_slipstate; unsigned char global_comm_currentrate; unsigned char global_lcd_buffer[20]; unsigned char global_lcd_index; bit global_led_0; bit global_led_1; bit global_led_2; bit global_reset_baudrate; char global_temp; unsigned char global_potmeter_hi; unsigned char global_potmeter_lo; /////////////////////////////////////////////////////////////////// // Interrupt funktioner void recieve_interrupt(void) { unsigned char data = RCREG; RB2 = !RB2; switch (global_comm_slipstate) { case SlipNormal: if (data == SLIP_END) { global_comm_ready = 1; global_comm_slipstate = SlipStopped; } else if (data == SLIP_ESC) { global_comm_slipstate = SlipEscaped; } else global_comm_buffer[ global_comm_length++ ] = data; break; case SlipEscaped: if (data == SLIP_ESCAPED_ESC) { global_comm_buffer[ global_comm_length++ ] = SLIP_ESC; global_comm_slipstate = SlipNormal; } else if (data ==SLIP_ESCAPED_END) { global_comm_buffer[ global_comm_length++ ] = SLIP_END; global_comm_slipstate = SlipNormal; } else { global_comm_slipstate = SlipError; } case SlipError: if (data == SLIP_END) { global_comm_error = 1; global_comm_slipstate = SlipStopped; global_comm_ready = 1; } case SlipStopped: //vi var ikke klar til at modtage data global_comm_error = 1; } } /* void transmit_interrupt(void) { RB2 = !RB2; } */ void interrupt interrupt_handler(void) { if (RCIF == 1) { recieve_interrupt(); RCIF = 0; } /*if (TXIF == 1) { transmit_interrupt(); TXIF = 0; } */ } /////////////////////////////////////////////////////////////////// // Slip funktioner void slip_reset(void) { global_comm_error = 0; global_comm_slipstate = SlipNormal; global_comm_ready = 0; global_comm_length = 0; memset(global_comm_buffer, 0, BUFFERLEN); } void slip_highlevel_protocol(void) { unsigned char cmd,target,data; cmd = global_comm_buffer[0] & 0x0F; target = ( global_comm_buffer[0] >> 4 ) & 0x0F; data = global_comm_buffer[1]; if (cmd == CmdRead || cmd == CmdWrite) { //sæt standart længde - da længden kun varierer ved læsning af potmeter if (cmd == CmdRead) global_comm_length = 2; else global_comm_length = 1; switch(target) { case TLed3: if (cmd == CmdRead) global_comm_buffer[1] = global_led_0; else global_led_0 = data; break; case TLed4: if(cmd == CmdRead) global_comm_buffer[1] = global_led_1; else global_led_1 = data; break; case TLed5: if (cmd == CmdRead) global_comm_buffer[1] = global_led_2; else global_led_2 = data; break; case TSwitch2: if (cmd == CmdRead) global_comm_buffer[1] = RA4; else global_comm_error = 1; break; case TSwitch3: if (cmd == CmdRead) global_comm_buffer[1] = RB0; else global_comm_error = 1; break; case TPotmeter: if (cmd == CmdRead) { global_comm_buffer[1] = global_potmeter_hi; global_comm_buffer[2] = global_potmeter_lo; global_comm_length = 3; } else global_comm_error = 1; break; case TTemp: if (cmd == CmdRead) global_comm_buffer[1] = global_temp; else global_comm_error = 1; break; case TBaud: if (cmd == CmdRead) global_comm_error = 1; else { //we can only handle 1200,2400,9600,19200 if (data == 0 || data == 1 || data == 3 || data == 4) global_reset_baudrate = 1; else global_comm_error = 1; } break; default: global_comm_error = 1; } } else //kommandoen var noget andet end read/write { global_comm_error = 1; } if (global_comm_error == 1) //we saw an error { global_comm_buffer[0] = CmdNAck | target<<4; global_comm_length = 1; } else { global_comm_buffer[0] = CmdAck | target<<4; //skriv acknowledge feltet } } void slip_send_byte(char data) { TXREG = data; while (TRMT==0) ; DelayUs(20); } void slip_send_response(void) { int i; for (i=0; i< global_comm_length;i++) { if ( global_comm_buffer[i] == SLIP_ESC) { slip_send_byte(SLIP_ESC); slip_send_byte(SLIP_ESCAPED_ESC); } else if (global_comm_buffer[i] == SLIP_END) { slip_send_byte(SLIP_ESC); slip_send_byte(SLIP_ESCAPED_END); } else { slip_send_byte( global_comm_buffer[i]); } } slip_send_byte(SLIP_END); } /////////////////////////////////////////////////////////////////// // Gennerelle funktioner void interrupt_init(void) { TXIE = 0; //Disable AUX TX interrupt - testes med TXIF; RCIE = 1; //Enable AUX Recieve interrupt - testes med RCIF; IPEN = 0; // IPEN=Interrupt Priority ENable bit - her bruges ingen prioritet PEIE = 1; // PEIE = PEriphal Interrupt Enable TXIF = 0; //nulstil intterupt flag RCIF = 0; GIE = 1; //Global interrupt enable bit } void serial_init(void) { SPEN = 0; //Make sure serial port is disabled // snupset fra Kim H Pedersens serialmain.c // Set Port C bit 6 output (TxD) and bit 7 input (RxD) TRISC6 = 0; TRISC7 = 1; SPBRG = 25; // x = Fosc/(16 * Baud Rate) - 1 // x = 4000000/(16 * 9600) - 1 // x = 25.0417 ~ 25 // Baud Rate = Fosc/(16 * (x+1)) // Baud Rate = 4000000/(16 * (25+1)) // Baud Rate = 9615 TXSTA = 0x24; // TXSTA7 = 0 Don't care in asynchronous // TXSTA6 = 0 8-bit transmission // TXSTA5 = 1 Transmit enabled // TXSTA4 = 0 Asynchronous mode // TXSTA3 = 0 Unimplemented // TXSTA2 = 1 High speed // TXSTA1 = 0 TSR empty // TXSTA0 = 0 9th bit */ RCSTA = 0x90; // RCSTA7 = 0 Serial port disabled // RCSTA6 = 0 8-bit reception // RCSTA5 = 0 Don't care in asynchronous // RCSTA4 = 1 Receiver enabled // RCSTA3 = 0 Don't care (8-bit operation) // RCSTA2 = 0 No framing error // RCSTA1 = 0 Overrun error bit // RCSTA0 = 0 9th bit */ //config completed SPEN = 1; //Enable Serial port } /* basic I/O ports */ void io_init(void) { TRISB3 = 0; //LED ports = output TRISB2 = 0; TRISB1 = 0; TRISB0 = 1; //Switch porte = input TRISA0 = 1; } void ad_init(void) { // AD Conversion clock ADCS0 = 0; ADCS1 = 0; ADCS2 = 0; //Select AN0/RA0 for AD source CHS0=0; CHS1=0; CHS2=0; //Only AN0 is selected for AD and with Vdd/Vss as limits PCFG0=0; PCFG1=1; PCFG2=1; PCFG3=1; //Result is right justified ADFM=1; //Fire up for A/D converter module ADON=1; } void i2c_init(void) { // I2C_MODULE hører hjemme i i2c.h #ifdef I2C_MODULE SSPMode(MASTER_MODE); SSPEN = 1; CKP = 1; #else SCL_DIR = I2C_OUTPUT; SDA_DIR = I2C_OUTPUT; SDA = 0; SCL = 0; #endif } char ReadTemp(void) { char temp; i2c_WriteTo(TC74); //write to, will automatically send a start condition i2c_PutByte(0x00); //tell TC74 we want to read i2c_ReadFrom(TC74); temp = i2c_GetByte(I2C_LAST); i2c_Stop(); //assert a stop condition on SDA & SCL return temp; } /////////////////////////////////////////////////////////////////// //Main void main(void) { char lcdbuf[20]; int i; lcd_init(0); //init in 4-bit mode i2c_init(); serial_init(); //9600 8N1 ad_init(); io_init(); interrupt_init(); slip_reset(); //take SLIP FSM into normal state global_comm_currentrate = Baud9600; //default baudrate = 9600 global_reset_baudrate = 0; // initialisation completed and we are ready to recieve commands - enable serial reception CREN = 1; while (1) { if (global_comm_ready == 1) { slip_highlevel_protocol(); //parse the slip frame recieved & generate response slip_send_response(); slip_reset(); } if ( global_reset_baudrate == 1) { } RB1 = global_led_0; RB2 = global_led_1; RB3 = global_led_2; global_temp = ReadTemp(); //potmeter if (GODONE ==0 )//hvis A/D-conv er færdig { global_potmeter_hi = ADRESH;//gem AD resultat global_potmeter_lo = ADRESL; GODONE = 1; //start ny konverering } //just for fun - blink RB3 // RB3 = !RB3; // DelayMs(250); } }