我是C编程和微控制器的新手。我正在使用带有C18的PIC18F24K20微控制器。我将其设置为使用USART发送和接收功能从计算机输入接收信息。我的目标是将收到的单词与已知单词进行比较,并根据收到的单词将某些内容传回计算机。以下是相关代码。
#include "p18f24k20.h"
#include "delays.h"
#include "string.h"
#include "stdlib.h"
void CommTransmit ( rom char * );
void main (void)
{
char buf[11], data, T;
int i;
i = 0;
memset(buf, 0, sizeof buf);
while(1)
{
if (PIR1bits.RCIF)
{
data = USART_receive();
if (data != 47) // 47 is /, indicates end of string
{
buf[i] = data;
i++;
}
else
{
// T = strcmppgm2ram(buf,(const far rom char*)"test");
CommTransmit(buf);
USART_transmit('t');
buf[0] = 0'
}
}
}
}
void CommTransmit ( rom char *CommVariable )
{
char test;
test = strcmppgm2ram(CommVariable, (const far rom char*)"test");
if (test == 0)
{
USART_transmit('g');
}
}
代码目前已设置为测试以尝试确定错误。如果按原样运行,计算机将收到't',就像微控制器通过CommTransmit功能一样。但是,它从不传输'g'。即使我在CommTransmit函数中调用USART_transmit('g')调用,在if语句之外和之后,它也永远不会被调用(就像它被卡在strcmppgm2ram函数中一样?)但它仍然传输't'。
这也很奇怪,因为如果我在CommTransmit函数中休息并逐行运行,它似乎正常工作。但是,如果我在MPLAB IDE中观察CommVariable,它永远不会是它应该是的(尽管在调用函数之前'buf'变量是正确的)。据我所知,CommVariable的价值取决于数组的大小。
从阅读开始,我认为它可能是由微控制器如何存储变量(程序与数据存储器?)引起的,但我不确定。非常感谢任何帮助!
编辑:我还应该补充说,如果我在CommTransmit行之前的else语句中取消注释T = strcmppgm2ram行,它就能正常工作(当两个字符串相同时,T = 0)。我相信当我通过函数传递它时数组会发生变化,这会导致strcmppgm2ram函数无法正常工作。
答案 0 :(得分:1)
查看 strcmppgm2ram
的签名signed char strcmppgm2ram(const char * str1, const rom char * str2 );
我不明白你为什么 rm char * CommVariable 。来自MPLAB® C18 C Compiler User’s Guide
的 2.4.3 ram / rom限定符一章因为PICmicro单片机使用单独的程序存储器和 数据存储器地址总线在其设计中,MPLAB C18要求 用于区分程序存储器中的数据的扩展 数据位于数据存储器中。 / --- /指针可以指向数据存储器(ram指针)或程序 记忆(rom指针)。 指针被认为是ram指针,除非 宣称为rom。
在 2.7.3字符串常量:
中MPLAB C18的单独地址空间的重要结果 是指向程序存储器中的数据和指向数据的指针 数据存储器不兼容。 / --- /因为他们指的是不同的 地址空间。 / --- / MPLAB C18自动将所有字符串常量放在程序存储器中。 这种类型的字符串常量是“位于程序中的char数组 记忆“,(const rom char [])。
并且还不清楚第二个参数类型转换为 const far rom char * 的目的。这可能导致堆栈损坏,因为远指针具有更大的大小(24位)。因此,看起来它应该被重写为:
void CommTransmit (const char *CommVariable )
{
if (!strcmppgm2ram(CommVariable, "test")) {
USART_transmit('g');
}
}