⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c

📁 ADS下开发的A/D转换器AD7892及LCD显示程序
💻 C
📖 第 1 页 / 共 2 页
字号:
   if (num == 0)
   	return 1;
   while(num != 0)
   {
   	num /= 10;
   	digCount++;
   }
   return digCount;
}

//===========Converting an integer to a character string, for LCD display===========
//int integer:		integer to be converted
//char *str:		the pointer of character string
//U8 FracLen:		digit of fraction
char * Integer2String(int integer, char *str)
{     
   char *address =str;
   U8 i, j, Length;
   int times;
   if(integer>=0)
	{
		str[0] = ' ';
	}
	else
	{
		str[0] = '-';
		integer *= (-1);
	}
	Length = Digit_Integer(integer);

	for(i=0; i<Length; i++)
	{
		times = 1;
		for(j=0; j<Length-1-i; j++)
			times *= 10;
		str[i+1]='0'+(integer/times)%10;		
	}
	return address;
}

//===========Converting a float number to a character string, for LCD display===========
//double floatnum:	float number
//char *str:		the pointer of character string
//U8 FracLen:		digit of fraction
char * Float2String(double floatnum, char *str, U8 FracLen)
{
   char *address = str;
   const double EPS = 1e-7;
   int integer, fraction;
   U8 IntLen, i, j;
   int times;
   if(floatnum>=EPS)	//floatnum is positive
   	str[0] = ' ';		//ASCII of 'space' is 32;
   else				//floatnum is minus
	{
		floatnum = (-1)*floatnum;
		str[0] = '-';
	}
   integer = (int)floatnum;
   IntLen = Digit_Integer(integer);
   for(i=0; i<IntLen; i++)
   {
   	times = 1;
	for(j=0; j<IntLen-1-i; j++)
		times *= 10;
		str[i+1]='0'+(integer/times)%10;		
   }
   str[IntLen+1]='.'; //dot of fraction
   for(i=0; i<FracLen; i++)
		times *= 10;
   fraction = (int)((floatnum-integer)*times);
   for(i=0; i<FracLen; i++)
   {
	times = 1;
	for(j=0; j<FracLen-1-i; j++)
			times *= 10;
	str[i+IntLen+2]='0'+(fraction/times)%10;
   }
   str[IntLen+FracLen+2]='\0';
   return address;
}

void Interrupt_Init(void)
{
    //the waveform will be distorted while using rising edge triggerd!
    rEXTINT0 = (rEXTINT0 & ~(7<<4))|(4<<4); //EINT1=rising edge triggered
    //rEXTINT0 = (rEXTINT0 & ~(7<<4))|(2<<4); //EINT1=falling edge triggered
  		        
    pISR_EINT1=(U32)Eint1Int;
    pISR_TIMER0=(int)Timer0Done;
       
    rSRCPND = (BIT_EINT1 | BIT_TIMER0); //to clear the previous pending states
    rINTPND = (BIT_EINT1 | BIT_TIMER0);
    rINTMSK =~(BIT_EINT1 | BIT_TIMER0);//enable external interrupt 1 and timer0
}

void Set_SamplingRate(int samp_freq)
{
    samplingrate = samp_freq;
    switch(samp_freq)
      {
      	case SAMP_RATE_1KHZ:
      	     rTCFG0 = rTCFG0 & ~(0xffffff) | 0x000fa8;   //Dead zone=0,Prescaler1=15(0x0f),Prescaler0=168(0xa8)
             rTCFG1 = rTCFG1 & ~(0xffffff) | 0x001230;   //All interrupt,Mux4=1/2,Mux3=1/4,Mux2=1/8,Mux1=1/16,Mux0=1/2
             rTCNTB0 = 150;                              //set timer0:1ms fs=50.7MHz/(168+1)/2/150=1kHz
             rTCMPB0 = 75;                              //(H/L)duty 50%
             break;
        case SAMP_RATE_2KHZ:
             rTCFG0 = rTCFG0 & ~(0xffffff) | 0x000fa8;   //Dead zone=0,Prescaler1=15(0x0f),Prescaler0=168(0xa8)
             rTCFG1 = rTCFG1 & ~(0xffffff) | 0x001230;   //All interrupt,Mux4=1/2,Mux3=1/4,Mux2=1/8,Mux1=1/16,Mux0=1/2
             rTCNTB0 = 75;                              //set timer0:0.5ms fs=50.7MHz/(168+1)/2/75=2kHz
             rTCMPB0 = 38;                              //(H/L)duty 50%
             break;
        case SAMP_RATE_5KHZ:
             rTCFG0 = rTCFG0 & ~(0xffffff) | 0x000fa8;   //Dead zone=0,Prescaler1=15(0x0f),Prescaler0=168(0xa8)
             rTCFG1 = rTCFG1 & ~(0xffffff) | 0x001230;   //All interrupt,Mux4=1/2,Mux3=1/4,Mux2=1/8,Mux1=1/16,Mux0=1/2
             rTCNTB0 = 30;                              //set timer0:0.2ms fs=50.7MHz/(168+1)/2/30=5kHz
             rTCMPB0 = 15;                              //(H/L)duty 50% 
        case SAMP_RATE_10KHZ:
             rTCFG0 = rTCFG0 & ~(0xffffff) | 0x000f10;   //Dead zone=0,Prescaler1=15(0x0f),Prescaler0=16(0x10)
             rTCFG1 = rTCFG1 & ~(0xffffff) | 0x001230;   //All interrupt,Mux4=1/2,Mux3=1/4,Mux2=1/8,Mux1=1/16,Mux0=1/2
             rTCNTB0 = 150;                              //set timer0:0.1ms fs=50.7MHz/(16+1)/2/150=0.9941kHz
             rTCMPB0 = 75;                              //(H/L)duty 50%
             break;
        case SAMP_RATE_20KHZ:
             rTCFG0 = rTCFG0 & ~(0xffffff) | 0x000f10;   //Dead zone=0,Prescaler1=15(0x0f),Prescaler0=16(0x10)
             rTCFG1 = rTCFG1 & ~(0xffffff) | 0x001230;   //All interrupt,Mux4=1/2,Mux3=1/4,Mux2=1/8,Mux1=1/16,Mux0=1/2
             rTCNTB0 = 75;                              //set timer0:0.05ms fs=50.7MHz/(16+1)/2/75=1.9882kHz
             rTCMPB0 = 38;                              //(H/L)duty 50%
             break;
        case SAMP_RATE_50KHZ:
             rTCFG0 = rTCFG0 & ~(0xffffff) | 0x000f10;   //Dead zone=0,Prescaler1=15(0x0f),Prescaler0=16(0x10)
             rTCFG1 = rTCFG1 & ~(0xffffff) | 0x001230;   //All interrupt,Mux4=1/2,Mux3=1/4,Mux2=1/8,Mux1=1/16,Mux0=1/2
             rTCNTB0 = 30;                              //set timer0:0.02ms fs=50.7MHz/(16+1)/2/30=49.7059kHz
             rTCMPB0 = 15;                              //(H/L)duty 50%
             break;
        case SAMP_RATE_100KHZ:
             rTCFG0 = rTCFG0 & ~(0xffffff) | 0x000f02;   //Dead zone=0,Prescaler1=15(0x0f),Prescaler0=2(0x02)
             rTCFG1 = rTCFG1 & ~(0xffffff) | 0x001230;   //All interrupt,Mux4=1/2,Mux3=1/4,Mux2=1/8,Mux1=1/16,Mux0=1/2
             rTCNTB0 = 85;                              //set timer0:10us fs=50.7MHz/(2+1)/2/85=99.4118kHz
             rTCMPB0 = 43;                              //(H/L)duty 50%
             break;
        case SAMP_RATE_200KHZ:
             rTCFG0 = rTCFG0 & ~(0xffffff) | 0x000f02;   //Dead zone=0,Prescaler1=15(0x0f),Prescaler0=2(0x02)
             rTCFG1 = rTCFG1 & ~(0xffffff) | 0x001230;   //All interrupt,Mux4=1/2,Mux3=1/4,Mux2=1/8,Mux1=1/16,Mux0=1/2
             rTCNTB0 = 42;                              //set timer0:5us fs=50.7MHz/(2+1)/2/42=201.1905kHz
             rTCMPB0 = 21;                              //(H/L)duty 50%
             break;
        default:
             break;      
      }
 }
 
void Main(void)
{    
    int j;
    int max, min, sum;
    int zero_cnt, zero_index[]={0};
    char buffer[20] = "\0";
    double freq, avg, peak;
        
    ChangeClockDivider(1, 1);    
    ChangeMPllValue(0xa1, 0x3, 0x1);
    Port_Init();
    Uart_Init(0,115200);
    Uart_Select(0);
            
    rBWSCON =rBWSCON & 0xffffffcf|(1<<4); //set bus width of BANK1 to 16 bit
             
 while(1)
  { 
    Timer_Port_Init();
    Interrupt_Init();
    //Uart_Printf("Timer Interrupt Start.\n");
    
    ADC_Index = 0;
    Conversion_Complete = 0;
    Set_SamplingRate(SAMP_RATE_100KHZ);
        
    rTCON   = rTCON & ~(0xf) | 0xa;               //stop timer0
    rTCON   = rTCON & ~(0xf) | 0x9;               //start timer0,enbale auto-reload
    while(!Conversion_Complete);                      //waiting for interrupts
	
    rTCON   = rTCON & ~(0xf) | 0x0;                   //stop timer0,very important!
    rINTMSK |= BIT_TIMER0;                            //disable Timer0 interrupt
    
    //display the waveform of acquisited data on the LCD panel
    Lcd_Port_Init();
    Lcd_Init();
    Lcd_EnvidOnOff(1);
    ClearScreen(BLACK);
    //Uart_Printf("Timer Interrupt Return.\n");                            
    //Uart_Printf("AD7892 digital output:\n");
    for(j=0; j<SAMP_NUM; j++)
         {
         result[j] >>= 4;
         result[j] &= 0xfff;
         if (result[j]&0x800)
             result[j] -= 4096;
         //Uart_Printf("%d\n",result[j]);
         //if((j+1)%20==0)
         	//Uart_Printf("\n");
         }
   Uart_Printf("\n");
   Uart_Printf("Sampling Rate of AD7892: %d kSPS\n", samplingrate);
   Uart_Printf("Sampling Number of AD7892: %d\n", ADC_Index);
   
   //acquisited signal filtering
   for(j=2; j<SAMP_NUM; j++)
   	result[j] = (result[j-2]+result[j-1]+result[j])/3; //Slip-average filtering with a 3-point window
   	
   //acquisited data processing
   max = min = 0;
   sum = 0;
   for(j=0; j<SAMP_NUM; j++)
   {
   	sum += result[j];
   	if(result[j]>max)
   		max = result[j];
   	if(result[j]<min)
   		min = result[j];
   }
   //[-2048, +2047]==>[-5V, +5V]
   peak = (max-min)/2048.0*5.0;//peak-to-peak value
   sum /= SAMP_NUM;
   avg = sum/2048.0*5.0; //average value
   Uart_Printf("Average: %d\n", sum);
   Uart_Printf("Maximum: %d\n", max);
   Uart_Printf("Minimum: %d\n", min);
   
   //Find index of front-direction zero-crossings to calculate period of original signal
   zero_cnt = 0;
   for(j=0; j<(SAMP_NUM-1); j++)
   {
   	if( (result[j] <sum) && (result[j+1]>sum) || (result[j]==sum) )
   	{
   		zero_index[zero_cnt] = j;
   		zero_cnt++;
       }
  }
   //Uart_Printf("Index of zero-crossings:");
   //for(j=0; j<zero_cnt; j++)
   	//Uart_Printf(" %d,", zero_index[j]);
   sum = 0;
   //consider two special circumstances: no front-direction zero-crossing, only one front-direction zero-crossing
   
   for(j=0; j<(zero_cnt-1); j++)
    {
   	zero_index[j] = zero_index[j+1] - zero_index[j]; //sampling point number per period
   	sum += zero_index[j];
   }
   sum /= (zero_cnt-1);
   Uart_Printf("Point per period: %d\n", sum+1);
   freq = samplingrate*1000.0/(sum+1); //kSPS==>Hz
       	
   for(j=0; j<SAMP_NUM; j++)
   	PutPixel((result[j]>>XSCALE)+90, (int)(j/YSCALE), YELLOW); 
       //horizontally display waveform with yellow color
   Draw_Line(90, 0, 90, 319, BLUE);
   
   Draw_Rectangle(20, 0, 220, 319, SKYBLUE);
   Draw_Line(160, 0, 160, 319, PURPLE);
   //Fill_Rectangle(238, 39, 222, 55, RED);
                
//Postscript
   Display_Ascii_Clockwise90("Dec 2006, Lab615 of NUAA,  GNU GPL", 0, 40, GREEN); 

//Title: 8-channel analog input   
   Display_Ascii_Clockwise90("8", 222, 60, RED);
   for (j=0; j<7; j++)
   	Display_Chinese_Clockwise90(&analog16S[j*32], 16, 222, 68+j*16, RED);
//(timing acquisition)
   Display_Ascii_Clockwise90("(", 222, 180, RED);
   for (j=0; j<2; j++)
   	Display_Chinese_Clockwise90(&timing16K[j*32], 16, 222, 188+j*16, RED);
   for (j=0; j<2; j++)
   	Display_Chinese_Clockwise90(&acquisition16K[j*32], 16, 222, 188+(j+2)*16, RED);
   Display_Ascii_Clockwise90(")", 222, 252, RED);
      	
//frequency
   for (j=0; j<2; j++)
        Display_Chinese_Clockwise90(&frequency16K[j*32], 16, 200, 10+j*16, YELLOW);
   Display_Ascii_Clockwise90(":", 200, 10+32, YELLOW);
   memset(buffer, 0, 20);
   Float2String(freq, buffer, 4);
   Display_Ascii_Clockwise90(buffer, 200, 10+32+8, ORANGE);
   Display_Ascii_Clockwise90(" Hz", 200, 10+32+8*10, YELLOW);

//period
   for (j=0; j<2; j++)
        Display_Chinese_Clockwise90(&period16K[j*32], 16, 182, 10+j*16, YELLOW);
   Display_Ascii_Clockwise90(":", 182, 10+32, YELLOW);
   memset(buffer, 0, 20);
   Float2String(1000/freq, buffer, 4);
   Display_Ascii_Clockwise90(buffer, 182, 10+32+8, ORANGE);
   Display_Ascii_Clockwise90(" ms", 182, 10+32+8*10, YELLOW);
    
//sampling rate
   for (j=0; j<2; j++)
   {
        Display_Chinese_Clockwise90(&sample16K[j*32], 16, 164, 10+j*16, YELLOW);
        Display_Chinese_Clockwise90(&frequency16K[j*32], 16, 164, 10+(j+2)*16, YELLOW);
   }
   Display_Ascii_Clockwise90(":", 164, 10+64, YELLOW);//':' and 'space'
   memset(buffer, 0, 20);
   Integer2String(samplingrate, buffer);
   Display_Ascii_Clockwise90(buffer, 164, 10+64+8, ORANGE);
   Display_Ascii_Clockwise90(" kSPS", 164, 10+64+8*6, YELLOW);
    
//peak-value
   for (j=0; j<2; j++)
        Display_Chinese_Clockwise90(&peak16K[0], 16, 200, 180+j*16, YELLOW);
   Display_Chinese_Clockwise90(&value16K[0], 16, 200, 180+2*16, YELLOW);
   Display_Ascii_Clockwise90(":", 200, 180+48, YELLOW);
   memset(buffer, 0, 20);
   Float2String(peak, buffer, 4);
   Display_Ascii_Clockwise90(buffer, 200, 180+48+8, ORANGE);
   Display_Ascii_Clockwise90(" V", 200, 180+48+8*8, YELLOW);
   
   //average value
   for (j=0; j<2; j++)
        Display_Chinese_Clockwise90(&average16K[j*32], 16, 182, 180+j*16, YELLOW);
   Display_Chinese_Clockwise90(&value16K[0], 16, 182, 180+2*16, YELLOW);
   Display_Ascii_Clockwise90(":", 182, 180+48, YELLOW);
   memset(buffer, 0, 20);
   Float2String(avg, buffer, 4);
   Display_Ascii_Clockwise90(buffer, 182, 180+48+8, ORANGE);
   Display_Ascii_Clockwise90(" V", 182, 180+48+8*8, YELLOW);
      
   //sampling point
   for (j=0; j<2; j++)
   {
        Display_Chinese_Clockwise90(&sample16K[j*32], 16, 164, 180+j*16, YELLOW);
        Display_Chinese_Clockwise90(&pointnum16K[j*32], 16, 164, 180+(j+2)*16, YELLOW);
   }
   Display_Ascii_Clockwise90(":", 164, 180+64, YELLOW);
   memset(buffer, 0, 20);
   Integer2String(ADC_Index, buffer);
   Display_Ascii_Clockwise90(buffer, 164, 180+64+8*2, ORANGE);
      
   Uart_Printf("\nPress any key to next loop.\n");
   Uart_Getch();
   Lcd_EnvidOnOff(0);
   Lcd_Port_Return();   
   Timer_Port_Return();
   Uart_Printf("\nPress any key to continue...\n");
   Uart_Getch();
   }   
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -