求是 程序doc.docx
《求是 程序doc.docx》由会员分享,可在线阅读,更多相关《求是 程序doc.docx(33页珍藏版)》请在冰豆网上搜索。
求是程序doc
顶层
libraryIEEE;
useIEEE.STD_LOGIC_1164.ALL;
useieee.std_logic_unsigned.all;
useieee.std_logic_arith.all;
entityTotal_Programis
port(CLK:
instd_logic;--100MHZ时钟信号
RESET:
instd_logic;
--人体热释电
INFRARED_RECEIVE:
instd_logic;--红外人体感应输出信号
INF_LED:
outstd_logic;--人体红外热释电感应到就灯亮
--按键控制
KEY_IN:
instd_logic_vector(3downto0);--四个按键
--AD7991采样
LED3:
outstd_logic;--转换成功标志
SDA:
inoutstd_logic;
SCL:
outstd_logic;
AD_CONVERSION_SPEED:
outstd_logic;--ad采样速度,用于观察
--电机控制
PWM_OUT:
outstd_logic;
--数码管显示
DOT:
outstd_logic;--小数点
LED7:
outstd_logic_vector(6downto0);--gfedcbacomAnode
BIT8:
outstd_logic_vector(0to7)--bit8(7)tothefirstsmg
);
endTotal_Program;
architectureBehavioralofTotal_Programis
--按键子程序
componentManyKeys
port(CLK:
instd_logic;
RESET:
instd_logic;
KEY_IN:
instd_logic_vector(3downto0);--四个按键
KEY_OUT:
outstd_logic_vector(3downto0)--按键输出指示,对应key1~key4
);
endcomponent;
--AD采样
componentack_check
port(CLK:
instd_logic;--100MHZ
RESET:
instd_logic;
Sampling_fre:
outstd_logic;--AD7991每次转换标志
LED3:
outstd_logic;--转换成功标志
SDA:
inoutstd_logic;
SCL:
outstd_logic;
AD_CONVERSION_SPEED:
outstd_logic;
DATA_OUT:
outstd_logic_vector(11downto0)
);
endcomponent;
--电机控制程序
componentMotor_Control
port(CLK:
instd_logic;
RESET:
instd_logic;
KEY1,KEY2,KEY3,KEY4:
instd_logic;--四个独立按键
SAMPLING_FLAG:
instd_logic;--AD7991每次采样标志
INFRARED_RECEIVE:
instd_logic;--红外热释电接收信号
INF_LED:
outstd_logic;--人体红外热释电感应到就灯亮
SAMPLING_DATA:
instd_logic_vector(11downto0);--AD7991每次采样输出的12bits数据
SMG_DATA_SV:
outstd_logic_vector(11downto0);--给数码管显示的设定数据;
SMG_DATA_PV:
outstd_logic_vector(11downto0);--给数码管显示的测量值
PWM_DUTY:
outstd_logic_vector(6downto0)--控制PWM的数值
);
endcomponent;
--PWM控制
componentPWM
port(CLK:
instd_logic;
RESET:
instd_logic;
DUTY:
instd_logic_vector(6downto0);--从0~100%
PWM_OUT:
outstd_logic
);
endcomponent;
--数码管显示
componentSmg_Display
port(CLK:
instd_logic;--100MHZ
RESET:
instd_logic;
DATA_SV:
instd_logic_vector(11downto0);
DATA_PV:
instd_logic_vector(11downto0);
DOT:
outstd_logic;--MSBLSB
LED7:
outstd_logic_vector(6downto0);--gfedcbacomAnode
BIT8:
outstd_logic_vector(0to7)--bit8(7)tothefirstsmg
);
endcomponent;
signalkey_reg:
std_logic_vector(3downto0);
signalsampling_reg:
std_logic;
signalad_reg:
std_logic_vector(11downto0);
signalduty_reg:
std_logic_vector(6downto0);
signalsv_smg,pv_smg:
std_logic_vector(11downto0);
begin
UA:
ManyKeysportmap(CLK=>CLK,
RESET=>RESET,
KEY_IN=>KEY_IN,
KEY_OUT=>key_reg
);
UB:
ack_checkportmap(CLK=>CLK,
RESET=>RESET,
Sampling_fre=>sampling_reg,
LED3=>LED3,
SDA=>SDA,
SCL=>SCL,
AD_CONVERSION_SPEED=>AD_CONVERSION_SPEED,
DATA_OUT=>ad_reg
);
UC:
Motor_Controlportmap(CLK=>CLK,
RESET=>RESET,
KEY1=>key_reg(3),
KEY2=>key_reg
(2),
KEY3=>key_reg
(1),
KEY4=>key_reg(0),
SAMPLING_FLAG=>sampling_reg,
INFRARED_RECEIVE=>INFRARED_RECEIVE,
INF_LED=>INF_LED,
SAMPLING_DATA=>ad_reg,
SMG_DATA_SV=>sv_smg,
SMG_DATA_PV=>pv_smg,
PWM_DUTY=>duty_reg
);
UD:
PWMportmap(CLK=>CLK,
RESET=>RESET,
DUTY=>duty_reg,
PWM_OUT=>PWM_OUT
);
UE:
Smg_Displayportmap(CLK=>CLK,
RESET=>RESET,
DATA_SV=>sv_smg,
DATA_PV=>pv_smg,
DOT=>DOT,
LED7=>LED7,
BIT8=>BIT8
);
endBehavioral;
2222222222UA-ManyKeys22222222222222222222222222222222222
libraryIEEE;
useIEEE.STD_LOGIC_1164.ALL;
useieee.std_logic_unsigned.all;
useieee.std_logic_arith.all;
entityManyKeysis
port(CLK:
instd_logic;
RESET:
instd_logic;
KEY_IN:
instd_logic_vector(3downto0);--四个按键
KEY_OUT:
outstd_logic_vector(3downto0)--按键输出指示,对应key1~key4
);
endManyKeys;
architectureBehavioralofManyKeysis
componentIndependent_Keys
port(
CLK:
instd_logic;--100MHZ
RESET:
instd_logic;--CPURESET
KEY:
instd_logic;--输入按键
KOUT:
outstd_logic--按键输出指示
);
endcomponent;
begin
G1:
foriin0to3generate
ux:
Independent_Keysportmap(CLK=>CLK,
RESET=>RESET,
KEY=>KEY_IN(i),
KOUT=>KEY_OUT(i)
);
endgenerate;
endBehavioral;
3333333333333333333333333333ux_indepent3333333333333333333333333333
---程序功能:
单个按键按下并要求释放后才算一次按键,按下和释放都去抖了,一次按键按下并释放后
------------按键输出只持续10ms高电平-----
------------------浙江求是科教设备有限公司----------------------------------
--------------------作者:
行云流水----------------------------------------
libraryIEEE;
useIEEE.STD_LOGIC_1164.ALL;
useieee.std_logic_unsigned.all;
useieee.std_logic_arith.all;
entityIndependent_Keysis
port(
CLK:
instd_logic;--100MHZ
RESET:
instd_logic;--CPURESET
KEY:
instd_logic;--输入按键
KOUT:
outstd_logic--按键输出指示
);
endIndependent_Keys;
architectureBehavioralofIndependent_Keysis
signalclk100hz:
std_logic;
typestateis(s0,s1,s2,s3,s4,s5);
signalcurrent_state:
state;
begin
process(CLK,RESET)--产生10ms周期的时钟信号
variablecount:
integerrange0to500000;
begin
ifRESET='0'thencount:
=0;clk100hz<='0';
elsifrising_edge(CLK)then
ifcount=500000-1thencount:
=0;clk100hz<=notclk100hz;
elsecount:
=count+1;
endif;
endif;
endprocess;
process(clk100hz,RESET)--按键消抖程序块
begin
ifRESET='0'thenKOUT<='0';current_state<=s0;
elsifrising_edge(clk100hz)then
casecurrent_stateis
whens0=>KOUT<='0';--检测有键按下
ifKEY='1'thencurrent_state<=s0;
elsecurrent_state<=s1;
endif;
whens1=>KOUT<='0';--延时10ms
ifKEY='1'thencurrent_state<=s0;
elsecurrent_state<=s2;
endif;
whens2=>ifKEY='1'thenKOUT<='0';current_state<=s0;--再次检测有键按下否
elseKOUT<='1';current_state<=s3;--确定按下,按下输出指示有效,kout=‘1’
endif;
whens3=>ifKEY='0'thencurrent_state<=s3;--等待按键高电平出现
elsecurrent_state<=s4;--出现后先不急着电平翻转,在等个10ms消除释放抖动
endif;
whens4=>current_state<=s5;--高电平出现后延时10ms,消除上升沿抖动
whens5=>KOUT<='0';--释放后结束
current_state<=s0;
whenothers=>current_state<=s0;
endcase;
endif;
endprocess;
endBehavioral;
4444444444444444444UB_ack_check444444444444444444
-------程序介绍----------------------------------------------
--该AD转换采用的是12bits的串行iic协议的AD7991,AD7991可以在三种模式下运行,分别是
--标准模式,快速模式,高速模式,对应的时钟最高分别为100K,400K,和3.4MHZ。
--此程序跑的是标准模式;SDA和SCL分别为AD7991的数据线和时钟线;
-----------------------------------------------------------
-------程序使用说明-------------------------------------------
--
(1)AD_CONVERSION_SPEED为采样观察信号,实际采样频率f=AD_CONVERSION_SPEED;
--通过改变第一个进程的count值可以改变采样频率;
--
(2)IIC地址选择:
0101000,即AD7991-0的地址
--(3)内部寄存器结构:
--D7D6D5D4D3D2D1D0
--当D3=0时,选择的参考电压时内部电压,即3.3v,反之则选择外部参考电压;
--D7~D4为通道选择设置,该程序D7~D4=0001,选择通道VIN0,即0~5v输入
--其他位默认为零,选择1或0差不多;
-----------------------------------------------------------
-----------AD采样值计算及信号观察------------------------------
--VIN=(DATA_OUT/4096)*5V,比如当VIN0=3.3V时,DATA_OUT=101010001111;
--备注:
12AD最小分辨率:
5/4096=1mv;
libraryIEEE;
useIEEE.STD_LOGIC_1164.ALL;
useieee.std_logic_unsigned.all;
useieee.std_logic_arith.all;
entityack_checkis
port(CLK:
instd_logic;--100MHZ
RESET:
instd_logic;
Sampling_fre:
outstd_logic;--AD7991每次转换标志
AD_CONVERSION_SPEED:
outstd_logic;--ad采样信号,用于观察采集频率
LED3:
outstd_logic;--转换成功标志
SDA:
inoutstd_logic;
SCL:
outstd_logic;
DATA_OUT:
outstd_logic_vector(11downto0)
);
endack_check;
architectureBehavioralofack_checkis
signalclock:
std_logic;
signaldata_reg:
std_logic_vector(11downto0);
typestateis(start,transmit_slave_address,check_ack1,transmit_reg,check_ack2,stop,read_start,read_slave_address,
read_check_ack1,read_data_high,read_check_ack2,read_data_low,ack_bymaster);
signalcurrent_state:
state:
=start;
begin
DATA_OUT<=data_reg;
--无叶风扇电机有惰性,所以采样速度要放慢
process(CLK,RESET)
variablecount:
integerrange0to500000;--产生100HZ的clock信号
begin
ifRESET='0'thennull;
elsifrising_edge(CLK)then
ifcount>=500000then
count:
=0;
clock<=notclock;
elsecount:
=count+1;
endif;
endif;
endprocess;
--AD7991IIC协议进程
process(clock,RESET)
variablecount1:
integerrange0to16;
variableslave_address,internal_reg,read_address,data_high,data_low:
std_logic_vector(8downto1);
variablecnt:
std_logic_vector(6downto0);
variablecnt1:
integerrange0to8;
--variablecnt2:
integerrange0to16;
begin
ifRESET='0'then
count1:
=0;
data_reg<="000000000000";
SDA<='1';
SCL<='1';
LED3<='1';
cnt1:
=8;--1bytelength
AD_CONVERSION_SPEED<='0';
slave_address:
="01010000";--lastbit0:
writeaddressmodel
current_state<=start;
read_address:
="01010001";--lastbit1:
readaddressmodel
internal_reg:
="00010000";--选择VINO通道,参考电压选择内部
elsifrising_edge(clock)then
casecurrent_stateis
whenstart=>count1:
=count1+1;--启动信号
casecount1is
when1=>SDA<='1';
when2=>SCL<='1';
when3=>SDA<='0';
when4=>SCL<='0';
when5=>count1:
=0;current_state<=transmit_slave_address;
whenothers=>null;
endcase;
whentransmit_slave_address=>count1:
=count1+1;--写地址
casecount1is
when1=>SDA<=slave_address(cnt1);
when2=>SCL<='1';
when4=>SCL<='0';
when5=>cnt1:
=cnt1-1;count1:
=0;
ifcnt1=0thencnt1:
=8;current_state<=check_ack1;