我用C8051F340的定时器0输出了一个250Hz的PWM(没用PCA模块是因为PCA输出的PWM好像到不了这么低的频率),我要用这个PWM去调节并输出一个电压,然后再用C8051F340内部的ADC0去采集硬件输出的电压值,再用程序实现闭环控制,定时器输出PWM的程序是从网上找的,如下:
- void timer0(void) interrupt 1 using 1 //Timer0,8位重装 ,时钟源500kHz,TH =(256-100)
- {
- uint8 count;
- aaaa = 1; //用于示波器测量
- i_PWM++;
- if(i_PWM==2)
- {
- i_PWM = 0;
- j_PWM++;
- j_PWM = j_PWM%10;
- }
-
- if(j_PWM>=duty) //duty改变占空比
- {
- pwm_out = 0;
- }
-
- else
- {
- pwm_out = 1;
- }
- aaaa = 0; //用于示波器测量
- AD0BUSY = 1;//软件开启ADC0测量
- }
复制代码定时器中断程序的思路是:定时器输出完PWM之后,再打开ADC0启动转换信号,这样会输出一个5kHz的AD采样频率(定时器设置的就是5k),也就是说,在1个PWM波里面进行20次采样;ADC0的转换完成中断是允许的,即EADC0 = 1;ADC0的时钟源(SAR CLK)设置的2MHz;低功耗跟踪模式;右对齐;AD0BUSY触发模式;ADC0的中断程序如下:
- void ADC0_interrupt(void) interrupt 10
- {
- bbbb = 1; //用于示波器测量
- temp_ADC0[i_ADC0]= ADC0H*256+ADC0L;
- v_value = v_value+temp_ADC0[i_ADC0-1];//20次采样求和
- if(i_ADC0 == 20)
- {
- i_ADC0 = 0;
- vout = v_value/20;
- }
-
- i_ADC0++;
- AD0INT = 0;
- bbbb= 0; //用于示波器测量
- }
复制代码上面两个程序都有配置用于示波器测量的外置引脚(变量aaaa和变量bbbb),示波器测量得到的波形如下:
黄 {MOD}的为定时器中断里的aaaa信号,相位靠前;绿 {MOD}的为ADC0中断里的bbbb信号,相位靠后,其中bbbb有一段高电平较长的波段,那个是在第20次中断里面做的除法运算,所以耗时较长。
/*********************************************************************************/
问题是:在允许了ADC0的中断后,定时器0的PWM没有了,但从上图示波器的情况可以看出,定时器0中断进去了,而且里的程序跑完了(因为有aaaa的下降沿)。然后我去掉ADC0的中断后,PWM波就恢复正常了;于是我debug进行单步调试,发现timer0中断里面PWM输出的相关程序只运行了20次,即,前20次定时器中断里面,一切正常,输出了一个PWM波,之后,定时器0里面的整个一段程序就不执行了,不执行的程序如下:
- if(i_PWM==2)
- {
- i_PWM = 0;
- j_PWM++;
- j_PWM = j_PWM%10;
- }
- if(j_PWM>=duty) //duty改变占空比
- {
- pwm_out = 0;
- }
- else
- {
- pwm_out = 1;
- }
复制代码debug中看到i_PWM跑飞了(本来应该只是0、1、2三个值循环的),说明上面的程序在定时器0中断里面没在跑,这程序为啥还能跳过去了呢?求各位大神帮忙解决一下呀
一周热门 更多>