问题标签 [c18]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
2 回答
371 浏览

memory - C18 中的 ORG 功能汇编块

你好,stackoverflow。

我正在使用带有引导加载程序的 pic 18f4550。

由于引导加载程序,我需要在内存中的指定地址中启动解码。

在这种情况下 0x1000 因为我没有任何中断。

到目前为止,这是我的代码(简单):

但!...

C:\Users\User\Documents\ProjectosPIC\testeled\main.c:13:Error: 语法错误

我知道如何解决吗?这是编译器的问题吗??

我正在使用带有 mpasm 和其他语言的微芯片 C18 工具套件的 mplab IDE。

为什么是 sintaxe 错误?

0 投票
1 回答
681 浏览

c - sprintf 正在输出一些奇怪的数据

我正在从事一个嵌入式项目,该项目涉及将结构读/写到 EEPROM 中。我正在使用 sprintf 来轻松显示一些调试信息。

由于某种原因,此代码存在两个问题。首先; sprintf 正在打印一个非常奇怪的输出。当我打印 'addr++' 时,它将遵循一个没有意义的模式 '0, 1, 2, 3, 4, 32, ...'。

上面的输出在这里:https ://gist.github.com/3803316 请注意,关于输出是用 %x 作为地址值(所以 addr 是十六进制)

您可能已经注意到输出的第二个问题是当 i > len 时它不会停止。它继续比我提供的输出更远,并且在微控制器的看门狗重新启动之前不会停止。

编辑: 调用函数

声明:

我不认为这是一个竞争条件。我禁用了使用 bf1 的中断。即使那样,如果发生这种情况,它也会破坏整个调试字符串,而且肯定不会如此可重复。

编辑 addr 的值从零开始,可以在这里看到:https ://gist.github.com/3803411

编辑 这应该做什么它将位置结构逐字节复制到 EEPROM 中,然后在需要时调用它。

关闭 所以我从来没有解决过这个问题。该项目从 EEPROM 移出,此后我更改了操作系统、编译器和 IDE。我不太可能复制这个问题。

0 投票
1 回答
2391 浏览

c - RAM变量中ROM变量的指针?

我正在使用 Microchip C18 编译器做一个项目。我有一个称为块的结构,它指向其他块(东北西南)。这些块将使我成为一张地图。然后我有一个指针,我用它来评估一切。

仅使用 RAM,它看起来像:

这让我可以做类似的事情:

问题是我的项目中的 RAM 用完了,需要使用 ROM 我目前拥有的是:

我已经做了一些调试,可以告诉上面的部分工作,但试图使位置指针让我很伤心。所以我想我的问题是:

如何将 ROM 变量地址保存在可以编辑其值的指针中?

当我尝试:

我收到“警告 [2066] 分配中的类型限定符不匹配”

我意识到 ROM 变量和 RAM 变量是两个不同的东西,但我不知道该怎么做。

0 投票
2 回答
1108 浏览

microcontroller - 如何在 MPLAB 中拥有多个 C18 源文件?

在许多语言中,例如 C++,有很多不同的源文件是正常的,但 PIC 微控制器程序似乎并不经常出现这种情况——至少在我读过的任何教程或书籍中都不是这样.

我想知道如何拥有一个包含一堆例程、全局变量和定义的源 (.c) 文件,这些文件可以由我的 main.c 文件使用。这甚至可能吗?

谢谢你的建议!

0 投票
0 回答
903 浏览

embedded - PIC 18F87J50 USART 配置和 ISR 故障

我在使用 PIC 18F87J50 的项目中遇到问题,特别是在我与它的 2 个 USART 通道协调时。

有2个主要问题。

1.) 无法设置目标波特率:

我正在使用 Open1USART() 和 Open2USART() 函数来初始化我正在使用的两个 USART 通道。我希望它们都配置为 14,400 波特。这些函数有 2 个参数。第一个是配置 USART 的位字段(异步与同步模式、8 位与 9 位等)。第二个是配置 USART 波特率的 SPBRG 值(取决于系统时钟速率)。

我打电话给两个像:Open1USART(USART_ASYNCH_MODE & USART_EIGHT_BIT & USART_BRGH_LOW & USART_RX_INT_ON & USART_TX_INT_OFF, 346);

在我的设置中,SPBRG 的 346 似乎给了我 14,400 波特(在 O 型示波器上证实,一位的宽度约为 70us)。

问题是这只适用于 USART 2。在 USART 1 上,相同的 SPBRG 值给了我 57,600 的波特率。此外,在使用 SPBRG 值(并查看示波器时序以了解实际波特率影响)时,我看到了一些有趣的事情。

波特率随着我将 SPBRG 值从 0 增加而降低。SPBRG 为 87 给我 57,600 波特,173 -> 28,800 ......但它在大约 255 处重置。在 255 时,我的波特率约为 19,000。但是在 256 时,我的波特率非常高(~1,000,000)。然后,当我将 SPBRG 数字进一步向上移动时,波特率会越来越慢,但永远不会低于 19,000 波特标记,也永远不会一直下​​降到我需要的 14,400。

好的,所以我溢出了 SPBRG 字节,对吧?但是 USART 1 和 2 的配置方式完全相同,我可以在 USART 2 上使用 > 255 的 SPBRG 值。它们都具有相同的 BRGH 设置(低)和 BRG16 设置(高)。此外,根据这篇文章(PIC18F2680 上的 UART 接收中没有触发中断),似乎 TRISC6-7 是正确设置的重要位。我按照帖子的建议设置了这些(6 低,7 高)。

如果有帮助,我可以分享一些代码片段。

2.) ISR 不为每个传入字节触发:

我为 USART1 和 2 打开了 UART RX 中断。我没有以正确的波特率在 USART1 上说话,所以没有收到我的外围设备的回复。但是,在 USART2 上,我正在以 14,400 波特率说话,并且我的外围设备正在适当地回复(通过范围验证)。通过示波器,我可以看到我希望收到的所有 16 个字节,并且在线上的时序看起来很棒。但是,我的这个端口的 RX 中断只触发前 2 或 3 个字节。我需要连续接收 8 个字节才能知道外围设备正在回复什么......但我从来没有超过 2 或 3。

所以中断正在触发,但不是针对所有字节。

我知道我需要保持我的 ISR 非常短,以免错过下一个传入字节的中断,但即使我将 ISR 剥离到它的核心功能(删除调试打印输出等),我仍然只看到前 3 个字节。在示波器上,我可以看到前 3 个字节和其余字节之间没有区别(至少在位时序上没有)。前三个字节的值始终为 0xFF(这是预期的)。其余字节是不同的值,但这是我能看到的唯一区别,它并不能真正解释为什么没有 ISR 触发器。上面提到的另一个问题的链接当然似乎也与这个问题有关。但 ISR 正在触发,但并非一直如此。

您可以提供的任何帮助或见解将不胜感激,我将与我的客户再次核对,以确保我可以添加更多代码片段。

0 投票
1 回答
971 浏览

c - 为什么没有正确传递 ROM 字符串?

我正在尝试将字符串传递给函数。我已经阅读了很多关于 C18 中 RAM/ROM 字符串的内容,我的代码似乎还可以,但它不起作用。我的功能是这样的:

我以这种方式使用它:

在 Proteus 中,我看到只有字母“B”被传递,当我将 ROM 字符串复制到 RAM 时,它简直是一团糟(见附图)。printf() 的输出只是 ATNAME,没有打印字符串。

我正在使用 C18 v4.40 和 MPLABX v1.41。非常感谢您的帮助。

在此处输入图像描述

0 投票
1 回答
456 浏览

c - PIC 上的 Bit-banged 串行停止使用 C 中的嵌套循环

Stackoverflow,你以前帮助过我,我想我再次需要你的帮助。我正在尝试使用 PIC18F2550 上的 GPIO 对我自己的串行进行 bit-bang。这连接到一些移位寄存器 (3x74LS595),其中最后一个连接到标准 HD44780 LCD。到目前为止,我的时钟和闩锁工作正常,经过长时间的战斗,数据现在也被正确吐出(结果桶移位效果不佳,事情会很乐意吐出数据超出范围但我离题了)。

我的问题是,要使用 LCD,我需要将启用引脚切换为数据时钟,因此为了保存代码,我只需嵌套另一个循环,该循环运行两次并切换启用标志,否则会吐出相同的字节。从理论上讲,这应该是从 12 到 24 吐出的字节数的两倍。无论出于何种原因,添加此循环时它都不起作用。它只是吐出两个字节并退出。没有它,它会吐出所有 12 个字节(尽管 LCD 设置不正确,因为启用不存在)。

这是它工作的图片,没有嵌套的启用循环:

链接,因为缺乏代表

D0 是数据,下面的 D1/2 分别是时钟/负载。

这里是 for 循环:

链接,因为缺乏代表

最左边的那个边缘是线的初始重置。我知道它在这两个字节之后完成,因为它会发出我拥有的小蜂鸣器的哔哔声,表明所有有意义的代码都已完成。

这是一个代码转储:

在上面的代码中,我什至禁用了切换以查看它是否会吐出所有字节。可能不会。我正在认真考虑只在汇编中完成这一切,因为对于 C 语言,我在看似简单的东西上遇到了很多问题。感觉就像我无法控制这件事的背景中发生的事情。我正在使用 Pickit 3,但如果我想了解实际情况,我可能只需要挖掘 ICD2。

0 投票
1 回答
364 浏览

c - C18:编译器会“知道”函数调用永远不会返回吗?

我正在使用 C18 在 PIC18 上构建 16 状态 FSM。我正在考虑将每个状态作为自己的函数,它会跳转到其他状态并被其他状态跳转。我很想在每个状态的末尾写一个“state##();”的分支案例来确定程序应该去哪里,但我认为这会很快死掉,因为编译器可能会期望这个回归,而不是永远的分支;我的微控制器上的堆栈会很快填满并最终溢出。

C18 是否足够聪明,知道我的函数调用永远不会返回并相应地用 GOTO/JMP 而不是 CALL/BRANCH 替换指令?我知道 GOTO 存在于 C 中(出于可读性原因,通常强烈建议不要这样做),但我想不出比这里更合适的理由来使用它。我知道我可以强制它使用 _asm _endasm 块转到,但如果没有必要,我会为自己省去麻烦。在 C 语言中说去一个函数并且永远不会回来的最好方法是什么?

自然,感谢所有帮助

0 投票
1 回答
106 浏览

c - C18:被调用的函数被跳过

如果您使用 C18 编译器的专家能给我指出我做错了什么,我将不胜感激。为了熟悉,我开始了一个简单的温度计项目:- NTC 热敏电阻 --> 18F2520 --> HD44780。

在对链进行调试并生成代码以转换 AN0 输入电压(中间范围 2.5V = 10000 ohm)后,一切都很好,包括将 TºC 显示到 LCD 上所需的例程。

以上只是简单的框架,但工作得很好,每秒产生一个新的 TºC 液晶显示器。

下一步是变得更加成熟,

在 tcalc 函数开始时,我进行了超出范围的测试。如果按照我最初的决定,应用程序将测量水温。那么大于 28000 的 Rntc 将是冰,(超出上述范围)在有效值的另一端 <1900 几乎要蒸腾了。我打电话给错误信息的例程被忽略了。

这是将 Rntc 更改为温度 TºC 的 tcalc 代码

调用的例程'Rntc_out'如下

基本上我的问题是在测试超出范围的 Rntc 时。代码被跳过,就好像它不存在一样。

PS如果我将Rntc模块的代码作为标签:并转到代码,那么是的,超出范围的测试不会被忽略并且可以处理条件。

当然,'goto' 策略有一点问题。读数超出范围意味着几秒钟后,必须再次读取热敏电阻。意味着另一个转到 tcalc。意思是自称。C18 似乎不喜欢这个。

如果有好心人至少可以指出我的代码的错误,我会非常高兴。

0 投票
1 回答
1749 浏览

microcontroller - 如何在 Microchip 的 C18 上使用更大的堆栈大小?

好的,我一直在尝试自己解决这个问题很长时间,我只是放弃了。我已经搜索了整个网络,直到我无法忍受,我需要帮助!

我阅读了整个“C18 编译器用户指南”,它说 C18 支持使用大小大于 256 字节的堆栈。但是我做了他们要求的所有事情,更改了链接器脚本并使用了多库堆栈模型编译器选项(-ls),但在堆栈的第一个库被填充后,我仍然无法访问变量。

我调试了一个简单的代码,它简单地递归调用一个函数。这个函数有 5 个浮点参数和 5 个浮点局部变量,每次调用在堆栈中使用大约 42 个字节(5*4 用于参数 + 5*4 用于局部变量 + 2 个字节用于保存旧的 SFR2 值)。第 6 次调用后,堆栈值被覆盖。

在网上搜索时,我发现很多人就如何创建和使用大数组(大于 256 字节)给出了具体说明。其中一个步骤建议使用指针来访问数组的元素。我觉得我的问题与“使用指针访问不同银行中的变量”有关,但我不知道如何将局部变量全部更改为函数调用中的指针。这没有任何意义。

老实说,恐怕我只是在做一些非常愚蠢的事情(因为我找不到人讨论这个问题)。我发现所有与增加堆栈大小相关的主题都建议使用静态变量。我以这种方式解决了我的问题,但我仍然想知道 C18 如何支持更大的堆栈大小。

下面是我用来理解这个问题的测试代码。调试时,我注意到 FSR1 寄存器已正确更新,以指向下一个存储区中的下一个地址,下一个函数参数和变量应放置在该地址中。但是当局部变量被写入时,它们会进入栈顶(只有地址的低字节被认为将数据移动到栈中,即使当 MPLABX IDE 指示给变量的地址时,在调试模式下,是正确的)。因此,我很确定问题在于编译器生成的代码没有使用 16 位地址来使用堆栈。不过,我不知道如何解决它。

任何有关此主题的讨论将不胜感激:) 谢谢!