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 + -
显示快捷键?