这两天做了一款产品,在编程时使用两个定时器同时工作就没起作用了,芯片手册也看了,也调试了N次还是这样,请各位大神指点下
程序如下:- #include "STC15W.H"
- #include"intrins.h"
- #define uchar unsigned char
- #define uint unsigned int
- #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 LED_Time1 500
- #define LED_Time2 3000
- void LED_TSK1(void);
- void LED_TSK2(void);
- void keyScan();
- void key_tak();
- void time0_Init(void);
- void t2int();
- void timer0();
- void time2_Init(void);
- void LED_san();
- void AD_ris();
- uint temper,tt=0;
- uint set_sum=0; //设定温度
- uchar num=0,time=0,n,c,g;
- uchar ZKB=100; //占空比调节参数
- volatile uchar key_sec=0;
- uchar kp,ki,kd;
- int e1,e2,e3,duk,uk;
- uint data1=0,data2=0,data3=0,temp=0,volatge=0,NTC_bat=0;
- uchar ADC_chunal_rnt=0;
- volatile uint s1=0,s2=0,j=0,m=0,d=0; //定时时间
- //bit flag1=0,flag2=0;
- sbit LED=P3^3;
- sbit Pout=P1^4; //开机/关机
- sbit PINT=P1^5;//检测
- sbit key=P1^3;
- sbit PWM_out=P3^6;
- /**********延时子程序**********/
- void Delay(uint z)
- {
- uint y,x;
- for(y=0;y<z;y++)
- for(x=0;x<120;x++);
- }
-
- /*********定时器初始化*********/
- void time0_Init(void)
- {
- // AURX=0x7f; //定时器时钟12T模式
- TMOD&=0xf0;
- TMOD|=0x01; //设置定时器模式
- TL0=0x9C; //设置定时初值100uS
- TH0=0xFF; //设置定时初值
-
- TF0=0; //清除TF0标志
- ET0=1;
- EA=1;
- TR0=1;
- }
- void time2_Init(void)
- {
- AUXR&=~0x04; //12T模式
- T2L=0x18; //设置定时初值 1ms
- T2H=0xfc; //设置定时初值
- AUXR|=0x10; //定时器0开始计时
- IE2|=0x04;
- EA=1;
- }
- /************IO初始化*************/
- void IO_Init(void)
- {
- P1M0=0X10;
- P1M1=0X2E;
- P3M0=0X48;
- P3M1=0X00;
- P5M0=0X00;
- P5M1=0X00;
- }
- /***************AD初始化*****************/
- void ADC_Init()
- {
- P1ASF=0x07; //设置P1.2和P1.1,P1.0为模拟输入
- ADC_RES=0;
- ADC_RESL=0;
- ADC_CONTR=0x80;
- Delay(1);
- if(ADC_chunal_rnt%3==0) //外部基准电压
- {
- ADC_CONTR=0xf4;//设P1.2口转换,90个时钟周期转换一次。
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- ADC_CONTR=0xe8;//(1110 1000)清零
- }
- if(ADC_chunal_rnt&3==1)
- {
- ADC_CONTR=0xe2;//设P1.1口转换,90个时钟周期转换一次。
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- ADC_CONTR=0xe8;//(1110 1000)清零
- }
- if(ADC_chunal_rnt%3==2)
- {
- ADC_CONTR=0xe1;//设P1.0口转换,90个时钟周期转换一次。
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- ADC_CONTR=0xe8;//(1110 1000)清零
- }
- }
- /***************ADC处理********************/
- void AD_ris() interrupt 5
- {
- ADC_CONTR &= !ADC_FLAG; //清除ADC中断标志
- if(ADC_chunal_rnt%3==0) //外部基准电压 (PTC采样处理)
- {
- data1=ADC_RES*4+ADC_RESL;//高八位+低两位结果
- for(n=0;n<10;n++) //采样10次滤波
- {
- temp+=data1;
- }
- temp=temp/10;
- }
- if(ADC_chunal_rnt%3==1) //外部电压设置值处理
- {
- data2=ADC_RES*4+ADC_RESL;
- for(c=0;c<10;c++)
- {
- volatge+=data2;
- }
- volatge=volatge/10;
- }
- if(ADC_chunal_rnt%3==2) //外部电池温度检测采样处理
- {
- data3=ADC_RES*4+ADC_RESL;
- data3=(uint)(data3*5)/1024;
- for(g=0;g<10;g++)
- {
- NTC_bat+=data3;
- }
- NTC_bat=NTC_bat/10;
- }
- }
- /*****************PID初始化****************/
- void PID_Init()
- {
- ZKB=0; //输出占空比
- e1=0; //本次的温度差
- e2=0; //前一次温度差
- e3=0; //前两次温度差
- kp=10; //比例值
- ki=0; //积分值
- kd=0; //微分值
- }
- /******************温度比较处理及PID运算*********************/
- void PID_compare_temp()
- {
-
- if(set_sum>temper) //如果设定温度大于实际温度
- {
- if(set_sum-temper>20) //如果相差20度
- {
- ZKB=100; //全速加热
-
- }
- else //否则进行PID运算平滑加热
- {
- e1=set_sum-temper;
- duk=(kp*(e1-e2)+ki*e1+kd*(e1-e2*2+e3))/10;
- uk=uk+duk;
- if(uk>100)
- uk=100;
- else
- if(uk<-100)
- uk=-100;
- if(uk<0)
- {
- ZKB=-uk;
- }
- else
- {
- ZKB=uk;
- }
- e3=e2;
- e2=e1;
- }
- }
- if(temper>=set_sum) //如果实际温度大于设定温度
- {
- if(temper-set_sum>0) //如果实际温度与设定温度不相等
- {
- ZKB=0; //停止加热
-
- }
- else
- {
- e1=temper-set_sum;
- duk=(kp*(e1-e2)+ki*e1+kd*(e1-e2*2+e3));
- uk=uk+duk;
- if(uk>100)
- uk=100;
- else
- if(uk<-100)
- uk=-100;
- e3=e2;
- e2=e1;
- }
- }
- }
-
- /********定时器0***********/
- void timer0() interrupt 1
- {
-
- TL0=0x9C; //设置定时初值 0.1ms
- TH0=0xFF; //设置定时初值
- time++;
- num++;
- if(num>=100)
- num=0;
- if(num<ZKB)
- PWM_out=1;
- else
- PWM_out=0;
- }
-
- /*********定时器2**********/
- void t2int() interrupt 12 //5ms定时
- {
- keyScan();
- m++;
- j++;
- if(m>=5)
- {
- m=0;
- ADC_Init(); //ADC每5MS转换一次通道
- }
- if(j==500) //0.5秒
- {
- j=0;
- s1++;
- if(s1==2000)//10分钟后停止输出
- {
- s1=0;
- TR0=0;
- s2++;
- }
- }
-
- // IE2&=~0x04; //清中断标志
- // IE2|=0x04; //再开中断
- }
- /**********LED闪**********/
- void LED_TSK1(void)
- {
- if(time>=5000)//0.5秒
- time=0;
- LED=!LED;
- /* Delay(1000); //约0.5秒闪
- LED=0;
- Delay(1000);
- LED=1;*/
- }
- void LED_TSK2(void) //约3秒闪
- {
- Delay(20000);
- LED=0;
- Delay(20000);
- LED=1;
- }
-
- /***********按键扫描及处理*************/
- void keyScan()
- {
- // static uchar tt=0;
- static bit key1_lock=0;
- static uchar count1=0;
-
- if(0==key)
- {
- if((count1++>=25)&&(key1_lock==0)&&(PINT==1))//延时滤波25ms
- {
- key1_lock=1;
- TR0=~TR0;
- LED_TSK2();
- }
-
- }
- else
- {
- key1_lock=0;//按键自锁标志清0
- count1=0; //消抖计数清0
- }
- if(PINT==0)
- {
- Pout=0;
-
- }
- }
- /*void key_tak()
- {
- if(key_sec==0)
- {
- return;
- }
- switch(key_sec)
- {
- case 1:
- TR0=~TR0;
- LED=0;
- key_sec=0;
- break;
- }
- } */
- /************判断LED闪烁处理***********/
- void LED_san()
- {
- if(temper<300)
- {
- LED_TSK1();
- }
- else
- if(temper>=300)
- {
- LED=1;
- }
-
- if((PWM_out==0)&&(tt++>=10000))
- {
-
- tt=0;
- LED_TSK2();
- }
- }
- /*void NTC_asc()
- {
- if(NTC_bat<=400)
- {
- Pout=0;
- PWM_out=0;
- }
- } */
-
- /**********主程序**********/
- void main()
- {
- Delay(100);
- time0_Init();
- time2_Init();
- IO_Init();
- PID_Init();
- while(1)
- {
- set_sum=volatge;//装载设定值
- temper=temp;//给PID装载实际值
- PID_compare_temp();
- // LED_san();
- LED_TSK1();
- if(s2==2)//20分钟后关机
- {
- s2=0;
- Pout=0;
- }
- }
- }
|