This is a multi-part message in MIME format. ------=_NextPart_000_003B_01C124D7.9DD8BC40 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit Hi all, I am a total PIC newbie and have a couple of questions. I am trying to develop my first PIC project in Hi-tech C. I want to create a library using the delay.c delay.h and iserial.c (attached) files. The problem is I can't create the .obj file for the iserial.c file as I keep getting the following errors. Warning[000 ] file c:\mydocu~1\personal\robotics\picstu~1\librarys\serial~1\iserial.c 114 : arithmetic overflow in constant expression Warning[000 ] file c:\mydocu~1\personal\robotics\picstu~1\librarys\serial~1\iserial.c 162 : arithmetic overflow in constant expression I can see that the code is trying to set the timer to a negative value, but don't understand why? Could anyone give me any pointers here. Secondly, the iserial.c file contains an interrupt routine. This is pretty much my first time dealing with interrupts, but from reading the hi-tech picc lite manual I see that you can only have one ISR on the 16F84. This leads me to the question, what happens if you are expecting interrupts from multiple sources eg. timer, pins, etc... Is it best to just build one huge ISR and use a switch statement (or something similar) to execute the appropriate part depending on what caused the interrupt? Thanks for any help you can provide! Regards, James Fitzsimons ------=_NextPart_000_003B_01C124D7.9DD8BC40 Content-Type: application/octet-stream; name="Iserial.c" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="Iserial.c" /* * Serial port driver for 16Cxx mid-range PIC devices * (Interrupt-driven) * * Copyright (C) 1997 HI-TECH Software. * Author: Jeremy Bennett *=09 * Comments: *=09 * The major limiting factor in how fast you can go is * the need to sample the RxData line at several times the * desired baud rate when looking for a start bit. 8 times is * used here - less may be possible. With 8 times sampling, the * maximum baud rate that can be reliably achieved with a 4MHz * PIC is 1200 baud. This results in about a 100uS interrupt interval, * with about 30uS used in the interrupt service routine. *=09 * Of course once the start bit has been recognised, the interrupt * interval could be dropped back to the baud rate, but since it's * pretty axiomatic that a PIC will wait for characters much more * than it will actually receive them, this wouldn't help much, and * would make for additional complication. *=09 * Another approach would be to use the external interrupt pin for the = serial input, * and start timing from the interrupt. This would have to be carefully = done * to allow simultaneous transmission, though. *=09 * This module compiles to about 125 words on a PIC16C84. *=09 */ #include #include #ifdef _16C71 bit adcconversionflag; // Used by main so it knows when to do a = conversion. #endif /************************************* * Tunable parameters */ /* Transmit and Receive port bits */ static volatile bit TxData @ (unsigned)&PORTA*8+3; /* bit3 in port A */ static volatile bit RxData @ (unsigned)&PORTA*8+2; /* bit2 in port A */ #define XTAL 4000000 /* Crystal frequency (Hz). */ #define BRATE 1200 /* Baud rate. */ #define RX_OVERSAMPLE 8 /* Amount of oversampling the receiver does. = Must be a power of two */ #define SAMPLE_ADC 200 /* sample the ADC this many interrupts /* * Don't change anything else ************************************/ #define TIMER_VALUE XTAL / (4 * BRATE * RX_OVERSAMPLE) #define TRANSMIT_NUM_BITS 13 // 1 start bit + 8 data bits + 2 stop bits = + safe. #if (RX_OVERSAMPLE-1)&RX_OVERSAMPLE #error RX_OVERSAMPLE_value must be a power of 2 #endif // Receiver states. enum receiver_state { RS_HAVE_NOTHING, RS_WAIT_HALF_A_BIT, RS_HAVE_STARTBIT, RS_WAIT_FOR_STOP =3D RS_HAVE_STARTBIT+8 }; static unsigned char sendbuffer; // Where the character to sent is = stored. static unsigned char receivebuffer; // Where the character is stored as = it is received. static bit receivebufferfull; // 1 =3D receivebuffer is full. #ifdef _16C71 static unsigned char adcconvertcount; // How often ADC is read. #endif static unsigned char send_bitno; static unsigned char receivestate; // Initial state of the receiver = (0). static unsigned char skipoversamples; // Used to skip receive samples. static unsigned char rxshift; static bit tx_next_bit; /** * init_uart *=20 * Initialises the serial port: *=20 * Sets up the I/O directions for the appropriate PortA pins; * Sets up Timer0. *=20 * */ void init_uart(void) { receivestate =3D RS_HAVE_NOTHING; skipoversamples =3D 1; // check each interrupt for start bit #ifdef _16C71 adcconvertcount =3D SAMPLE_ADC; ADCON1 =3D 2; // 16C71 requires Port A reconfiguration - make RA2/3 = digital I/0, // leave RA0 and RA1 as analog. #endif TRISA =3D 0x17; // Set up I/O direction. TRISB =3D 0xFE; /* Set up the timer. */ T0CS =3D 0; // Set timer mode for Timer0. TMR0 =3D (2-TIMER_VALUE); // +2 as timer stops for 2 cycles // when writing to TMR0 T0IE =3D 1; // Enable the Timer0 interrupt. GIE =3D 1; } void putch(char c) { while(send_bitno) continue; tx_next_bit =3D 0; sendbuffer =3D c; send_bitno =3D TRANSMIT_NUM_BITS*RX_OVERSAMPLE; } char getch(void) { while(!receivebufferfull) continue; receivebufferfull =3D 0; return receivebuffer; } bit kbhit(void) { return receivebufferfull; } /** * serial_isr *=20 * Transmits and receives characters which have been * "putch"ed and "getch"ed. *=20 * This ISR runs BRATE * RX_OVERSAMPLE times per second. *=20 * */ interrupt void serial_isr(void) { // Reset Timer0 value // This is added to TMR0 because there is a delay to get to the isr. PORTB |=3D 1; TMR0 +=3D -TIMER_VALUE + 4; // +2 as timer stops for 2 cycles when = writing to TMR0 +2 for tweak T0IF =3D 0; #ifdef _16C71 /*** ADC ***/ /* This will be called every SAMPLE_ADCth time. */ if(--adcconvertcount =3D=3D 0) { adcconversionflag =3D 1; adcconvertcount =3D SAMPLE_ADC; } #endif /*** RECEIVE ***/ if( --skipoversamples =3D=3D 0) { skipoversamples++; // check next time switch(receivestate) { case RS_HAVE_NOTHING: /* Check for start bit of a received char. */ if(!RxData){ skipoversamples =3D RX_OVERSAMPLE/2; receivestate++; } break; case RS_WAIT_HALF_A_BIT: if(!RxData) { // valid start bit skipoversamples =3D RX_OVERSAMPLE; receivestate++; } else receivestate =3D RS_HAVE_NOTHING; break; =09 // case RS_HAVE_STARTBIT: and subsequent values default: rxshift =3D (rxshift >> 1) | (RxData << 7); skipoversamples =3D RX_OVERSAMPLE; receivestate++; break; case RS_WAIT_FOR_STOP: receivebuffer =3D rxshift; receivebufferfull =3D 1; receivestate =3D RS_HAVE_NOTHING; break; } } =09 /*** TRANSMIT ***/ /* This will be called every RX_OVERSAMPLEth time * (because the RECEIVE needs to over-sample the incoming * data). */ if(send_bitno) { if((send_bitno & (RX_OVERSAMPLE-1)) =3D=3D 0) { TxData =3D tx_next_bit; // Send next bit. tx_next_bit =3D sendbuffer & 1; sendbuffer =3D (sendbuffer >> 1) | 0x80; } send_bitno--; } PORTB &=3D ~1; } ------=_NextPart_000_003B_01C124D7.9DD8BC40-- -- http://www.piclist.com#nomail Going offline? Don't AutoReply us! email listserv@mitvma.mit.edu with SET PICList DIGEST in the body