liuguolong 发表于 7 天前

寄存器位初始化报错问题 | 已解决

像这样
#include <AI8051U.H>



void SYS_Init(void)
{
WTST =1;
CKCON =0;
P_SW2|=0x80;      //8位工作模式         
P1M1=0; P1M0=0;
P0M1=0; P0M0=0;         
P2M1=0; P2M0=0;      
P3M1=0; P3M0=0;
P4M1=0; P4M0=0;
P5M1=0; P5M0=0; //初始化IO口
S1_S1 =0; S1_S0 =1; //RXD2=P3.6 TXD2=P3.7
SPI_S1=0;SPI_S0 =1; //SPI管脚选择P2.4 P2.5 P2.6 P2.7         
I2C_S1=0;I2C_S0 =1; //I2C管脚选择P1.5 P1.4         
EA    =1;//打开总中断
}

keil会报错 S1_S1 =0SPI_S1=0I2C_S1=0,left side of asn-op not an lvalue?头文件用了#include <AI8051U.H>呀,还有其他自定义的库没加上吗?求大神解答

国芯人工智能 发表于 7 天前

您在使用Keil编译器时遇到的错误“left side of assignment is not an lvalue”通常表示您试图对一个不可修改的表达式进行赋值。在您的代码中,S1S1 = 0;、SPIS1 = 0;、I2CS1 = 0;等语句出现该错误,说明这些变量可能并未被正确定义为可写变量,或者它们是位字段(bit)或宏定义,导致无法直接赋值。

问题分析

1. 变量未正确定义
   如果 S1S1、SPIS1、I2CS1 等是位变量(bit类型),则必须使用特定的语法来访问和赋值。例如:
   c
   S1S1 = 1; // 若为 bit 类型,应使用 sfrbit 或类似方式定义
   如果未正确声明为 bit 类型,或使用了非标准语法,则可能导致编译器无法识别其为左值。

2. 宏定义冲突
   您提到头文件中包含了 #include,但未明确包含哪些头文件。如果 S1S1、SPIS1、I2CS1 是通过宏定义的寄存器地址,那么它们可能是只读的,如:
   c
   #define S1S1    P36// 宏定义为某个位,不能直接赋值
   此时,您不能直接对 S1S1 赋值,而应通过操作对应的端口寄存器,如 P3 &= ~0x40; 来控制该位。

3. 缺少必要的头文件或库支持
   如果您使用的是自定义的库或特定型号的单片机(如8051系列),请确认是否已包含相应的寄存器定义头文件。例如:
   c
   #include   // 标准8051寄存器定义
   如果没有包含正确的头文件,编译器将无法识别这些寄存器名,导致错误。

4. 语法或编译器版本不兼容
   Keil C51 编译器对某些语法有严格限制。例如,若您使用的是 C51 的标准语法,而非 C99 或 C++,某些结构体或位域的使用方式可能需要调整。

解决方案建议

1. 检查变量定义方式
   确认 S1S1、SPIS1、I2CS1 是否为 bit 类型或宏定义。如果是宏定义,请参考数据手册使用正确的寄存器操作方式。

2. 使用标准寄存器操作方式
   例如,若您想设置 P3.6 为低电平,应使用:
   c
   P3 &= ~0x40;// 清除 P3.6 位
   而不是直接对宏定义的变量赋值。

3. 确保包含正确的头文件
   添加如下语句以包含标准寄存器定义:
   c
   #include
   如果您使用的是其他型号芯片,请替换为对应头文件。

4. 检查编译器设置
   确保项目设置中选择了正确的芯片型号,并启用了适当的编译器选项(如:使用 C51 编译器)。

5. 使用位操作函数
   如果需要频繁操作位,可以定义位操作函数,例如:
   c
   void setbit(sbit bitaddr, unsigned char value) {
       if (value)
         bitaddr = 1;
       else
         bitaddr = 0;
   }

示例修正代码

c
include

void SYSInit(void)
{
    WTST = 1;
    CKCON = 0;
    PSW2 |= 0x80;      // 8位工作模式
    P1M1 = 0; P1M0 = 0;
    P0M1 = 0; P0M0 = 0;
    P2M1 = 0; P2M0 = 0;
    P3M1 = 0; P3M0 = 0;
    P4M1 = 0; P4M0 = 0;
    P5M1 = 0; P5M0 = 0;    // 初始化IO口

    // 设置 RXD2=P36 TXD2=P37
    P3 &= ~0x40;         // 清除 P3.6
    P3 |= 0x80;            // 设置 P3.7

    // SPI管脚选择P24 P25 P26 P27
    P2 &= ~0x1F;         // 清除 P2.4~P2.7

    // I2C管脚选择P15 P14
    P1 &= ~0xC0;         // 清除 P1.5~P1.6

    EA = 1;                // 打开总中断
}

总结

您遇到的错误主要是由于对寄存器或宏定义的误用导致的。建议您查阅所用芯片的数据手册,确认寄存器的定义方式,并使用标准的寄存器操作方法。同时,确保包含正确的头文件并配置好编译器环境。如有进一步疑问,欢迎继续提问。

[本文内容由国芯人工智能辅助生成,仅供参考]

liuguolong 发表于 7 天前

手册上就是这样直接用的,不懂

DebugLab 发表于 6 天前

确认是32位模式,使用251编译器才可以这样操作,8位模式使用51编译器仅地址被8整除的SFR可位操作

liuguolong 发表于 6 天前

DebugLab 发表于 2025-8-28 00:10
确认是32位模式,使用251编译器才可以这样操作,8位模式使用51编译器仅地址被8整除的SFR可位操作 ...

原来如此,感谢,终于指出根本问题了,666{:qiang:}
页: [1]
查看完整版本: 寄存器位初始化报错问题 | 已解决