2016年4月8日 星期五

使用乙級檢定的CPLD製作出簡單的超音波距離感測器

先來看一下編譯結果吧
使用63個macrocells,幾乎不浪費阿XD

所需材料:
1.HC-SR04 超音波距離感測器
2.數位電子乙級檢定的CPLD子板
3.7段顯示器(4位數封裝)
4.驅動7段顯示器的電路(參考下圖)

使用語言:VHDL

HC-SR04 超音波距離感測器介紹:
共有4隻腳位,分別為Vcc,Trig,Echo,Gnd;
電源與TTL相容(5V)
<以下腳位皆為高電位致能>
Trig:脈波輸入腳,建議使用負緣與正緣長度>=60mS且寬度>=10uS的脈波。
Echo:資料輸出腳,輸出的時間(uS)/(58)=距離(cm)。
NOTE:
1.發射角度15~30度。

2.建議偵測物體面積>0.5公尺平方(距離越遠面積要越大)。
3.距離偵測範圍:2~400cm(精確度:3mm)。
4.當距離太遠無法接收到回來的聲波,或是發射or接收器被阻擋時,資料會亂跳。
5.遇到會吸收聲音的材質時(ex:布料),數據會失準。

運作過程:
1.偵測到脈波,且脈波結束(負緣觸發)
2.發射8個週期的40kHZ超音波之後,Echo將呈現高電位狀態,直到接收端收到8個週期的40kHZ超音波為止。

原理:
利用聲波反射及音速,輸出發射出去和接收回來的時間,再透過計算之後(/58)得到長度。

VHDL程式碼:
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;

ENTITY TEST IS
PORT(clk,echo:in std_logic;
trig:out std_logic;
scanout:out std_logic_vector(3 downto 0);
segout:out std_logic_vector(6 downto 0)
);
END;

ARCHITECTURE A OF TEST IS
signal cnt:std_logic_vector(16 downto 0);
signal cnt1:integer range 0 to 63;
signal bcd1,bcd0,bcd_1,bcd_0,bcd:std_logic_vector(3 downto 0);
signal bcd_2,bcd2:std_logic_vector(2 downto 0);
signal state:integer range 0 to 1;
signal f:std_logic_vector(1 downto 0);
begin

PROCESS(clk)
begin
 if rising_edge(clk)then
  f<=f+1;
 end if;
 
 if rising_edge(f(1))then
  cnt<=cnt+1;
  if cnt1/=57 then
   cnt1<=cnt1+1;
  else
   cnt1<=0;
   if echo='1'then
    if bcd0/=x"9" then
     bcd0<=bcd0+1;
    else
     bcd0<=x"0";
     if bcd1/=x"9" then
      bcd1<=bcd1+1;
     else
      bcd1<=x"0";
      if bcd2/="111" then
       bcd2<=bcd2+1;
      end if;
     end if;
    end if;
    state<=0;
   else
    case state is
    when 0=>bcd_2<=bcd2;bcd_1<=bcd1;bcd_0<=bcd0;state<=1;
    when 1=>bcd2<="000";bcd1<=x"0";bcd0<=x"0";
    end case;
   end if;
  end if;
 end if;
end process;

 trig<=cnt(16);
 
 with cnt(9 downto 8) select
 scanout<="1110"when "00",
   "1101"when "01",
   "1011"when "10",
   "0111"when "11";
 
 with cnt(9 downto 8) select
 bcd<=bcd_0 when "00",
   bcd_1 when "01",
   "0"& bcd_2 when "10",
   x"f" when "11";
   
 with bcd select
 segout<="0000001"when x"0",
   "1001111"when x"1",
   "0010010"when x"2",
   "0000110"when x"3",
   "1001100"when x"4",
   "0100100"when x"5",
   "1100000"when x"6",
   "0001101"when x"7",
   "0000000"when x"8",
   "0001100"when x"9",
   "1111111"when others;
END A;


VHDL程式碼使用與解析:
clk連接到p43,使用4MHZ的石英震盪
echo和trig請連接至超音波感測器
scanout是四位數七段顯示器的掃描訊號輸出(3~0),請接至驅動電路的P1
segout是四位數七段顯示器的資料訊號輸出(a~g),請接至驅動電路的P2
這邊建議,CPLD用3.3V,超音波感測器用5V;雖然CPLD吃5V短時間不會出問題,但時間一久CPLD會變超燙,是很有可能燒掉CPLD的!另外也可以試試看讓超音波感測吃3.3V,我手上的似乎不會出問題。

24~26行:除頻用,將4MHZ轉成1MHZ,方便計算(1uS)。

29行:計算時脈訊號,2^17=131072,1MHZ/131072=7.6HZ,負緣與正緣的距離66mS。
59行:引出時脈訊號。

30~55行:該if主要是讓計數器每58uS上數一次,這樣就會有/58的效果。
35~47行:上數的程式,有做過乙級題目的都知道,因為該CPLD邏輯閘數量很少,所以不能用一般的方式(用整數上數,再/1000輸出....),另外這邊將第三位數限制在8以內,因為官方資料最遠是4m,而4這個數字的二進制為100(3bits),因此將第三位數限制在8(111)以內。
48~54行:送出資料與清空資料。

61~65行:掃描訊號輸出。
67~71行:bcd碼掃描選擇。
73~84行:七段解碼。

成品:



4 則留言:

  1. 請問bcd_1跟bcd1是什麼的定義

    回覆刪除
  2. 還有請問state是定義什麼
    謝謝

    回覆刪除
  3. 有底線(_)的是處理好的資料的暫存器,沒底線是處理中的資料;bcd1計算完成時會丟到bcd_1
    state主要是要處理:bcd1丟到bcd_1、清空計算用的bcd1

    回覆刪除
  4. 作者已經移除這則留言。

    回覆刪除