打印

一段和arm无关的程序,我的最近的作品

[复制链接]
1312|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
wangkj|  楼主 | 2008-9-22 08:25 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
/*
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 

相关帖子

沙发
wangkj|  楼主 | 2008-9-22 08:30 | 只看该作者

本来想做一个led显示的简单东西

结果后来把 扫描键盘(支持组合键) 电子琴 复杂流水灯 都加上了,感兴趣的看看吧。 很多程序是老verilog程序员跟我一起调试通过的

串口有点问题没调好,那个老程序员出差了,我也不想调试了,以后再说

顺便改正了开发板的两个bug
1. 蜂鸣器换成交流的,而且,加上了限流电阻
2. 行列扫描线加上上拉电阻

真想自己做个cpld开发板,可是,做完了,也没啥意思

verilog算是基本会用了。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

581

主题

9976

帖子

24

粉丝