Stilaan komt de hardware beschikbaar. Straks zullen er heel wat startersvragen komen om kleine voorbeelden. Daarom deze nieuwe topic met de bedoeling dat zoveel mogelijk eenvoudige voorbeeldjes inkomen. Liefst geteste en werkende versie's zodat een starter niet meteen een hoop problemen ondervindt.
Hier een eerste voorbeeldje:
Nodige:
- een rotary encodertje. ( met 2 pullup weerstandje 10K naar VCC)
- 8 leds met ieder een serie weerstandje vb 330 ohm.
- een FPGA of CPLD met een clock vb 50 Mhz.
Het programma kan hier gedownload worden
Functie:
Een 8 bit binaire up/down teller wordt gestuurd door een rotary encoder. Het resultaat wordt als een binaire aanduiding op de 8 leds gebracht.
Code:
code:
module encoder
(
input clk_50, // 50 MHz clock op MAX II board
output reg [7:0] led_max, // leds op MAX II board
input encoder_A, // rotary encoder A kanaal
input encoder_B // rotary encoder B kanaal
);
reg [15:0] prescaler; // 50 MHz mag gerust gedeeld worden
reg [2:0] encoder_A_reg; // synchronisatie A kanaal
reg [2:0] encoder_B_reg; // synchronisatie B kanaal
reg enc_ena; // actief bij een flankwissel van A of B
reg richting2; // draairichting encoder
wire clk_enc; // draadje reserveren voor clk_enc
assign clk_enc = prescaler[15]; // toekennen clk_enc draadje
always @ (posedge clk_50) // delen van de clock door 65536
begin
prescaler <= prescaler + 1;
end
always @(posedge clk_enc)
begin
encoder_A_reg <= {encoder_A_reg[1:0], encoder_A}; // rotary encoder_A doorschuiven
encoder_B_reg <= {encoder_B_reg[1:0], encoder_B}; // rotary encoder_B doorschuiven
enc_ena <= encoder_A_reg[1] ^ encoder_A_reg[2] ^ encoder_B_reg[1] ^ encoder_B_reg[2];
richting2 <= encoder_A_reg[1] ^ encoder_B_reg[2];
if(enc_ena)
begin
if (richting2)
led_max <= led_max +1;
else
led_max <= led_max -1;
end
end
endmodule
Er is hierbij een 50 Mhz xtal gebruikt omdat dit standaard op mijn modules zit. Maar dit mag om het even welke waarde zijn. De prescaler is gebruikt om die hoge sample frequentie wat te verlagen maar speeld wening rol hoeveel.
Bij mij zijn er 32 LE's nodig, waarvan de helft voor de prescaler. Ik ben een absolute fan om meestal de ingangen eerst te synchroniseren op een clock. Hierdoor heb je zuivere verwerkings signalen die duidelijke setup tijden garanderen voor de verdere verwerking.
Zoals je ziet zijn er heel snel wat LE's nodig. Vandaar dat de kleine oudere CPLD's met vb 72 LE's maar heel kleine toepassingen aan kunnen. Zodra we wat verder verschillende pwm's gaan gebruiken kom je daar niet meer mee toe. Zo heeft een RC5 dekoder ook algauw een kleine 80 LE's nodig en een 2x16 character LCD display zit ook al gauw boven de 100 LE's. Je moet toch ook de registers voorzien om bepaalde resultaten weer te geven.
Voor degenen die Quartus gebruiken, gewoon de code nemen en opslaan in een nieuwe map vb: encoder.
daarin dit klein programma opslaan onder de naam encoder.v
Met de Quartus wizard een nieuw project aanmaken met als werkdirectory de map encoder en als projectnaam ook encoder.
Via file open het programma encoder.v laden.
Via de toets CTRL L alles compileren.
Pinout en device kunt je ingeven volgens je type hardware. heb je nog niets dan zal de compiler wel zelf iets kiezen. Voor hem maakt het weinig uit.