原创 动态扫描的数码管SlaveIP设计

2010-8-1 13:27 2014 10 10 分类: FPGA/CPLD

 


写一个简单的Avalon_MM Slave IP,


供初学者学习.


 


[描述]


控制七段数码管显示,动态扫描,


每组4个数码管,共用数据线,一共两组.


 


[程序]


 // seven-seg led
 // James 2009.08.05
 
 module sevenled( clk,rst_n,
          write,writedata,address,
          seg_com,seg_led0,seg_led1
       );
                  
 // for Avalon clock interface                 
 input clk,rst_n;
 
 // for Avalon-MM slave port
 input write;
 input [7:0] writedata;
 input [2:0] address;
 
 // for User port
 output [7:0] seg_led0;
 output [7:0] seg_led1;
 output [7:0] seg_com;
 
 
 
 reg [7:0] seg_led0;
 reg [7:0] seg_led1;
 reg [7:0] seg_com;
 reg [7:0] displaydata;
 
  
 // write regs
 reg [7:0] avalon_data[7:0]; //8 regs[7:0]
 always @(posedge clk or negedge rst_n)
 if(!rst_n)
  begin
  avalon_data[0] <=8'h00;
  avalon_data[1] <=8'h00;
  avalon_data[2] <=8'h00;
  avalon_data[3] <=8'h00;
  avalon_data[4] <=8'h00;
  avalon_data[5] <=8'h00;
  avalon_data[6] <=8'h00;
  avalon_data[7] <=8'h00;
  end
 else if(write)       //IOWR send the write signal automatically
     avalon_data[address] <= writedata;
  
 // counter++
 reg [15:0] count;
 always @(posedge clk or negedge rst_n)
 if(!rst_n)
  count <= 16'h0;
 else
  count <= count + 1'b1;
 
 
 // scan dynamically and CS
 always @(count[14:12])  //82us的扫描速度,大一些也可以
 begin
 case(count[14:12])
  3'b000: begin               
      displaydata = avalon_data[0];              
      seg_com = 8'h01;              
       end              
  3'b001: begin              
      displaydata = avalon_data[1];              
      seg_com = 8'h02;              
      end              
  3'b010: begin              
      displaydata = avalon_data[2];              
      seg_com = 8'h04;              
      end              
  3'b011: begin              
      displaydata = avalon_data[3];              
      seg_com = 8'h08;              
      end              
  3'b100: begin              
      displaydata = avalon_data[4];              
      seg_com = 8'h10;              
      end                
  3'b101: begin              
      displaydata = avalon_data[5];              
      seg_com = 8'h20;              
      end              
  3'b110: begin              
      displaydata = avalon_data[6];              
      seg_com = 8'h40;              
      end              
  3'b111: begin              
      displaydata = avalon_data[7];              
      seg_com = 8'h80;              
      end              
  default: seg_com = 8'h00;
 endcase
 end
 
 
 // Segment Select LED0
 always @(seg_com[3:0])
 case(displaydata)  
   4'h1: seg_led0 = 8'h06;     // 1
   4'h2: seg_led0 = 8'h5b;     // 2
   4'h3: seg_led0 = 8'h4f;     // 3 
   4'h4: seg_led0 = 8'h66;     // 4
   4'h5: seg_led0 = 8'h6d;     // 5
   4'h6: seg_led0 = 8'h7d;     // 6
   4'h7: seg_led0 = 8'h07;     // 7
   4'h8: seg_led0 = 8'h7f;     // 8
   4'h9: seg_led0 = 8'h6f;     // 9
   4'ha: seg_led0 = 8'h77;   // A
   4'hb: seg_led0 = 8'h7c;   // b
   4'hc: seg_led0 = 8'h39;   // c
   4'hd: seg_led0 = 8'h5e;   // d
   4'he: seg_led0 = 8'h79;   // E
   4'hf: seg_led0 = 8'h71;   // F
   4'h0: seg_led0 = 8'h3f;   // 0
   default : seg_led0 = 8'h00;
 endcase
 
 // Segment Select LED1
 always @(seg_com[7:4]) 
 case(displaydata)  
   4'h1: seg_led1 = 8'h06;    
   4'h2: seg_led1 = 8'h5b;   
   4'h3: seg_led1 = 8'h4f;     
   4'h4: seg_led1 = 8'h66;    
   4'h5: seg_led1 = 8'h6d;    
   4'h6: seg_led1 = 8'h7d;     
   4'h7: seg_led1 = 8'h07;   
   4'h8: seg_led1 = 8'h7f;     
   4'h9: seg_led1 = 8'h6f;     
   4'ha: seg_led1 = 8'h77; 
   4'hb: seg_led1 = 8'h7c; 
   4'hc: seg_led1 = 8'h39; 
   4'hd: seg_led1 = 8'h5e; 
   4'he: seg_led1 = 8'h79; 
   4'hf: seg_led1 = 8'h71; 
   4'h0: seg_led1 = 8'h3f; 
   default : seg_led1 = 8'h00;
 endcase
 
 endmodule


[添加]


在SopcBuilder下面,New Component…


Signals界面设置如下,



interface下面设置,



把没有用的删掉



最后一步,选择添加到哪个类别下面,如果有Parameter,可以选择哪些是可以设置的.



finish完成.


双击添加后,自动和MM-Master连起来,一般就一个Master即Nios.


编译即可.


[控制]


在IDE下,用C控制,代码这样即可.


IOWR_8DIRECT(SEVENLED_BASE, 0 , 0x01);


IOWR_8DIRECT(SEVENLED_BASE, 1 , 0x02);


IOWR_8DIRECT(SEVENLED _BASE, 4 , 0x05);


IOWR_8DIRECT(SEVENLED _BASE, 5 , 0x06);


即第一个数码管显示1,第二个显示2;


第五个数码管(第二组的第一个)显示5,第六个显示6.


  


[完成]


直接给对应寄存器值即可,8个寄存器,对应8个数码管.


硬件完成动态扫描,解放软件的工作.


这样用起来很方便,避免软件上用while或是定时器动态扫描数码管.


尽管简单,但体现了软,硬件协同设计的灵活性.


 


程序放这了


有错误的地方还请大家指教


 

PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
EE直播间
更多
我要评论
0
10
关闭 站长推荐上一条 /3 下一条