通用 MPLAB X、XC8 和 C。跨函数和源文件使用变量
MPLAB X, XC8, and C in general. Using variables across functions and source files
我很难将变量传递给函数——尤其是不在同一个源文件中的函数。我怀疑这两个问题实际上是同一个问题。我确定这是在互联网上的某个地方,但我已经做了很多搜索,现在我更加困惑了。大多数情况下,我需要有人指导我应该 reading/searching 做什么。
问题 1:
假设我有一个名为 main.c 的源文件。在#includes 和#defines 之后,我声明了一个变量
int count;
然后我声明一个函数
void increment () {
count++;
}
在函数 main() 中;我调用函数 increment();,然后更新 PORTA 以在 LED 中显示它。 "count" 和 PORTA 在 main() 之前都被赋值为零; 运行s.
void main () {
increment();
PORTA = count;
}
问题是 "count" 似乎有两个版本。如果这个程序是 运行,PORTA 永远不会点亮 LED。但是,如果将 "PORTA = count;" 移到函数内部,它会正确递增。此外,所有硬件写入(端口、tris 等)在函数内部都可以正常工作,但我认为我全局声明的变量却没有。因此,我假设编译器正在为函数调用制作 "count" 的副本,并在 return 时忘记它。
我通常只 return 函数中的一个值来解决这个问题,但是 PIC 的中断例程不能 return 一个值,我必须使用中断。
我该怎么办?我当然错过了一个主要概念!
问题 2:常见问题示例
假设我正在使用 MLA 设备库并为 HID_Mouse 加载演示 material。尽管它有 1000 万个文件夹以及相互包含的源文件和头文件,但我能够编辑一些子程序并让它执行我的命令。但是,我需要声明一个在 main.c 中使用并由 app_device_mouse.c 中的函数修改的变量。我如何声明这个东西以便它在全局范围内得到 read/written,但我没有从编译器那里得到声明错误?
../src/app_device_mouse.c:306: error: (192) undefined identifier "position_x"
即“您没有在 app_device_mouse.c 中声明 'int position_x',即使您在 main.c
中声明了
我不确定在这两个地方声明它的结果,但有些事情告诉我这是个坏主意。
非常感谢您抽出宝贵时间。我从这个社区学到了很多东西!
-GB
你缺少的是"scope"。它不是XC8特有的,任何C书都会帮助你。
PIC 中断不会 take/return 是有原因的。在定义 ISR 的同一个文件中定义一个全局变量 read/change。如果您要从 ISR 写入它,请声明它 'volatile':
volatile int foo = 0x00;
如果你需要从另一个文件访问它(初学者应该避免这种情况)在这个文件中声明它'extern'(或包含):
extern int foo;
对于落后的人来说,问题 1 中的代码实际上是工作代码。相反,我的错误是不小心将我的 TRISC 初始化为 1 而不是 0xff;这意味着我试图 运行 关闭输出的按钮。我应该比这更清楚。
但是,我在其他场合通过在 main() 中声明我的变量而遇到了这个问题;而不是在功能之外。这意味着我试图在一个没有声明它的函数内修改局部变量——这给了我空值和垃圾。 Pedwards 正确地指出我在处理全局变量和局部变量时遇到了麻烦; "scope" 是一个非常有用的关键字。
要让 ISR 修改变量,必须将变量声明为 volatile。在 Oled 的评论之后,我能够在 XC8 编译器手册的第 169 页上找到此信息。
我很难将变量传递给函数——尤其是不在同一个源文件中的函数。我怀疑这两个问题实际上是同一个问题。我确定这是在互联网上的某个地方,但我已经做了很多搜索,现在我更加困惑了。大多数情况下,我需要有人指导我应该 reading/searching 做什么。
问题 1:
假设我有一个名为 main.c 的源文件。在#includes 和#defines 之后,我声明了一个变量
int count;
然后我声明一个函数
void increment () {
count++;
}
在函数 main() 中;我调用函数 increment();,然后更新 PORTA 以在 LED 中显示它。 "count" 和 PORTA 在 main() 之前都被赋值为零; 运行s.
void main () {
increment();
PORTA = count;
}
问题是 "count" 似乎有两个版本。如果这个程序是 运行,PORTA 永远不会点亮 LED。但是,如果将 "PORTA = count;" 移到函数内部,它会正确递增。此外,所有硬件写入(端口、tris 等)在函数内部都可以正常工作,但我认为我全局声明的变量却没有。因此,我假设编译器正在为函数调用制作 "count" 的副本,并在 return 时忘记它。
我通常只 return 函数中的一个值来解决这个问题,但是 PIC 的中断例程不能 return 一个值,我必须使用中断。
我该怎么办?我当然错过了一个主要概念!
问题 2:常见问题示例
假设我正在使用 MLA 设备库并为 HID_Mouse 加载演示 material。尽管它有 1000 万个文件夹以及相互包含的源文件和头文件,但我能够编辑一些子程序并让它执行我的命令。但是,我需要声明一个在 main.c 中使用并由 app_device_mouse.c 中的函数修改的变量。我如何声明这个东西以便它在全局范围内得到 read/written,但我没有从编译器那里得到声明错误?
../src/app_device_mouse.c:306: error: (192) undefined identifier "position_x"
即“您没有在 app_device_mouse.c 中声明 'int position_x',即使您在 main.c
中声明了我不确定在这两个地方声明它的结果,但有些事情告诉我这是个坏主意。
非常感谢您抽出宝贵时间。我从这个社区学到了很多东西!
-GB
你缺少的是"scope"。它不是XC8特有的,任何C书都会帮助你。
PIC 中断不会 take/return 是有原因的。在定义 ISR 的同一个文件中定义一个全局变量 read/change。如果您要从 ISR 写入它,请声明它 'volatile':
volatile int foo = 0x00;
如果你需要从另一个文件访问它(初学者应该避免这种情况)在这个文件中声明它'extern'(或包含):
extern int foo;
对于落后的人来说,问题 1 中的代码实际上是工作代码。相反,我的错误是不小心将我的 TRISC 初始化为 1 而不是 0xff;这意味着我试图 运行 关闭输出的按钮。我应该比这更清楚。
但是,我在其他场合通过在 main() 中声明我的变量而遇到了这个问题;而不是在功能之外。这意味着我试图在一个没有声明它的函数内修改局部变量——这给了我空值和垃圾。 Pedwards 正确地指出我在处理全局变量和局部变量时遇到了麻烦; "scope" 是一个非常有用的关键字。
要让 ISR 修改变量,必须将变量声明为 volatile。在 Oled 的评论之后,我能够在 XC8 编译器手册的第 169 页上找到此信息。