/* 7段数码管测试实验1:以动态扫描方式在4位数码管,显示32计数器的高16位值 hex码 实验的目的是向用户介绍多个数码管动态显示的方法。 动态显示的方法是,按一定的频率轮流向各个数码管的COM端送出低电平,同时送出对应的数据给各段。 -- segment encoding -- 0 -- --- -- 5 | | 1 -- --- <- 6 -- 4 | | 2 -- --- -- 3 COM is GND */
module seg71(clk,dataout,en,led,row,col,reset,beep,txd,ds);
input clk; output[7:0] dataout; output[3:0] en;//COM使能输出 output[7:0] led; input reset; reg[7:0] led; reg[7:0] dataout;//各段数据输出 reg[3:0] en;
inout[3:0] row; inout[3:0] col; wire[3:0] row; wire[3:0] col; reg[7:0] key; reg COL_ZERO; reg ROW_ZERO;
output reg beep; reg playing; reg[19:0] counter,counter_end;
assign col[3:0]=COL_ZERO?4'b0000:4'bzzzz; assign row[3:0]=ROW_ZERO?4'b0000:4'bzzzz; reg[31:0] cnt_scan;//扫描频率计数器 10M/2^32=0.02Hz 429.5S reg[3:0] dataout_buf;
output txd; reg txd; output ds; reg ds; reg txd_end=0; reg txd_flag=1; reg[7:0] txd_clk; reg[3:0] txd_counter; reg[7:0] sbuf=8'h33;//first out data reg[19:0] i=0;
always@(posedge clk) begin cnt_scan=cnt_scan+1; //////////////////////////txd/////////////////////////////// if (txd_flag) //txd_flag=1表示用数据需要发送 begin if (txd_clk==8'd86) //10000000/115200.0=86.805555555555557 begin txd_clk=0; end if (txd_clk==0) // begin case (txd_counter) //传送时,数据的低位在前,高位在后 4'h0: begin txd=0; //start bit 0 txd_end=0; end 4'h1: txd=sbuf[0]; 4'h2: txd=sbuf[1]; 4'h3: txd=sbuf[2]; 4'h4: txd=sbuf[3]; 4'h5: txd=sbuf[4]; 4'h6: txd=sbuf[5]; 4'h7: txd=sbuf[6]; 4'h8: txd=sbuf[7]; 4'h9: txd=1; //stop bit 1 default: txd=1; endcase if (txd_counter==4'ha) begin txd_counter=0; txd_end=1; //add stop bit 1 end txd_counter=txd_counter+4'h1; end txd_clk=txd_clk+4'h1; end else//if (txd_flag) //txd_flag=1表示用数据需要发送 begin end /////////////////////rxd//////////////////////// /* if(rxd==0 && rxd_start==0) begin rxd_clk=rxd_clk+1; if (rxd_clk==87) //10000000/115200.0=86.805555555555557 rxd_clk=0; if(rxd_clk=43)//中点取样 begin end; end */ end
always@(posedge clk) begin i=i+20'h1; if (txd_end) txd_flag=0; if (i==20'hfff) //10M/1M = 0.1/256 s 发送一个数据 begin ds=~ds; i=0; if (!txd_flag) begin sbuf[7:0]=8'h01; txd_flag=1; end end end always@(posedge cnt_scan[19])// or negedge reset) begin // if (led[7:0]==0) // led[7:0]=8'b1111_1111; // led[7:0]=led[7:0]<<1; // temp = led[7]; // if (!reset) // led[7:0]=8'b1111_1110; // else // led[7:0]={led[6:0],led[7]}; // begin //led[7:1]<=led[6:0]; //led[0]<=led[7]; // led[7:4]=~{key[4],key[5],key[6],key[7]}; // led[3:0]=~{key[0],key[1],key[2],key[3]}; // end // led[0]=~led[0]; // led[7:0]=cnt_scan[17:10]; case (led[7:0]) 8'b1111_1111: led[7:0]= 8'b1111_1110; 8'b1111_1110: led[7:0]= 8'b1111_1101; 8'b1111_1101: led[7:0]= 8'b1111_1011; 8'b1111_1011: led[7:0]= 8'b1111_0111; 8'b1111_0111: led[7:0]= 8'b1110_1111; 8'b1110_1111: led[7:0]= 8'b1101_1111; 8'b1101_1111: led[7:0]= 8'b1011_1111; 8'b1011_1111: led[7:0]= 8'b0111_1111; 8'b0111_1111: led[7:0]= 8'b0011_1111;
8'b0011_1111: led[7:0]= 8'b1001_1111; 8'b1001_1111: led[7:0]= 8'b1100_1111; 8'b1100_1111: led[7:0]= 8'b1110_0111; 8'b1110_0111: led[7:0]= 8'b1111_0011; 8'b1111_0011: led[7:0]= 8'b1111_1001; 8'b1111_1001: led[7:0]= 8'b1111_1100; 8'b1111_1100: led[7:0]= 8'b1111_1110; default:led[7:0]= 8'b1111_1111; endcase
end
//频率 10M/65535 = 152 Hz always @(cnt_scan or row or col or key or COL_ZERO or ROW_ZERO) begin case(cnt_scan[15:14]) 2'b00 : begin en = 4'b1110; dataout_buf[3:0]= cnt_scan[31:28]; COL_ZERO=1;//col 输出0 ROW_ZERO=0;//row zzzz end 2'b01 : begin en = 4'b1101; dataout_buf[3:0]=cnt_scan[27:24]; key[3:0]=row[3:0]; end 2'b10 : begin en = 4'b1011; dataout_buf[3:0]=key[3:0]; COL_ZERO=0; //col zzzzzzzz ROW_ZERO=1; end 2'b11 : begin en = 4'b0111; key[7:4]=col[3:0]; dataout_buf[3:0]=key[7:4];
end default : begin en = 4'b1111; dataout_buf[3:0]=4'b1111;
end endcase end
always@(dataout_buf) begin case(dataout_buf) 4'b0000: dataout[7:0]=8'b00111111; //0 4'b0001: dataout[7:0]=8'b00000110; //1 4'b0010: dataout[7:0]=8'b01011011; //2 4'b0011: dataout[7:0]=8'b01001111; //3 4'b0100: dataout[7:0]=8'b01100110; //4 4'b0101: dataout[7:0]=8'b01101101; //5 4'b0110: dataout[7:0]=8'b01111101; //6 4'b0111: dataout[7:0]=8'b00000111; //7 4'b1000: dataout[7:0]=8'b01111111; //8 4'b1001: dataout[7:0]=8'b01101111; //9 4'b1010: dataout[7:0]=8'b11110111; //A 4'b1011: dataout[7:0]=8'b11111100; //b 4'b1100: dataout[7:0]=8'b10111001; //C 4'b1101: dataout[7:0]=8'b11011110; //d 4'b1110: dataout[7:0]=8'b11111001; //E 4'b1111: dataout[7:0]=8'b11110001; //F default: dataout[7:0]=8'b00000000; // endcase end
always@(posedge clk) begin if ((playing)) begin counter=counter+20'd1; if (counter[19:0]==counter_end[19:0]) begin counter=0; beep=~beep; end end else begin beep=0; end end
always@(key or reset) begin if (!reset) begin counter_end=5000; playing=1; end else case(key) 8'h77: begin counter_end<=19111;//低音1 5000000/261.63 playing<=1; end 8'hb7: begin counter_end<=17026;//低音2 293.67 playing<=1; end 8'hd7: begin counter_end<=15169;//低音3 5000000/329.63 15168.522282559234 playing<=1; end 8'he7: begin counter_end<=14317;//低音4 5000000/349.23 playing<=1; end 8'h7b: begin counter_end<=12778;//低音5 5000000/391.39 12774.98147627686 playing<=1; end 8'hbb: begin counter_end<=11364;//低音6 5000000/440.0 11363.636363636364 playing=1; end 8'hdb: begin counter_end=10124;//低音7 5000000/493.88 10123.916740908722 playing=1; end 8'heb: begin counter_end=9556;//中音1 5000000/523.25 9555.6617295747728 playing=1; end 8'h7d: begin counter_end=8513;//中音2 5000000/587.33 8513.1016634600637 playing:=1; playing=1; end 8'hbd: begin counter_end=7584;//中音3 5000000/659.25 7584.3761850587789 playing=1; end 8'hdd: begin counter_end=7159;//中音4 45000000/698.46 7158.6060762248371 playing=1; end 8'hed: begin counter_end=6378;//中音5 55000000/783.99 6377.6323677597929 playing=1; end 8'h7e: begin counter_end=5682;//中音6 5000000/880.0 5681.818181818182 playing=1; end 8'hbe: begin counter_end=5062;//中音7 75000000/987.76 5061.9583704543611 playing=1; end 8'hde: begin counter_end=4778;//高音1 5000000/1046.50 4777.8308647873864 playing=1; end 8'hee: begin counter_end=4257;//高音2 5000000/1174.66 4256.5508317300319 playing=1; end 8'h6e: begin counter_end=3792;//高音3 5000000/1318.51 3792.1593313664666 playing=1; end 8'hae: begin counter_end=3579;//高音4 5000000/1396.92 3579.3030381124186 playing=1; end 8'hce: begin counter_end=3189;//高音5 5000000/1567.98 3188.8161838798965 playing=1; end 8'hec: begin counter_end=2841;//高音6 5000000/1760.0 2840.909090909091 playing=1; end 8'hea: begin counter_end=2531;//高音7 5000000/1975.52 2530.9791852271806 playing=1; end 8'hff: begin //counter_end=20'hx_xxxx;//静音 playing=0; end default: begin //counter_end[19:12]=1000;//key test playing=0; end endcase end
endmodule
|