STM32
直播中

一刀两断

9年用户 1067经验值
私信 关注
[问答]

STVD中断中不能设置超过32767的数吗?

很简单的一个定时中断,平台是STVD+COSMIC。完全不能理解。stm8s有什么特殊的吗?
首选定义一个全局变量,类型是unsigned int,明显数值范围应该是0~65535.
定时器初始为1ms产生一次中断,这里就不贴了。

  • @far @interrupt void irq_time_ovf(void)
  • {
  •         jiffies++;
  •         if (jiffies >= 32767)
  •                 jiffies = 0;
  • }


这个函数是能编译通过的,不过当我改了一下。

  • @far @interrupt void irq_time_ovf(void)
  • {
  •         jiffies++;
  •         if (jiffies >= 32768)
  •                 jiffies = 0;
  • }

复制代码
这个函数就不能编译通过,错误是

  • segments .text (0x8083-0x813a) and .const (0x8000-0x8084) overlap
  • segments .const (0x8000-0x8084) and .init (0x8080-0x8083) overlap


也就是说在中断里面,jiffies不能超过32767.
而在中断外面,比如放在主函数或者任意其他非中断,我实测是可以通过的。
此外,我也测试过使用long类型,然后把判断清零值写的很低,同样的错误。
也就是说,中断中最大计数不能超过32767.
这究竟是什么原因。在其他单片机完全没有问题。
IAR下还未测试。


回帖(1)

纯纯纯牛奶

2024-5-16 17:47:42
在STM8S平台上使用STVD和COSMIC编译器时,确实需要注意一些限制。首先,让我们了解一下STM8S的特性和COSMIC编译器的一些限制。

STM8S是一款8位微控制器,其寄存器和内存空间有限。在这种情况下,使用`unsigned int`类型的全局变量可能会导致一些问题,因为STM8S的寄存器大小有限。在STM8S上,寄存器通常是8位的,这意味着它们的最大值是255。然而,STM8S的内存空间可以支持更大的数据类型,如16位的`unsigned int`。

COSMIC编译器是一个适用于8位和16位微控制器的编译器,它对内存和寄存器的使用有一定的限制。在这种情况下,使用`@far`和`@interrupt`属性可以确保中断函数被正确地放置在内存中,并在中断发生时被调用。

现在,让我们回到您的问题。您提到了一个定时器中断,它每1ms产生一次中断。在您的代码中,您定义了一个名为`jiffies`的全局变量,类型为`unsigned int`。这个变量的数值范围应该是0到65535。在中断服务例程(ISR)中,您使用了以下代码:

```c
@far @interrupt void irq_time_ovf(void){
    jiffies++;
    if (jiffies >= 32767)
        jiffies = 0;
}
```

这段代码的目的是当`jiffies`的值达到32767时,将其重置为0。然而,您提到当您尝试修改这段代码时,遇到了一些问题。这可能是因为您尝试将`jiffies`的值设置为超过32767的数,这在STM8S平台上可能会导致问题。

为了解决这个问题,您可以尝试以下方法:

1. 确保您的全局变量`jiffies`使用16位的`unsigned int`类型,而不是8位的。这可以通过在变量定义前添加`__code`关键字来实现:

```c
__code unsigned int jiffies;
```

2. 在中断服务例程中,您可以使用一个较小的计数器来跟踪中断次数,然后将这个计数器的值累加到`jiffies`变量中。这样可以避免在中断服务例程中直接操作`jiffies`变量,从而减少潜在的问题。

例如:

```c
__code unsigned int jiffies = 0;
__bit overflow_flag = 0;

@far @interrupt void irq_time_ovf(void){
    static __xdata unsigned int local_jiffies = 0;
   
    local_jiffies++;
    if (local_jiffies >= 32767) {
        local_jiffies = 0;
        overflow_flag = 1;
    }
   
    if (overflow_flag) {
        jiffies += local_jiffies;
        overflow_flag = 0;
    }
}
```

这样,您可以在中断服务例程中使用一个较小的计数器(`local_jiffies`)来跟踪中断次数,然后将这个计数器的值累加到全局变量`jiffies`中。这可以确保`jiffies`的值不会超过其允许的范围,同时避免在中断服务例程中直接操作全局变量,从而减少潜在的问题。
举报

更多回帖

×
20
完善资料,
赚取积分