简介
EEPROM是指带电可擦可编程只读取存储器是一种掉电后数据不丢失的存储芯片。EEPROM可以在电脑上或专用设备上擦除已有信息,重新编程。
本次实验使用ZYNQ的自带IIC库函数读写EEPROM,笔者也是最近由于某些原因才开始学习ZYNQ,并完成了基础部分的学习开始通信协议的库函数部分。
ZYNQ硬件设计部分
第一步创建Block Design,在其中添加ZYNQ7 Processing System
第二步双击配置
查看开发板原理图后,添加配置将IIC0,映射到EMIO上。
设置引出的EMIO引脚
选中后右击,选择Make External,将映射到EMIO的IIC0引脚引出,并添加引脚配置文件
Make External
在资源页面右键选中设计完成的Black Design(①) 然后选择创建HDL (②)最后输出(③)
添加引脚配置文件
点击Open Enaborated Design
查看原理图可知EEPROM_I2C_SCL接开发板T19,EEPROM_I2C_SDA接开发板U19,引脚电压就是3.3V。配置完成后保存,然后就可以创建比特流,最后输出。
SDK代码部分
/*
* eeprom.h
*
* Created on: 2021年11月13日
* Author: heihei
*/
#ifndef SRC_EEPROM_H_
#define SRC_EEPROM_H_
#include "xiicps.h"
#include "xuartps.h"
#include "sleep.h"
#define IIC_DEVICE_ID XPAR_PS7_I2C_1_DEVICE_ID
#define IIC_SLAVE_ADDR 0x50 //IIC地址这里是7位地址而不是8位
#define IIC_START_ADDR 0 //IIC从机开始读写寄存器数据位置
/*IIC Init*/
u32 IIC_Init_EEPORM(XIicPs *Xiicps,u16 deviceid,u32 FsclHz);
u32 IIC_Write_EEPROM(XIicPs *Xiicps,u8 *MsgPtr,u16 ByteCount);
u32 IIC_Read_EEPROM(XIicPs *Xiicps,u8 *MsgPtr_w,u8 *MsgPtr_r,u16 ByteCount);
#endif /* SRC_EEPROM_H_ */
/*
* eeprom.c
*
* Created on: 2021年11月13日
* Author: heihei
*/
#include "eeprom.h"
/* 初始化IIC
* Xiicps 驱动实例
* deviceid 设备ID
* FsclHz IIC传输速率
* */
u32 IIC_Init_EEPORM(XIicPs *Xiicps,u16 deviceid,u32 FsclHz)
{
u32 state;
XIicPs_Config * IIC_Config;
IIC_Config=XIicPs_LookupConfig(deviceid);
state=XIicPs_CfgInitialize(Xiicps,IIC_Config,IIC_Config->BaseAddress);
if(state!=XST_SUCCESS){
print("CfgInit Error!\r\n");
return XST_FAILURE;
}
state=XIicPs_SelfTest(Xiicps);//IIC自查
if(state!=XST_SUCCESS){
print("SelfTest Error!\r\n");
return XST_FAILURE;
}
state=XIicPs_SetSClk(Xiicps,FsclHz);//IIC设置传输速度
if(state!=XST_SUCCESS){
print("SetClk Error!\r\n");
return XST_FAILURE;
}
return XST_SUCCESS;
}
/*
*在EEPROM中写入数据
* Xiicps 驱动实例
* MsgPtr 写入的数组的首地址
* ByteCount 写入的宽度 单位:字节
* */
u32 IIC_Write_EEPROM(XIicPs *Xiicps,u8 *MsgPtr,u16 ByteCount){
u16 Address=IIC_START_ADDR;
u32 WrOffset;
u32 status;
MsgPtr[0] = (u8) (Address);
WrOffset = 1;
status = XIicPs_MasterSendPolled(Xiicps,MsgPtr,ByteCount+WrOffset,IIC_SLAVE_ADDR);
if (status != XST_SUCCESS) {
print("WriteData Erro\r\n");
return XST_FAILURE;
}
while (XIicPs_BusIsBusy(Xiicps)); //等待总线空闲
usleep(250000);
return XST_SUCCESS;
}
u32 IIC_Read_EEPROM(XIicPs *Xiicps,u8 *MsgPtr_w,u8 *MsgPtr_r,u16 ByteCount){
u16 Address=IIC_START_ADDR;
u32 WrOffset;
u32 status;
MsgPtr_w[0] = (u8) (Address);
WrOffset = 1;
status = XIicPs_MasterSendPolled(Xiicps,MsgPtr_w,WrOffset,IIC_SLAVE_ADDR);
while (XIicPs_BusIsBusy(Xiicps));
usleep(250000);
if (status != XST_SUCCESS) {
print("Find Slave Address Error\r\n");
return XST_FAILURE;
}
status = XIicPs_MasterRecvPolled(Xiicps, MsgPtr_r,ByteCount,IIC_SLAVE_ADDR);
if (status != XST_SUCCESS) {
print("Read Address Error\r\n");
return XST_FAILURE;
}
while (XIicPs_BusIsBusy(Xiicps));//等待总线空闲
return XST_SUCCESS;
}
/*************************************************main.c******************************/
#include "xparameters.h"
#include "sleep.h"
#include "xiicps.h"
#include "xil_printf.h"
#include "xplatform_info.h"
#include "string.h"
#include "eeprom.h"
#define MAX_SIZE 64 //最大传输大小
#define IIC_SCLK_RATE 100000 //IIC速率
#define SIZE 16 //写多少个数据
u8 WriteBuffer[sizeof(u16) + MAX_SIZE]; //发送数组
u8 ReadBuffer[MAX_SIZE]; //接收数组
XIicPs Xiicps; //IIC驱动实例
int main(){
u16 Address=IIC_START_ADDR;
u32 WrBOffset;
u32 states;
WriteBuffer[0] = (u8) (Address); //将IIC开始地址赋值给读数组的第一位
WrBOffset = 1; //写数组存储偏移量
IIC_Init_EEPORM(&Xiicps,IIC_DEVICE_ID,IIC_SCLK_RATE);//初始化IIC
//将数据写入 写数组并清空读数组的内容
for (int Index = 0;Index < SIZE;Index++) {
WriteBuffer[WrBOffset + Index] = 20+Index;
ReadBuffer[Index] = 0;
printf("WriteBuffer:%d,ReadBuffer:%d,Index:%d\r\n",WriteBuffer[WrBfrOffset + Index],ReadBuffer[Index],Index);
}
states=IIC_Write_EEPROM(&Xiicps,WriteBuffer,SIZE); //寻找开始读的地址
if (states != XST_SUCCESS) {
print("Write Erro\r\n");
return XST_FAILURE;
}
states=IIC_Read_EEPROM(&Xiicps,WriteBuffer,ReadBuffer,SIZE); //读IIC
if (states != XST_SUCCESS) {
print("read Erro\r\n");
return XST_FAILURE;
}
for (int Index = 0; Index < SIZE; Index++) {
printf("2__ReadBuff[%d]:%d,WriteBuffer[%d]:%d\r\n",Index,ReadBuffer[Index],Index+WrBOffset,WriteBuffer[Index + WrBOffset]);
}
return 0;
}
注意:在使用ZYNQ自带的库函数,其中的读数据是将需要读的从机寄存器地址放入读的数组的第一位,然后需要写入寄存器的数据也要放入读数组中,但是写入的数据是从数组的第二位开始写入的。(就因为这点导致笔者的代码一直出现问题)
有问题评论区或者私信!
原文地址:http://www.cnblogs.com/amxiang/p/16901236.html
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,请务用于商业用途!
3. 如果你也有好源码或者教程,可以到用户中心发布,分享有积分奖励和额外收入!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需!
7. 如遇到加密压缩包,默认解压密码为"gltf",如遇到无法解压的请联系管理员!
8. 因为资源和程序源码均为可复制品,所以不支持任何理由的退款兑现,请斟酌后支付下载
声明:如果标题没有注明"已测试"或者"测试可用"等字样的资源源码均未经过站长测试.特别注意没有标注的源码不保证任何可用性