您的位置:首页 > 其它

MYIR-ZYNQ7000系列-zturn教程(11):i2c对24c32进行读写

2018-02-23 20:04 1681 查看
开发板环境:vivado 2017.1 ,开发板型号xc7z020clg400-1,这个工程主要是用i2c对24c32进行读写 

Step1 新建工程然后按照下面截图中进行配置(主要配置了DDR、i2c)



配置完成后进行综合、生成顶层文件,生成的顶层文件如下图所示
//Copyright 1986-2017 Xilinx, Inc. All Rights Reserved.
//--------------------------------------------------------------------------------
//Tool Version: Vivado v.2017.1 (win64) Build 1846317 Fri Apr 14 18:55:03 MDT 2017
//Date        : Sun Feb 18 22:06:05 2018
//Host        : MS-20180107KQQK running 64-bit Service Pack 1  (build 7601)
//Command     : generate_target design_1_wrapper.bd
//Design      : design_1_wrapper
//Purpose     : IP block netlist
//--------------------------------------------------------------------------------
`timescale 1 ps / 1 ps

module design_1_wrapper
(DDR_addr,
DDR_ba,
DDR_cas_n,
DDR_ck_n,
DDR_ck_p,
DDR_cke,
DDR_cs_n,
DDR_dm,
DDR_dq,
DDR_dqs_n,
DDR_dqs_p,
DDR_odt,
DDR_ras_n,
DDR_reset_n,
DDR_we_n,
FIXED_IO_ddr_vrn,
FIXED_IO_ddr_vrp,
FIXED_IO_mio,
FIXED_IO_ps_clk,
FIXED_IO_ps_porb,
FIXED_IO_ps_srstb,
iic_0_scl_io,
iic_0_sda_io);
inout [14:0]DDR_addr;
inout [2:0]DDR_ba;
inout DDR_cas_n;
inout DDR_ck_n;
inout DDR_ck_p;
inout DDR_cke;
inout DDR_cs_n;
inout [3:0]DDR_dm;
inout [31:0]DDR_dq;
inout [3:0]DDR_dqs_n;
inout [3:0]DDR_dqs_p;
inout DDR_odt;
inout DDR_ras_n;
inout DDR_reset_n;
inout DDR_we_n;
inout FIXED_IO_ddr_vrn;
inout FIXED_IO_ddr_vrp;
inout [53:0]FIXED_IO_mio;
inout FIXED_IO_ps_clk;
inout FIXED_IO_ps_porb;
inout FIXED_IO_ps_srstb;
inout iic_0_scl_io;
inout iic_0_sda_io;

wire [14:0]DDR_addr;
wire [2:0]DDR_ba;
wire DDR_cas_n;
wire DDR_ck_n;
wire DDR_ck_p;
wire DDR_cke;
wire DDR_cs_n;
wire [3:0]DDR_dm;
wire [31:0]DDR_dq;
wire [3:0]DDR_dqs_n;
wire [3:0]DDR_dqs_p;
wire DDR_odt;
wire DDR_ras_n;
wire DDR_reset_n;
wire DDR_we_n;
wire FIXED_IO_ddr_vrn;
wire FIXED_IO_ddr_vrp;
wire [53:0]FIXED_IO_mio;
wire FIXED_IO_ps_clk;
wire FIXED_IO_ps_porb;
wire FIXED_IO_ps_srstb;
wire iic_0_scl_i;
wire iic_0_scl_io;
wire iic_0_scl_o;
wire iic_0_scl_t;
wire iic_0_sda_i;
wire iic_0_sda_io;
wire iic_0_sda_o;
wire iic_0_sda_t;

design_1 design_1_i
(.DDR_addr(DDR_addr),
.DDR_ba(DDR_ba),
.DDR_cas_n(DDR_cas_n),
.DDR_ck_n(DDR_ck_n),
.DDR_ck_p(DDR_ck_p),
.DDR_cke(DDR_cke),
.DDR_cs_n(DDR_cs_n),
.DDR_dm(DDR_dm),
.DDR_dq(DDR_dq),
.DDR_dqs_n(DDR_dqs_n),
.DDR_dqs_p(DDR_dqs_p),
.DDR_odt(DDR_odt),
.DDR_ras_n(DDR_ras_n),
.DDR_reset_n(DDR_reset_n),
.DDR_we_n(DDR_we_n),
.FIXED_IO_ddr_vrn(FIXED_IO_ddr_vrn),
.FIXED_IO_ddr_vrp(FIXED_IO_ddr_vrp),
.FIXED_IO_mio(FIXED_IO_mio),
.FIXED_IO_ps_clk(FIXED_IO_ps_clk),
.FIXED_IO_ps_porb(FIXED_IO_ps_porb),
.FIXED_IO_ps_srstb(FIXED_IO_ps_srstb),
.IIC_0_scl_i(iic_0_scl_i),
.IIC_0_scl_o(iic_0_scl_o),
.IIC_0_scl_t(iic_0_scl_t),
.IIC_0_sda_i(iic_0_sda_i),
.IIC_0_sda_o(iic_0_sda_o),
.IIC_0_sda_t(iic_0_sda_t));
IOBUF iic_0_scl_iobuf
(.I(iic_0_scl_o),
.IO(iic_0_scl_io),
.O(iic_0_scl_i),
.T(iic_0_scl_t));
IOBUF iic_0_sda_iobuf
(.I(iic_0_sda_o),
.IO(iic_0_sda_io),
.O(iic_0_sda_i),
.T(iic_0_sda_t));
endmodule
这个i2c工程的管脚是用emio引出的,所以要加这两个IOBUF,如果是mio引出的可以不加这两个IOBUF
IOBUF iic_0_scl_iobuf IOBUF iic_0
4000
_sda_iobufStep2 新建一个xdc文件set_property PACKAGE_PIN B19 [get_ports iic_0_sda_io]
set_property PACKAGE_PIN A20 [get_ports iic_0_scl_io]
set_property IOSTANDARD LVCMOS33 [get_ports iic_0_scl_io]
set_property IOSTANDARD LVCMOS33 [get_ports iic_0_sda_io]

set_property PULLUP true [get_ports iic_0_scl_io]
set_property PULLUP true [get_ports iic_0_sda_io]新建的工程因为是emio引出的所以要分配管脚,如果mio就不用分配引脚。
这个xdc文件主要注意下面这两行,这两行主要是加内部上拉电阻set_property PULLUP true [get_ports iic_0_scl_io]
set_property PULLUP true [get_ports iic_0_sda_io]Step3 生成bit文件



Step4点击菜单栏上的 File->Export->Export Hardware 导出硬件配置文件





Step5 打开SDK,然后新建一个fsbl


点击Next



点击Finish



Step 6  新建一个hello_world模板工程





新建完成后如下图所示



下面是hello_world的主程序这里是写入16位起始地址0x00进行连续写和读



/******************************************************************************
*
* Copyright (C) 2009 - 2014 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/

/*
* helloworld.c: simple test application
*
* This application configures UART 16550 to baud rate 9600.
* PS7 UART (Zynq) is not initialized by this application, since
* bootrom/bsp configures it to baud rate 115200
*
* ------------------------------------------------
* | UART TYPE BAUD RATE |
* ------------------------------------------------
* uartns550 9600
* uartlite Configurable only in HW design
* ps7_uart 115200 (configured by bootrom/bsp)
*/

#include <stdio.h>
#include "platform.h"
#include "xil_printf.h"

#include "sleep.h"
#include "xiicps.h"

XIicPs IicInstance; /* The instance of the IIC device. */

#define IIC_DEVICE_ID XPAR_XIICPS_0_DEVICE_ID

u8 WriteBuffer[2 + 1];

u8 ReadBuffer[1]; /* Read buffer for reading a page. */

struct sensor_register {
u8 value;
};

static const struct sensor_register i2c_data[] = {

{ 0x00},
{ 0x70},
{ 0x00},
{ 0x00},
{ 0x04},
{ 0x01},
{ 0x11},
{ 0x02},
{ 0x3a},
{ 0x70},
{ 0x17},
{ 0x98},
{ 0x08},
{ 0x65},
{ 0x04},
{ 0x70},
{ 0x01},

{ 0xff},/* over */
};

int iic_master_init(void)
{
int Status;
XIicPs_Config *ConfigPtr; /* Pointer to configuration data */

ConfigPtr = XIicPs_LookupConfig(IIC_DEVICE_ID);
if (ConfigPtr == NULL) {
return XST_FAILURE;
}

Status = XIicPs_CfgInitialize(&IicInstance, ConfigPtr,
ConfigPtr->BaseAddress);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}

XIicPs_SetSClk(&IicInstance, 400000);

return XST_SUCCESS;
}

int iic_write_read_8(u8 Device_Address,u8 First_Word_Address,u8 Second_Word_address,u8 data)
{
int Status;

WriteBuffer[0] = First_Word_Address;
WriteBuffer[1] = Second_Word_address;
WriteBuffer[2] = data;

Status = XIicPs_MasterSendPolled(&IicInstance, WriteBuffer,
3, Device_Address>>1);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}

while (XIicPs_BusIsBusy(&IicInstance));

usleep(2500);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}

WriteBuffer[0] = First_Word_Address;
WriteBuffer[1] = Second_Word_address;

Status = XIicPs_MasterSendPolled(&IicInstance, WriteBuffer,
2, Device_Address>>1);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}

while (XIicPs_BusIsBusy(&IicInstance));

usleep(2500);

Status = XIicPs_MasterRecvPolled(&IicInstance, ReadBuffer,
1, Device_Address>>1);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
while (XIicPs_BusIsBusy(&IicInstance));
xil_printf("0x%02x\r\n",ReadBuffer[0]);
return 0;
}

int main(void)
{
int i;
u8 Device_Address;
u8 First_Word_Address;
u8 Second_Word_address;

Device_Address = 0xAE;
First_Word_Address = 0x00;
Second_Word_address = 0x00;
i = 0;

iic_master_init();

while(1)
{
if(i2c_data[i].value==0xff)
break;
iic_write_read_8(Device_Address,First_Word_Address,Second_Word_address,i2c_data[i].value);
i++;
}

return 0;
}
这两个i2c的读写程序都比较简单,这里只是简单的介绍下要注意的地方
这个主要是对master控制器进行初始化
iic_master_init();初始化中主要主要注意:
ConfigPtr = XIicPs_LookupConfig(IIC_DEVICE_ID);其中这个i2c的设备ID主要是看你用zynq哪个设备,一般都是用的i2c0、i2c1
XPAR_XIICPS_0_DEVICE_ID  //对应i2c0

XPAR_XIICPS_1_DEVICE_ID //对应i2c1

下面的这段代码主要设置i2c的工作频率,我这里用的是400k
XIicPs_SetSClk(&IicInstance, 400000);初始化完成后主要就是进行读写了,在读写之前要将进行的读写的数据进行缓冲,所以会用到Buffer
这个24c32的地址是16位数据是8位,所以一共要用到3个Buffer进行缓冲
WriteBuffer[0] = First_Word_Address;
WriteBuffer[1] = Second_Word_address;
WriteBuffer[2] = data;上面的是写的3个缓冲Buffer,这个是读的缓冲Buffer只有一个ReadBuffer[0]缓冲Buffer做完后就开始进行写,这里进行写的函数只要设置缓冲Buffer的个数以及所接的24C32的设备地址就可以了
Status = XIicPs_MasterSendPolled(&IicInstance, WriteBuffer,
3, Device_Address>>1);
当数据写完成后开始进行读,读分为两步:第一步写入你所要读的地址、第二步读写入的这个地址里的数据
1. Status = XIicPs_MasterSendPolled(&IicInstance, WriteBuffer,
2, Device_Address>>1);
2.   Status = XIicPs_MasterRecvPolled(&IicInstance, ReadBuffer,
1, Device_Address>>1);
这里是连续读写,所以开始写入16位的0x00的起始地址,然后对这个起始地址不断累加进行连续读
对特定地址进行读写和连续读写差不多,这里不再进行介绍
最后的这个是打印i2c读Buffer里的数据
xil_printf("0x%02x\r\n",ReadBuffer[0]);



                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: