凄雨辰 发表于 2023-3-13 09:32:37

凄雨辰 发表于 2023-3-13 09:31
把AD采集屏蔽了,就没问题了,是不是AD采集有中断,影响PWM输出呢,怎么处理呢? ...

我把PCA的优先级升高,把AD采集优先级降低,依然出问题!!!

凄雨辰 发表于 2023-3-13 09:34:03

AD中断也是关闭的

凄雨辰 发表于 2023-3-13 09:35:24

/******************* ADÅäÖú¯Êý *******************/
void        ADC_config(void)
{
        ADC_InitTypeDef                ADC_InitStructure;                //½á¹¹¶¨Òå
        ADC_InitStructure.ADC_SMPduty   = 31;                //ADC Ä£ÄâÐźŲÉÑùʱ¼ä¿ØÖÆ, 0~31£¨×¢Ò⣺ SMPDUTY Ò»¶¨²»ÄÜÉèÖÃСÓÚ 10£©
        ADC_InitStructure.ADC_CsSetup   = 0;                //ADC ͨµÀÑ¡Ôñʱ¼ä¿ØÖÆ 0(ĬÈÏ),1
        ADC_InitStructure.ADC_CsHold    = 1;                //ADC ͨµÀÑ¡Ôñ±£³Öʱ¼ä¿ØÖÆ 0,1(ĬÈÏ),2,3
        ADC_InitStructure.ADC_Speed   = ADC_SPEED_2X1T;                //ÉèÖà ADC ¹¤×÷ʱÖÓÆµÂÊ        ADC_SPEED_2X1T~ADC_SPEED_2X16T
        ADC_InitStructure.ADC_Power   = ENABLE;                                //ADC¹¦ÂÊÔÊÐí/¹Ø±Õ        ENABLE,DISABLE
        ADC_InitStructure.ADC_AdjResult = ADC_RIGHT_JUSTIFIED;        //ADC½á¹ûµ÷Õû,        ADC_LEFT_JUSTIFIED,ADC_RIGHT_JUSTIFIED
        ADC_InitStructure.ADC_Priority    = Priority_0;                        //Ö¸¶¨ÖжÏÓÅÏȼ¶(µÍµ½¸ß) Priority_0,Priority_1,Priority_2,Priority_3
        ADC_InitStructure.ADC_Interrupt = DISABLE;                        //ÖжÏÔÊÐí        ENABLE,DISABLE
        ADC_Inilize(&ADC_InitStructure);                                        //³õʼ»¯
        ADC_PowerControl(ENABLE);                                                        //µ¥¶ÀµÄADCµçÔ´²Ù×÷º¯Êý, ENABLE»òDISABLE
}这是AD初始化

梁工 发表于 2023-3-13 09:50:16

凄雨辰 发表于 2023-3-13 08:58
难道是AD影响的吗?
MCU的外设都是相互独立的。PWM是硬件PWM,不会受程序影响的。

凄雨辰 发表于 2023-3-13 11:41:03

目前发现,只要进行除法运算就会影响PWM输出呢!!!其他运算没事!!!

凄雨辰 发表于 2023-3-13 11:41:38

:L

梁工 发表于 2023-3-13 14:59:57

本帖最后由 梁工 于 2023-3-13 15:08 编辑

楼主,我从同事陈工那里拿到你的代码,发现你的不是PWM,而是高速输出,高速输出是需要时间来处理中断的,而你给的值太小了,30个时钟,11MHz时才2.7us,MCU在30个时钟内要响应中断、跳转到中断入口、现场保护(堆栈)、任务处理、现场恢复(出栈),30个时钟处于临界状态,就是说,刚好勉强够时间。
此时,主程序执行不同的指令,个别指令的执行时间多1、2个时钟,就会导致中断不能及时响应而错过重装时刻,哪怕中断设置为高优先级也一样,因为偶条指令总要执行完毕才能响应中断。
楼主的PCA中断,中断间隔至少要60个时钟,所以下面指令由30改为60,随便你主程序怎么写都不会有问题。
//      PWMn_Update(2,30);   //30个时钟太短了
      PWMn_Update(2,60);//要求60个或以上时钟数

下面是楼主的中断处理程序:
void      PCA_Handler (void) interrupt PCA_VECTOR
{
      if(CCF2)      //PCA模块2中断
      {
                CCF2 = 0;                //清PCA模块1中断标志
                if(P37)      CCAP2_tmp += PCA_Timer2;      //输出为高电平,则给影射寄存器装载高电平时间长度
                else      CCAP2_tmp += PWM2_low;      //输出为低电平,则给影射寄存器装载低电平时间长度
                CCAP2L = (u8)CCAP2_tmp;                        //将影射寄存器写入捕获寄存器,先写CCAP0L
                CCAP2H = (u8)(CCAP2_tmp >> 8);      //后写CCAP0H
      }

      if(CF)      //PCA溢出中断
      {
                CF = 0;                        //清PCA溢出中断标志
      }
}


比如某一时刻PCA发起中断,之后CH、CL继续计数,响应PCA中断,计算重装时间,重装低字节,此时CH CL计数值刚好超过这个重装时间值,只能等走一圈回来才能匹配,而走一圈的时间刚好是65536/11.0592=5926us=5.9ms,就出现楼主所说的,时不时出现6ms的高电平,而上述中断就是装载匹配低电平的时间错过,所以5.9ms后才能再次匹配。


楼主的周期是270个时钟,同理,如果你给定 PWMn_Update(2,240);那么,你就会看到,时不时会有连续5.9ms的低电平出现。

梁工 发表于 2023-3-14 16:19:36

楼主看到了吗?一直没看到回复。

凄雨辰 发表于 2023-3-15 10:16:53

嗯嗯,看到了,陈工给问题解决了,多谢!!!

凄雨辰 发表于 2023-3-15 10:17:51

梁工 发表于 2023-3-14 16:19
楼主看到了吗?一直没看到回复。

陈工把问题给解决了,昨天没有看贴吧!:lol
页: 1 2 [3] 4
查看完整版本: 用STC8G1K08 16pin的单片机PCA输出PWM问题在线等