【问题标题】:Problems with literal constants文字常量的问题
【发布时间】:2013-10-21 11:47:41
【问题描述】:

我正在使用 Hi-Tech C 编译器对 PIC16F876 进行编程。我正处于必须使用延迟的地步,每次程序运行的持续时间都不同。

我想要这个函数

__delay_us() 

然而,

此功能只取,如手册所述; “字面常量”参数。我曾想过,在计算延迟的持续时间 => 我可以使用的持续时间之后:

__delay_us(D);

只要 D 是这样分配的:

#define D duration  //where duration is an unsigned long

但是,方法不起作用。似乎每当我使用#define 时,如果我分配的值是变量,编译器会抛出错误? (没想到会这样,我还以为变量的当前值会在赋值的时候变成常量..)

如果我分配一个实际的数字,例如:

#define D 20 

这很好用,但我希望能够更改 D 的值。

我可以猜到为什么这不起作用:Hi-tech C 编译器无法为延迟生成汇编代码,除非它确切知道它是什么(在编译器时)。

我不能使用具有例如 1us 延迟的循环,因为单步执行循环所需的时间会改变延迟(我需要它非常准确)。

我唯一的选择是编写一个汇编函数并将持续时间的值传递给它吗?

【问题讨论】:

  • 您的设计中有任何有限数量的延迟吗?我的意思是说 1 秒、5 秒、20 秒.. 仅此而已。像那样,您有任何有限的延误清单吗?如果是这样,您可以编写这样的函数void delay_user_defined(int delay) { switch(delay) { case 1: __delay_us(1); break; case 2: __delay_us(2); break; case 3: __delay_us(3); break; case 4: __delay_us(4); break; default: __delay_us(0); break; } }
  • 我可以拥有,我可以很快地制作它们,但是,如前所述,如果我调用多个东西(通常在循环内),(因为 C 非常低效)它增加了很多延迟时间。我需要大约 1us 的精度,而仅使用 for 循环就需要几个我们的精度。
  • 我已经编辑了我的评论并检查示例程序是否符合您的要求。
  • 您尝试做什么,delay_us() 方式是最佳解决方案吗?通常你不应该依赖这样的 critical
  • 对不起,我现在明白你的意思了。在这个系统中,可能会出现许多不同的延迟,远远超过使用 switch case 语句可以处理的延迟。

标签: c embedded c-preprocessor


【解决方案1】:

如果您的控制器频率较低(~10 MHz),那么依赖于用 C 编写的延迟函数将不准确(如您所说)和可靠。

应该使用汇编代码来获得适当的延迟。

在汇编级别,您可以微调延迟,因为您将知道每条指令所需的时间(机器周期和所需的 T 状态数)。您也可以在控制器的数据表中找到相同的内容。

根据编译器的不同,您可以使用 #asm - #endasm 指令或 asm 关键字或编译器手册中指定的任何其他方式将汇编代码 sn-p 插入到 C 程序中。

附: :我从事过微控制器工作,我知道需要向 LCD 提供 1 微秒的 ON 脉冲是多么困难。

【讨论】:

  • 您好,感谢您的建议。我正在使用具有 20MHz 时钟的 PIC,所以我想我将不得不继续使用在线组装。 #notgoingtoenjoythis
猜你喜欢
  • 2012-07-08
  • 2017-06-20
  • 1970-01-01
  • 2010-09-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-08
  • 1970-01-01
相关资源
最近更新 更多