📄 spy主控程序ok.c
字号:
/* Set baud rate */
UBRRH = (unsigned char)(baud>>8); //由于在20MHZ以下晶振,baud右移8位后最高位肯定位0,所以访问的是UBRRH
UBRRL = (unsigned char)baud;
/* Enable receiver and transmitter */
UCSRB = (0<<RXEN)|(0<<TXEN);
/* Set frame format: 8data, 1stop bit */
UCSRC = (1<<URSEL)|(3<<UCSZ0);
}
/*d指向发送缓冲区,a发送字节数*/
void send_sp(unsigned char *d,uchar a)
{
uchar i;
UCSRB_TXEN=1;
/* 等待发送缓冲器为空 */
while(!( UCSRA & (1<<UDRE)));
//pf=0;
for(i=0;i<a;i++)
{
UDR=d[i];
//pf+=d[i];
while(UCSRA_TXC==0);
UCSRA_TXC=1;
//WDR();
}
UCSRB_TXEN=0;
}
//----------------------------------------------------------------------------------------------//
/*显示增益数字电位器抽头加1子程序*/
void X9C104_up()
{
uchar j;
CS2=0;
if(reso_num!=99)
{
UD=1;
INC=1;
j=20;
do{__delay_cycles(1);} while(--j!=0);
INC=0;
j=20;
do{__delay_cycles(1);} while(--j!=0);
INC=1;
reso_num++;
//save_data(2);
}
CS2=1;
}
/*显示增益数字电位器抽头减1子程序*/
void X9C104_down()
{
uchar j;
CS2=0;
if(reso_num!=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;
reso_num--;
}
CS2=1;
}
/**********************************以下是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<16;i++) //连续采样16次在求平均值
{ 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();
*/
}
// current =ad1>>2; // ad1/4送current
voltage=ad0>>4; // ad0/16送voltage
ad0=0;temp=0;
//ad1=0;
}
/**********************************以上是A/D转换程序**********************************************************************************/
//---------------------------------------------幅度调节函数----------------------------------------------------------------------------------//
void fudutiaojie()
{
PORTB_Bit4=0;
PORTB_Bit3=0;
loop5: YS=65535;
do{__delay_cycles(2);} while(--YS!=0); //延时23us,有待信号幅值稳定下来在进行AD测量
AD(); //启动AD转换函数,
Uad3=voltage*2.5;
if(Uad3>=plus)
{ while((Uad3>plus+4)&&(reso_num>0))
{ X9C104_down();
YS=65535;
do{__delay_cycles(1);} while(--YS!=0); //延时23us,有待信号幅值稳定下来在进行AD测量
AD(); //启动AD转换函数,
Uad3=voltage*2.5;
}
if((Uad3<=plus+4)&&(Uad3>=plus-4)) //判断是否在预输出值允许误差内之间
{ YS=65535;
do{__delay_cycles(1);} while(--YS!=0);
AD(); //启动AD转换函数,
Uad3=voltage*2.5;
BL.plus_out=Uad3; //输出Uad3
send_buf[1]=0x11;
send_buf[2]=BL.plus_out&0x00ff;
send_buf[3]=(BL.plus_out&0xff00)>>8;
send_sp(send_buf,4); // 先发送为扫频议发出的幅值低8位,在发送为扫频议发出的幅值高8位
diss(11);//显示监视值
return;//goto loop2;
}
if(Uad3<plus-4) //说明:Uad3<plus-2,为了调试用
{if(reso_num<=0) {YS=65535;
do{__delay_cycles(1);} while(--YS!=0);
AD(); //启动AD转换函数,
Uad3=voltage*2.5;
BL.plus_out=Uad3; //输出Uad3
send_buf[1]=0x11;
send_buf[2]=BL.plus_out&0x00ff;
send_buf[3]=(BL.plus_out&0xff00)>>8;
send_sp(send_buf,4); // 先发送为扫频议发出的幅值低8位,在发送为扫频议发出的幅值高8位
diss(22);
//goto loop4;
return;
} //说明电位器出头调到头了,无法在调小了
else {PORTB_Bit4=1;diss(33);goto loop4;}//灯亮说明:Uad3<plus2-2,为了调试用
}
}
loop4: if((Uad3<plus)||(Uad3<plus-4))
{ while((Uad3<plus-2)&&(reso_num<99))
{ X9C104_up();
YS=65535;
do{__delay_cycles(1);} while(--YS!=0); //延时23us,有待信号幅值稳定下来在进行AD测量
AD(); //启动AD转换函数,
Uad3=voltage*2.5;
}
if((Uad3<=plus+4)&&(Uad3>=plus-4))
{ YS=65535;
do{__delay_cycles(1);} while(--YS!=0);
AD(); //启动AD转换函数,
Uad3=voltage*2.5;
BL.plus_out=Uad3; //输出Uad3
send_buf[1]=0x11;
send_buf[2]=BL.plus_out&0x00ff;
send_buf[3]=(BL.plus_out&0xff00)>>8;
send_sp(send_buf,4); // 先发送为扫频议发出的幅值低8位,在发送为扫频议发出的幅值高8位
diss(44);
return;//goto loop2;
}
if(Uad3>plus+4) //说明:Uad3>plus+2
{if(reso_num>=99) {YS=65535;
do{__delay_cycles(1);} while(--YS!=0);
AD(); //启动AD转换函数,
Uad3=voltage*2.5;
BL.plus_out=Uad3; //输出Uad3
send_buf[1]=0x11;
send_buf[2]=BL.plus_out&0x00ff;
send_buf[3]=(BL.plus_out&0xff00)>>8;
send_sp(send_buf,4); // 先发送为扫频议发出的幅值低8位,在发送为扫频议发出的幅值高8位
diss(55);
// goto loop5;
return;
} //说明电位器出头调到头了,无法在调大了
else {PORTB_Bit3=1;diss(66);goto loop5; }//灯亮说明:Uad3>plus+2,为了调试用
}
}
}
//----------------------------------------------------------------------------------------------------------------//
//定时器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;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -