S02_CH10_ User GPIO实验

在之前的第四章课程中,我们详细的讲解了如何在VIVADO软件下封装一个简单的流水灯程序。在ZYNQ开发过程中,有时候我们可能会需要与ARM硬核进行通信,在这种情况之下,可能就需要用到更高速的接口与ARM通信。本章就将讲解如何创建一个基于高速的AXI总线的IP。本章将带领大家创建一个带AXI总线接口的自定义GPIO模拟的流水灯实验。通过这种方法,我们可以在GPIO资源缺乏的情况下,利用PL的资源来扩充GPIO资源。

10.1 创建IP

Step1:打开VIVADO软件,新建一个工程。

Step2:单击Tools菜单下的Create and package IP。

Step3:单击Next,选择Create a new AXI4 peripheral,单击Next。

Step4:输入要创建的IP名字,此处我们命名为GPIO_LITE_ML,选择好保存路劲,单击Next。

Step5:选择接口类型为lite,数据位宽为32位,寄存器数量为4,然后单击next。

Step6:选择Edit IP,然后选择Finish按钮将打开一个新的编辑IP的工程。

Step7:选中Project Manager,双击GPIO_LITE_ML_v1_0_S00_inst,用以下程序替换原来的程序。

`timescale 1 ns / 1 ps

module GPIO_LITE_ML_v1_0_S00_AXI #

(

// Users to add parameters here

// User parameters ends

// Do not modify the parameters beyond this line

// Width of S_AXI data bus

parameter integer C_S_AXI_DATA_WIDTH = 32,

// Width of S_AXI address bus

parameter integer C_S_AXI_ADDR_WIDTH = 4

)

(

// Users to add ports here

output wire [7:0]GPIO_LED,

// User ports ends

// Do not modify the ports beyond this line

// Global Clock Signal

input wire  S_AXI_ACLK,

// Global Reset Signal. This Signal is Active LOW

input wire  S_AXI_ARESETN,

// Write address (issued by master, acceped by Slave)

input wire [C_S_AXI_ADDR_WIDTH-1 : 0] S_AXI_AWADDR,

// Write channel Protection type. This signal indicates the

// privilege and security level of the transaction, and whether

// the transaction is a data access or an instruction access.

input wire [2 : 0] S_AXI_AWPROT,

// Write address valid. This signal indicates that the master signaling

// valid write address and control information.

input wire  S_AXI_AWVALID,

// Write address ready. This signal indicates that the slave is ready

// to accept an address and associated control signals.

output wire  S_AXI_AWREADY,

// Write data (issued by master, acceped by Slave)

input wire [C_S_AXI_DATA_WIDTH-1 : 0] S_AXI_WDATA,

// Write strobes. This signal indicates which byte lanes hold

// valid data. There is one write strobe bit for each eight

// bits of the write data bus.    

input wire [(C_S_AXI_DATA_WIDTH/8)-1 : 0] S_AXI_WSTRB,

// Write valid. This signal indicates that valid write

// data and strobes are available.

input wire  S_AXI_WVALID,

// Write ready. This signal indicates that the slave

// can accept the write data.

output wire  S_AXI_WREADY,

// Write response. This signal indicates the status

// of the write transaction.

output wire [1 : 0] S_AXI_BRESP,

// Write response valid. This signal indicates that the channel

// is signaling a valid write response.

output wire  S_AXI_BVALID,

// Response ready. This signal indicates that the master

// can accept a write response.

input wire  S_AXI_BREADY,

// Read address (issued by master, acceped by Slave)

input wire [C_S_AXI_ADDR_WIDTH-1 : 0] S_AXI_ARADDR,

// Protection type. This signal indicates the privilege

// and security level of the transaction, and whether the

// transaction is a data access or an instruction access.

input wire [2 : 0] S_AXI_ARPROT,

// Read address valid. This signal indicates that the channel

// is signaling valid read address and control information.

input wire  S_AXI_ARVALID,

// Read address ready. This signal indicates that the slave is

// ready to accept an address and associated control signals.

output wire  S_AXI_ARREADY,

// Read data (issued by slave)

output wire [C_S_AXI_DATA_WIDTH-1 : 0] S_AXI_RDATA,

// Read response. This signal indicates the status of the

// read transfer.

output wire [1 : 0] S_AXI_RRESP,

// Read valid. This signal indicates that the channel is

// signaling the required read data.

output wire  S_AXI_RVALID,

// Read ready. This signal indicates that the master can

// accept the read data and response information.

input wire  S_AXI_RREADY

);

// AXI4LITE signals

reg [C_S_AXI_ADDR_WIDTH-1 : 0] axi_awaddr;

reg   axi_awready;

reg   axi_wready;

reg [1 : 0] axi_bresp;

reg   axi_bvalid;

reg [C_S_AXI_ADDR_WIDTH-1 : 0] axi_araddr;

reg   axi_arready;

reg [C_S_AXI_DATA_WIDTH-1 : 0] axi_rdata;

reg [1 : 0] axi_rresp;

reg   axi_rvalid;

// Example-specific design signals

// local parameter for addressing 32 bit / 64 bit C_S_AXI_DATA_WIDTH

// ADDR_LSB is used for addressing 32/64 bit registers/memories

// ADDR_LSB = 2 for 32 bits (n downto 2)

// ADDR_LSB = 3 for 64 bits (n downto 3)

localparam integer ADDR_LSB = (C_S_AXI_DATA_WIDTH/32) + 1;

localparam integer OPT_MEM_ADDR_BITS = 1;

//----------------------------------------------

//-- Signals for user logic register space example

//------------------------------------------------

//-- Number of Slave Registers 4

reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg0;

reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg1;

reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg2;

reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg3;

wire  slv_reg_rden;

wire  slv_reg_wren;

reg [C_S_AXI_DATA_WIDTH-1:0]  reg_data_out;

integer  byte_index;

// I/O Connections assignments

assign S_AXI_AWREADY = axi_awready;

assign S_AXI_WREADY = axi_wready;

assign S_AXI_BRESP = axi_bresp;

assign S_AXI_BVALID = axi_bvalid;

assign S_AXI_ARREADY = axi_arready;

assign S_AXI_RDATA = axi_rdata;

assign S_AXI_RRESP = axi_rresp;

assign S_AXI_RVALID = axi_rvalid;

// Implement axi_awready generation

// axi_awready is asserted for one S_AXI_ACLK clock cycle when both

// S_AXI_AWVALID and S_AXI_WVALID are asserted. axi_awready is

// de-asserted when reset is low.

always @( posedge S_AXI_ACLK )

begin

if ( S_AXI_ARESETN == 1'b0 )

begin

axi_awready <= 1'b0;

end

else

begin    

if (~axi_awready && S_AXI_AWVALID && S_AXI_WVALID)

begin

// slave is ready to accept write address when

// there is a valid write address and write data

// on the write address and data bus. This design

// expects no outstanding transactions.

axi_awready <= 1'b1;

end

else           

begin

axi_awready <= 1'b0;

end

end

end       

// Implement axi_awaddr latching

// This process is used to latch the address when both

// S_AXI_AWVALID and S_AXI_WVALID are valid.

always @( posedge S_AXI_ACLK )

begin

if ( S_AXI_ARESETN == 1'b0 )

begin

axi_awaddr <= 0;

end

else

begin    

if (~axi_awready && S_AXI_AWVALID && S_AXI_WVALID)

begin

// Write Address latching

axi_awaddr <= S_AXI_AWADDR;

end

end

end       

// Implement axi_wready generation

// axi_wready is asserted for one S_AXI_ACLK clock cycle when both

// S_AXI_AWVALID and S_AXI_WVALID are asserted. axi_wready is

// de-asserted when reset is low.

always @( posedge S_AXI_ACLK )

begin

if ( S_AXI_ARESETN == 1'b0 )

begin

axi_wready <= 1'b0;

end

else

begin    

if (~axi_wready && S_AXI_WVALID && S_AXI_AWVALID)

begin

// slave is ready to accept write data when

// there is a valid write address and write data

// on the write address and data bus. This design

// expects no outstanding transactions.

axi_wready <= 1'b1;

end

else

begin

axi_wready <= 1'b0;

end

end

end       

// Implement memory mapped register select and write logic generation

// The write data is accepted and written to memory mapped registers when

// axi_awready, S_AXI_WVALID, axi_wready and S_AXI_WVALID are asserted. Write strobes are used to

// select byte enables of slave registers while writing.

// These registers are cleared when reset (active low) is applied.

// Slave register write enable is asserted when valid address and data are available

// and the slave is ready to accept the write address and write data.

assign slv_reg_wren = axi_wready && S_AXI_WVALID && axi_awready && S_AXI_AWVALID;

always @( posedge S_AXI_ACLK )

begin

if ( S_AXI_ARESETN == 1'b0 )

begin

slv_reg0 <= 0;

slv_reg1 <= 0;

slv_reg2 <= 0;

slv_reg3 <= 0;

end

else begin

if (slv_reg_wren)

begin

case ( axi_awaddr[ADDR_LSB+OPT_MEM_ADDR_BITS:ADDR_LSB] )

2'h0:

for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 )

if ( S_AXI_WSTRB[byte_index] == 1 ) begin

// Respective byte enables are asserted as per write strobes

// Slave register 0

slv_reg0[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8];

end  

2'h1:

for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 )

if ( S_AXI_WSTRB[byte_index] == 1 ) begin

// Respective byte enables are asserted as per write strobes

// Slave register 1

slv_reg1[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8];

end  

2'h2:

for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 )

if ( S_AXI_WSTRB[byte_index] == 1 ) begin

// Respective byte enables are asserted as per write strobes

// Slave register 2

slv_reg2[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8];

end  

2'h3:

for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 )

if ( S_AXI_WSTRB[byte_index] == 1 ) begin

// Respective byte enables are asserted as per write strobes

// Slave register 3

slv_reg3[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8];

end  

default : begin

slv_reg0 <= slv_reg0;

slv_reg1 <= slv_reg1;

slv_reg2 <= slv_reg2;

slv_reg3 <= slv_reg3;

end

endcase

end

end

end    

// Implement write response logic generation

// The write response and response valid signals are asserted by the slave

// when axi_wready, S_AXI_WVALID, axi_wready and S_AXI_WVALID are asserted.  

// This marks the acceptance of address and indicates the status of

// write transaction.

always @( posedge S_AXI_ACLK )

begin

if ( S_AXI_ARESETN == 1'b0 )

begin

axi_bvalid  <= 0;

axi_bresp   <= 2'b0;

end

else

begin    

if (axi_awready && S_AXI_AWVALID && ~axi_bvalid && axi_wready && S_AXI_WVALID)

begin

// indicates a valid write response is available

axi_bvalid <= 1'b1;

axi_bresp  <= 2'b0; // 'OKAY' response

end                   // work error responses in future

else

begin

if (S_AXI_BREADY && axi_bvalid)

//check if bready is asserted while bvalid is high)

//(there is a possibility that bready is always asserted high)   

begin

axi_bvalid <= 1'b0;

end  

end

end

end   

// Implement axi_arready generation

// axi_arready is asserted for one S_AXI_ACLK clock cycle when

// S_AXI_ARVALID is asserted. axi_awready is

// de-asserted when reset (active low) is asserted.

// The read address is also latched when S_AXI_ARVALID is

// asserted. axi_araddr is reset to zero on reset assertion.

always @( posedge S_AXI_ACLK )

begin

if ( S_AXI_ARESETN == 1'b0 )

begin

axi_arready <= 1'b0;

axi_araddr  <= 32'b0;

end

else

begin    

if (~axi_arready && S_AXI_ARVALID)

begin

// indicates that the slave has acceped the valid read address

axi_arready <= 1'b1;

// Read address latching

axi_araddr  <= S_AXI_ARADDR;

end

else

begin

axi_arready <= 1'b0;

end

end

end       

// Implement axi_arvalid generation

// axi_rvalid is asserted for one S_AXI_ACLK clock cycle when both

// S_AXI_ARVALID and axi_arready are asserted. The slave registers

// data are available on the axi_rdata bus at this instance. The

// assertion of axi_rvalid marks the validity of read data on the

// bus and axi_rresp indicates the status of read transaction.axi_rvalid

// is deasserted on reset (active low). axi_rresp and axi_rdata are

// cleared to zero on reset (active low).  

always @( posedge S_AXI_ACLK )

begin

if ( S_AXI_ARESETN == 1'b0 )

begin

axi_rvalid <= 0;

axi_rresp  <= 0;

end

else

begin    

if (axi_arready && S_AXI_ARVALID && ~axi_rvalid)

begin

// Valid read data is available at the read data bus

axi_rvalid <= 1'b1;

axi_rresp  <= 2'b0; // 'OKAY' response

end   

else if (axi_rvalid && S_AXI_RREADY)

begin

// Read data is accepted by the master

axi_rvalid <= 1'b0;

end                

end

end    

// Implement memory mapped register select and read logic generation

// Slave register read enable is asserted when valid address is available

// and the slave is ready to accept the read address.

assign slv_reg_rden = axi_arready & S_AXI_ARVALID & ~axi_rvalid;

always @(*)

begin

// Address decoding for reading registers

case ( axi_araddr[ADDR_LSB+OPT_MEM_ADDR_BITS:ADDR_LSB] )

2'h0   : reg_data_out <= slv_reg0;

2'h1   : reg_data_out <= slv_reg1;

2'h2   : reg_data_out <= slv_reg2;

2'h3   : reg_data_out <= slv_reg3;

default : reg_data_out <= 0;

endcase

end

// Output register or memory read data

always @( posedge S_AXI_ACLK )

begin

if ( S_AXI_ARESETN == 1'b0 )

begin

axi_rdata  <= 0;

end

else

begin    

// When there is a valid read address (S_AXI_ARVALID) with

// acceptance of read address by the slave (axi_arready),

// output the read dada

if (slv_reg_rden)

begin

axi_rdata <= reg_data_out;     // register read data

end   

end

end    

// Add user logic here

assign  GPIO_LED[7:0] = slv_reg0[7:0];

// User logic ends

endmodule

以上程序与生成的程序基本一致,只是添加了一个用户输出端口和用户逻辑。修改部分如下图所示:

最后的用户逻辑将slv_reg0的值赋值给了用户输出逻辑,当我们向slv_reg0写入数据的时候,也就相当于向GPIO_LED赋值。

Step8:双击GPIO_LITE_ML文件,用以下程序替换原来的程序。

`timescale 1 ns / 1 ps

module GPIO_LITE_ML #

(

// Users to add parameters here

// User parameters ends

// Do not modify the parameters beyond this line

// Parameters of Axi Slave Bus Interface S00_AXI

parameter integer C_S00_AXI_DATA_WIDTH = 32,

parameter integer C_S00_AXI_ADDR_WIDTH = 4

)

(

// Users to add ports here

output wire [7:0]GPIO_LED,

// User ports ends

// Do not modify the ports beyond this line

// Ports of Axi Slave Bus Interface S00_AXI

input wire  s00_axi_aclk,

input wire  s00_axi_aresetn,

input wire [C_S00_AXI_ADDR_WIDTH-1 : 0] s00_axi_awaddr,

input wire [2 : 0] s00_axi_awprot,

input wire  s00_axi_awvalid,

output wire  s00_axi_awready,

input wire [C_S00_AXI_DATA_WIDTH-1 : 0] s00_axi_wdata,

input wire [(C_S00_AXI_DATA_WIDTH/8)-1 : 0] s00_axi_wstrb,

input wire  s00_axi_wvalid,

output wire  s00_axi_wready,

output wire [1 : 0] s00_axi_bresp,

output wire  s00_axi_bvalid,

input wire  s00_axi_bready,

input wire [C_S00_AXI_ADDR_WIDTH-1 : 0] s00_axi_araddr,

input wire [2 : 0] s00_axi_arprot,

input wire  s00_axi_arvalid,

output wire  s00_axi_arready,

output wire [C_S00_AXI_DATA_WIDTH-1 : 0] s00_axi_rdata,

output wire [1 : 0] s00_axi_rresp,

output wire  s00_axi_rvalid,

input wire  s00_axi_rready

);

// Instantiation of Axi Bus Interface S00_AXI

GPIO_LITE_ML_v1_0_S00_AXI # (

.C_S_AXI_DATA_WIDTH(C_S00_AXI_DATA_WIDTH),

.C_S_AXI_ADDR_WIDTH(C_S00_AXI_ADDR_WIDTH)

) GPIO_LITE_ML_v1_0_S00_AXI_inst (

.S_AXI_ACLK(s00_axi_aclk),

.S_AXI_ARESETN(s00_axi_aresetn),

.S_AXI_AWADDR(s00_axi_awaddr),

.S_AXI_AWPROT(s00_axi_awprot),

.S_AXI_AWVALID(s00_axi_awvalid),

.S_AXI_AWREADY(s00_axi_awready),

.S_AXI_WDATA(s00_axi_wdata),

.S_AXI_WSTRB(s00_axi_wstrb),

.S_AXI_WVALID(s00_axi_wvalid),

.S_AXI_WREADY(s00_axi_wready),

.S_AXI_BRESP(s00_axi_bresp),

.S_AXI_BVALID(s00_axi_bvalid),

.S_AXI_BREADY(s00_axi_bready),

.S_AXI_ARADDR(s00_axi_araddr),

.S_AXI_ARPROT(s00_axi_arprot),

.S_AXI_ARVALID(s00_axi_arvalid),

.S_AXI_ARREADY(s00_axi_arready),

.S_AXI_RDATA(s00_axi_rdata),

.S_AXI_RRESP(s00_axi_rresp),

.S_AXI_RVALID(s00_axi_rvalid),

.S_AXI_RREADY(s00_axi_rready),

//user port

.GPIO_LED(GPIO_LED)

);

// Add user logic here

// User logic ends

endmodule

以上的程序也只是在原来的程序的基础上增加了一个用户端口而已,并无什么大的改变。

Step9:单击Tools菜单下的Create and package IP命令,重新封装IP。

Step10:单击Next,选择第一项,单击Next。

Step11:选择保存的路劲,单击Next。

Step12:选择Overwrite,然后单击Finish。

Step13:在新弹出的窗口中,我们注意到有一个警告,直接忽略它,选择Review and package IP选项,单击底部的package IP按钮完成IP的创建。


10.2 搭建硬件工程

Step1:另外新建一个VIVADO工程,根据自己的开发板正确配置芯片型号。

Step2:在Project manager区中单击Project settings。

Step3:选择IP设置区中的repository manager,将上一节我们封装好的IP的路劲添加进去。

Step:4:单击+号图标,将上一节封装的IP的路劲存放进去,单击OK。

Step5:新建一个BD文件,输入文件名,完成创建。

Step6:向BD文件中添加一个ZYNQ Processing system,根据自身硬件完成IP的配置。

Step7:单击添加IP图标,输入上一节我们自定义IP的模块名,将其添加入BD文件中。

Step8:直接点击Run connection automation。

Step9:选中GPIO_LED端口,按Ctrl+T引出端口,整体硬件电路如下。

Step10:右键单击Block文件,文件选择Generate the Output Products。

Step9:右键单击Block文件,选择Create a HDL wrapper,根据Block文件内容产生一个HDL 的顶层文件,并选择让vivado自动完成。

Step10:添加一个约束文件,打开对应自己硬件的原理图,查看按键部分引脚连接情况,此次我们只用4个LED完成实验。Miz702约束文件如下所示:

set_property SEVERITY {Warning} [get_drc_checks NSTD-1]  

set_property SEVERITY {Warning} [get_drc_checks UCIO-1]

set_property PACKAGE_PIN T22 [get_ports {GPIO_LED[0]}]

set_property IOSTANDARD LVCMOS33 [get_ports {GPIO_LED[0]}]

set_property PACKAGE_PIN T21 [get_ports {GPIO_LED[1]}]

set_property IOSTANDARD LVCMOS33 [get_ports {GPIO_LED[1]}]

set_property PACKAGE_PIN U22 [get_ports {GPIO_LED[2]}]

set_property IOSTANDARD LVCMOS33 [get_ports {GPIO_LED[2]}]

set_property PACKAGE_PIN U21 [get_ports {GPIO_LED[3]}]

set_property IOSTANDARD LVCMOS33 [get_ports {GPIO_LED[3]}]

其他型号开发板参照对应型号的原理图的LED部分,修改成对应的引脚即可。

Step11:生成bit文件。

10.3 加载到SDK

Step1:导出硬件。

Step2:新建一个空SDK工程,并添加一个main.c的文件。

Step3:在main.c文件中添加以下程序,按Ctrl+S保存后自动开始编译。

/*

* main.c

*

*  Created on: 2016年11月8日

*      Author: Administrator

*/

#include <stdio.h>

#include "xparameters.h"

#include "xil_io.h"

#include "sleep.h"

#include "xil_types.h"

#define XGpio_axi_WriteReg(BaseAddr, RegOffset, Data) \

Xil_Out32((BaseAddr) + (u32)(RegOffset), (u32)(Data))

#define XPAR_GPIO_LITE_ML_0 XPAR_GPIO_LITE_ML_0_BASEADDR

#define GPIO_LITE_ML_REG0 0

int main()

{

u8 i=0;

XGpio_axi_WriteReg(XPAR_GPIO_LITE_ML_0,GPIO_LITE_ML_REG0,0X00);

while(1)

{

for(i=0;i<=3;i++)

{

XGpio_axi_WriteReg(XPAR_GPIO_LITE_ML_0,GPIO_LITE_ML_REG0,1<<i);

usleep(500000);

}

i=0;

}

}

Step4:右击工程,选择Debug as ->Debug configuration。

Step5:选中system Debugger,双击创建一个系统调试。

Step6:设置系统调试。

点击运行按钮开始运行程序,在开发板上四个LED循环流水操作。


10.4 程序分析

XGpio_axi_WriteReg()函数实现的是向AXI的寄存器中写入数据,它的三个参数分别为基地址,偏移量和数据。需要注意的是此处的偏移量,AXI的相邻寄存器偏移量相差4个字节,默认slv_reg0的偏移量是0,因此,可以推导出slv_reg1,slv_reg2的偏移量分别为4和8,本章中,我们只用到了slv_reg0,所以偏移量为0。

10.4 本章小结

本章介绍了一种创建AXI总线高速接口的方法,在实际开发中,有非常重要的意义,大家可以根据这种方法,自行设计其他带AXI总线的IP。

S02_CH10_ User GPIO实验的更多相关文章

  1. Cortex-M3学习日志(一)-- GPIO实验

    因为项目所需,所以不得不开始研究M3,我用的是NXP公司的LPC1768这个芯片,它是具有三级流水线的哈佛结构,带独立的本地指令和数据总线以及用于外设的稍微低性能的第三条总线,还包含一个支持随机跳转的 ...

  2. GPIO实验之c语言

    上一章节进行实验使用的是汇编进行编程的,本次实验是使用c语言进行编写的. (1)点亮一个led灯   1)启动文件:    crt.S   .text   .global _start   _star ...

  3. Beaglebone Back学习四(GPIO实验)

    GPIO Beaglebone Back开发板引出了92个引脚,其中只有65个GPIO口可通过配置使用,由于引脚具有“复用”的特性,大约每个引脚有8种工作模式(Beagle System Refere ...

  4. GPIO实验(二)

    =============第三个实验============用c语言轮流点亮3个LED=================== 1.crt0.S.text.global _start_start:    ...

  5. GPIO实验(一)

    目标:点亮LED1.看原理图,找到对应的引脚和寄存器2.a.配置寄存器为输入/出引脚    GPFCON[9:8]=0b01  b.设置输出高/低电平    GPDAT[4]=0b0 1.预处理2.编 ...

  6. 02-JZ2440裸机学习之GPIO实验【转】

    本文转载自:http://blog.csdn.net/fengyuwuzu0519/article/details/54910717 版权声明:本文为博主原创文章,转载请注明http://blog.c ...

  7. GPIO实验

    一.目标:点亮led 1.看原理图:怎样点亮led 2.怎样GPF4输出0/1 a.配置功能  输出/输入/其他功能(中断或者其他) b.设置输出高电平/低电平 操作寄存器--->看芯片手册 A ...

  8. JZ2440之GPIO篇

    买来开发板已经有一段时间了,刚接触时兴奋至极,后来跟着视频看下去发现似乎自己并没有学到太多东西,于是发现自己可能欠缺的太多以致从课程中无法提取出重要的东西来,所以并没有得到太多的营养成分.因此我个人认 ...

  9. DSP5509的GPIO学习-第5篇

    1. 使用CCS V6.1版本,目前已经不局限于仅仅把实验搞清楚了,要深入去探究内部的原理,本章看下GPIO实验 2. 在CCS启动的时候,提示,这个问题是什么,XDAIS是什么?XDAIS (eXp ...

随机推荐

  1. AcWing:244. 谜一样的牛(树状数组 + 二分)

    有n头奶牛,已知它们的身高为 1~n 且各不相同,但不知道每头奶牛的具体身高. 现在这n头奶牛站成一列,已知第i头牛前面有AiAi头牛比它低,求每头奶牛的身高. 输入格式 第1行:输入整数n. 第2. ...

  2. docker数据持久化

    转载/参考: https://www.jianshu.com/p/ef0f24fd0674 Docker的数据持久化主要有两种方式: bind mount docker managed volume ...

  3. Spring Boot 中 Druid 的监控页面配置

    Druid的性能相比HikariCp等其他数据库连接池有一定的差距,但是数据库的相关属性的监控,别的连接池可能还追不上,如图: 今天写一下 Spring Boot 中监控页面的配置,我是直接将seat ...

  4. 应用fluent二维单向流泥沙冲刷作用下河床变形代码【转载】

    本代码转载自:http://www.codeforge.cn/read/260028/keti_2d_b.c__html #include "udf.h" #define Rho ...

  5. 【SVN】彻底 svn 服务器上的 删除某一个文件或文件夹

    参考: CSDN1:https://blog.csdn.net/u011729865/article/details/78764523 CSDN2:https://blog.csdn.net/wyyo ...

  6. mysql数据库每个表的备份脚本

    对mysql数据库中的每张表进行按日期备份,思想是:先把每张表的表名取出取出,然后通过for循环去对每个表进行按日期备份 [root@ZFVM-APP-- backup]# vim dataname. ...

  7. 阶段5 3.微服务项目【学成在线】_day04 页面静态化_09-freemarker基础-内建函数

    可以理解为freemaker提供的一些函数和方法 controller里面记得把map的数据注释去掉,.放开代码 工程需要重启下 <br/> 学生的个数: ${stus?size} < ...

  8. 阶段5 3.微服务项目【学成在线】_day03 CMS页面管理开发_16-异常处理-可预知异常处理-自定义异常类型和抛出类

    在common工程创建捕获异常的类:CustomException Runtime叫做运行异常.在代码中抛出的话 对我们的代码没有可侵入性 如果在代码上抛出 如果改成Exception 这时候就会有错 ...

  9. Spring Security(1):认证和授权的核心组件介绍及源码分析

    Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方式的安全框架.它包括认证(Authentication)和授权(Authorization)两个部 ...

  10. 6种php加密解密方法

    <?php function encryptDecrypt($key, $string, $decrypt){ if($decrypt){ $decrypted = rtrim(mcrypt_d ...