用AiCube创建基础工程、串口、USB、ADC 等等工程成功之后,
在尝试添加硬件I2C的程序时,遇到有两个问题。
问题一、
型号选择STC8H和STC32G,创建启用I2C的工程文件之后,在编译的时候都会报出一个错误提示:
Sources\i2c.c(37): error C202: 'I2CPSCR': undefined identifier
错误定位在设置时钟速度的地方
- void I2C_Init(void)
- {
- I2C_SwitchP1415(); //选择I2C数据口: SCL(P1.5), SDA(P1.4)
-
- I2C_MasterMode(); //设置I2C为主机模式
- (有问题) I2C_SetClockDivider(0); //设置I2C为主机模式时钟
-
- I2C_Enable(); //使能I2C功能
-
- //<<AICUBE_USER_I2C_INITIAL_BEGIN>>
- // 在此添加用户初始化代码
- //<<AICUBE_USER_I2C_INITIAL_END>>
- }
复制代码
查找发现,在stc8h_def.h和stc32g_def.h里的关于I2C_SetClockDivider的宏定义里,多了一个不存在的寄存器 I2CPSCR
- #define I2C_SetClockDivider(n) MODIFY_REG(I2CCFG, I2CCFG_SPEED_MSK, ((n) << 0)); \
- I2CPSCR = ((n) >> 6)
复制代码
注释掉第二行这句之后,编译就正常通过了。
如果选择AI8051U,生成的工程里同样也有这句,但是因为有这个寄存器所以不会报错。
、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、
问题二、
I2C编译通过之后,尝试加入OLED的驱动程序。
看到stc8h_def.h里有关于硬件I2C的驱动函数的宏定义
#define I2C_Idle() I2C_SetMasterCommand(I2CCMD_IDLE)
#define I2C_Start() I2C_SetMasterCommand(I2CCMD_START)
#define I2C_SendData() I2C_SetMasterCommand(I2CCMD_SENDDATA)
#define I2C_RecvACK() I2C_SetMasterCommand(I2CCMD_RECVACK)
#define I2C_RecvData() I2C_SetMasterCommand(I2CCMD_RECVDATA)
#define I2C_SendACK() I2C_SetMasterCommand(I2CCMD_SENDACK)
#define I2C_Stop() I2C_SetMasterCommand(I2CCMD_STOP)
#define I2C_StartSendDataRecvACK() I2C_SetMasterCommand(I2CCMD_START_SENDDATA_RECVACK)
#define I2C_SendDataRecvACK() I2C_SetMasterCommand(I2CCMD_SENDDATA_RECVACK)
#define I2C_RecvDataSendACK() I2C_SetMasterCommand(I2CCMD_RECVDATA_SENDACK)
#define I2C_RecvDataSendNAK() I2C_SetMasterCommand(I2CCMD_RECVDATA_SENDNA)
但是不知道怎么使用,除了初始化函数I2C_Init() 之外,其它函数直接调用都没有效果,
比如发送数据的SendData没有关于数据缓冲区的I2CTXD的赋值部分,手动添加上也没效果。
而使用数据手册和试验箱例程里的硬件I2C的函数
- void Wait()
- {
- while (!(I2CMSST & 0x40));
- I2CMSST &= ~0x40; //清中断标志
- }
-
- void Start()
- {
- I2CMSCR = 0x01; //发送 START命令
- Wait();
- }
-
- void SendData(char dat)
- {
- I2CTXD = dat; //写数据到数据缓冲区
- I2CMSCR = 0x02; //发送SEND命令
- Wait();
- }
-
- void RecvACK()
- {
- I2CMSCR = 0x03; //发送读ACK命令
- Wait();
- }
-
- char RecvData()
- {
- I2CMSCR = 0x04; //发送RECV命令
- Wait();
- return I2CRXD;
- }
-
- void SendACK()
- {
- I2CMSST = 0x00; //设置ACK信号
- I2CMSCR = 0x05; //I发送ACK命令
- Wait();
- }
-
- void SendNAK()
- {
- I2CMSST = 0x01; //设置NAK信号
- I2CMSCR = 0x05; //发送ACK命令
- Wait();
- }
-
- void Stop()
- {
- I2CMSCR = 0x06; //I发送STOP命令
- Wait();
- }
复制代码
则可以顺利点亮OLED屏幕。
因为之前没用过I2C库,所以不知道是不是我的操作有什么问题。
以及AiCube生成的工程里有没有直接可以用的I2C函数,而不用自己额外写一份。
|