I2C在芯片的配置中应用还是很多的,比如摄像头、VGA转HDMI转换芯片,之前博主分享过一篇I2C协议的基础学习IIC协议学习笔记,这篇就使用Verilog来实现EEPROM的读写,进行一个简单的I2C实战应用。

EEPROM

我使用的这个芯片是AT24C32,它手册上还有一种AT24C64,其实操作都是一样的,只是内存大小不同,AT24C32是32k(4096x8)AT24C64是64k(9=8192x8),

SCL设置为频率200Khz

SCL clk posedge data输入EEPROM

SCL clk negedge data输出EEPROM

SDA 双向Pin

A2,A1,A0 Device Addr default all 0,只操作一片可悬空引脚。

WP 接地正常读写,WP接Vcc写操作被禁止

字节寻址地址,是由12(AT24C32)或13bit(AT24C64)的地址组成,需要操作16位字地址高3或4位忽略即可。

Device Address    8’hA0写器件地址,8’hA1读器件地址

写字节操作

随机读字节操作

我这个芯片是双字节数据地址,所以在写数据地址时要写两次,先是高字节后是低字节。

开始结束标志

这个I2C总线的时序是一致的。

EEPROM应答

输出应答scl的第九个周期给出,低电平应答。如果主机没有收到应答,需要重新配置。

数据传输时序

sda数据线在scl时钟的下降沿中间变化,可以避免产生误触开始结束标志。

I2C Design

i2c_start为高电平有效,传输完成后会产生一个i2c_done结束标志,表示操作完成。

I2C状态转移图

I2C写操作

(1)产生start位

(2)传送器件地址ID_Address,器件地址的最后一位为数据的传输方向位,R/W,低电平0表示主机往从机写数据(W),1表示主机从从机读数据(R)。这里按照手册给出的操作图,应该是W即低电平。ACK应答,应答是从机发送给主机的应答,这里不用管。

(3)传送写入器件寄存器地址,即数据要写入的位置。同样ACK应答不用管。

(4)传送要写入的数据。ACK应答不用管。

(5)产生stop信号。

I2C读操作

(1)产生start信号

(2)传送器件地址(写ID_Address),这里按照手册给出的操作图,最低位是W即低电平。ACK。

(3)传送字地址(写REG_Address),ACK。

(4)再次产生start信号

(5)再传送一次器件地址,这里根据手册最低位是读R高电平,ACK。

(6)读取一个字节的数据,读数据最后结束前无应答ACK信号。

(7)产生stop信号。

读写操作的写器件地址和写数据地址操作是一样的,状态转移图中读写操作中这两部分复用了,根据读写标志来判断。

其他部分没啥好说的根据时序图写就行了,需要注意的一点是我们应该在sclk的高电平的中间采样数据,在sclk低电平的中间改变数据,当sclk为高电平的时候,sda为出现下降沿为start位, sda出现上升沿为stop位,所以在sclk为高电平的时候sda应该保持稳定不能随意乱动。这就又回到了数据传输有效的条件,只有在sclk为低电平期间,才允许数据变化,在高电平期间,不允许数据变化,否则就会出现起始位或结束位。

EEPROM有个仿真模型,在夏雨闻老师的书里面就有,这个模型默认是200khz的sclk驱动,仿真的时候可以将时间参数改小,我这里也分享出来。

仿真模型代码

 `timescale 1ns/1ns
`define timeslice
//`define timeslice 300 module EEPROM_AT24C64(
scl,
sda
);
input scl; //串行时钟线
inout sda; //串行数据线 reg out_flag; //SDA数据输出的控制信号 reg[:] memory[:]; //数组模拟存储器
reg[:]address; //地址总线
reg[:]memory_buf; //数据输入输出寄存器
reg[:]sda_buf; //SDA数据输出寄存器
reg[:]shift; //SDA数据输入寄存器
reg[:]addr_byte_h; //EEPROM存储单元地址高字节寄存器
reg[:]addr_byte_l; //EEPROM存储单元地址低字节寄存器
reg[:]ctrl_byte; //控制字寄存器
reg[:]State; //状态寄存器 integer i; //---------------------------
parameter
r7 = 'b1010_1111, w7 = 8'b1010_1110, //main7
r6 = 'b1010_1101, w6 = 8'b1010_1100, //main6
r5 = 'b1010_1011, w5 = 8'b1010_1010, //main5
r4 = 'b1010_1001, w4 = 8'b1010_1000, //main4
r3 = 'b1010_0111, w3 = 8'b1010_0110, //main3
r2 = 'b1010_0101, w2 = 8'b1010_0100, //main2
r1 = 'b1010_0011, w1 = 8'b1010_0010, //main1
r0 = 'b1010_0001, w0 = 8'b1010_0000; //main0
//--------------------------- assign sda = (out_flag == ) ? sda_buf[] : 'bz; //------------寄存器和存储器初始化---------------
initial
begin
addr_byte_h = ;
addr_byte_l = ;
ctrl_byte = ;
out_flag = ;
sda_buf = ;
State = 'b00;
memory_buf = ;
address = ;
shift = ; for(i=;i<=;i=i+)
memory[i] = ;
end //启动信号
always@(negedge sda)
begin
if(scl == )
begin
State = State + ;
if(State == 'b11)
disable write_to_eeprom;
end
end //主状态机
always@(posedge sda)
begin
if(scl == ) //停止操作
stop_W_R;
else
begin
casex(State)
'b01:begin
read_in;
if(ctrl_byte == w7 || ctrl_byte == w6
|| ctrl_byte == w5 || ctrl_byte == w4
|| ctrl_byte == w3 || ctrl_byte == w2
|| ctrl_byte == w1 || ctrl_byte == w0)
begin
State = 'b10;
write_to_eeprom; //写操作
end
else
State = 'b00;
//State = State;
end 'b11:
read_from_eeprom; default:
State = 'b00;
endcase
end
end //主状态机结束 //操作停止
task stop_W_R;
begin
State = 'b00;
addr_byte_h = ;
addr_byte_l = ;
ctrl_byte = ;
out_flag = ;
sda_buf = ;
end
endtask //读进控制字和存储单元地址
task read_in;
begin
shift_in(ctrl_byte);
shift_in(addr_byte_h);
shift_in(addr_byte_l);
end
endtask //EEPROM的写操作
task write_to_eeprom;
begin
shift_in(memory_buf);
address = {addr_byte_h[:], addr_byte_l};
memory[address] = memory_buf;
State = 'b00;
end
endtask //EEPROM的读操作
task read_from_eeprom;
begin
shift_in(ctrl_byte);
if(ctrl_byte == r7 || ctrl_byte == w6
|| ctrl_byte == r5 || ctrl_byte == r4
|| ctrl_byte == r3 || ctrl_byte == r2
|| ctrl_byte == r1 || ctrl_byte == r0)
begin
address = {addr_byte_h[:], addr_byte_l};
sda_buf = memory[address];
shift_out;
State = 'b00;
end
end
endtask //SDA数据线上的数据存入寄存器,数据在SCL的高电平有效
task shift_in;
output[:]shift;
begin
@(posedge scl) shift[] = sda;
@(posedge scl) shift[] = sda;
@(posedge scl) shift[] = sda;
@(posedge scl) shift[] = sda;
@(posedge scl) shift[] = sda;
@(posedge scl) shift[] = sda;
@(posedge scl) shift[] = sda;
@(posedge scl) shift[] = sda; @(negedge scl)
begin
#`timeslice;
out_flag = ; //应答信号输出
sda_buf = ;
end @(negedge scl)
begin
#`timeslice;
out_flag = ;
end
end
endtask //EEPROM存储器中的数据通过SDA数据线输出,数据在SCL低电平时变化
task shift_out;
begin
out_flag = ;
for(i=; i>=; i=i-)
begin
@(negedge scl);
#`timeslice;
sda_buf = sda_buf << ;
end
@(negedge scl) #`timeslice sda_buf[] = ; //非应答信号输出
@(negedge scl) #`timeslice out_flag = ;
end
endtask endmodule
//eeprom.v文件结束

根据仿真模型仿真的话基本不会有什么问题,需要注意的是操作的完成标志。从仿真上看到输入读写都没问题,但是stop标志没产生好,仿真看到读写操作没问题,但实际还是不行的,需要严格按照EEPROM的手册操作时序进行,差一点就不行。

I2C的代码我分享出来,我最后使用拨码开关作为读写使能,数码管显示读出来的输出,最后实现了对指定存储地址读写数据。

I2C设计代码点击阅读原文可以查看。

 `timescale      1ns/1ps
// *********************************************************************************
// Project Name :
// Author : NingHeChuan
// Email : ninghechuan@foxmail.com
// Blogs : http://www.cnblogs.com/ninghechuan/
// File Name : I2C_Ctrl_EEPROM.v
// Module Name :
// Called By :
// Abstract :
//
// CopyRight(c) 2018, NingHeChuan Studio..
// All Rights Reserved
//
// *********************************************************************************
// Modification History:
// Date By Version Change Description
// -----------------------------------------------------------------------
// 2018/8/15 NingHeChuan 1.0 Original
//
// ********************************************************************************* module I2C_Ctrl_EEPROM(
input clk,
input rst_n,
input [:] eeprom_config_data,
input i2c_start, //1 valid
inout i2c_sdat,
output i2c_sclk,
output i2c_done,
output reg [:] i2c_rd_data
); //-------------------------------------------------------
parameter I2C_IDLE = 'd0;
parameter I2C_START = 'd1;
parameter I2C_WR_IDADDR = 'd2;
parameter I2C_WR_ACK1 = 'd3;
parameter I2C_WR_REGADDR1 = 'd4;
parameter I2C_WR_ACK2 = 'd5;
parameter I2C_WR_REGADDR2 = 'd6;
parameter I2C_WR_ACK3 = 'd7;
parameter I2C_WR_DATA = 'd8;
parameter I2C_WR_ACK4 = 'd9;
parameter I2C_WR_STOP = 'd10;
//-------------------------------------------------------
parameter I2C_RD_START = 'd11;
parameter I2C_RD_IDADDR = 'd12;
parameter I2C_RD_ACK = 'd13;
parameter I2C_RD_DATA = 'd14;
parameter I2C_RD_NPACK = 'd15;
parameter I2C_RD_STOP = 'd16;
//i2c_sclk freq
parameter I2C_FREQ = ; //50Mhz/200Khz/2 = 125
parameter TRANSFER = ;
parameter CAPTURE = ;
//parameter I2C_FREQ = 60; //50Mhz/200Khz/2 = 125
//parameter TRANSFER = 1;
//parameter CAPTURE = 30;
parameter SEND_BIT = ; //-------------------------------------------------------
reg [:] pre_state;
reg [:] next_state;
//
reg i2c_sdat_r;
wire bir_en;
//
wire transfer_en;
wire capture_en;
reg i2c_sclk_r;
reg [:] sclk_cnt;
//
reg [:] tran_cnt;
//
wire [:] wr_device_addr = {eeprom_config_data[:], 'b0};
wire [:] rd_device_addr = {eeprom_config_data[:], 'b1};
wire wr_rd_flag = eeprom_config_data[];
wire [:] reg_addr1 = eeprom_config_data[:];
wire [:] reg_addr2 = eeprom_config_data[:];
wire [:] wr_data = eeprom_config_data[:];
//
reg wr_ack1;
reg wr_ack2;
reg wr_ack3;
reg wr_ack4;
reg rd_ack1; //-------------------------------------------------------
//i2c_sclk
always @(posedge clk or negedge rst_n)begin
if(rst_n == 'b0)
sclk_cnt <= 'd1;
else if(sclk_cnt == I2C_FREQ - 'b1)
sclk_cnt <= 'd0;
else
sclk_cnt <= sclk_cnt + 'b1;
end always @(posedge clk or negedge rst_n)begin
if(rst_n == 'b0)
i2c_sclk_r <= 'b0;
else if(sclk_cnt >= (I2C_FREQ>>)* && sclk_cnt <= (I2C_FREQ>>)*)
i2c_sclk_r <= 'b1;
else
i2c_sclk_r <= 'b0;
end
//
assign transfer_en = (sclk_cnt == TRANSFER - )? 'b1: 1'b0;
assign capture_en = (sclk_cnt == CAPTURE - )? 'b1: 1'b0; //-------------------------------------------------------
always @(posedge clk or negedge rst_n)begin
if(rst_n == 'b0)
tran_cnt <= 'd0;
else if(tran_cnt == SEND_BIT && transfer_en == 'b1)
tran_cnt <= 'd0;
else if(((next_state == I2C_WR_IDADDR || next_state == I2C_WR_REGADDR1 ||
next_state ==I2C_WR_REGADDR2 || next_state == I2C_WR_DATA ||
next_state == I2C_RD_IDADDR) && transfer_en == 'b1) ||
(next_state == I2C_RD_DATA && capture_en == 'b1))
tran_cnt <= tran_cnt + 'b1;
else
tran_cnt <= tran_cnt;
end //-------------------------------------------------------
//FSM step1
always @(posedge clk or negedge rst_n)begin
if(rst_n == 'b0)
pre_state <= I2C_IDLE;
else
pre_state <= next_state;
end //FSM step2
always @(*)begin
next_state = I2C_IDLE;
case(pre_state)
I2C_IDLE:
if(i2c_start == 'b1 && transfer_en == 1'b1)
next_state = I2C_START;
else
next_state = I2C_IDLE;
I2C_START:
if(transfer_en == 'b1)
next_state = I2C_WR_IDADDR;
else
next_state = I2C_START;
I2C_WR_IDADDR:
if(transfer_en == 'b1 && tran_cnt == SEND_BIT)
next_state = I2C_WR_ACK1;
else
next_state = I2C_WR_IDADDR;
I2C_WR_ACK1:
if(transfer_en == 'b1 && wr_ack1 == 1'b0)
next_state = I2C_WR_REGADDR1;
else if(transfer_en == 'b1)
next_state = I2C_IDLE;
else
next_state = I2C_WR_ACK1;
I2C_WR_REGADDR1:
if(transfer_en == 'b1 && tran_cnt == SEND_BIT)
next_state = I2C_WR_ACK2;
else
next_state = I2C_WR_REGADDR1;
I2C_WR_ACK2:
if(transfer_en == 'b1 && wr_ack2 == 1'b0)
next_state = I2C_WR_REGADDR2;
else if(transfer_en == 'b1)
next_state = I2C_IDLE;
else
next_state = I2C_WR_ACK2;
I2C_WR_REGADDR2:
if(transfer_en == 'b1 && tran_cnt == SEND_BIT)
next_state = I2C_WR_ACK3;
else
next_state = I2C_WR_REGADDR2;
I2C_WR_ACK3:
if(transfer_en == 'b1 && wr_ack3 == 1'b0 && wr_rd_flag == 'b0)
next_state = I2C_WR_DATA;
else if(transfer_en == 'b1 && wr_ack3 == 1'b0 && wr_rd_flag == 'b1)
next_state = I2C_RD_START;
else if(transfer_en == 'b1)
next_state = I2C_IDLE;
else
next_state = I2C_WR_ACK3;
I2C_WR_DATA:
if(transfer_en == 'b1 && tran_cnt == SEND_BIT)
next_state = I2C_WR_ACK4;
else
next_state = I2C_WR_DATA;
I2C_WR_ACK4:
if(transfer_en == 'b1 && wr_ack4 == 1'b0)
next_state = I2C_WR_STOP;
else if(transfer_en == 'b1)
next_state = I2C_IDLE;
else
next_state = I2C_WR_ACK4;
I2C_WR_STOP:
if(transfer_en == 'b1)
next_state = I2C_IDLE;
else
next_state = I2C_WR_STOP;
I2C_RD_START:
if(transfer_en == 'b1)
next_state = I2C_RD_IDADDR;
else
next_state = I2C_RD_START;
I2C_RD_IDADDR:
if(transfer_en == 'b1 && tran_cnt == SEND_BIT)
next_state = I2C_RD_ACK;
else
next_state = I2C_RD_IDADDR;
I2C_RD_ACK:
if(transfer_en == 'b1 && rd_ack1 == 1'b0)
next_state = I2C_RD_DATA;
else if(transfer_en == 'b1)
next_state = I2C_IDLE;
else
next_state = I2C_RD_ACK;
I2C_RD_DATA:
if(transfer_en == 'b1 && tran_cnt == SEND_BIT)
next_state = I2C_RD_NPACK;
else
next_state = I2C_RD_DATA;
I2C_RD_NPACK:
if(transfer_en == 'b1)
next_state = I2C_RD_STOP;
else
next_state = I2C_RD_NPACK;
I2C_RD_STOP:
if(transfer_en == 'b1)
next_state = I2C_IDLE;
else
next_state = I2C_RD_STOP;
default:next_state = I2C_IDLE;
endcase
end //FSM step3
always @(posedge clk or negedge rst_n)begin
if(rst_n == 'b0)
i2c_sdat_r <= 'b1;
else begin
case(next_state)
I2C_IDLE: if(capture_en == 'b1) i2c_sdat_r <= 1'b1;
I2C_START: if(capture_en == 'b1) i2c_sdat_r <= 1'b0;
I2C_WR_IDADDR: if(transfer_en == 'b1) i2c_sdat_r <= wr_device_addr['d7 - tran_cnt];
I2C_WR_REGADDR1:if(transfer_en == 'b1) i2c_sdat_r <= reg_addr1['d7 - tran_cnt];
I2C_WR_REGADDR2:if(transfer_en == 'b1) i2c_sdat_r <= reg_addr2['d7 - tran_cnt];
I2C_WR_DATA: if(transfer_en == 'b1) i2c_sdat_r <= wr_data['d7 - tran_cnt];
I2C_WR_ACK4: if(transfer_en == 'b1) i2c_sdat_r <= 1'b0;
I2C_WR_STOP: if(capture_en == 'b1) i2c_sdat_r <= 1'b1;
I2C_RD_START: if(capture_en == 'b1) i2c_sdat_r <= 1'b0;
I2C_RD_IDADDR: if(transfer_en == 'b1) i2c_sdat_r <= rd_device_addr['d7 - tran_cnt];
I2C_RD_NPACK: if(transfer_en == 'b1) i2c_sdat_r <= 1'b0;
I2C_RD_STOP: if(capture_en == 'b1) i2c_sdat_r <= 1'b1;
default: i2c_sdat_r <= i2c_sdat_r;
endcase
end
end always @(posedge clk or negedge rst_n)begin
if(rst_n == 'b0)begin
i2c_rd_data <= 'b0;
wr_ack1 <= 'b1;
wr_ack2 <= 'b1;
wr_ack3 <= 'b1;
wr_ack4 <= 'b1;
rd_ack1 <= 'b1;
end
else if(capture_en == 'b1)begin
case(next_state)
I2C_WR_ACK1: wr_ack1 <= i2c_sdat;
I2C_WR_ACK2: wr_ack2 <= i2c_sdat;
I2C_WR_ACK3: wr_ack3 <= i2c_sdat;
I2C_WR_ACK4: wr_ack4 <= i2c_sdat;
I2C_WR_STOP: begin
wr_ack1 <= 'b1;
wr_ack2 <= 'b1;
wr_ack3 <= 'b1;
wr_ack4 <= 'b1;
rd_ack1 <= 'b1;
end
I2C_RD_ACK: rd_ack1 <= i2c_sdat;
I2C_RD_DATA: i2c_rd_data['d7 - tran_cnt] <= i2c_sdat;
I2C_RD_STOP:begin
wr_ack1 <= 'b1;
wr_ack2 <= 'b1;
wr_ack3 <= 'b1;
wr_ack4 <= 'b1;
rd_ack1 <= 'b1;
end
default:begin
i2c_rd_data <= i2c_rd_data;
wr_ack1 <= wr_ack1;
wr_ack2 <= wr_ack2;
wr_ack3 <= wr_ack3;
wr_ack4 <= wr_ack4;
rd_ack1 <= rd_ack1;
end
endcase
end
else begin
i2c_rd_data <= i2c_rd_data;
wr_ack1 <= wr_ack1;
wr_ack2 <= wr_ack2;
wr_ack3 <= wr_ack3;
wr_ack4 <= wr_ack4;
rd_ack1 <= rd_ack1;
end
end //-------------------------------------------------------
assign bir_en = (pre_state == I2C_WR_ACK1 || pre_state == I2C_WR_ACK2 || pre_state == I2C_WR_ACK3 ||
pre_state == I2C_WR_ACK4 || pre_state == I2C_RD_ACK || pre_state == I2C_RD_DATA)? 'b0: 1'b1; assign i2c_sdat = (bir_en == 'b1)? i2c_sdat_r: 1'bz; assign i2c_sclk = i2c_sclk_r;
assign i2c_done = (pre_state == I2C_WR_STOP && next_state == I2C_IDLE ||
pre_state == I2C_RD_STOP && next_state == I2C_IDLE)? 'b1: 1'b0; endmodule

转载请注明出处:NingHeChuan(宁河川)

个人微信订阅号:开源FPGA

如果你想及时收到个人撰写的博文推送,可以扫描左边二维码(或者长按识别二维码)关注个人微信订阅号

知乎ID:NingHeChuan

微博ID:NingHeChuan

原文地址:https://www.cnblogs.com/ninghechuan/p/9534893.html

基于FPGA的I2C读写EEPROM的更多相关文章

  1. STM32F10x_模拟I2C读写EEPROM

    Ⅰ.写在前面 说到IIC,大家都应该不会陌生,我们初学单片机的时候或多或少都知道或了解过,甚至使用I2C控制过器件.但是,有多少人真正去深入理解,或者深入研究过I2C通信协议呢? 1.我们有必要学习I ...

  2. STM32F10x_硬件I2C读写EEPROM(标准外设库版本)

    Ⅰ.写在前面 上一篇文章是“STM32F10x_模拟I2C读写EEPROM”,讲述使用IO口模拟I2C总线通信,对EEPROM(AT24Xxx)进行读写操作的过程. 上一篇文章主要内容:I2C协议.模 ...

  3. 第23章 I2C—读写EEPROM—零死角玩转STM32-F429系列

    第23章     I2C—读写EEPROM 全套200集视频教程和1000页PDF教程请到秉火论坛下载:www.firebbs.cn 野火视频教程优酷观看网址:http://i.youku.com/f ...

  4. 转载:关于STM32硬件I2C读写EEPROM代码实现原理的理解与总结

    http://home.eeworld.com.cn/my/space-uid-716241-blogid-655190.html 一.I2C协议简介 I2C是两线式串行总线,用于连接微控制器及其外围 ...

  5. I2C读写EEPROM—EEPROM简介

    EEPROM 是一种掉电后数据不丢失的存储器,常用来存储一些配置信息,以便系统重新上电的时候加载之.EEPOM 芯片最常用的通讯方式就是 I 2C 协议,本小节以 EEPROM 的读写实验为大家讲解如 ...

  6. STM32F10x_模拟I2C读写_硬件I2C读写

    STM32F10x_模拟I2C读写EEPROM STM32F10x_硬件I2C读写EEPROM(标准外设库版本) STM32F10x_硬件I2C主从通信(轮询发送,中断接收)

  7. 第23章 I2C—读写EEPR

    本章参考资料:<STM32F76xxx参考手册>.<STM32F7xx规格书>.库帮助文档<STM32F779xx_User_Manual.chm>及<I2C ...

  8. 【应用笔记】【AN002】通过iTool2基于MinGW平台读写EEPROM

    为了增加大家 DIY 的乐趣,XiaomaGee今天为大家只做了一篇使用iTool2内置的USB转I2C来读写EEPROM的方法和代码. iTool2简介 iTool2为银杏公司面向电子类研发工程师推 ...

  9. 基于FPGA的DDR3多端口读写存储管理系统设计

    基于FPGA的DDR3多端口读写存储管理系统设计 文章出处:电子技术设计 发布时间: 2015/03/12 | 1747 次阅读 每天新产品 时刻新体验专业薄膜开关打样工厂,12小时加急出货   机载 ...

随机推荐

  1. 5.Mysql常用函数

    5.常用函数函数可以进行字符串的处理.数值计算和日期计算等,mysql可以用在SQL(DML)中以增加SQL的功能.5.1 数值函数1. abs(x) 返回x的绝对值select abs(5),abs ...

  2. virtaulbox docker虚拟机使用主机代理shandowsocks

    1.virtaulbox 配置NatNetwork File->Preference->network->add new nat network 2.virtaulbox 虚拟机配置 ...

  3. hdu 5532 (LIS) Almost Sorted Array

    http://acm.hdu.edu.cn/showproblem.php?pid=5532 题意大致是一组数中去掉一个数后问剩下的数是否构成非严格单调序列 正反各跑一遍最长非严格连续子序列,存在长度 ...

  4. 异常检测(Anomaly Detection)

    十五.异常检测(Anomaly Detection) 15.1 问题的动机 参考文档: 15 - 1 - Problem Motivation (8 min).mkv 在接下来的一系列视频中,我将向大 ...

  5. N! (大数,优化)

    Problem Description 输出N的阶乘.(注意时间限制150ms&&注意不能打表后输出) 打表的定义:在本地主机预先计算出了每个值对应的答案,并把输入和输出的映射直接写入 ...

  6. linux(centOS7,mini),python环境的搭建

    今天想试一试python在linux下的工作,在vmware中安装了centOS7版本的linux,先前装过一个带GUI的,但是感觉在虚拟机理跑的太慢,干脆直接装一个最精简的mini版,试一下ifco ...

  7. 拼图类APP原型模板分享——简拼

    简拼是一款记录美好.抒写情怀的拼图APP,模板设计风格简约文艺,种类齐全. 此原型模板所用到的组件有标签组.水平分隔线.圆形工具.交互动作有结合标签组实现页面跳转,选择组件触发按钮状态变化等. 此原型 ...

  8. ceres入门学习

    转载自https://www.jianshu.com/p/e5b03cf22c80 Ceres solver 是谷歌开发的一款用于非线性优化的库,在谷歌的开源激光雷达slam项目cartographe ...

  9. centos6.5上配置apache + mysql + php4.4.9 + eaccelerator-0.9.5 + postgresql-8.3.13 备忘

    1.apache + mysql 直接利用 yum 安装 yum -y install httpd httpd-devel mysql mysql-server httpd-manual mod_pe ...

  10. 【记录】解决VS2015调试Xamarin程序一闪而过(使用微软ANDROID模拟器)

    越来越多的人去安装Visual Studio 2015,也会去试试其中的C#跨平台开发利器Xamarin,但是也会发现很多问题. 我相信我不会是唯一遇到以下问题的,也不会是最后一个,特此记录. 微软的 ...