程序设计步骤
1.复制赛场资源包,把里面的I2C的头文件和.c文件复制进编辑工程;
2.在main.c调用I2C部分IO初始化代码;(PB6,PB7);
3.在I2C.C里面编程,读写EEPROM和MCP4017函数;
4.在main.c调用读写函数,完成实现效果;
第一步
把复制好的I2C文件放入整个工程,在主函数中初始化I2CInit();
//EEPROM
I2CInit();
第二步
在I2C.h中添加EEPROM的读写函数然后在I2C.c文件中补充函数(先说EEPROM)
void EEPROM_Write(u8 add, u8 dat);
u8 EEPROM_Read(u8 add);
我们可以看到上述图中设备地址(赛事AT24C02芯片提供),AT24C02大小是2K的,所以是设备地址里面的第一行,前四个数字固定,A2,A1,A0由电路图得知全为0,最后一位为读写位,故0xa0为写地址,0xa1为读地址。
可以根据芯片手册的读写操作,写出以下代码
void EEPROM_Write(u8 add, u8 dat)
{
I2CStart(); //开始信号
I2CSendByte(0xa0); //给设备地址(写)
I2CWaitAck(); //等待应答
I2CSendByte(add); //需要存储到哪块地址0~255
I2CWaitAck(); //等待应答
I2CSendByte(dat); //需要存储的数据
I2CWaitAck(); //等待应答
I2CStop(); //停止写入
HAL_Delay(5); //每写一次EEPROM需要间隔一段时间
}
前面部分为假写操作,按手册来写
u8 EEPROM_Read(u8 add)
{
u8 dat;
I2CStart(); //开始信号
I2CSendByte(0xa0); //给设备地址(写)
I2CWaitAck(); //等待应答
I2CSendByte(add); //需要存储到add
I2CWaitAck(); //等待应答
I2CStart(); //开始信号
I2CSendByte(0xa1); //给设备地址(写)
I2CWaitAck(); //等待应答
dat = I2CReceiveByte(); //读I2C接收到的字节,读取add里面的数据
I2CSendNotAck(); //等待应答
I2CStop(); //停止写入
return (dat); //返回读取的数据
最后检验代码功能
main函数里面写
//EEPROM
I2CInit();
time_start = EEPROM_Read(0x20); //time_start为u8类型的全局变量
EEPROM_Write(0x20,++time_start); //每次复位上电time_start加1
u8 text[30];
sprintf((char*)text," %d",time_start);
LCD_DisplayStringLine(Line0,text); //打印time_start数值
只实践了写操作,读操作可以自行实践。
接下来是MCP4017的操作,MCP4017等同于一个电位器,只是区别在一个硬件改变阻值,一个软件改变阻值。PB14上面就是分到的电压,Rwb电阻和R17分压。
void MCP4017_Write(u8 dat);
u8 MCP4017_Read(void);
void MCP4017_Write(u8 dat)
{
I2CStart(); //开始
I2CSendByte(0x5e); //写入地址0x5e(01011110)
I2CWaitAck(); //等待应答
I2CSendByte(dat); //写入数据0~127,可以看到只有7位可以有效,最高位无效
I2CWaitAck(); //等待应答
I2CStop(); //停止
}
u8 MCP4017_Read(void)
{
u8 val;
I2CStart(); //开始
I2CSendByte(0x5f); //读命令地址
I2CWaitAck(); //等待应答
val = I2CReceiveByte(); //读取数值
I2CSendNotAck(); //I2C发送非确认信号
I2CStop(); //停止
return val;
}
一般不要求读MCP4017,不过个人建议写下来最好,可以验证写入是否成功,在写操作前需要初始化
主函数调用
//MCP4017
I2CInit();
MCP4017_Write(0x20);
写入数值后可以用万用表去测量PB14的电压,与理论值相比较,可以验证是否写入成功