我是新的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”。即使我在if语句之外和之后的CommTransmit函数中放入USART_transmit('g')调用,它也永远不会被调用(就像它卡在strcmpgm2ram函数中一样?)但它仍然传递着“t”。
这也很奇怪,因为如果我中断CommTransmit函数并逐行运行,它似乎可以正常工作。但是,如果我观察MPLAB IDE中的CommVariable,它永远不会是它应该是的(尽管在被调用到函数中之前的buf变量是正确的)。据我所知,CommVariable的值取决于数组的大小。
从阅读来看,我认为这可能是由于微控制器如何存储变量(程序与数据存储器?)但我不确定。非常感谢您的帮助!
编辑:我还应该添加,如果在CommTransmit行之前取消对else语句中T=strcmpgm2ram行的注释,那么它将正常工作(当两个字符串相同时,T=0)。我相信当我通过函数传递数组时,数组会发生变化,这会导致strcmpgm2ram函数无法正常工作。

最佳答案

查看strcmpgm2ram的签名

signed char strcmppgm2ram(const char * str1, const rom char * str2 );

我不明白为什么CommVariable有rom char*。摘自第2.4.3章MPLAB® C18 C Compiler User’s Guide的ram/rom限定符
因为PICmicro微控制器使用单独的程序存储器和
数据存储器地址总线在其设计中,MPLAB C18要求
用于区分位于程序内存中的数据和
位于数据存储器中的数据。/---/指针可以指向数据存储器(ram指针)或程序
内存(rom指针)。指针被假定为ram指针,除非
声明为rom。
在2.7.3字符串常量中:
MPLAB C18地址空间分离的一个重要结果
是指向程序内存中数据的指针还是指向
数据存储器不兼容。/---/因为他们指的是不同的
地址空间。/---/
MPLAB C18自动将所有字符串常量放入程序内存。
这种类型的字符串常量是“位于程序中的字符数组”
内存“,(const rom char[])。
另外,对于第二个参数,还不清楚将类型转换为const far rom char*的目的。这可能会导致堆栈损坏,因为远指针的大小更大(24位)。所以,它看起来应该重写为:
void CommTransmit (const char *CommVariable )
{
    if (!strcmppgm2ram(CommVariable, "test")) {
         USART_transmit('g');
    }
}

08-19 22:40