#include #include #include "c8051f350.h" // Peripheral specific initialization functions, // Called from the Init_Device() function void PCA_Init() { PCA0MD &= ~0x40; // disable watchdog timer PCA0MD = 0x00; } void Timer_Init() { TCON = 0x40; // configure timers for 9600 bit/s UART data rate TMOD = 0x20; CKCON = 0x01; TH1 = 0x60; } void UART_Init() { SCON0 = 0x10; // enable UART for 8-bit, variable baud mode } // Configure the ADC: // 100Hz sample rate, unipolar mode // gain=1, external voltage reference // analog input buffers are bypassed // ADC input is AIN7 and GND void ADC_Init() { ADC0CN = 0x00; // disable ADC, will be enabled later ADC0CF = 0x04; ADC0MD = 0x80; ADC0CLK = 0x04; ADC0DECH = 0x00; ADC0DECL = 0xBE; ADC0MUX = 0x78; } void Port_IO_Init() { P1MDIN = 0xBF; // P1. is analog P0MDOUT = 0x90; // P0.4 (UART TX) and P0.7 (LED) are push-pull, digital P1SKIP = 0x40; XBR0 = 0x01; XBR1 = 0x40; } void Oscillator_Init() { OSCICN = 0x82; // internal oscillator, 12.25MHz } // Initialization function for device, void Init_Device(void) { PCA_Init(); Timer_Init(); UART_Init(); ADC_Init(); Port_IO_Init(); Oscillator_Init(); } unsigned char SIn(void) { while (!RI); // wait for a byte RI=0; return SBUF; // return the byte } void SOut(char a) { TI=0; SBUF=a; // transmit a byte while (!TI); // wait for end of transmission } void CalibrateADC(void) { ADC0MD = 0x81; // ADC0 MODE: FULL INTERNAL CALIBRATION while(AD0CBSY); // end of cal step while(ADC0MD & 0x07); // wait return to IDLE!!! AD0INT=0; } // Do continuos sampling // every sample will be sent to the host // detect also heart beats and flash the LED accordingly void HeartBeats(void) { unsigned char c; int x2,x1,y; CalibrateADC(); // ADC calibration is required before measurements x1=0; // initial value of data y=0; // initial value of filtered data c=0; // initialize UART input variable ADC0MD = 0x83; // enable ADC do { while(!AD0INT); // wait for end of conversion AD0INT=0; // clear flag SOut(ADC0H); // send ADC most significant byte SOut(ADC0M); // send ADC middle byte SOut(ADC0L); // send ADC least significant byte x2=(ADC0H<<8) | ADC0M; // most significant 16-bits of data y=((243L*y) >> 8)+x2-x1; // (243L*y)/256+x2-x1 : do digital high-pass filtering P0_7=(y>0); // drive LED to visualize heart beats x1=x2; // shift data for digital high-pass filtering if (RI) c=SIn(); } while (P1_0 && c!=27); // stop if button is not pressed or ESC received ADC0MD = 0x80; } void main(void) { unsigned char i; Init_Device(); while (1) { i=SIn(); // wait for a byte SOut(i); // return to the host for "software handshaking" if (i=='m') // if 'm' is received, start measurement { HeartBeats(); } } }