0
\$\begingroup\$

I'm designing a number exchange module, and so far I've been able to make it display on Seven Segment Display (S-S-D), like if I press 0 it shows 0... etc. I'm using 2 sets of 4-bits S-S-D (Common Anode).

Now I want to do like:

  • default states : 0000_0000
  • Now if I press 1 : 0000_0001
  • If I press 2 : 0000_0012
  • etc.

Whichever key I press, the display will not erase the already displaying number, it will shift it to the left...

And when all 8 S-S-D is full of displaying numbers like: 486C_8763, at this moment, when I press a key enter a number, like 1 it should be like : 86C8_7631; it should keep shifting to the left.

Here's my attempted code, and only been able to display it on S-S-D, and display all S-S-D 0000_0000... still not able to do what's been describe above...

Photo explain

module keydata 
(
 input clk, //input clk 50MHz
 output reg [3:0]keyout=4'b1110, //Default scan value 4bits 
 input [3:0]keyin, //Keypad receive value
 output reg [7:0]SegOut, //Seven Segment Display output
 output reg [15:0]scano //Seven Segment Display Scans
);
integer z1=0,zz=0; //Registers for frequency dividing
reg dclk; //Divided frequency clock
reg [7:0]bcdz; //register for saving keypad's number value
reg [3:0]scan; //scan states 
always@(posedge clk)
begin
//---------------------
if(z1==50000) //frequency divider 
 begin
 z1<=0;
 scan<={scan[2:0],scan[3]}; //scanning pattern shifting resgister
 keyout<={keyout[2:0],keyout[3]}; //keypad column scanning 1110->1101->1011->0111->1110(loop)
 end
else
 z1<=z1+1;
//---------------------
//---------------------
if(zz==10000) //frequency divider for scanning
 begin
 zz<=0;
 dclk<=~dclk;
 end
else
 zz<=zz+1;
//--------------------- 
end
always@(posedge dclk) //Seven Segment Scanning
 begin
 case(scan)
 0: scano<=scano[3:0];
 1: scano<=scano[7:4];
 2: scano<=scano[11:8];
 3: scano<=scano[15:12];
 endcase
 end
always@(posedge dclk) //4x4 Keypad detecting 
begin
 if (keyout==4'b1110) //Detecting which keyout is currently at scanning
 begin
 if(keyin==4'b0111) //Tell which key it is
 begin
 bcdz<=4'b1100;//C //the key's value,save by a register
 end
 else if(keyin==4'b1011)
 begin
 bcdz<=4'b1101; //D
 end
 else if(keyin==4'b1101)
 begin
 bcdz<=4'b1110; //E
 end
 else if(keyin==4'b1110)
 begin
 bcdz<=4'b1111;//F
 end
 end
 else if (keyout==4'b1101) //Using **else if** to differentiate priorities.
 begin
 if(keyin==4'b0111)
 begin
 bcdz<=4'b1000; //8
 end
 else if(keyin==4'b1011)
 begin
 bcdz<=4'b1001; //9
 end
 else if(keyin==4'b1101)
 begin
 bcdz<=4'b1010; //A
 end
 else if(keyin==4'b1110)
 begin
 bcdz<=4'b1011; //B
 end
 end
 else if (keyout==4'b1011) //4 scanning possibilities
 begin
 if(keyin==4'b0111)
 begin
 bcdz<=4'b0100; //4
 end
 else if(keyin==4'b1011)
 begin
 bcdz<=4'b0101; //5
 end
 else if(keyin==4'b1101)
 begin
 bcdz<=4'b0110; //6
 end
 else if(keyin==4'b1110)
 begin
 bcdz<=4'b0111; //7
 end
 end
 else if (keyout==4'b0111)
 begin
 if(keyin==4'b0111)
 begin
 bcdz<=4'b0000; //0
 end
 else if(keyin==4'b1011)
 begin
 bcdz<=4'b0001; //1
 end
 else if(keyin==4'b1101)
 begin
 bcdz<=4'b0010; //2
 end
 else if(keyin==4'b1110)
 begin
 bcdz<=4'b0011; //3
 end
 end
 end
always@(bcdz) //Seven Segment Decoder
begin
 case(bcdz)
 0 : SegOut <= 8'hC0;
 1 : SegOut <= 8'hF9;
 2 : SegOut <= 8'hA4;
 3 : SegOut <= 8'hB0;
 4 : SegOut <= 8'h99;
 5 : SegOut <= 8'h92;
 6 : SegOut <= 8'h82;
 7 : SegOut <= 8'hF8;
 8 : SegOut <= 8'h80;
 9 : SegOut <= 8'h98;
 10 : SegOut <= 8'h88;
 11 : SegOut <= 8'h83;
 12 : SegOut <= 8'hC6;
 13 : SegOut <= 8'hA1;
 14 : SegOut <= 8'h86;
 15 : SegOut <= 8'h8E;
 default : SegOut <= 8'hFF;
 endcase
end
endmodule
asked Jun 27, 2019 at 16:36
\$\endgroup\$

1 Answer 1

0
\$\begingroup\$

I can see several problems. First, scan is never initialized, and you're shifting it and not incrementing it, so it doesn't match the case statement that looks at scan and sets scano. Second, scano is also not initialized, and the case statement that sets scano from segments of scano makes no sense. Third, you never actually store and shift the values anywhere. You'll need to have a memory location per digit, and I don't see that. They key scanning code also needs work. You'll want to have some delay between when keyout is changed and when you check keyin. Perhaps what you could do is have 'shift' and 'check' control lines that get pulses at different times, and you update keyout when 'shift' pulses and you check for a key press when 'check' pulses. You also need to detect both when a key is pressed and when a key is released, so you can register the key presses as separate events as opposed to just filling all the displays with '7' the moment the '7' key is pressed. Baasically, you need to detect the press, then ignore the keypad until the key is released. You could also turn that nested if statement into a single case statement by concatenating keyout and keyin like so: case ({keyout, keyin})

Try writing some code that just displays '123456' or simiar, ignoring the keyboard. Make that work first, then build on top of it.

answered Jun 28, 2019 at 16:48
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.