Verilog实现IIC通讯第二版
HMC5883三轴磁力传感器IIC通讯模块的VerilogHDL的实现
上一版并没有实现我想要的功能
0.0.1版 正在修订中 2013/9/2
//date :2013/7/7
//designer :pengxiaoen
//synthesizer:QuartusII 12.1
//function : IIC实现HMC5883的通讯 50M /(400k × 4)= 32 `define WriteAddress 'h3c
`define ReadAddress 'h3d `define RegAAddress 'h00 //配置寄存器A
`define RegBAddress 'h01 //配置寄存器B
`define ModelAddress 'h02 //模式寄存器
`define X_MSBAddress 'h03 //X MSB寄存器
`define X_LSBAddress 'h04
`define Z_MSBAddress 'h05
`define Z_LSBAddress 'h06
`define Y_MSBAddress 'h07
`define Y_LSBAddress 'h08
`define STATEAddress 'h09 //状态寄存器
`define IdentifyAAddress 'h10 //识别寄存器A
`define IdentifyBAddress 'h10
`define IdentifyCAddress 'h10 `define INITIAL
`define DELAY
`define MEASURE `define START
`define Re
`define Se
`define STOP //`default_nettype none module HMC5883_2 (
clock,reset,
sda,scl,
out_seg, sel_seg,
IIC_result
); input clock,reset;
inout sda,scl;
output reg [:]out_seg;
output reg IIC_result; output reg [:]sel_seg; reg [:] SEND_buffer;
reg [:] Re_buffer ;
reg sda_reg;
reg scl_reg;
reg ack_reg;
reg sda_enable;
reg scl_enable; reg IC_state;
reg n_IC_state;
reg [:]state; //当前状态寄存器
reg state_finish_flag ; // reg [:] scl_4;
reg [:] step_counter;
reg [:] clk_temp ; //==============================================================================================
//-------------时钟控制模块------------------start---------------
always @ (posedge clock or negedge reset)
if (!reset)
begin
clk_temp <= 'd0;
scl_4 <= 'd0;
end
else if (clk_temp=='d15)
begin
clk_temp <= 'd0;
if (state_finish_flag) scl_4 <= 'd0;
else if (scl_4 == 'b111_111) //这里是一个保护机制,可以设置一个flag
scl_4 <= 'b111_111;
else scl_4 <= scl_4 + ;
end
else clk_temp <= clk_temp + ;
//----------时钟控制模块----------end----------- //--------一个检测的pin---------start-----------
always @(posedge clock or negedge reset)
if(!reset)
IIC_result <= 'd0;
else if(scl_4 == 'b111_111)
IIC_result <= 'd1;
else ;
//-----------一个检测的pin-------end---------- //-------延时模块----5us------start--------
reg [:] delay_counter;
reg delay_enable;
always @(posedge clock )
if(!delay_enable)
begin
delay_counter <= 'd0;
state_finish_flag <= 'd0;
end
else if(delay_counter == 'd250)
begin
state_finish_flag <= 'd1;
delay_counter <= 'd0;
end
else begin
delay_counter <= delay_counter + ;
state_finish_flag <= 'd0;
end
//--------------延时模块-------end--------------- //----------状态机控制模块---------start-------
always @ (posedge clock or negedge reset)
if(!reset)
IC_state <= `INITIAL;
else IC_state <= n_IC_state; //------------------------------------------
always @ (posedge state_finish_flag or negedge reset)
if (!reset)
begin
SEND_buffer <= 'd0;
n_IC_state <= 'd0;
end
else if(IC_state == `INITIAL)
case (step_counter)
: begin state <= `START;end
: begin state <= `Se; SEND_buffer <= `WriteAddress; end
: begin state <= `Se; SEND_buffer <= `ModelAddress; end
: begin state <= `Se; SEND_buffer <= `RegAAddress; end
: begin state <= `STOP; end : begin n_IC_state <= `MEASURE; end
default state <= `START;
endcase
else if (IC_state == `MEASURE)
case (step_counter)
: begin state <= `START; end
: begin state <= `Se; SEND_buffer <= `WriteAddress; end
: begin state <= `Se; SEND_buffer <= `X_MSBAddress; end
: begin state <= `START; end
: begin state <= `Se; SEND_buffer <= `ReadAddress;end
: begin state <= `Re; end
: begin state <= `Re; end
: begin state <= `Re; end
: begin state <= `Re; end
: begin state <= `Re; end
: begin state <= `Re; end
: begin state <= `STOP; end :begin n_IC_state <= `INITIAL; end
default state <= `START;
endcase
else ;
//----------状态机控制模块----------end--- --- //----------执行步骤计数--------start------------
always @ (posedge clock or negedge reset)
if (!reset) begin
step_counter <= 'd0; end
else if((IC_state == `INITIAL)&& (state_finish_flag)) begin
if(step_counter == 'd5) step_counter <= 4'd0;
else step_counter <= step_counter + ; end
else if((IC_state == `MEASURE) && (state_finish_flag)) begin
if(step_counter == 'd12 ) step_counter <= 4'd0;
else step_counter <= step_counter + ; end
else ;
//----------执行步骤计数--------end------------ //-----------外部数据线 控制模块----start------
always @ (posedge clock or negedge reset)
if(!reset)
begin
Re_buffer <= 'd0;
sda_enable <= 'd0;
scl_enable <= 'd0;
delay_enable <= 'd0;
end
else case (state)
`START : case (scl_4)
: begin sda_enable <= 'd1; scl_enable <= 1'd1; delay_enable <= 'd0;
sda_reg <= 'd1; scl_reg <= 1'd0; end
: begin sda_reg <= 'd1; scl_reg <= 1'd0; end
: begin sda_reg <= 'd1; scl_reg <= 1'd1; end
: begin sda_reg <= 'd0; scl_reg <= 1'd1; end
: delay_enable <= 'd1;
default begin sda_reg <= 'dz; scl_reg <= 1'dz; end
endcase
`STOP : case (scl_4)
: begin sda_enable <= 'd1; scl_enable <= 1'd1; delay_enable <= 'd0;
sda_reg <= 'd0; scl_reg <= 1'd0; end
: begin sda_reg <= 'd0; scl_reg <= 1'd0; end
: begin sda_reg <= 'd0; scl_reg <= 1'd1; end
: begin sda_reg <= 'd1; scl_reg <= 1'd1; end
: delay_enable <= 'd1;
default begin sda_reg <= 'dz; scl_reg <= 1'dz; end
endcase
`Se : case (scl_4)
: begin sda_enable <= 'd1; scl_enable <= 1'd1; delay_enable <= 'd0;
sda_reg <= 'd0; scl_reg <= 1'd0; end
: begin sda_reg <= SEND_buffer[]; scl_reg <= 'd0; end
: begin sda_reg <= SEND_buffer[]; scl_reg <= 'd1; end
: begin sda_reg <= SEND_buffer[]; scl_reg <= 'd1; end
: begin scl_reg <= 'd0; end
: begin sda_reg <= SEND_buffer[]; scl_reg <= 'd0; end
: begin sda_reg <= SEND_buffer[]; scl_reg <= 'd1; end
: begin sda_reg <= SEND_buffer[]; scl_reg <= 'd1; end
: begin scl_reg <= 'd0; end
: begin sda_reg <= SEND_buffer[]; scl_reg <= 'd0; end
: begin sda_reg <= SEND_buffer[]; scl_reg <= 'd1; end
: begin sda_reg <= SEND_buffer[]; scl_reg <= 'd1; end
: begin scl_reg <= 'd0; end
: begin sda_reg <= SEND_buffer[]; scl_reg <= 'd0; end
: begin sda_reg <= SEND_buffer[]; scl_reg <= 'd1; end
: begin sda_reg <= SEND_buffer[]; scl_reg <= 'd1; end
: begin scl_reg <= 'd0; end
: begin sda_reg <= SEND_buffer[]; scl_reg <= 'd0; end
: begin sda_reg <= SEND_buffer[]; scl_reg <= 'd1; end
: begin sda_reg <= SEND_buffer[]; scl_reg <= 'd1; end
: begin scl_reg <= 'd0; end
: begin sda_reg <= SEND_buffer[]; scl_reg <= 'd0; end
: begin sda_reg <= SEND_buffer[]; scl_reg <= 'd1; end
: begin sda_reg <= SEND_buffer[]; scl_reg <= 'd1; end
: begin scl_reg <= 'd0; end
: begin sda_reg <= SEND_buffer[]; scl_reg <= 'd0; end
: begin sda_reg <= SEND_buffer[]; scl_reg <= 'd1; end
: begin sda_reg <= SEND_buffer[]; scl_reg <= 'd1; end
: begin scl_reg <= 'd0; end
: begin sda_reg <= SEND_buffer[]; scl_reg <= 'd0; end
: begin sda_reg <= SEND_buffer[]; scl_reg <= 'd1; end
: begin sda_reg <= SEND_buffer[]; scl_reg <= 'd1; end
//此时序之后必须释放掉sda控制权 等待响应
: begin sda_enable <= 'd0; scl_enable <= 1'd0; delay_enable <= 'd1;
ack_reg <= 'd0; scl_reg <= 1'd0; end //这里出现了一个警告,因为ack_reg没有利用到
: begin ack_reg <= sda; scl_reg <= 'd0; end
: begin ack_reg <= sda; scl_reg <= 'd1; end
: begin ack_reg <= sda; scl_reg <= 'd1; end
//此时IC有可能在一个时钟下来不及响应,从而导致主机没有接收到响应信号
default begin scl_reg <= 'dz; end
endcase `Re : case (scl_4)
: begin sda_enable <= 'd0; scl_enable <= 1'd1; delay_enable <= 'd0;
scl_reg <= 'd0; end
: begin scl_reg <= 'd0; end
: begin scl_reg <= 'd1; end
: begin Re_buffer[] <= sda; scl_reg <= 'd1; end
: begin scl_reg <= 'd0; end
: begin scl_reg <= 'd0; end
: begin scl_reg <= 'd1; end
: begin Re_buffer[] <= sda; scl_reg <= 'd1; end
: begin scl_reg <= 'd0; end
: begin scl_reg <= 'd0; end
: begin scl_reg <= 'd1; end
: begin Re_buffer[] <= sda; scl_reg <= 'd1; end
: begin scl_reg <= 'd0; end
: begin scl_reg <= 'd0; end
: begin scl_reg <= 'd1; end
: begin Re_buffer[] <= sda; scl_reg <= 'd1; end
: begin scl_reg <= 'd0; end
: begin scl_reg <= 'd0; end
: begin scl_reg <= 'd1; end
: begin Re_buffer[] <= sda; scl_reg <= 'd1; end
: begin scl_reg <= 'd0; end
: begin scl_reg <= 'd0; end
: begin scl_reg <= 'd1; end
: begin Re_buffer[] <= sda; scl_reg <= 'd1; end
: begin scl_reg <= 'd0; end
: begin scl_reg <= 'd0; end
: begin scl_reg <= 'd1; end
: begin Re_buffer[] <= sda; scl_reg <= 'd1; end
: begin scl_reg <= 'd0; end
: begin scl_reg <= 'd0; end
: begin scl_reg <= 'd1; end
: begin Re_buffer[] <= sda; scl_reg <= 'd1; end
//此时序之后主机夺回sda控制权,延时开始
: begin sda_enable <= 'd1; delay_enable <= 1'd1;
sda_reg <= ; scl_reg <= 'd0; end
: begin sda_reg <= ; scl_reg <= 'd0; end
: begin sda_reg <= ; scl_reg <= 'd1; end
: begin sda_reg <= ; scl_reg <= 'd1; end
default begin sda_reg <= 'dz; scl_reg <= 1'dz;end
endcase
endcase
//-------外部数据线 控制模块----------end--------------- assign sda = sda_enable ? sda_reg : 'dz ;
assign scl = scl_enable ? scl_reg : 'dz ;
//==================================================================================== //--------------数码管显示部分=======只显示了一部分,有待优化============================
always @ ( posedge clock or negedge reset)
if (!reset)
begin
sel_seg <= 'b111110;
end
else if(state_finish_flag)
begin
sel_seg <= {sel_seg[:],sel_seg[]};
end
//------------------------------------------------
always @(posedge clock or negedge reset)
if (!reset) out_seg <= 'd0;
else
begin
case (Re_buffer[:]) //刚开始这里没有[3:0] 居然没有报错,连个警告都没有,这是为什么呢
'b0000 : out_seg<=8'b1100_0000;//0000_0011
'b0001 : out_seg<=8'b1111_1001;//1001_1111
'b0010 : out_seg<=8'b1010_0100;//0010_0101
'b0011 : out_seg<=8'b1011_0000;//0000_1101
'b0100 : out_seg<=8'b1001_1001;//1001_1001
'b0101 : out_seg<=8'b1001_0010;//0100_1001
'b0110 : out_seg<=8'b1000_0010;//0100_0001
'b0111 : out_seg<=8'b1111_1000;//0001_1111
'b1000 : out_seg<=8'b1000_0000;//0000_0001
'b1001 : out_seg<=8'b1001_1000;//0001_1001
'b1010 : out_seg<=8'b1000_1000;//0001_0001
'b1011 : out_seg<=8'b1000_0011;//1100_0001
'b1100 : out_seg<=8'b1100_0110;//0110_0011
'b1101 : out_seg<=8'b1010_0001;//1000_0101
'b1110 : out_seg<=8'b1000_0110;//0110_0001
'b1111 : out_seg<=8'b1000_1110;//0111_0001
endcase
end
//-------------------------------================================= endmodule
Verilog实现IIC通讯第二版的更多相关文章
- Verilog笔记——Verilog数字系统设计(第二版)夏宇闻
本片记录Verilog学习笔记,主要是和以往用的C语言的不同之处,以例子.代码的形式记录.学习以<Verilog数字系统设计>(第二版)为参考资料,援助作者夏宇闻. 1. C语言和Veri ...
- 用Verilog实现IIC通讯
注意,此代码是错误代码,并不能实现想要的结果. 之所以留着,因为里面的enable 是独立开来的思想值得借鉴.就是控制单元和运算单元分开(我也是借鉴别人的实现思想).具体用verilogHDL实现II ...
- 一套简单的web即时通讯——第二版
前言 接上一版,这一版的页面与功能都有所优化,具体如下: 1.优化登录拦截 2.登录后获取所有好友并区分显示在线.离线好友,好友上线.下线都有标记 3.将前后端交互的值改成用户id.显示值改成昵称ni ...
- python核心编程第二版笔记
python核心编程第二版笔记由网友提供:open168 python核心编程--笔记(很详细,建议收藏) 解释器options:1.1 –d 提供调试输出1.2 –O 生成优化的字节码(生成 ...
- 读书笔记:JavaScript DOM 编程艺术(第二版)
读完还是能学到很多的基础知识,这里记录下,方便回顾与及时查阅. 内容也有自己的一些补充. JavaScript DOM 编程艺术(第二版) 1.JavaScript简史 JavaScript由Nets ...
- 《selenium2 Java 自动化测试实战(第二版)》 更新2016.5.3
java 版来了!! 本文档在<selenium2 Python 自动化测试实战>的基础上,将代码与实例替换为java ,当然,部分章节有变更.这主要更语言本身的特点有关.集合和java下 ...
- 《Java程序设计与数据结构教程(第二版)》学习指导
<Java程序设计与数据结构教程(第二版)>学习指导 欢迎关注"rocedu"微信公众号(手机上长按二维码) 做中教,做中学,实践中共同进步! 原文地址:http:// ...
- (转载)持续集成(第二版)[来自:Martin Fowler]
转载自:iTech的博客 持续集成(第二版) 作者:Martin Fowler 译者:雷镇 持续集成 是一种软件开发实践.在持续集成中,团队成员频繁集成他们的工作成果,一般每人每天至少集成一次,也可以 ...
- Learning ROS for Robotics Programming - Second Edition(《学习ROS机器人编程-第二版》)
Learning ROS for Robotics Programming - Second Edition <学习ROS机器人编程-第二版> ----Your one-stop guid ...
随机推荐
- PROTEL 99SE的打印设置
现在市面上关于PTROTEL99SE的书很多,但都没有具体叙述有关电路图的打印设置方法.PROTEL99SE的打印设置较之以前的版本有了很多不同之处.特别是在实际做电路板时有些细节须注意. 原理图的打 ...
- centos6.5 搭建php5.5+mysql5.5+apache2.4
本文总结了Linux下 root.常用查找命令.卸载软件方法(见二.安装PHP5.5).配置软件源(见二).安装软件(见二)与高版本替换软件(见三.安装MySQL)的方法. 迁移网站,机器上原本已有p ...
- openstack之cinder
一.cinder概述: 1.F版之前,并没有cinder,对应的组件为nova-volume:以Rest API的形式提供服务 2.cinder目标: 减少nova的复杂性,降低nova的负载,支持多 ...
- Razor强类型视图下的文件上传
域模型Users.cs using System;using System.Collections.Generic;using System.Linq;using System.Web; namesp ...
- TCP粘包和半包的处理方法
先把处理的方法的代码放这里: 解析数据帧的代码: bool CSocket::findData(byte* buff, int& len) { for (int i = 0; i <= ...
- Dapper 多数据库优化
Dapper是近2年异军突起的新ORM工具,它有ado.net般的高性能又有反射映射实体的灵活性,非常适合喜欢原生sql的程序员使用,而且它源码很小,十分轻便.我写本博客的目的不是为了介绍Dapper ...
- 用SQL实现统计报表中的"小计"与"合计"的方法详解
本篇文章是对使用SQL实现统计报表中的"小计"与"合计"的方法进行了详细的分析介绍,需要的朋友参考下 客户提出需求,针对某一列分组加上小计,合计汇总.网上找 ...
- ie条件注释还能这样写
通过条件注释给html开始标签定义不同的class, 来区分不同版本的IE,可以在样式表中避免 样式属性hack (如 _margin-top, *float:none ) 注意: IE10+不支持条 ...
- 多少遍ner让他加56看6
http://www.huihui.cn/share/8112372 http://www.huihui.cn/share/8112363 http://www.huihui.cn/share/811 ...
- 资源文件(.RES)的应用
资源档有什麽用处呢?最重要的有两个地方1.国际发行:我们将Application中所有的文字从Resource用读取,那麽,只要更动 Resource档的内容,就可以用不同语言的 ...