VHDL编写IIC程序

更新时间:2023-10-24 19:52:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

如题所示,本文是使用VHDL语言编写的IIC 总线的24C02的读写例程,程序加了中文注释便于想我一样的初学者理解,写使用的写一个字节,读使用的随机读,具体参考24c02的手册

library IEEE;

use IEEE.std_logic_1164.all; use IEEE.std_logic_arith.all; use IEEE.std_logic_unsigned.all;

entity iic_com is port( clk: in STD_LOGIC; rst_n: in STD_LOGIC; sw1_en: in STD_LOGIC; --读使能 sw2_en: in STD_LOGIC; --写使能 scl: out STD_LOGIC; sda: inout STD_LOGIC; dis_data: out STD_LOGIC_VECTOR (7 downto 0) );

end entity iic_com;

architecture iic_communication of iic_com is signal sw_state: STD_LOGIC; signal cnt_delay: STD_LOGIC_VECTOR (8 downto 0); signal scl_pos: STD_LOGIC; signal scl_hig: STD_LOGIC; signal scl_neg: STD_LOGIC; signal scl_low: STD_LOGIC; signal db_r: STD_LOGIC_VECTOR (7 downto 0); signal read_data: STD_LOGIC_VECTOR (7 downto 0); signal sda_r: STD_LOGIC; signal sda_in: STD_LOGIC; signal sda_link: STD_LOGIC; signal num: STD_LOGIC_VECTOR (3 downto 0); constant DEVICE_READ: STD_LOGIC_VECTOR (7 downto 0) := \器件地址读 constant DEVICE_WRITE: STD_LOGIC_VECTOR (7 downto 0) := \器件地址写 constant WRITE_DATA: STD_LOGIC_VECTOR (7 downto 0) := \写入的数据 constant BYTE_ADDR: STD_LOGIC_VECTOR (7 downto 0) := \写入的地址 type state (IDLE,START1,ADD1,ACK1,ADD2,ACK2,START2,ADD3,ACK3,DATA,ACK4,STOP1,STOP2); signal cstate: state; signal temp_sw1,temp_sw2:Std_LOGIC; begin

---------------------- process(clk,rst_n)

is begin if (rst_n = '0') then sw_state <= '0'; elsif (clk'event AND clk = '1') then if(sw1_en = '1') then sw_state <= '0'; elsif (sw2_en = '1') then sw_state <= '1'; end if; end if; end process; ---------------------- process(clk,rst_n) begin if (rst_n = '0') then cnt_delay <= '0' & x\ elsif (clk'event AND clk = '1') then if(cnt_delay = 10#499#) then cnt_delay <= '0' & x\ else cnt_delay <= cnt_delay+'1'; end if; end if; end process;

scl_pos <= '1' when (cnt_delay = 10#499#) else '0'; scl_hig <= '1' when (cnt_delay = 10#124#) else

'0'; scl_neg <= '1' when (cnt_delay = 10#249#) else '0'; scl_low <= '1' when (cnt_delay = 10#374#) else '0'; process(clk,rst_n) begin if (rst_n = '0') then scl <= '0'; elsif (clk'event AND clk = '1') then if(scl_pos = '1') then scl <= '1'; elsif(scl_neg = '1') then scl <= '0'; end if; end if;

end process;

--相当于500分频,得到100K时钟 --IIC时钟上升沿 --IIC时钟高电平

--IIC时钟下降沿

--IIC时钟低电平

---------------------- process(clk,rst_n) begin if (rst_n = '0') then cstate <= IDLE; sda_r <= '1'; sda_link <= '0'; num <= x\ read_data <= x\ elsif (clk'event AND clk = '1') then case cstate is when IDLE => sda_link <= '1'; sda_r <= '1';

if (sw1_en/=temp_sw1)or(sw2_en/=temp_sw2) then --当sw1_en 和sw2_en 变化一次,只读或写一次,避免多次读写 temp_sw1<=sw1_en;temp_sw2<=sw2_en; if ((sw1_en = '1') OR (sw2_en = '1')) then db_r <= DEVICE_WRITE; cstate <= START1; else cstate <= IDLE; end if; else cstate <= IDLE; end if; when START1 => if (scl_hig = '1') then --起始位 sda_link <= '1';--数据线由sda_r控制 sda_r <= '0'; cstate <= ADD1; num <= x\ else cstate <= START1; end if; when ADD1 => --器件地址&'0' if (scl_low = '1') then if (num = x\ num <= x\ sda_r <= '1'; sda_link <= '0';--数据线设为高阻态,允许输入 cstate <= ACK1; else

cstate <= ADD1; num <= num+'1'; case num is

的地址

when x\ when x\ when x\ when x\ when x\ when x\ when x\ when x\ when others => NULL; end case; end if; else cstate <= ADD1; end if;

when ACK1 =>

--应答

if (scl_neg = '1') then cstate <= ADD2; db_r <= BYTE_ADDR; else cstate <= ACK1;

end if; when ADD2 =>

--要写入数据或读取数据

if (scl_low = '1') then if (num = x\ num <= x\

sda_r <= '1'; sda_link <= '0';--数据线设为高阻态,允许输入 cstate <= ACK2; else sda_link <= '1';--数据线由sda_r控制 num <= num+'1'; cstate <= ADD2; case num is when x\ when x\ when x\ when x\ when x\

when x\

when x\ when x\ when others => NULL; end case; end if; else cstate <= ADD2; end if;

--应答

when ACK2 => if (scl_neg = '1') then

if (sw_state = '0') then --如果写入数据 cstate <= DATA; db_r <= WRITE_DATA;

--如果读取数据

elsif (sw_state = '1') then db_r <= DEVICE_READ; cstate <= START2; end if; else cstate <= ACK2; end if;

when START2 => --起始位 if (scl_low = '1') then sda_link <= '1'; sda_r <= '1'; cstate <= START2; elsif (scl_hig = '1') then sda_r <= '0'; cstate <= ADD3; else cstate <= START2; end if; when ADD3 => --器件地址&'1' if (scl_low ='1') then if (num = x\ num <= x\ sda_r <= '1'; sda_link <= '0'; cstate <= ACK3; l11<='0'; else num <= num+'1'; cstate <= ADD3; case num is when x\

本文来源:https://www.bwwdw.com/article/b492.html

Top