⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 libreria_i2c.vhd

📁 用VHDL实现视频控制程序
💻 VHD
📖 第 1 页 / 共 3 页
字号:
			-- un '0' en el biestable de salida
			-- para ir preparando la condicion de
			-- START.
			load_new <= '0';
			inc_punt <= '0';
			inc_sel_byte <= '0';
			reset_sel_byte <= '0';
			ENespera64 <= '0';
			ENespera128 <= '0';
			ready <= '1';
			-- CONTROL SCL.
			preset_div <= '1';
			reset_div <= '0';
			OESCL <= '0';
			-- CONTROL SDA.
			reset_bit <= '1';
			load_bit <= '0';		
			OESDA <= '0';
			if (trans = '1') then
				siguiente <= captura_datos;
			else
				siguiente <= reposo;
			end if;
		when captura_datos =>
			-- Se ha detectado una orden de inicio
			-- de transferencia.
			-- Cargamos tanto la direccion como el
			-- dato en los registros de entrada.
			-- Se supone que cuando se da esta orden
			-- de inicio de transferencia, estos 2 
			-- bytes estan preparados en los buses 
			-- de entrada a ambos registros.
			-- Reseteamos el puntero de bytes.
			-- Habilitamos la salida de SCL.
			load_new <= '1';
			inc_punt <= '0';
			inc_sel_byte <= '0';
			reset_sel_byte <= '1';
			ENespera64 <= '0';
			ENespera128 <= '0';
			ready <= '0';
			-- CONTROL SCL.
			preset_div <= '0';
			reset_div <= '0';
			OESCL <= '1';
			-- CONTROL SDA.
			reset_bit <= '0';
			load_bit <= '0';		
			OESDA <= '0';
			siguiente <= cond_start;
		when cond_start =>
			-- Generamos la condicion de start
			-- poniendo SDA a '0' con SCL a '1'.
			-- Lo que hacemos es dejar salir el
			-- contenido del biestable de salida,
			-- el cual precargamos al principio con
			-- un '0'.
			load_new <= '0';
			inc_punt <= '0';
			inc_sel_byte <= '0';
			reset_sel_byte <= '0';
			ENespera64 <= '0';
			ENespera128 <= '0';
			ready <= '0';
			-- CONTROL SCL.
			preset_div <= '0';
			reset_div <= '0';
			OESCL <= '1';
			-- CONTROL SDA.
			reset_bit <= '0';
			load_bit <= '0';		
			OESDA <= '1';
			siguiente <= esp_SCL0;
		when esp_SCL0 =>
			-- Esperamos a que SCL sea '0'
			-- para poder poner el bit a transmitir
			-- sobre la linea SDA.
			load_new <= '0';
			inc_punt <= '0';
			inc_sel_byte <= '0';
			reset_sel_byte <= '0';
			ENespera64 <= '0';
			ENespera128 <= '0';
			ready <= '0';
			-- CONTROL SCL.
			preset_div <= '0';
			reset_div <= '0';
			OESCL <= '1';
			-- CONTROL SDA.
			reset_bit <= '0';
			load_bit <= '0';		
			OESDA <= '1';
			if (SCL = '0') then
				siguiente <= espera_64;
			else
				siguiente <= esp_SCL0;
			end if;
		when espera_64 =>
			-- SCL = '0'.
			-- Esperamos a que pasen 64 Tclk
			-- para capturar el bit a transmitir
			-- en el latch de salida. Asi 
			-- aseguramos que SDA solo conmuta 
			-- en la mitad del semiperiodo '0'
			-- de SCL.
			load_new <= '0';
			inc_punt <= '0';
			inc_sel_byte <= '0';
			reset_sel_byte <= '0';
			ENespera64 <= '1';
			ENespera128 <= '0';
			ready <= '0';
			-- CONTROL SCL.
			preset_div <= '0';
			reset_div <= '0';
			OESCL <= '1';
			-- CONTROL SDA.
			reset_bit <= '0';
			load_bit <= '0';		
			OESDA <= '1';
			if (fin_espera64= '1') then
				siguiente <= envia_bit;
			else	
				siguiente <= espera_64;
			end if;
		when envia_bit =>
			-- Capturamos el bit a transmitir
			-- en el biestable de salida, es decir,
			-- ponemos el bit en SDA.
			load_new <= '0';
			inc_punt <= '0';
			inc_sel_byte <= '0';
			reset_sel_byte <= '0';
			ENespera64 <= '0';
			ENespera128 <= '0';
			ready <= '0';
			-- CONTROL SCL.
			preset_div <= '0';
			reset_div <= '0';
			OESCL <= '1';
			-- CONTROL SDA.
			reset_bit <= '0';
			load_bit <= '1';		
			OESDA <= '1';
			siguiente <= esp_SCL1;
		when esp_SCL1 =>
			-- Esperamos a que SCL sea '1'.
			load_new <= '0';
			inc_punt <= '0';
			inc_sel_byte <= '0';
			reset_sel_byte <= '0';
			ENespera64 <= '0';
			ENespera128 <= '0';
			ready <= '0';
			-- CONTROL SCL.
			preset_div <= '0';
			reset_div <= '0';
			OESCL <= '1';
			-- CONTROL SDA.
			reset_bit <= '0';
			load_bit <= '0';		
			OESDA <= '1';
			if (SCL = '1') then 
				siguiente <= hold_bit;
			else
				siguiente <= esp_SCL1;
			end if;	
		when hold_bit =>
			-- Mantenemos el bit cargado en el 
			-- biestable de salida durante todo el
			-- tiempo en que SCL = '1' para respetar
			-- el protocolo.
			load_new <= '0';
			inc_punt <= '0';
			inc_sel_byte <= '0';
			reset_sel_byte <= '0';
			ENespera64 <= '0';
			ENespera128 <= '0';
			ready <= '0';
			-- CONTROL SCL.
			preset_div <= '0';
			reset_div <= '0';
			OESCL <= '1';
			-- CONTROL SDA.
			reset_bit <= '0';
			load_bit <= '0';		
			OESDA <= '1';
			if (SCL = '0') then 
				siguiente <= nuevo_bit;
			else
				siguiente <= hold_bit;
			end if;			
		when nuevo_bit =>
			-- Llegamos a SCL = '0' de nuevo.
			-- Hemos de evaluar si quedan mas bits
			-- por transmitir del byte en cuestion.
			-- Esperamos 64 Tclk antes de cambiar
			-- SDA.
			load_new <= '0';
			inc_punt <= '0';
			inc_sel_byte <= '0';
			reset_sel_byte <= '0';
			ENespera64 <= '1';
			ENespera128 <= '0';
			ready <= '0';
			-- CONTROL SCL.
			preset_div <= '0';
			reset_div <= '0';
			OESCL <= '1';
			-- CONTROL SDA.
			reset_bit <= '0';
			load_bit <= '0';		
			OESDA <= '1';
			if (fin_espera64 = '1') then 
				siguiente <= mira_puntero;
			else
				siguiente <= nuevo_bit;
			end if;
		when mira_puntero =>
			-- Hemos de cambiar SDA segun el valor
			-- del puntero. Si puntero = "111"
			-- significa que hemos enviado el ultimo
			-- bit y debemos poner SDA en alta 
			-- impedancia para recibir el ACK.
			-- Si puntero < "111" aun quedan bits
			-- por enviar. 
			load_new <= '0';
			inc_punt <= '0';
			inc_sel_byte <= '0';
			reset_sel_byte <= '0';
			ENespera64 <= '0';
			ENespera128 <= '0';
			ready <= '0';
			-- CONTROL SCL.
			preset_div <= '0';
			reset_div <= '0';
			OESCL <= '1';
			-- CONTROL SDA.
			reset_bit <= '0';
			load_bit <= '0';		
			OESDA <= '1';
			if (puntero = "111") then
				siguiente <= reset_puntero;
			else
				siguiente <= incrementa_puntero;
			end if;
		when incrementa_puntero =>
			-- Incrementamos el puntero para 
			-- seleccionar el siguiente bit a enviar.
			load_new <= '0';
			inc_punt <= '1';
			inc_sel_byte <= '0';
			reset_sel_byte <= '0';
			ENespera64 <= '0';
			ENespera128 <= '0';
			ready <= '0';
			-- CONTROL SCL.
			preset_div <= '0';
			reset_div <= '0';
			OESCL <= '1';
			-- CONTROL SDA.
			reset_bit <= '0';
			load_bit <= '0';		
			OESDA <= '1';
			siguiente <= espera_cargar_bit;
		when espera_cargar_bit =>
			-- Introducimos este periodo de espera
			-- de 1 Tclk para dar tiempo a la 
			-- actualizacion del puntero.
			-- Despues volvemos al estado en que 
			-- generamos la salida del bit a SDA.
			load_new <= '0';
			inc_punt <= '0';
			inc_sel_byte <= '0';
			reset_sel_byte <= '0';
			ENespera64 <= '0';
			ENespera128 <= '0';
			ready <= '0';
			-- CONTROL SCL.
			preset_div <= '0';
			reset_div <= '0';
			OESCL <= '1';
			-- CONTROL SDA.
			reset_bit <= '0';
			load_bit <= '0';		
			OESDA <= '1';
			siguiente <= envia_bit;		
		when reset_puntero =>
			-- El puntero senalaba al ultimo bit.
			-- Lo incrementamos para ponerlo a 0 y
			-- asi volver a senalar al primero.
			-- Despues ponemos SDA en alta impedancia
			-- para recibir el ACK.
			load_new <= '0';
			inc_punt <= '1';
			inc_sel_byte <= '0';
			reset_sel_byte <= '0';
			ENespera64 <= '0';
			ENespera128 <= '0';
			ready <= '0';
			-- CONTROL SCL.
			preset_div <= '0';
			reset_div <= '0';
			OESCL <= '1';
			-- CONTROL SDA.
			reset_bit <= '0';
			load_bit <= '0';		
			OESDA <= '1';
			siguiente <= comprueba_ACK1;
		when comprueba_ACK1 =>
			-- Hemos transmitido el byte completo.
			-- Hacemos que SDA este en alta 
			-- impedancia para que el procesador
			-- de video pueda transmitir el ACK.
			-- Esperamos a que SCL sea '1' para 
			-- comprobar el valor de SDA.
			load_new <= '0';
			inc_punt <= '0';
			inc_sel_byte <= '0';
			reset_sel_byte <= '0';
			ENespera64 <= '0';
			ENespera128 <= '0';
			ready <= '0';
			-- CONTROL SCL.
			preset_div <= '0';
			reset_div <= '0';
			OESCL <= '1';
			-- CONTROL SDA.
			reset_bit <= '0';
			load_bit <= '0';		
			OESDA <= '0';
			if (SCL = '1') then
				siguiente <= comprueba_ACK2;
			else
				siguiente <= comprueba_ACK1;
			end if;			
		when comprueba_ACK2 =>
			-- SCL = '1', esperamos 64 Tclk para
			-- mirar el valor de SDA a mitad del
			-- semiperiodo '1' de SCL.
			load_new <= '0';
			inc_punt <= '0';
			inc_sel_byte <= '0';
			reset_sel_byte <= '0';
			ENespera64 <= '1';
			ENespera128 <= '0';
			ready <= '0';
			-- CONTROL SCL.
			preset_div <= '0';
			reset_div <= '0';
			OESCL <= '1';
			-- CONTROL SDA.
			reset_bit <= '0';
			load_bit <= '0';		
			OESDA <= '0';
			if (fin_espera64 = '1') then
				siguiente <= comprueba_ACK3;
			else
				siguiente <= comprueba_ACK2;
			end if;
		when comprueba_ACK3 =>
			-- En este momento comprobamos si SDA
			-- esta a '0' (ACK).
			-- Tambien determinamos si hemos enviado
			-- los tres bytes necesarios para 
			-- especificar la escritura de un 
			-- registro interno del procesador de
			-- video via I2C, o bien, aun nos queda
			-- alguno por enviar.
			load_new <= '0';
			inc_punt <= '0';
			inc_sel_byte <= '0';
			reset_sel_byte <= '0';
			ENespera64 <= '0';
			ENespera128 <= '0';
			ready <= '0';
			-- CONTROL SCL.
			preset_div <= '0';
			reset_div <= '0';
			OESCL <= '1';
			-- CONTROL SDA.
			reset_bit <= '0';
			load_bit <= '0';		
			OESDA <= '0';
			if (SDAent = '0') then
			-- Si detectamos ACK correcto...
				if (punt_byte = "10") then
					siguiente <= set_punt_byte;
				else
					siguiente <= sig_byte;
				end if;
			else
			-- Si no hay ACK por parte del
			-- procesador de video... 
				siguiente <= STOP1;
			end if;
		when sig_byte =>
			-- Se ha detectado con exito el ACK del
			-- ultimo byte enviado pero nos quedan
			-- bytes por enviar para completar la 
			-- escritura.
			-- Aqui hacemos que el multiplexor
			-- encargado de seleccionar el byte a
			-- transmitir, seleccione al siguiente.
			load_new <= '0';
			inc_punt <= '0';
			inc_sel_byte <= '1';
			reset_sel_byte <= '0';
			ENespera64 <= '0';
			ENespera128 <= '0';
			ready <= '0';
			-- CONTROL SCL.
			preset_div <= '0';
			reset_div <= '0';
			OESCL <= '1';
			-- CONTROL SDA.
			reset_bit <= '0';
			load_bit <= '0';		
			OESDA <= '0';
			siguiente <= esp_SCL0_sigbyte;
		when esp_SCL0_sigbyte =>
			-- Esperamos a que SCL sea '0' para
			-- preparar la transmision del 
			-- siguiente byte.
			load_new <= '0';
			inc_punt <= '0';
			inc_sel_byte <= '0';
			reset_sel_byte <= '0';
			ENespera64 <= '0';
			ENespera128 <= '0';
			ready <= '0';
			-- CONTROL SCL.
			preset_div <= '0';
			reset_div <= '0';
			OESCL <= '1';
			-- CONTROL SDA.
			reset_bit <= '0';
			load_bit <= '0';		
			OESDA <= '0';
			if (SCL = '0') then
				siguiente <= esp_sig_dato;
			else 
				siguiente <= esp_SCL0_sigbyte;
			end if;
		when esp_sig_dato =>
			-- Reseteamos el divisor mientras
			-- incluimos una espera adicional de
			-- 128 Tclk antes de enviar el siguiente
			-- byte (dato).
			load_new <= '0';
			inc_punt <= '0';
			inc_sel_byte <= '0';
			reset_sel_byte <= '0';
			ENespera64 <= '0';
			ENespera128 <= '1';
			ready <= '0';
			-- CONTROL SCL.
			preset_div <= '0';
			reset_div <= '1';
			OESCL <= '1';
			-- CONTROL SDA.
			reset_bit <= '0';

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -