Merhaba arkadaşlar, bu yazımızda sizlere Marmara Üniversitesi Digital Design dersinin dönem sonu projesi olarak geliştirdiğimiz refleks ölçer projesinden bahsedeceğiz ve gerekli kaynak kodları sağlayacağız.
Refleks Ölçer Nedir ve Nerelerde Kullanılır?
Refleks ölçerin çalışma mantığında belli bir süre geçmesinin ardından bir uyarıcının gösterilmesi yer alır. Bu bir ses veya görüntü olabilir. Kullanan kişi bu uyarıcı alır almaz bir düğmeye basmalı, bir hareket yapmalı veya bir şey söylemelidir. Bu araç sayesinde kullanan kişinin harekete geçme süresi ölçülebilir.
Refleks ölçerler ise özellikle maraton koşucuların da zil ile yarışa başlama sürelerini ölçmede ve kısaltmada, drag yarışlarında yeşil ışık yandıktan sonra gaza basılma süresini ölçmede ve kısaltmada ve bilimsel çalışmalarda kas ile beyin arasındaki iletişimin süresini ölçmede kullanılır.
Projenin Ana Çalışma Mantığı
Projemizde ana ekipman olarak 3 adet düğme, 3 adet LED, 7-Segment ve bir adet başlatıcı kapasitif sensör bulunuyor. Kapasitif sensöre dokunulduğunda yaklaşık olarak 3 saniye geçtikten sonra random olarak 3 LED’den birisi yanıyor. LED yandığı anda 0.1ms hassasiyetine sahip olan sayacımız devreye giriyor ve 7-Segment’de geçen süreyi gösteriyor. Siz LED’in karşılık geldiği düğmeye bastığınız anda ise sayaç duruyor ve sizin LED yanmasının ve düğmeye basmanızın ardından geçen süreyi gösteriyor.
Kullanılan Malzemeler
- FPGA Altera De2-115
- 4 Adet 7-Segment LED /Kart üzerinde bulunuyor.
- 3 Adet 10mm LED
- 3 Adet Buton
- TTP223B Dijital Dokunma Sensörü
Kod Algoritma Mantığı ve Kullanılan Program
Projeye başlarken ki amacımız olabildiğince verimli ve hassas çalışan bir refleks ölçer yapmak olmuştu. Bunun için FPGA kartı kullanarak kodlamanın da büyük bir kısmını kapı düzeyinde yazarak bu amacımıza ulaştık. Kodlamada 4 adet modül kullanıyoruz. Kodu yazmak ve gözlemlemek için kullandığımız program Quartus Prime 18.1
- Random Number Module -> Bu modülün çalışma mantığı programı başlatır başlatmaz arka plan 1 ila 3 arasında bir sayı dönüyor. Kapasitif sensöre dokunulduğu anda ise o sıra arka planda hangi sayı varsa onu seçiyor ve ona göre bir LED yanıyor.
- 7- Segment Module -> Burada Clock sinyalinden gelen sinyali sayarak iç içe if yapıları kullanarak sayma işlemini gerçekleştiriyoruz. Clock sinyalini keserek saati durdurabiliyoruz.
- Clock Module -> Bu kısım clock sinyalini üretiyor. Daha ayrıntılı anlatılacak.
- Main Module -> Tüm modüllerin bağlandığı kısım reset gibi komutlar burada duruyor.
Clock Module Çalışma Mantığı
Bu kısım genelde kafa karıştıcı olduğu için daha ayrıntılı anlatalım dedik. Bizim kullandığımız Altera De2-115’in içerisindeki clock hızı 50MHz. Peki 50MHz neyi ifade ediyor? Bizim kare sinyalimiz 1 saniyede 50.000.000 kere yukarı çıkıp aşağı iniyor demek. Yani 1 saniyede 25.000.000 kere yukarı çıkıyor. Buna posedge deniyor. Bizde sayacımızda bu posedge’leri sayıyoruz. Eğer sayaç 25.000.000 olursa ms_clock 0 iken 1 oluyor. Yani kare sinyalimiz posedge oldu. Böylece 50Mhz clock’u 1Hz’e dönüştürmüş oluyor. Not: Aşağıda ms_clock yazıyor ama bu kod 1 saniyeye çevirmek için.
module s_clock(clock, ms_clock); input clock; output ms_clock; reg ms_clock; reg [0:27] count; //Generate 100 Hz clock from a 50 mHz clock input always @ (posedge clock) begin count <= count + 1; if (count == 25000000) //1000ms -> 0.001 begin ms_clock <= ~ms_clock; count <= 0; end end endmodule
Tüm Kod
///RESPONSE TIME METER - 3LED 4BUTTON //YUSUF SAVAŞ //ALPER SARIÇAM module SP(clk,button0,button1,button2,button3,reset_button,ledo0,ledo1,ledo2,ledo3,ledo4,ledo5,ledo6,HEX0, HEX1, HEX2, HEX3, HEX4, HEX5); //Button0 -> Main-Start Button //Button1,2,3 -> Red,Green,Blue Buttons //Led0,1,2 -> Red,Green,Blue Leds, //Led2,3,4,5,6 -> Debugging Leds /No need to connect. //Hex4,5 -> For visual purpose. input clk,button0,button1,button2,button3,reset_button; output ledo0,ledo1,ledo2,ledo3,ledo4,ledo5,ledo6; output [0:6] HEX0, HEX1, HEX2, HEX3, HEX4, HEX5; wire [1:0] KEY; wire wire1,wire2,wire3; wire pause,stopwatch_start; //Key[1] -> Reset //Key[0] -> Pause random_number rnd1(clk,button0,reset_button,ledo0,ledo1,ledo2,ledo3,ledo4,ledo5,ledo6); and a1(wire1,ledo0,button1); and a2(wire2,ledo1,button2); and a3(wire3,ledo2,button3); or or1(pause,wire1,wire2,wire3); or(stopwatch_start,ledo0,ledo1,ledo2); assign KEY[0] = ~pause; assign KEY[1] = stopwatch_start; segment_hex hex1(clk, KEY, HEX0, HEX1, HEX2, HEX3, HEX4, HEX5); endmodule //////////////////////////////////////////////////////////////////////////////// //////////////////////7SEGMENTHEX/////////////////////////////////////////////// module segment_hex(CLOCK_50, KEY, HEX0, HEX1, HEX2, HEX3, HEX4, HEX5); //Binary_Coded_Decimal -> BCD //Key[1] -> Reset //Key[0] -> Pause /Pause is working by toggling. //Clock_50 -> 50Mhz input CLOCK_50; //50Mhz Clock input [1:0] KEY; //Key1 and Key2 output [0:6] HEX0, HEX1, HEX2, HEX3, HEX4, HEX5; //4 Hex for Digits 2 Hex for Alphabet wire ms_clk; wire tenths_in, ones_in, tens_in; wire [3:0] hundredths_bcd, tenths_bcd, ones_bcd, tens_bcd; ms_clock ms_clock1(CLOCK_50, clk); //50Mhz to 1ms(clk) ms_clock_switched ms_clock_switched1(clk, KEY[0], ms_clk); //Key 0 stops the watch ->ms_clock is the new_clock bcd_counter bcd_counter_hundredths(ms_clk, KEY[1], hundredths_bcd[3:0], tenths_in); // xxx9 [3:0]-> Because 4 bit. 1001->9 bcd_counter bcd_counter_tenths(tenths_in, KEY[1], tenths_bcd[3:0], ones_in); //xx9x bcd_counter bcd_counter_ones(ones_in, KEY[1], ones_bcd[3:0], tens_in); //x9xx bcd_counter bcd_counter_tens(tens_in, KEY[1], tens_bcd[3:0], ); //9xxx seven_segment_decoder seven_segment_decoder_hundredths(hundredths_bcd[3:0], HEX0[0:6]); //Hex0 Decoder seven_segment_decoder seven_segment_decoder_tenths(tenths_bcd[3:0], HEX1[0:6]); seven_segment_decoder seven_segment_decoder_ones(ones_bcd[3:0], HEX2[0:6]); seven_segment_decoder seven_segment_decoder_tens(tens_bcd[3:0], HEX3[0:6]); //Turn the unused displays off assign HEX4[0:6] = 7'b0100100; assign HEX5[0:6] = 7'b0110000; endmodule module bcd_counter(clock, reset, bcd, next); input clock, reset; output bcd, next; reg [3:0] bcd; reg next; wire not_reset; not(not_reset, reset); always @(posedge clock or posedge not_reset) begin if (not_reset == 1) bcd <= 0; else begin bcd <= bcd + 1; next <= 0; if (bcd > 8) begin bcd <= 0; next <= 1; //if xxx9 --> xx10 end end end endmodule //CLOCK MODULE 1-Miliseconds Delay module ms_clock(clock, ms_clock); input clock; output ms_clock; reg ms_clock; reg [0:17] count; //Generate 100 Hz clock from a 50 mHz clock input always @ (posedge clock) begin count <= count + 1; if (count == 25000) //1ms begin ms_clock <= ~ms_clock; count <= 0; end end endmodule module ms_clock_switched(ms_clock, control, ms_clock_switched); input ms_clock, control; output ms_clock_switched; reg ms_clock_switched; reg state; //0 paused, 1 active //Basic state machine for toggleing the clock always @ (negedge control) state <= ~state; always @ (ms_clock) begin if (state == 0) ms_clock_switched <= 0; else ms_clock_switched <= ms_clock; end endmodule module seven_segment_decoder(bcd[3:0], HEX[0:6]); //Binary Number to 7-Segment Number. input [3:0] bcd; output [0:6] HEX; reg [0:6] HEX; always @ (bcd) case(bcd) 4'b0000:HEX[0:6] = 7'b0000001; //0 4'b0001:HEX[0:6] = 7'b1001111; //1 4'b0010:HEX[0:6] = 7'b0010010; //2 4'b0011:HEX[0:6] = 7'b0000110; //3 4'b0100:HEX[0:6] = 7'b1001100; //4 4'b0101:HEX[0:6] = 7'b0100100; //5 4'b0110:HEX[0:6] = 7'b0100000; //6 4'b0111:HEX[0:6] = 7'b0001111; //7 4'b1000:HEX[0:6] = 7'b0000000; //8 4'b1001:HEX[0:6] = 7'b0001100; //9 default: HEX[0:6] = 7'b1111111; //Empty endcase endmodule ///////////////////////7SEGMENTHEX/////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////// /////////////////////////RANDOM_NUMBER//////////////////////////////////////////// module random_number(input clk,button_input,button_input2,output ledo0,ledo1,ledo2,ledo3,ledo4,ledo5,ledo6); reg led0,led1,led2,led3,led4,led5,led6; reg button1; //assign button = button_input; reg selectedpin; reg selectedpin_assign; reg[1:0] selectedled; reg[1:0] randcounter; wire resetor; // initial // begin // button <= 1'b0; // led0 <= 1'b0; // led1 <= 1'b0; // led2 <= 1'b0; // randcounter <= 2'b00; // end wire new_clock; or or1(resetor,~selectedpin,button_input2); and a1(new_clock,clk,resetor); //if selectedpin is 1 stop the controlling(clock) always @ (posedge new_clock) begin ////////////////////////////////////////RESET if (button_input2 == 1'b1) //Reset İf begin selectedpin <= 1'b0; // selectedled <= randcounter; led6 <= 1'b1; //led6 Debugg // delay_count <= 4'b0000; // delay_completed <= 1'b0; // end else begin led6 <= 1'b0; end ////////////////////////////////////////RESET button1 <= button_input; if (randcounter == 2'b11) begin randcounter <= 2'b00; end else begin randcounter <= randcounter + 1'b1; end if (button_input == 1'b1) begin selectedpin <= 1'b1; selectedled <= randcounter; led5 <= 1'b1; //led5 Debugg end else begin selectedpin <= 1'b0; //1 kalmalı yoksa buton mantıgı olmuyor. selectedled <= 2'b11; led5 <= 1'b0; //led5 Debugg end end s_clock clocke1(clk,ms_clock); //Uptade the clock reg[3:0] delay_count; reg delay_completed; //LED SELECT Always always @ (posedge ms_clock) begin led4 <= 1'b1; //delay_count <= delay_count +1; ////////////////////////////////////////RESET if (button_input2 == 1'b1) //Reset İf begin //selectedpin <= 1'b0; // selectedled <= randcounter; // led6 <= 1'b1; //led6 Debugg delay_count <= 4'b0000; delay_completed <= 1'b0; // end else begin //led6 <= 1'b0; end ////////////////////////////////////////RESET if (selectedpin == 1'b1) //Eger dugmeye basıldıysa delay_count artsın begin delay_count <= delay_count + 1'b1; if (delay_count == 4'b0100) //4second is passed begin delay_completed <= 1'b1; led3 <= 1'b1; //debug_led end else if(delay_count > 4'b1010) //8second is passed delay->0 begin //delay_completed <= 1'b0; led3 <= 1'b0; //debu_led end end else begin //Kodgelecek end if( delay_completed == 1'b1 & selectedpin == 1'b1 & (selectedled == 2'b00 | selectedled == 2'b11)) //led0 begin led0 <= 1'b1; led1 <= 1'b0; led2 <= 1'b0; end else if ( delay_completed == 1'b1 & selectedpin == 1'b1 & selectedled == 2'b01 ) //led1 begin led1 <= 1'b1; led0 <= 1'b0; led2 <= 1'b0; end else if ( delay_completed == 1'b1 & selectedpin == 1'b1 & selectedled == 2'b10 ) //led2 begin led2 <= 1'b1; led0 <= 1'b0; led1 <= 1'b0; end else begin led0 <= 1'b0; led1 <= 1'b0; led2 <= 1'b0; led4 <= 1'b1; //debugg end end assign ledo0=led0; assign ledo1=led1; assign ledo2=led2; assign ledo3=led3; assign ledo4=led4; assign ledo5=led5; assign ledo6=led6; endmodule //CLOCK MODULE 1-Seconds delay module s_clock(clock, ms_clock); input clock; output ms_clock; reg ms_clock; reg [0:27] count; //Generate 100 Hz clock from a 50 mHz clock input always @ (posedge clock) begin count <= count + 1; if (count == 25000000) //1000ms -> 0.001 begin ms_clock <= ~ms_clock; count <= 0; end end endmodule //////////////////////////RANDOM_NUMBER///////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
Aşağıdaki dropbox linkinden tüm projeyi, proje dosyasını ve kodlarının yanı sıra tüm Digital Design dersinde yapmış olduğumuz projeleri, ödevleri, araştırmaları ve vize notlarını indirebilirsiniz.
Projenin sonuna gelmiş bulunuyoruz eğer herhangi bir sorunuz varsa Hakkımda bölümünden veya aşağıya cevap yazarak bana ulaşabilirsiniz. Bir sonraki projede görüşmek üzere.