STC单片机比较器用作AD例程
所有源程序下载:
比较器做AD用.zip
(49.18 KB, 下载次数: 123)
部分源码预览:
- //工作频率为20M
- #include <STC15F2K60S2.H>
- #include <intrins.h>
- #include"CMP-AD.H"
- #include"math.h"
- #define uint unsigned int
- #define ulint unsigned long int
- #define uchar unsigned char
- //对ADC控制寄存器ADC_CONTR进行位定义 (ADC_CONTR寄存器不能进行位操作)
- #define ENABLE_IAP 0x82 //if SYSCLK<20MH
- #define ADC_POWER 0x80 //ADC电源控制位
- #define ADC_FLAG 0x10 //ADC完成标志
- #define ADC_START 0x08 //ADC起始控制位
- #define ADC_SPEEDLL 0x00 //540个时钟
- #define ADC_SPEEDL 0x20 //360个时钟
- #define ADC_SPEEDH 0x40 //180个时钟
- #define ADC_SPEEDHH 0x60 //90个时钟
- #define CH6 6
- sfr ADC_LOW2=0XBE; //ADC低2位结果
- //sbit P_ADC=P3^3; //定义比价器的输出口
- sbit P_ADC=P1^4; //定义比价器的输出口
- sbit power=P3^3; //主电源开机使能位
- sbit in_ac=P3^2; //AC输入电压类型 1:AC60V 0:AC90v
- sbit smg1=P1^5;
- sbit smg2=P1^6;
- sbit smg3=P1^7;
- uchar ch=0;
- uchar i_t2;
- uint t0val; //定时器0的初值
- uint t2val; //定时器2的初值
- uint adc_scal; //AD量程
- uint adc_count; //比较结果为高计数
- uint adc_duty; //ADC计数周期
- uint adc_val; //ADC值
- bit adc_ok; //ADC转换完成标志
- uchar ok_count; //AD采集次数
- bit one_ok; //取样完成标志
- ulint val1,val2; //中间临时值
- uint rmsval; //输入电压有效值
- uchar smgval[11]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
- uchar temp[4];
- uchar i;
- //1ms延时子程序
- void delay(uint x)
- {uint a,b;
- for (a=x; a>0;a--)
- for (b=100;b>0; b--);
- }
- //AD初始化程序
- void intad()
- { ch=0;
- P1ASF = 0x01 ; //设置P1口为AD口
- ADC_RES = 0; //清除结果寄存器
- ADC_CONTR = ADC_POWER | ADC_SPEEDHH | ADC_START | ch;
- delay(2);
- }
- //读取AD结果
- int getad()
- {ADC_CONTR=ADC_POWER|ADC_SPEEDHH|ch|ADC_START;
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- while(!(ADC_CONTR&ADC_FLAG)) ;
- ADC_CONTR=~ADC_CONTR;
- return ((uint)((uint)(ADC_RES<<2)+(uint)(ADC_LOW2)));
- }
- //主程序初始化
- void int_main()
- {
- intad();
- P3M1=0;
- P3M0=0XFF;
- P1M1=0;
- P1M0=0Xf0;
- /////////////
- power=0;
- in_ac=1; //刚上电时候先关闭主电源
- P5M1=0XFF;
- P5M0=0; //P54 P55设为高阻状态
- adc_scal=500; //AD量程
- adc_duty=adc_scal;
- //P3M0=0X80; //P33为强推挽模式 P32为准双向口模式
- CMPCR1=0; //比价器寄存器1初始化
- CMPCR2=0; //比较器寄存器2初始化
- CMPCR1&=~PIS; //选择P55脚为比较器的正极输入端
- CMPCR1|= NIS; //选择P54脚为比较器的负极输入端
- CMPCR1&=~CMPOE; //禁止比较器的结果输出
- CMPCR2&=~INVCMPO; //比机器结果正常输出
- CMPCR2|=DISFLT; //不使能比较器输出0.1us滤波
- CMPCR2&=~LCDTY; //比较器结果不去抖 直接输出
- CMPCR1|=CMPEN; //使能比机器
- t0val=55536; //定时器0定时时间为0.5ms
- t2val=45536; //定时器0定时时间为1ms
- TH0=t0val>>8;
- TL0=t0val;
- T2H=t2val>>8;
- T2L=t2val;
- AUXR=0X94; //定时器0的速度为传统8051的12倍,即不分频 允许定时器2运行 速度为1分频
- //IE2|=ET2; //定时器2中断开启
- TMOD=0; //定时器0工作模式为16位自动重装
- ET0=1; //允许T0中断
- TR0=1; //定时器0使能
- PT0=1; //定时器0中断为最高优先级中断
- EA=1; //开启总中断
- }
- main()
- {
- int_main();
- while(1)
- {
- //if(adc_ok==1)
- {
- adc_ok=0;
- temp[0]=rmsval/100;
- temp[1]=rmsval%100/10;
- temp[2]=rmsval%100%10;
- }
- P3=smgval[temp[0]];
- smg1=1;
- delay(5);
- smg1=0;
- P3=smgval[temp[1]];
- smg2=1;
- delay(5);
- smg2=0;
- P3=smgval[temp[2]];
- smg3=1;
- delay(5);
- smg3=0;
- }
- }
- //定时器中断0入口
- void t0() interrupt 1
- {
- ulint ls1,ls2,ls3;
- i_t2++;
- ls1=getad();
- ls2=ls1*ls1;
- val1=val1+ls2;
- if(i_t2>=200)
- {
- i_t2=0;
- ls3=sqrt(val1/200);
- val1=0;
- rmsval=ls3*90/594 ;
- }
- }
复制代码
|