C18将字符数组传递给函数

C18将字符数组传递给函数,c,arrays,embedded,pic18,c18,C,Arrays,Embedded,Pic18,C18,我不熟悉C编程和微控制器。我使用的是带有C18的PIC18F24K20微控制器。我将其设置为使用USART发送和接收功能从计算机输入接收信息。我的目标是将接收到的单词与已知单词进行比较,并根据接收到的单词将某些内容发送回计算机。以下是相关代码 #include "p18f24k20.h" #include "delays.h" #include "string.h" #include "stdlib.h" void CommTransmit ( rom char * ); void mai

我不熟悉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语句之外和之后,它也不会被调用(比如它卡在strcppgm2ram函数中?),但它仍然传输't'

这也很奇怪,因为如果我在CommTransmit函数上设置一个中断,并逐行运行,它似乎工作正常。但是,如果我观察mplabide中的CommVariable,它永远不会是它应该的样子(尽管调用函数之前的'buf'变量是正确的)。据我所知,当我观察CommVariable时,它的值取决于数组的大小

从阅读来看,我认为这可能是由微控制器如何存储变量(程序与数据存储器?)引起的,但我不确定。非常感谢您的帮助


编辑:我还应该补充一点,如果我在CommTransmit行之前的else语句中取消注释T=strcmppgm2ram行,它将正常工作(当两个字符串相同时,T=0)。我相信当我将数组传递给函数时,它会发生变化,这会导致strcmppgm2ram函数无法正常工作。

查看strcmppgm2ram的签名

signed char strcmppgm2ram(const char * str1, const rom char * str2 );
我不明白你为什么用rom char*来表示CommVariable。来自第2.4.3章ram/rom限定符

因为PICmicro微控制器使用单独的程序存储器和 数据存储器地址总线在其设计中,MPLAB C18要求 用于区分位于程序内存中的数据和 位于数据存储器中的数据。/--/指针可以指向数据内存(ram指针)或程序 内存(rom指针)指针假定为ram指针,除非 声明为rom。

2.7.3字符串常量中:

MPLAB C18使用单独地址空间的一个重要结果 这是指向程序内存中的数据和程序内存中的数据的指针吗 数据内存不兼容。/--/因为他们指的是不同的 地址空间/---/ MPLAB C18自动将所有字符串常量放入程序内存中。 这种类型的字符串常量是“程序中的字符数组” 内存“,(常量rom字符[])

对于第二个参数,将类型转换为const far rom char*的目的也不清楚。这可能会导致堆栈损坏,因为远指针的大小更大(24位)。因此,它看起来应该重写为:

void CommTransmit (const char *CommVariable )
{
    if (!strcmppgm2ram(CommVariable, "test")) {
         USART_transmit('g');
    }
}

你好我没有在C18上编程(但在其他嵌入式系统上有);但是我怀疑
(const far rom char*)“test”
。如果字符串文字不在内存的正确区域中,则此强制转换不会移动它,它只会发送一个伪指针。没有强制转换会发生什么?顺便检查
数据中的
i<11
47
case考虑到这种看似随机的行为,听起来好像你在某个地方有一些与内存相关的bug。某些指针或数组错误会损坏内存,可能在strcppgm2ram()中。这是用户定义的函数还是某个库函数?另外,由于这是一个PIC,堆栈溢出总是一个可能的候选项。@lundin strcmppgm2ram()是一个库函数。下面是string.h文件对它的描述:signed char strcmppgm2ram(auto const char s1,auto const MEM_MODEL rom char*s2);/*名称strcmpram2pgm*{\bf strcmpram2pgm}函数执行{\bf strcmp},其中{\bf s1}*指向程序内存,{\bf s2}指向数据内存。*参数s1指向程序内存中字符串的指针*参数s2指向数据内存中字符串的指针*/通信函数的参数可疑。为什么是
rom
?您正在堆栈上传递一个变量。(通常,我更喜欢在main之外声明缓冲区,以避免使用堆栈。)