0

我正在使用仅支持 C90 的 keil C51 C 编译器对 8051 微控制器进行编程。

我想通过UART发送一个字节的数据,函数如下所示:

void Uart_send(char data){
   //...
}

使用1:

char a = 123;
Uart_send(a); //work great

使用2:

Uart_send(123);//doesn't work, but no error or warning from compiler

在后一种情况下,发送了 1 个字节,但不是正确的值 (123)。

如果我将代码更改为:

void Uart_send(const char data){
   //...
}

然后一切正常。

根据我的理解和互联网上的几个来源,“const”的唯一目的是防止函数更改其参数(换句话说,防止程序员错误地更改参数)。那为什么我的第二种方法不起作用?

编辑:这是我的完整代码:

UART.h

typedef struct {
    char Buffer[10];
    char *p;
    char Ready;
    void (*Load)(char Data);
    void (*Transmit)();
    void (*Flush)();
} _uart;
extern _uart UART;

UART.c

#include "UART.h"
#include <reg51.h>

#define EOF 0x00
/*
0000_0000: EOF
0000_0001: countdown
1xxx_xxxx: primary time set
1xxx_xxxx: secondary time set
0111_xxxx: set phase

*/
#define Wait() for(i = 0; i < 3; ++i)
void Load(const char Data){
    *UART.p = Data;
    if(Data == EOF){
        UART.Ready = 1;
    }
    ++UART.p;
}
void Transmit(){
    int i;
    char *p;
    p = UART.Buffer;
    while(1){
        SBUF = *p;
        while(~TI);
        TI = 0;
        Wait();//make sure slave finish process data before sending next byte
        if(*p == EOF) break;//we are done
        ++p;
    }
    UART.Flush();
}
void Flush(){
    UART.p = UART.Buffer;
    UART.Ready = 0;
}
_uart UART = {
    {EOF, EOF, EOF, EOF, EOF, EOF, EOF, EOF, EOF, EOF},
    UART.Buffer, 0,
    Load,
    Transmit,
    Flush
};

主程序

#include "UART.h"
//.....
UART.Load(123);
UART.Load(0x00); //0x00 = EOF
UART.Transmit();
4

2 回答 2

5

现在,当我们看到您的代码时,问题就很清楚了:头文件中没有函数声明(原型)。

在 C 中,您确实需要在使用它们之前声明它们,否则编译器将不知道它们。

请注意,这里的标准版本之间存在很大差异。在较旧的 C 标准(C99 之前)中,使用函数将通过从调用中推导参数类型来隐式声明(在您的情况下,这将是错误的,因为123is an int)。从 C99 及以后,这不再是真正允许的了。

于 2018-10-04T11:31:13.657 回答
2

const 参数的目的不是避免错误

编译器可以用const现在做一些优化。

于 2018-10-04T11:23:27.010 回答