1

我是 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 函数无法正常工作。

4

1 回答 1

1

查看strcmppgm2ram的签名

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

我不明白为什么你有rom char *用于CommVariable。来自MPLAB® C18 C 编译器用户指南的2.4.3 章 ram/rom 限定符

由于 PICmicro 单片机在其设计中使用单独的程序存储器和数据存储器地址总线,MPLAB C18 需要扩展来区分位于程序存储器中的数据和位于数据存储器中的数据。/---/ 指针可以指向数据存储器(ram 指针)或程序存储器(rom 指针)。除非声明为 rom,否则指针被假定为 ram 指针。

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');
    }
}
于 2014-06-23T23:10:55.200 回答