问题标签 [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.
memory - C18 中的 ORG 功能汇编块
你好,stackoverflow。
我正在使用带有引导加载程序的 pic 18f4550。
由于引导加载程序,我需要在内存中的指定地址中启动解码。
在这种情况下 0x1000 因为我没有任何中断。
到目前为止,这是我的代码(简单):
但!...
C:\Users\User\Documents\ProjectosPIC\testeled\main.c:13:Error: 语法错误
我知道如何解决吗?这是编译器的问题吗??
我正在使用带有 mpasm 和其他语言的微芯片 C18 工具套件的 mplab IDE。
为什么是 sintaxe 错误?
泰
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。我不太可能复制这个问题。
c - RAM变量中ROM变量的指针?
我正在使用 Microchip C18 编译器做一个项目。我有一个称为块的结构,它指向其他块(东北西南)。这些块将使我成为一张地图。然后我有一个指针,我用它来评估一切。
仅使用 RAM,它看起来像:
这让我可以做类似的事情:
问题是我的项目中的 RAM 用完了,需要使用 ROM 我目前拥有的是:
我已经做了一些调试,可以告诉上面的部分工作,但试图使位置指针让我很伤心。所以我想我的问题是:
如何将 ROM 变量地址保存在可以编辑其值的指针中?
当我尝试:
我收到“警告 [2066] 分配中的类型限定符不匹配”
我意识到 ROM 变量和 RAM 变量是两个不同的东西,但我不知道该怎么做。
microcontroller - 如何在 MPLAB 中拥有多个 C18 源文件?
在许多语言中,例如 C++,有很多不同的源文件是正常的,但 PIC 微控制器程序似乎并不经常出现这种情况——至少在我读过的任何教程或书籍中都不是这样.
我想知道如何拥有一个包含一堆例程、全局变量和定义的源 (.c) 文件,这些文件可以由我的 main.c 文件使用。这甚至可能吗?
谢谢你的建议!
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 正在触发,但并非一直如此。
您可以提供的任何帮助或见解将不胜感激,我将与我的客户再次核对,以确保我可以添加更多代码片段。
c - 为什么没有正确传递 ROM 字符串?
我正在尝试将字符串传递给函数。我已经阅读了很多关于 C18 中 RAM/ROM 字符串的内容,我的代码似乎还可以,但它不起作用。我的功能是这样的:
我以这种方式使用它:
在 Proteus 中,我看到只有字母“B”被传递,当我将 ROM 字符串复制到 RAM 时,它简直是一团糟(见附图)。printf() 的输出只是 ATNAME,没有打印字符串。
我正在使用 C18 v4.40 和 MPLABX v1.41。非常感谢您的帮助。
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。
c - C18:编译器会“知道”函数调用永远不会返回吗?
我正在使用 C18 在 PIC18 上构建 16 状态 FSM。我正在考虑将每个状态作为自己的函数,它会跳转到其他状态并被其他状态跳转。我很想在每个状态的末尾写一个“state##();”的分支案例来确定程序应该去哪里,但我认为这会很快死掉,因为编译器可能会期望这个回归,而不是永远的分支;我的微控制器上的堆栈会很快填满并最终溢出。
C18 是否足够聪明,知道我的函数调用永远不会返回并相应地用 GOTO/JMP 而不是 CALL/BRANCH 替换指令?我知道 GOTO 存在于 C 中(出于可读性原因,通常强烈建议不要这样做),但我想不出比这里更合适的理由来使用它。我知道我可以强制它使用 _asm _endasm 块转到,但如果没有必要,我会为自己省去麻烦。在 C 语言中说去一个函数并且永远不会回来的最好方法是什么?
自然,感谢所有帮助
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 似乎不喜欢这个。
如果有好心人至少可以指出我的代码的错误,我会非常高兴。
microcontroller - 如何在 Microchip 的 C18 上使用更大的堆栈大小?
好的,我一直在尝试自己解决这个问题很长时间,我只是放弃了。我已经搜索了整个网络,直到我无法忍受,我需要帮助!
我阅读了整个“C18 编译器用户指南”,它说 C18 支持使用大小大于 256 字节的堆栈。但是我做了他们要求的所有事情,更改了链接器脚本并使用了多库堆栈模型编译器选项(-ls),但在堆栈的第一个库被填充后,我仍然无法访问变量。
我调试了一个简单的代码,它简单地递归调用一个函数。这个函数有 5 个浮点参数和 5 个浮点局部变量,每次调用在堆栈中使用大约 42 个字节(5*4 用于参数 + 5*4 用于局部变量 + 2 个字节用于保存旧的 SFR2 值)。第 6 次调用后,堆栈值被覆盖。
在网上搜索时,我发现很多人就如何创建和使用大数组(大于 256 字节)给出了具体说明。其中一个步骤建议使用指针来访问数组的元素。我觉得我的问题与“使用指针访问不同银行中的变量”有关,但我不知道如何将局部变量全部更改为函数调用中的指针。这没有任何意义。
老实说,恐怕我只是在做一些非常愚蠢的事情(因为我找不到人讨论这个问题)。我发现所有与增加堆栈大小相关的主题都建议使用静态变量。我以这种方式解决了我的问题,但我仍然想知道 C18 如何支持更大的堆栈大小。
下面是我用来理解这个问题的测试代码。调试时,我注意到 FSR1 寄存器已正确更新,以指向下一个存储区中的下一个地址,下一个函数参数和变量应放置在该地址中。但是当局部变量被写入时,它们会进入栈顶(只有地址的低字节被认为将数据移动到栈中,即使当 MPLABX IDE 指示给变量的地址时,在调试模式下,是正确的)。因此,我很确定问题在于编译器生成的代码没有使用 16 位地址来使用堆栈。不过,我不知道如何解决它。
任何有关此主题的讨论将不胜感激:) 谢谢!