[新連載]CPLD入門!
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
いつか使うことになるだろうと思ってはいたのですが。
何を今頃になって、というようなものですが。
ようやく本気で、CPLDと四つに取り組みます。
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
[第107回]
●周波数カウンタ(2)
プログラムの説明です。
今までに説明した内容と同じか、それに近い内容のプログラム部分については説明を省きます。
前回書きましたが周波数カウンタの下位4桁の値は3組あるうちの2組の8ビット出力表示LEDに表示するようにプログラムしています。
それが下の部分です。
PA(7 downto 4)<=fcntr3; PA(3 downto 0)<=fcntr2; PB(7 downto 4)<=fcntr1; PB(3 downto 0)<=fcntr0; |
周波数カウンタは1秒の間、入力パルスをカウントします。
下ではそのための1秒の時間を4.096MHzのクロックを分周して作成しています。
デジタル時計プログラムでも同じように4.096MHzのクロックから1秒のパルスを得ていますが、そのプログラムと今回のプログラムは少し異なっています。
作成した時期の関係でそうなったのですが、考え方としてはデジタル時計プログラムのほうがすっきりしているように思います。
ここでは4.096MHzの入力クロックを14ビットのバイナリカウンタで分周して250Hzのクロックを得た後、それをcntr1で250カウントして(250はFA、11111010です)、1秒のクロックを得ています。
-- 7seg drive clock 1kHz
process(CK1)
begin
if CK1'event and CK1='1' then
cntr0<=cntr0+"00000000000001";
end if;
end process;
--
-- ******* fcounter ******
ck13<=cntr0(13);--250hz
--
--1sec and fcclr
process(ck13)
begin
if cntr1(7 downto 3)="11111" and gateon='0' then
fcclr<='1';
else
fcclr<='0';
end if;
if cntr1="11111010" then
cntr1<="00000000";
elsif ck13'event and ck13='0' then
cntr1<=cntr1+"00000001";
end if;
end process;
ck1sec<=cntr1(7);
--
process(ck1sec)
begin
if ck1sec'event and ck1sec='0' then
gateon<=gateon+'1';
end if;
end process;
--
|
if cntr1(7 downto 3)="11111" and gateon='0' then
fcclr<='1';
else
fcclr<='0';
end if;
のところは説明が必要です。
gateonは1秒のカウント期間と1秒の静止表示期間を規定するための変数です。
1秒ごとに値が交互に’1’と’0’を繰り返します。
gateonが’0’のときがカウントを停止して値を表示している期間です。
その期間の終了直前(cntr1=”11111000”)に周波数カウンタをクリアするための変数fcclrを’1’にしています。
上のプログラム部分の最後のところでは、1秒ごとに交互にgateonの値を’1’、’0’にしています。
その次のところ(下のリスト)はちょっと長いですが、8桁の10進カウンタ(各桁は4ビットのバイナリカウンタ)、fcntr0〜fcntr7を直列につないでカウントを行なっています。
各桁の処理は皆同じです。
最初のfcntr0のところでは、CK2端子から入力されるパルスをgateonとの間のandをとることで1秒間だけアクティブにしてfcntr0に伝えています。
ck2in<=CK2 and gateon;
--
process(ck2in)
begin
if fcntr0="1010" or fcclr='1' then
fcntr0<="0000";
elsif ck2in'event and ck2in='1' then
fcntr0<=fcntr0+"0001";
end if;
end process;
--
process(fcntr0(3))
begin
if fcntr1="1010" or fcclr='1' then
fcntr1<="0000";
elsif fcntr0(3)'event and fcntr0(3)='0' then
fcntr1<=fcntr1+"0001";
end if;
end process;
--
process(fcntr1(3))
begin
if fcntr2="1010" or fcclr='1' then
fcntr2<="0000";
elsif fcntr1(3)'event and fcntr1(3)='0' then
fcntr2<=fcntr2+"0001";
end if;
end process;
--
process(fcntr2(3))
begin
if fcntr3="1010" or fcclr='1' then
fcntr3<="0000";
elsif fcntr2(3)'event and fcntr2(3)='0' then
fcntr3<=fcntr3+"0001";
end if;
end process;
--
process(fcntr3(3))
begin
if fcntr4="1010" or fcclr='1' then
fcntr4<="0000";
elsif fcntr3(3)'event and fcntr3(3)='0' then
fcntr4<=fcntr4+"0001";
end if;
end process;
--
process(fcntr4(3))
begin
if fcntr5="1010" or fcclr='1' then
fcntr5<="0000";
elsif fcntr4(3)'event and fcntr4(3)='0' then
fcntr5<=fcntr5+"0001";
end if;
end process;
--
process(fcntr5(3))
begin
if fcntr6="1010" or fcclr='1' then
fcntr6<="0000";
elsif fcntr5(3)'event and fcntr5(3)='0' then
fcntr6<=fcntr6+"0001";
end if;
end process;
--
process(fcntr6(3))
begin
if fcntr7="1010" or fcclr='1' then
fcntr7<="0000";
elsif fcntr6(3)'event and fcntr6(3)='0' then
fcntr7<=fcntr7+"0001";
end if;
end process;
--
|
プログラムの最後の部分(下のリスト)では、7セグメントLEDに周波数カウンタの上位4桁、下位4桁を切り換えて表示させています。
スイッチAを押す(SWA=’0’)かまたは、SP1の右端にジャンパピンをセットする(PCL(0)=’0’)と、7セグメントLEDに周波数カウンタの下位4桁が表示され、それ以外のときには上位4桁が表示されます。
--7seg disp select
--H4 or L4
process(ledcntr,SWA,PCL(0))
begin
if SWA='0' or PCL(0)='0' then
leddatabf3<=fcntr0;
leddatabf2<=fcntr1;
leddatabf1<=fcntr2;
leddatabf0<=fcntr3;
else
leddatabf3<=fcntr4;
leddatabf2<=fcntr5;
leddatabf1<=fcntr6;
leddatabf0<=fcntr7;
end if;
end process;
--
|
下は前回お見せしたプログラムのソースファイルです。
trngfcntr1b.txt
[第91回]の通りに作業してください。
今回新規作成するフォルダはtrngwatch1cです。
作業が済んだら[第92回]以後のところを参考にして、コンパイル、端子名ファイルのコピー作業を行なってください。
CPLD入門![第107回]
2019.9.7upload
前へ
次へ
ホームページトップへ戻る