spy主控程序阶段1.c

来自「此程序主要测试50HZ~3KHZ音频范围幅频特性测试程序.程序包含主控程序和显示」· C语言 代码 · 共 893 行 · 第 1/3 页

C
893
字号
	}
	
}

/*显示增益数字电位器抽头减1子程序*/
void X9C104_down()
{
	uchar j;
	
	if(reso_num!=0)
	{       CS2=0;
		UD=0;
		INC=1;
		j=20;
		do{__delay_cycles(1);} while(--j!=0);
		INC=0;
		j=20;
		do{__delay_cycles(1);} while(--j!=0);
		INC=1;CS2=1;
		reso_num--;
		
	}
	
}
  
  

/**********************************以下是A/D转换程序*************************************************************************************/
void adc_init(void)     //A/D转换初始化函数
{
  ADMUX=(1<<REFS1)|(0<<ADLAR)|(1<<REFS0);   /*选择2.56V的片内基准电压源, AREF 引脚外加滤波电容,数据为右对齐,通道AD0*/


  ADCSRA=(1<<ADEN)|(0<<ADIE)|(1<<ADPS2)|(1<<ADPS1); //自动触发使能,中断使能,预分频器为64,11059.2/64=172.8khz
  ADCSRA_Bit5=0;

  SFIOR=(0<<ADTS2)|(0<<ADTS1)|(0<<ADTS0);  //触发源为:连续转换模式
}

/*a内存ADC转换的通道号*/
void start_adc(uchar a)
{
  ADMUX=0x40|a;		//ADC允许中断,采样通道为a
  ADCSRA_ADEN=1;        //使能ADC
  ADCSRA_ADSC=1;	//启动第一次AD转换
}
void close_adc()
{
   ADCSRA_ADEN=0;         //关闭ADC
}

void AD(void)  //AD转换函数
{ uchar i;
  uint temp=0;
  uint temp2=0;
  uint ad0=0;
//  uint ad1=0;
  for(i=0;i<4;i++)
   { start_adc(0);
     while(ADCSRA_ADSC); //转换未结束则等      //以下是AD延时时间的计算:延时0.7ms足够4次AD转换时间了,因AD转换为自动触发的连续转换模式,此模式下AD转换一次
                        //这里是读转换标志位   //所需时间为13.5个AD时钟周期, AD时钟周期为T=1/(11.0592/64(分频))=0.005787ms,这里为每次
                        //来判断AD转换是否完成 //AD转换设余量30个AD时钟周期,那么4次AD转换为:0.005787*30*4=0.697ms=0.7ms
     close_adc();
     temp=ADCL;
     temp2=ADCH & 0x03;
     temp=(temp2<<8)|temp;
     ad0=temp+ad0;

     close_adc();
     temp=0;

  /*  start_adc(3);          //ADCDATA=0;
     while(ADCSRA_ADSC);    //营换未结束则等
     temp=ADCL;
     temp2=ADCH & 0x03;
     temp=(temp2<<8)|temp;
     ad1=temp+ad1;
      close_adc();
  */
    }  

   voltage=ad0>>2; // ad0/4送voltage
 //  current =ad1>>2; // ad1/4送current
   ad0=0;temp=0;
   //ad1=0;
}
/**********************************以上是A/D转换程序**********************************************************************************/


//定时器T1,用来产生50HZ~3KHZ脉冲
void timer1_init(void)      //定时1器配置函数
{        //TCCR1A为控制寄存器A              /.COM1A1=0,COM1A0=1  比较输出模式,快速PWM
  TCCR1A=(0<<COM1A1)|(1<<COM1A0)|(1<<WGM11)|(1<<WGM10);  //WGM10=1 WGM11=1  WGM12=1  WGM13=1    波形产生模式(15)为快速PWM模式
  TCCR1B=(1<<WGM12)|(1<<WGM13)|(0<<CS12)|(1<<CS11)|(0<<CS10);  // CS10=0  CS11=1  CS12=0  时钟选择位模式为8分频模式 晶震用的是f=11.0592MHZ
                                                               //即Tf=11.0592/8=1.3824MHZ
  OCR1A=13823; //输出比较寄存器=39->时钟周期,也就是TT=0.7233796296us, T=1/50hz=20000us (此分频模式下Fmax=1/(x(1)*0.7233796296*2)=1/1.4467592592us=691.2khz)   
            //20000/1.4467592592=13824   所以OCR1A=13823 (此分频模式下Fmin=1/(65535*0.7233796296*2)= 1/94813.368051672us=10.547hz  )  
 
  TCNT1=0X00;
}


/*
//定时器T2:普通模式;允许中断。用来延时
void ini_t2(void)  //50us中断一次
{
TCNT2=253;  // T=1/11.0592MHZ=0.0904224537us,采用256分频(TCCR2=0X06)所以TCNT数值改变一次时间就变化为TT=256*0.0904224537=23.1481481472us
TCCR2 =0;   //   0.05ms/0.023148148147ms=2.16  255-2=253=TCNT      
TIMSK_TOIE2=1;
}


#pragma vector=TIMER2_OVF_vect   //定时器0中断函数50us中断一次
__interrupt void timer2(void)
{ 
  TCCR2=0;TIMSK_TOIE2=0; //关中断
  TCNT2=253; //重新赋计数器初值
  yihaomiao++;  //中断次数标志+1
  if(yihaomiao>20) { yihaomiao=1; }
  TCCR2=0x06;//启动定时器2
}

*/


//定时器T0:普通模式;允许中断,用来控制扫频状态时的速度
void ini_t0(void)   //23.6ms中断
{
TCNT0=0;    // T=1/11.0592MHZ=0.0904224537us,采用1024分频(TCCR0=0X05)所以TCNT数值改变一次时间就变化为TT=1024*0.0904224537=92.5925925888us
TCCR0=0;    //23.6ms/0.0925925925888ms=255  256-255=1=TCNT 
TIMSK_TOIE0=1;
}


/*
#pragma vector=TIMER0_OVF_vect
__interrupt void timer0(void)   //定时器0中断函数 23.6ms中断一次
{
 uchar jj;
 TCCR0=0;TCNT0=0; 
 PORTB_Bit3=!PORTB_Bit3;
 //++ZDCSBZ;  //中断次数标志加1
// if(ZDCSBZ>3) { ZDCSBZ=1;} 
// if(ZDCSBZ==3) //17.7ms到了么?
  {   
    PORTB_Bit2=!PORTB_Bit2; //灯亮,为了调试用
    if(*(++ff)<f_sectmax) //判断本频段扫频完了么?
      { if(single_cycle==2) //判断当前状态为循环扫频么?
           {  ff=0; u_number=0; //复位频率和幅值指针,使其还指向本频段的首址
           }
        if (single_cycle==1) //判断当前状态为循环扫频么?
              { swept_flag=0;//置为非扫频状态标志 
                f_sect=1;// 置默认扫频频段标志为A频段
              }
       } 
         PORTA_Bit2=0;  //切换CD4066开关为内AD采样模式
         PORTA_Bit3=1;
         PORTA_Bit4=1; 
         jj=1;  
         do{__delay_cycles(1);} while(--jj!=0); //延时23us,有待信号幅值稳定下来在进行AD测量   
         AD(); //启动AD转换函数,
         Ui=voltage*2.5; //记录扫频议切换到内部发出幅值
         PORTA_Bit2=1;  //切换CD4066开关为外AD采样模式
         PORTA_Bit3=0;
         PORTA_Bit4=0;
         jj=1; 
         do{__delay_cycles(1);} while(--jj!=0); //延时23us,有待信号幅值稳定下来在进行AD测量   
         AD(); //启动AD转换函数,
         Uo=voltage*2.5; //记录扫频议切换到外部发出幅值
         BL.u_ratio=Uo/Ui;    //求得幅值比
         
         aa_u[++u_number]=BL.u_ratio;//记录幅值比
         
         send_buf[1]=0x92; 
         BL.zancun=1000000/((*ff)*1.4467592592);
         send_buf[2]=BL.zancun&0x00ff; //取得低8位
         send_buf[3]=(BL.zancun&0xff00)>>8; //取得高8位
         send_sp(send_buf,4); //先发送频率低8位,在发送频率高8位
         YS=1;
         do{__delay_cycles(1);} while(--YS!=0); //延时23us,以使显示刷新 '' __delay_cycles(1)''延时一个机器周期即:1/11.0592MHZ0.0904224537us
        
         send_buf[1]=0x94;  //发送幅值低8位
         send_buf[2]=BL.u_ratio&0x00ff; //取得低8位
         send_buf[3]=(BL.u_ratio&0xff00)>>8; //取得高8位
         send_sp(send_buf,4); //先发送幅值低8位,在发送幅值高8位
         
         OCR1A=*(++ff); //更新PWM频率修改参数  
         
   }
 TCCR0=0x05;
}

  */

void init_port(void)  //I/0口初始化
{ DDRC=0xC0;   //=0为输入,=1为输出
  DDRD=0xFC;
  DDRA=0xFC;
  DDRB=0xFF;
  PORTC=0xFF;
  PORTA=0xFC;
  PORTB_Bit4=0;  //为了调试用
  PORTB_Bit3=0;  //为了调试用
  PORTB_Bit2=0;  //为了调试用
  PORTB_Bit1=0;  //为了调试用
}



    void main(void)
     {uchar i,j;
      //uchar jj;
       init_port();  //I/O口初始化
       
       usart_init(71);  //异步串口初始化,9600 BAUD RATE
       adc_init();   //A/D转换初始化函数
      
       ini_t0();   //定时器0初始化 5.9ms中断一次 
     //  ini_t2();   //定时器0初始化 50us中断一次 
        __enable_interrupt(); // 启动全局中断
    while(1)
{   

 loop2:  
       if(swept_flag) //判断当前还处于扫频状态么?
         { 
           if(single_cycle==2) //判断当前状态为循环扫频么?
           { 
            key=0xff;
            key=kbscan();//调用键盘扫描
            
            if(key==0x3e)//是暂停键按下了么?
             {  
                    ++start_pause;  
                    if(start_pause>2) {start_pause=1;}  
                    if(start_pause==2) //是暂停功能键按下么?
                      { 
                        //diss(start_pause);//显示监视值 
                        
                        start_pause=0;  
                        swept_flag=0;//置为非扫频状态标志
                        TCCR1B=(0<<CS12)|(0<<CS11)|(0<<CS10); //关频率产生PWM定时器1,CS10=0,CS11=0,CS12=0 为无时钟源,所以T/C1停止             
                      //  TCCR0=0;  //关闭扫频时间控制定时器0, 
                       saopin=0; //清扫频标志位
                        goto loop2;
                        }
                     else   goto loop3; 
                   }      
               }
            loop3: if(saopin==1)    //扫频状态位置位了么? //否则位单次扫频 
                    {   
                     if((*(++ff))<f_sectmax) //判断本频段扫频完了么?
                      { 
                        if(single_cycle==2) //判断当前状态为循环扫频么?
                          {ff=0; u_number=0; //复位频率和幅值指针,使其还指向本频段的首址
                         
                          }
                        if (single_cycle==1) //判断当前状态为单次扫频么?
                          { swept_flag=0;//置为非扫频状态标志 
                            f_sect=1;// 置默认扫频频段标志为A频段
                            TCCR1B=(0<<CS12)|(0<<CS11)|(0<<CS10); //关频率产生PWM定时器1,CS10=0,CS11=0,CS12=0 为无时钟源,所以T/C1停止 
                            saopin=0; //清扫频标志位 
                          }   
                          
                       } 
                      PORTA_Bit2=0;  //切换CD4066开关为内AD采样模式
                      PORTA_Bit3=1;
                      PORTA_Bit4=1; 
                      YS=55296;  
                      do{__delay_cycles(1);} while(--YS!=0); //延时5ms,有待信号幅值稳定下来在进行AD测量   
                      AD(); //启动AD转换函数,
                      
                       
                      PORTB_Bit1=!PORTB_Bit1; //灯亮,为了调试用
                      Ui=voltage*2.5; //记录扫频议切换到内部发出幅值
                    
                      
                      PORTA_Bit2=1;  //切换CD4066开关为外AD采样模式
                      PORTA_Bit3=0;
                      PORTA_Bit4=0;
                      YS=55296; 
                      do{__delay_cycles(1);} while(--YS!=0); //延时5ms,有待信号幅值稳定下来在进行AD测量  
                      
                      AD(); //启动AD转换函数,
                      
                      Uo=voltage*2.5; //记录扫频议切换到外部发出幅值

                      BL.u_ratio=Uo/Ui;    //求得幅值比
                     
                      
                      aa_u[++u_number]=BL.u_ratio;//记录幅值比
 
                       
                      
                      send_buf[1]=0x92; 
                    
                      BL.zancun=1000000/((*ff)*1.4467592592);
                     

⌨️ 快捷键说明

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