陌风 发表于 2024-5-29 22:30:50

由C251控制pwm引伸重入函数的一点疑问

本帖最后由 陌风 于 2024-5-30 22:10 编辑

在使用stc32fk54时,我遇到了这一个问题,我在定时器1的中断和主函数都调用了这一个函数。(比较新手,谢谢大神的解答)


void pwm_duty(PWMCH_enum pwmch, uint32 duty)
{
      uint32 match_temp;
      //读取ARR寄存器值
      uint32 arr = ((*(unsigned char volatile far *) (PWM_ARR_ADDR))<<8) | (*(unsigned char volatile far *) (PWM_ARR_ADDR + 1 ));
//arr寄存器和频率有关
//      P_SW2 |= 0x80;

      if(duty != PWM_DUTY_MAX)
      {
                match_temp = arr * ((float)duty/PWM_DUTY_MAX);                              //占空比
      }
      else
      {
                match_temp = arr + 1;
      }
      //用这个值设置比较寄存器CCR寄存器,当达到ccr寄存器的值时,输出0,没达到输出1
                                                      
      
      //设置捕获值|比较值
      (*(unsigned char volatile far *) (PWM_CCR_ADDR))                = match_temp>>8;                        //高8位
      (*(unsigned char volatile far *) (PWM_CCR_ADDR + 1))= (uint8)match_temp;                //低8位

//      P_SW2 &= ~0x80;
      
}

主函数用了while(1){pwm_duty(PWMB_CH3_P33, 5250);}定时器1放了pwm_duty(P13,1000);已知这两个通道不冲突,但是现在出现了主函数的pwm_duty(PWMB_CH3_P33, 5250),会影响P13的输出,如图是P13的波,
可是我在网络上了解到,中断时,数据会被储存到堆栈中断退出时,自动恢复这些寄存器原本的值,那么为啥定时器的函数运行,会影响到主函数呢?是形参不堆栈吗?只有形参引脚变了才会影响P13??
第二次编辑:

类比C51,我想我可能知道了大概是,C251在重入中,把局部变量重新赋值,并没有堆栈,所以导致主函数的引脚错误,而在最后设置比较值时,将match_temp也就是5250赋值给了,PWM_CCR_ADDR但是注意,这个pwmch时重写的,也就是P13。

但是说法还是有一些问题 为什么局部变量match_temp;没有改变。2 在我将这两个函数分别放在不同定时中断内,运行两分钟 没出现冲突。   希望大家能给出更具体的解答   

陌风 发表于 2024-5-29 22:32:43

我问别人说是同一函数调用,在运行过程中触发中断,改变了变量,但是还是不懂具体原因

_奶咖君_ 发表于 2024-5-30 08:50:58

C51里会有这种问题,,,C251还不太清楚,,

梁工 发表于 2024-5-30 12:04:55

陌风 发表于 2024-5-29 22:32
我问别人说是同一函数调用,在运行过程中触发中断,改变了变量,但是还是不懂具体原因 ...

所谓“重入”,即重复进入函数处理,同一个函数,如果外部程序正在调用一个函数处理,执行到中途,进入某个中断,中断又调用这个函数,则中断返回后从刚才的断点继续执行函数,此时一些变量肯恩更衣镜倍中断调用时改变了,会得到错误的结果。
处理方法:
1、程序定义为重入函数。
2、互斥调用。

陌风 发表于 2024-5-30 21:30:58

梁工 发表于 2024-5-30 12:04
所谓“重入”,即重复进入函数处理,同一个函数,如果外部程序正在调用一个函数处理,执行到中途,进入某 ...

是的,我查询了重入函数的相关概念,发现网上有很多说法,而对于c51(虽然这是C251)如果你不特别设计你的函数,它就是不可重入的。引起这个差别的原因在于:一般的 C 编译器(或者更确切点地说:基于一般的处理器上的 C 编译器),其函数的局部变量是存放于堆栈中的,而 C51 是存放于一个可覆盖的(数据)段中的。我想应该是他将局部变量的内存覆盖了,并没有堆栈。虽然没有更明确的C251定义。

陌风 发表于 2024-5-30 21:32:10

_奶咖君_ 发表于 2024-5-30 08:50
C51里会有这种问题,,,C251还不太清楚,,

是的,我有查询了资料,在这一篇文章提到了这个问题,http://blog.chinaunix.net/uid-27675161-id-3458297.html,我想可能C251中,他把局部变量重新赋值了

bkeuqoaq 发表于 2024-11-6 14:21:03

勾选产生重入函数选项

bkeuqoaq 发表于 2024-11-6 14:21:51

bkeuqoaq 发表于 2024-11-6 14:23:58

另外如果函数使用了公共变量或其它公共资源,一般是没法重入的,此情况不会警告或错误
页: [1]
查看完整版本: 由C251控制pwm引伸重入函数的一点疑问