找回密码
 立即注册
查看: 44|回复: 4

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

[复制链接]
  • 打卡等级:初来乍到
  • 打卡总天数:3
  • 最近打卡:2025-08-29 09:11:23
已绑定手机

1

主题

2

回帖

21

积分

新手上路

积分
21
发表于 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 =0  SPI_S1=0  I2C_S1=0,  left side of asn-op not an lvalue?头文件用了#include <AI8051U.H>呀,还有其他自定义的库没加上吗?求大神解答

回复

使用道具 举报 送花

3

主题

2001

回帖

850

积分

等待验证会员

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

问题分析

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

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

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

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

解决方案建议

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

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

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

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

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

示例修正代码
  1. c
  2. include
  3. void SYSInit(void)
  4. {
  5.     WTST = 1;
  6.     CKCON = 0;
  7.     PSW2 |= 0x80;        // 8位工作模式
  8.     P1M1 = 0; P1M0 = 0;
  9.     P0M1 = 0; P0M0 = 0;
  10.     P2M1 = 0; P2M0 = 0;
  11.     P3M1 = 0; P3M0 = 0;
  12.     P4M1 = 0; P4M0 = 0;
  13.     P5M1 = 0; P5M0 = 0;    // 初始化IO口
  14.     // 设置 RXD2=P36 TXD2=P37
  15.     P3 &= ~0x40;           // 清除 P3.6
  16.     P3 |= 0x80;            // 设置 P3.7
  17.     // SPI管脚选择P24 P25 P26 P27
  18.     P2 &= ~0x1F;           // 清除 P2.4~P2.7
  19.     // I2C管脚选择P15 P14
  20.     P1 &= ~0xC0;           // 清除 P1.5~P1.6
  21.     EA = 1;                // 打开总中断
  22. }
复制代码

总结

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

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

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:3
  • 最近打卡:2025-08-29 09:11:23
已绑定手机

1

主题

2

回帖

21

积分

新手上路

积分
21
发表于 7 天前 | 显示全部楼层
手册上就是这样直接用的,不懂
截图202508272150277585.jpg
回复

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:546
  • 最近打卡:2025-09-02 06:28:13
已绑定手机

85

主题

6045

回帖

1万

积分

超级版主

积分
11106
发表于 6 天前 | 显示全部楼层
确认是32位模式,使用251编译器才可以这样操作,8位模式使用51编译器仅地址被8整除的SFR可位操作
回复

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:3
  • 最近打卡:2025-08-29 09:11:23
已绑定手机

1

主题

2

回帖

21

积分

新手上路

积分
21
发表于 6 天前 | 显示全部楼层
Debu*** 发表于 2025-8-28 00:10
确认是32位模式,使用251编译器才可以这样操作,8位模式使用51编译器仅地址被8整除的SFR可位操作 ...

原来如此,感谢,终于指出根本问题了,666
回复

使用道具 举报 送花

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-9-3 08:33 , Processed in 0.129643 second(s), 71 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表