/********************************************************************* Author : Marcus Moser Date : 13.07.2007 File : main0607.c Hardware : ADuC7020 auf Miniboard/ AD5933 Description : Impedanzmessung *********************************************************************/ #include"ADuC7020.h" #include #define CR 0x0D // I2C und UART Initializierung #define I2CUARTON 0x2211 // I2C on P1.2 and P1.3 plus UART on P1.0 and P1.1 #define CLOCK 0x82 // Master Enable & Enable Generation of Master Clock // I2C-Master setup #define Freq100 0xCFCF // 0x3232 = 400kHz // 0xCFCF = 100kHz // Start setting up UART at 9600bps #define SETDLAB 0x080 // Setting DLAB #define DIV0 0x088 // Setting DIV0 and DIV1 to DL calculated #define DIV1 0x000 #define CLRDLAB 0x007 // Clearing DLAB // LED #define AUS 0x00000000 #define AN 0x04000000 //I2C bus Status #define SLA_W 0x1A #define SLA_R 0x1B //AD5933 control codes #define Init 0x10 //Initialize with start Freq #define Sweep 0x20 //Start Frequency Sweep #define IncFreq 0x30 //Increment Frequency #define RepFreq 0x40 //Repeat Frequency #define PowerDown 0xA0 //Power down mode #define Standby 0xB0 //Standby mode #define AP 0x0B; //Addresspointer command #define BW 0xA0; //Block write command #define BR 0xA1; //Block read command //Prototypes int write (int file, char *ptr, int len); char getchar (void); int putchr(char); void delay (int); void LED(int); void warteTX(void); void warteRX(void); void configuration_I2C_UART(void); void configuration_AD5933(void); void writeI2C_Block (int reg_loc,int byte_num,int *data_p); int readI2C_Block (int reg_loc,int byte_num); void save_data(void); //Declarations of parameters: int m; int b; int i = 0; int j; int test; double RealData; //current sweep frequency REAL value double ImagineryData; //current sweep frequency imaginary value long RealDataUpper; long RealDataLower; long ImagineryDataLower; long ImagineryDataUpper; double Magnitude; //current sweep magnitude value double Impedance; //current sweep impedance value double MaxMagnitude; //variable which holds the max impedance point double MinMagnitude; //variable which holds the min impedance point long phase; //current phase point double Frequency = 30000; //current frequency point double FrequencyIncrements = 10; double Gainfactor; long Increment; //counter for number of increments in the sweep int IndexArray = 0; int MagnitudeArray[150]; int PhaseArray[150]; int ImagineryDataArray[150]; int RealDataArray[150]; int FrequencyPoints[150]; char jchar = 0x30; char output1[200] = "#####################[Mainmenue]########################\n\n\n\n\n\n\n Auswahl:\n\n\n\n 1: Configuration\n 2: Messung starten\n 3: Messdaten auslesen\n"; /**************************************************************************** Function : char getchar(void) read symbol from serial port ****************************************************************************/ char getchar (void) { while(!(0x01==(COMSTA0 & 0x01))) {} return (COMRX); } /**************************************************************************** Function : int putchr(char ch) write symbol to serial port ****************************************************************************/ int putchr(char ch) { if (ch == '\n') { while((0x000==(COMSTA0 & 0x020))) {} return (COMTX = CR); // Ausgabe von CR } else { while((0x000==(COMSTA0 & 0x020))) {} return (COMTX = ch); } } /**************************************************************************** Function : int write (int file, char *ptr, int len) write symbol to putchar ****************************************************************************/ int write (int file, char *ptr, int len) { int i; for (i = 0; i < len; i++) putchr (*ptr++); return len; } /**************************************************************************** Function : void warte (long length) Wartefukntion >> Attention: value x 1E6 then it's sec ****************************************************************************/ void warte (long length) { while (length >0) length--; } /**************************************************************************** Function : void configuration(void) Configuration of I2C and UART ****************************************************************************/ void configuration_I2C_UART(void) { GP1CON = I2CUARTON; I2C1CFG = CLOCK; I2C1DIV = Freq100; COMCON0 = SETDLAB; COMDIV0 = DIV0; COMDIV1 = DIV1; COMCON0 = CLRDLAB; } /**************************************************************************** Function : void LED(int n) LED to control the program ****************************************************************************/ void LED(int n) { if(n) { GP4DAT = AUS; } else { GP4DAT = AN; } } /*************************************************/ /*************************************************/ /************ IRQ Service Routine *************/ /*************************************************/ /************************************************* //IRQEN = 400; //Aufruf so: IRQ = My_IRQ-Funktion void My_IRQ_Function() { // Transmit while((I2C1MSTA & 0x4) != 0x4) // Master Transmit IRQ { } // Receive while((I2C1MSTA & 0x8) != 0x8) // Master Recieve IRQ { } } */ /**************************************************************************** Function : void warteTX(void) wait for the transmit register: if second bit in I2C1MSTA 1 it goes on //Slave transmit IRQ ****************************************************************************/ void warteTX(void) { while ((I2C1MSTA & 0x4) != 0x4) {}; } /**************************************************************************** Function : void warteRX(void) wait for the receive register: if third bit in I2C1MSTA 1 it goes on //Slave receive IRQ ****************************************************************************/ void warteRX(void) { while ((I2C1MSTA & 0x8) != 0x8) {}; } /**************************************************************************** Function : void writeI2C (int location) Byte write ****************************************************************************/ void writeI2C (int location) { I2C1ADR = SLA_W; I2C1MTX = AP; I2C1MTX = location; warteTX(); } /**************************************************************************** Function : int readI2C (int location) Byte read ****************************************************************************/ int readI2C (int location) { I2C1ADR = SLA_W; I2C1MTX = AP; I2C1MTX = location; warteTX(); I2C1ADR = SLA_R; warteRX(); int tmp; tmp= I2C1MRX; return (tmp); } /**************************************************************************** Function : void writeI2C_Block (int reg_loc,int byte_num,int *data_p) Block write ****************************************************************************/ void writeI2C_Block (int reg_loc,int byte_num,int *data_p) { writeI2C(reg_loc); I2C1ADR = SLA_W; warteTX(); I2C1MTX = BW; for(i=0;i < byte_num; i++) { I2C1MTX = *(data_p+i); warteTX(); } } /**************************************************************************** Function : int readI2C_Block (int reg_loc,int byte_num) Block read ****************************************************************************/ int readI2C_Block (int reg_loc,int byte_num) { int *data_p; writeI2C(reg_loc); I2C1ADR = SLA_W; I2C1MTX = BR; I2C1CNT = byte_num; warteTX(); I2C1ADR = SLA_R; warteRX(); for(i=0;i < byte_num; i++) { *(data_p+i)= I2C1MRX; warteTX(); } return (*data_p); } /**************************************************************************** Function : void configuration_AD5933(void) Configuration of AD5933 ****************************************************************************/ void configuration_AD5933(void) { // Start Frequency Register = 1 khz = 0x008312 // 30 khz = 0x0F5C28 int startfreq = 0x008312; //writeI2C_Block (0x82,3,startfreq); writeI2C(0x84); I2C1MTX = 0x12; // Value warteTX(); writeI2C(0x83); I2C1MTX = 0x83; // Value warteTX(); writeI2C(0x82); I2C1MTX = 0x00; // Value warteTX(); // numbers of increments Register: Value: 150 increments = 0x0096 // here: 0x0001 Increment writeI2C(0x89); I2C1MTX = 0x01; // Value lsb warteTX(); writeI2C(0x88); I2C1MTX = 0x00; // Value msb warteTX(); // Frequenz Sweep Register: Value: 10 Hz entspricht 0x00014F int sweep = 0x00014F; //writeI2C_Block (0x85,3,sweep); writeI2C(0x87); I2C1MTX = 0x4F; // Value:0x00 warteTX(); writeI2C(0x86); I2C1MTX = 0x01; // Value warteTX(); writeI2C(0x85); I2C1MTX = 0x00; // Value warteTX(); // Settling time cycles register writeI2C(0x8B); I2C1MTX = 0x0F; // Value warteTX(); writeI2C(0x8A); I2C1MTX = 0x00; // Value warteTX(); // set AD5933 in Standby Modus writeI2C(0x80); I2C1MTX = Standby; // Standby Modus warteTX(); } /**************************************************************************** Function : double phase2(double img, double real) This function accepts the real and imaginary data(R,I) at each valid sweep point and converts it to a degree ****************************************************************************/ double phase2(double img, double real) { double theta; double pi; double phase3; pi = 3.141592654; if ((real > 0) && (img > 0)) { theta = atan(img / real); //theta = arctan (imaginary part/real part) phase3 = (theta * 180) / pi; //convert from radians to degrees } if ((real > 0) && (img < 0)) { theta = atan(img / real); //4th quadrant theta = minus angle phase3 = ((theta * 180) / pi ) + 360; } if ((real < 0) && (img < 0)) { theta = -pi + atan(img / real); //3rd quadrant theta img/real is positive phase3 = (theta * 180) / pi; } if ((real < 0) && (img > 0)) { theta = pi + atan(img / real); //2nd quadrant img/real is neg phase3 = (theta * 180) / pi; } return (phase3); } /**************************************************************************** Function : void save_data(void) Format and Save the data ****************************************************************************/ void save_data(void) { // valid Data for this frequency point is now available to read RealDataUpper = readI2C(0x94); RealDataLower = readI2C(0x95); RealData = RealDataLower + (RealDataUpper * 256); if (RealData < 0x7FFF) //0x7FFF = 32767.Data stored in 2?s complement format, transform to decimal data is Positive {} else { //data is Negative RealData = RealData + 0x7FFF; RealData = RealData - 0x7FFF; } ImagineryDataUpper = readI2C(0x96); ImagineryDataLower = readI2C(0x97); ImagineryData = ImagineryDataLower + (ImagineryDataUpper * 256); if (ImagineryData < 0x7FFF) {}//Positive Data. else {//Negative ImagineryData = ImagineryData + 0x7FFF; ImagineryData = ImagineryData - 0x7FFF; } //Calculate the Impedance and Phase of the data at this frequency sweep point Magnitude = sqrt(((RealData * RealData) + (ImagineryData * ImagineryData))); phase = phase2(ImagineryData, RealData); Gainfactor = 0x0000; ////see gain factor calculation Impedance = 1 / (Magnitude * Gainfactor); //Write Data to each array MagnitudeArray [IndexArray] = Impedance; PhaseArray [IndexArray] = phase; ImagineryDataArray [IndexArray] = ImagineryData; RealDataArray [IndexArray] = RealData; Increment = Increment - 1; // decrement the frequency increment point by 1 FrequencyPoints [IndexArray] = Frequency; Frequency = Frequency + FrequencyIncrements; //holds the current value of the sweep freq IndexArray = IndexArray + 1; } /*********************************MAIN Programm**************************************** Start program: 1. Configuration I2C and UART 2. Configuration AD5933 //3. Read the numbers of increments form UART 4. While function: a. Initialization with Start Frequency b. Start Frequenz Sweep c. Poll Status Register, if Sweep is complete d. Format the data and save it in arrays 5. Power down Modus **************************************************************************************/ int main(void) { configuration_I2C_UART(); write(0,output1,200); configuration_AD5933(); write(0,"Anzahl von Durchläufen eingeben!\n",35); //jchar = getchar(); // RX Data, Single Byte Increment = 1; write(0,"Messung starten\n",20); while (1) { write(0,"Zum Neustart beliebige Taste\n",32); jchar = getchar(); //Initialization with Start Frequency write(0,"Initializieren mit Start Frequenz\n",35); writeI2C(0x80); I2C1MTX = Init; warteTX(); warte(5000); //Start Frequenz Sweep write(0,"Start Frequenz Sweep\n",22); writeI2C(0x80); I2C1MTX = Sweep; warteTX(); // poll Status Register, if Sweep is complete: 0x04 = Frequenz Sweep complete do { test = readI2C(0x8F); LED(0);//for controll if((test & 0x02)== 0x02) {}//valid data else { do { writeI2C(0x80); I2C1MTX = RepFreq; //repeat sweep point //warteTX(); test = readI2C(0x8F); }while(test == 0x02); } // format the data and save it in arrays save_data(); // check to see if sweep complete test = readI2C(0x8F); //for controll //warte(500000); //LED(1); //warte(500000); // Increment Command to Control Register writeI2C(0x80); I2C1MTX = IncFreq; Increment = Increment -1; }while(Increment != 0); // ((Increment !=0)&&(test & 0x04) != 0x04)); } //LED(1); //LED off // Power down Modus writeI2C(0x80); I2C1MTX = PowerDown; warteTX(); return 0; }