#include #define START_SIGNAL RXD //address 0 is driven by p3.5, //address 1 is driven by p3.6, //address 2 is driven by p3.7 // //the at89x55.h file incorrectly identifies RD as p3.6 and //WR as p3.7, which is contrary to what the manual specifies. //these #define's take the incorrect definitions into account, //which is why it would appear that RD and WR are assigned to the wrong //pins. #define ADDR0 T1 #define ADDR1 RD #define ADDR2 WR #define ADC_ALE INT1 #define PHASE_CHECK 500 #define INCREASING 0 #define DECREASING 1 #define Q_SIZE 64 unsigned char head; unsigned char tail; unsigned char sig[Q_SIZE]; //a counter to make sure that a //pulse is sent to start, if nothing happens //after a certain amount of time int restartCounter; int counter; int phaseShift; int difference; unsigned char lowest; unsigned char oldLowest; unsigned char enq(unsigned char value); unsigned char deq(); unsigned char next( unsigned char ptr ); // we have a variable called 'data_out' at the position // 0 in external memory int xdata data_out _at_ 0x00; unsigned char enq(unsigned char value) { if( next(head) == tail ) return 0; sig[head] = value; //EA = 0; // queue access is atomic head = next(head); //EA = 1; return 1; } unsigned char deq() { unsigned char value; if (head == tail) return 0; // if queue is empty then return 0 value = sig[tail]; tail = next(tail); // queue access is atomic return value; } unsigned char next(unsigned char ptr) { if ( ++ptr == Q_SIZE) ptr = 0; return ptr; } // external interrupt zero routine // for now we're just going to get this to // read the port that the ADC is hooked into // (port one) and write to the DAC using // memory mapped IO void pulse_high (void) interrupt 0 using 1{ // we get to this interupt on pulse high->low // ex int 0; we get this when the ADC // finishes a reading // transfer data from port 2 to // DAC i think we need to // place it in an interum data point // to make it work right. but i'm not sure. int i = 0; i = P1; // if this is an ordiary read if( !ADDR0 && !ADDR1 && !ADDR2 ) { // invert the wave // and en-q i = 255 - i; //keep a record of the lowest values seen since the previous //phasecheck. this aids us in making sure that the output //is not offset from zero if(i < lowest) lowest = i; i -= oldLowest; if (i < 0) i = 0; if(phaseShift == 1) { P2 = i; goto RETURN_INT; } enq( i ); //find the difference between head and tail //in the circular Queue if( head < tail ) { //if head is less than tail... obvious difference = head + Q_SIZE - tail; } else { //... difference = head - tail; } //dequeue the data when the difference is a //phaseShift's length if( phaseShift == difference ) { P2 = deq(); } else if (phaseShift < difference ) { tail = tail + (difference - phaseShift); tail = tail % Q_SIZE; P2 = deq(); } } // we are reading phase shift else if( ADDR0 && !ADDR1 && !ADDR2 ) { // phase shift == i/4 --> between 0 and 64 phaseShift = i >> 3; //make sure that phase shift is not zero if( phaseShift < 1 ) phaseShift = 1; //update the lowest values to aid in our gain oldLowest = lowest; lowest = 255; restartCounter = 0; // go back to input checking for signal ADDR0 = 0; } else // WHAT THE HELL ARE WE DOING HERE? { //a good default setting for the address... ADDR0 = 0; ADDR1 = 0; ADDR2 = 0; } RETURN_INT: // increment counter and check for phase shift if time counter++; if( counter == PHASE_CHECK ) { counter = 0; ADDR0 = 1; } // start a new ADC reading ADC_ALE = 1; START_SIGNAL = 1; } int main() { head = 0; tail = 0; phaseShift = 1; restartCounter = 0; //we want to read from this port // and this is the read state P1 = 255; //enable timer zero interrupt, //and external interrupt zero. //and timer 1 EA = 1; EX0 = 1; IT0 = 1; // initialize counter counter = 0; // set address pins to phase shift // which we should read from the offset ADDR0 = 1; ADDR1 = 0; ADDR2 = 0; // start pulsing to get our first ADC // signal ADC_ALE = 1; START_SIGNAL = 1; counter = 1; while(1) { // lower the adc_ale ADC_ALE = 0; // lower the ADC start signal START_SIGNAL = 0; restartCounter++; //this pulses the start, in case we need to restart if( restartCounter > 60,000 ) { ADC_ALE = 1; START_SIGNAL = 1; } } }