///////////////////////////////////// // Generated Initialization File // ///////////////////////////////////// #include "C8051F520.h" #define LED P0_6 // on-board LED control #define IRLED P1_2 // infra LED on/off control #define PULLUP1 P1_1 // 10k pullup resistor on channel 1 (0=ON, 1=OFF) #define PULLUP2 P1_7 // 10k pullup resistor on channel 2 (0=ON, 1=OFF) #define PULLUP3 P1_5 // 10k pullup resistor on channel 3 (0=ON, 1=OFF) #define PULLDN3 P0_7 // 10k pulldown resistor on channel 3 (0=OFF, 1=ON) #define IN1 1 // ADC multiplexer setting for channel 1 #define IN2 2 // ADC multiplexer setting for channel 2 #define IN3 14 // ADC multiplexer setting for channel 3 #define INAMP 12 // ADC multiplexer setting for the internal differential amplifier #define PHOTO 11 // ADC multiplexer setting for the internal photosensor unsigned char ChannelArray[3] = { IN1, IN2, IN3 }; // this array is used as channel sequencer during the sampling process // Peripheral specific initialization functions, // Called from the Init_Device() function void PCA_Init() { PCA0MD &= ~0x40; // switch the watchdog timer off PCA0MD = 0x00; } void Timer_Init() { TCON = 0x40; // enable Timer1 for UART baud rate generation TMOD = 0x20; CKCON = 0x08; TH1 = 0xCB; // 230kbaud UART } void UART_Init() { SCON0 = 0x10; // enable UART RI0=0; // clear the receive flag TI0=1; // set this flag to indicate empty output buffer } void ADC_Init() { ADC0MX = 0x01; // default multiplexer setting ADC0CF = 0xA0; // default ADC configuration ADC0CN = 0x80; // enable ADC } void Voltage_Reference_Init() { REF0CN = 0x02; // external voltage reference, bias generation for analog peripherals is on } void Port_IO_Init() { // P0.0 - Skipped, Open-Drain, Analog // P0.1 - Skipped, Open-Drain, Analog // P0.2 - Skipped, Open-Drain, Analog // P0.3 - Unassigned, Open-Drain, Digital // P0.4 - TX (UART), Push-Pull, Digital // P0.5 - RX (UART), Open-Drain, Digital // P0.6 - Unassigned, Open-Drain, Digital // P0.7 - Unassigned, Push-Pull, Digital // P1.0 - Unassigned, Open-Drain, Digital // P1.1 - Unassigned, Push-Pull, Digital // P1.2 - Unassigned, Push-Pull, Digital // P1.3 - Skipped, Open-Drain, Analog // P1.4 - Skipped, Open-Drain, Analog // P1.5 - Unassigned, Push-Pull, Digital // P1.6 - Skipped, Open-Drain, Analog // P1.7 - Unassigned, Push-Pull, Digital P0MDIN = 0xF8; P1MDIN = 0xA7; P0MDOUT = 0x90; P1MDOUT = 0xA6; P0SKIP = 0x07; P1SKIP = 0x58; P0SKIP |= 0x30; XBR0 = 0x01; XBR1 = 0x40; } void Oscillator_Init() { OSCICN = 0xC7; // 24.5MHz internal oscillator } /************************************************************************** Initialization function for device, Call Init_Device() from your main program ***************************************************************************/ void Init_Device(void) { PCA_Init(); Timer_Init(); UART_Init(); ADC_Init(); Voltage_Reference_Init(); Port_IO_Init(); Oscillator_Init(); } /************************************************************************** Wait for a byte from serial port (UART1-FT232RL USB) ***************************************************************************/ unsigned char SIn(void) { while (!RI0); RI0=0; return SBUF0; } /************************************************************************** sends a byte over the serial port ***************************************************************************/ void SOut(unsigned char a) { while (!TI0); TI0=0; SBUF0=a; } /************************************************************************** waits for a byte, when arrived, sends back and returns with the value ***************************************************************************/ unsigned char SInOut(void) { char c; c=SIn(); while (!TI0); TI0=0; SBUF0=c; return c; } /************************************************************************** waits for the specified time ***************************************************************************/ void Delay_ms(unsigned int ms) { unsigned int i; for(i=0; i>1) & 3) { case 0: break; case 1: freq*=4; break; case 2: if (freq<=1500) freq*=8; else { ADC0CF = (ADC0CF & 0xF0) | 2; freq*=4; } break; case 3: if (freq<=750) { freq*=16; } else if (freq>1500) { ADC0CF = (ADC0CF & 0xF0) | 2; freq*=4; } else { ADC0CF = (ADC0CF & 0xF0) | 4; freq*=8; } break; } tmr2value=65536-(2041666L)/freq; TMR2CN = 0x00; TMR2RLL = tmr2value; TMR2RLH = tmr2value >> 8; TMR2L = TMR2RLL; TMR2H = TMR2RLH; } /************************************************************************** Messures the voltage on the specified channel ***************************************************************************/ unsigned int Measure(unsigned char channel) { ADC0MX = channel; // set the multiplexer ADC0CN = 0x80; // enable the ADC AD0INT=0; // clear the end of conversion flag AD0BUSY=1; // start A/D conversion while (!AD0INT); // wait for end of conversion AD0INT=0; // clear the end of conversion flag return (ADC0H << 8)+ADC0L; } /************************************************************************** Starts continuous sampling ***************************************************************************/ void ContSampling(void) { unsigned char c,chn; chn=0; // reset the channel sequencer index ADC0MX = ChannelArray[chn]; AD0INT=0; ADC0CN = 0x83; // enable the ADC in Timer 2 as sampling clock mode TMR2CN = 0x04; // enable Timer 2 to generate the sampling clock while (!AD0INT); // wait for first conversion, do not use it AD0INT=0; // clear the end of conversion flag c=0; do { if (RI0) // if a byte has been received by the UART { c=SBUF0; // read the byte RI0=0; // clear the receive flag } if (AD0INT) // if an A/D conversion has been completed { chn=(chn+1); // set the next channel index if (chn==3) chn=0; // period is 3 channels ADC0MX = ChannelArray[chn]; // set the multiplexer to the next channel AD0INT=0; // clear the end of conversion flag while (!TI0); // wait for UART transmit buffer empty TI0=0; // clear the flag SBUF0=ADC0H; // send ADC higher order byte while (!TI0); // wait for UART transmit buffer empty TI0=0; // clear the flag SBUF0=ADC0L; // send ADC lower order byte LED=!LED; // complement LED to visualise the sampling } } while (c!=27); // stop only if an ESC character has been received TMR2CN=0; // switch the timeroff LED=0; // LED = ON } /************************************************************************** Sends an identification string to the host ***************************************************************************/ void SendID() { unsigned char *s; s="EDAQ530C (c) 30/06/2010 www.noise.physx.u-szeged.hu"; do { if (SIn()==27) break; // the host can abort the process by sending an ESC character SOut(*s); // send the current character if (*s) s++; // if there are more characters in the string, increment the pointer } while (*s); // continue if the end of string has not been detected yet } /************************************************************************** The main program ***************************************************************************/ void main(void) { unsigned char c; Init_Device(); // initialise the processor and the peripherals IRLED=0; // switch the inrared LED on for(c=0; c<3; c++) // flash the power LED three times to indicate booting { LED=0; Delay_ms(200); LED=1; Delay_ms(200); } LED=0; while(1) // the command processor loop { while (SInOut()!='@'); // all commands must be started with a '@' character c=SInOut(); if (c=='I') // send identification string command { SendID(); } else if (c=='M') // measure command, all three channels are measured and the data will be sent to the host { unsigned d; SInOut(); d=Measure(ChannelArray[0]); SOut(d>>8); SOut(d); d=Measure(ChannelArray[1]); SOut(d>>8); SOut(d); d=Measure(ChannelArray[2]); SOut(d>>8); SOut(d); } else if (c=='S') // start continuous sampling, ESC exits { ContSampling(); } else if (c=='f') // set sampling frequency { unsigned int samplingfreq; ADC0CF = (ADC0CF & 0xF0) | ((SInOut() << 1) & 0x0F); samplingfreq = SInOut(); samplingfreq = (samplingfreq << 8)+SInOut(); if (samplingfreq<32) samplingfreq=32; if (samplingfreq>3000) samplingfreq=3000; SetSamplingFreq(samplingfreq); } else if (c=='Q') // query parameters { SOut(TMR2RLH); // sample rate = (24,5MHz/12)/(65536-TMR2RL)/(number of averages) SOut(TMR2RLL); SOut((ADC0CF>>1) & 3); // averages: 1,4,8,16 } else if (c=='C') // set channel sequencer for continuous sampling mode { c=SInOut(); // read the selection for the first channel ChannelArray[0] = (c) ? ((c==1) ? INAMP:PHOTO): IN1; c=SInOut(); // read the selection for the second channel ChannelArray[1] = (c) ? ((c==1) ? INAMP:PHOTO): IN2; c=SInOut(); // read the selection for the third channel ChannelArray[2] = (c) ? ((c==1) ? INAMP:PHOTO): IN3; } else if (c=='P') // switch pullup resistors on or off { c=SInOut(); PULLUP1 = c & 1; PULLUP2 = c & 2; PULLUP3 = c & 4; PULLDN3 = c & 8; } else if (c=='E') // switch IR LED on of off { IRLED = SInOut(); } } }