2

我正在尝试使用 PICC18 进行一个相当简单的调用。

使用 MPLAB 模拟器,我看到参数,即使在进入函数时,也是完全乱码。

我有以下类型定义

typedef struct
{
    //  t_ax25AddressChar callsign[6];
    unsigned char callsign[6];
    union
    {
        struct
        {
            unsigned isRepeated:1; // MSB - 1=repeated
            unsigned reserved:2; // Reserved
            unsigned ssid:4; // SSID
            unsigned isLast:1; // LSB - Is the last address
        };
        unsigned char value;
    } flags;
} t_ax25Callsign;

(我的 TODO 列表包括制定我需要指定位域的顺序)

嵌入在另一个结构中

typedef struct
{
    union
    {
        struct
        {
            t_ax25Callsign to;
            t_ax25Callsign from;
            t_ax25Callsign path[APRS_MAX_REPEATERS];
        };
        t_ax25Callsign allCallsigns[APRS_MAX_REPEATERS + 2];
    } address;
    // PID and Control are hard coded for APRS
    const char message[APRS_MAX_MESSAGE_LENGTH + 1]; // null terminated message string
} t_aprsPacket;

并分配在分页 RAM 中的某处(在 main.c 中)

#pragma udata   
static t_aprsPacket s_packet;

aprs.h中定义的方法

extern void aprsMakeCallsignPgm(t_ax25Callsign *buffer,
                                const rom char *callsign, unsigned char ssid);

(我确实尝试在 string.h 的示例后面放一个“远”。没有效果 - 在这张 PIC 上我没有 64K 所以真的应该将所有内容重新编译为“近”)

aprs.c 中的实现是

void aprsMakeCallsignPgm(t_ax25Callsign *buffer,
                     const rom char *callsign,
                     unsigned char ssid)
{
    int i = 0;
    volatile char ch;
    for(i=0; i<6 && (ch = callsign[i]) != 0; i++)
    {
        buffer->callsign[i] = ch << 1;
    }
    for(   ; i<6; i++)
    {
        buffer->callsign[i] = (' '<<1);
    }

    buffer->flags.value = 0;
    buffer->flags.ssid = ssid;
}

(它可以被优化。最好先让它工作。这个实现让我看到它在循环中的内容。)

main.c 中来自 main() 的几个调用是

aprsMakeCallsignPgm(&(s_packet.address.from), "M0RJC", (unsigned char)9);
aprsMakeCallsignPgm(&(s_packet.address.to), "APRS", 0);
s_packet.address.to.flags.isLast = 1;
strcpypgm2ram(s_packet.message, "Hard coded test message");

转换为 (unsigned char) 也无济于事。

前三行编译,但在 MPLAB 模拟器中运行时,函数实现的参数中会产生乱码。

strcpy 行给出编译器警告“Warning [2066] type qualifier mismatch in assignment”。如果它告诉我哪个任务会很好。

我在这里做错了什么?

谢谢

  • 理查德
4

1 回答 1

3

我正在调用一个使用 FSR2 的汇编程序初始化例程,因此破坏了 C 堆栈。我将其更改为使用 FSR0,现在它可以工作了。

做同样事情的较短代码是

void aprsMakeCallsignPgm(t_ax25Callsign *buffer,
                         const rom char *callsign,
                         unsigned char ssid)
{
    int i; 
    overlay char *dst = buffer->callsign;
    for(i = 6; i && (*dst++ = (*callsign++ << 1)); i--);
    dst--; // Rewind that 0. Good job flags is there to save from overrun
    for(   ; i ; i--) *dst++ = (' '<<1);

    buffer->flags.value = (ssid & 0x0F) << 1;
}

我正在“调试”模式下编译,所以没有优化。因为我只有编译器的评估版本,所以看看它在这种模式下的表现很有用。新版本节省了 66 个程序位置和 3 个字节的 RAM。它还告诉我,位域的正确方法是

   struct
    {
        unsigned isLast:1;     // LSB - Is the last address
        unsigned ssid:4;       // SSID
        unsigned reserved:2;   // Reserved
        unsigned isRepeated:1; // MSB - 1=repeated
    };

我认为 << 运算符不包括进位。

谢谢 - 理查德

(我会将此问题标记为删除 - 但请注意它已被标记为收藏,因此不想从某人的脚下扫过它)

于 2011-08-23T21:48:33.300 回答