十进制数转换BCD码

本文详细介绍了如何在单片机中使用加三移位法来转换十进制数字为BCD码,以适应数码管显示。通过给出的Verilog代码,展示了如何在每次移位后判断是否需要加三,以及如何最终分配到数码管的各个段。这种方法旨在节省存储器资源。
摘要由CSDN通过智能技术生成

有必要仔细阐述这一节,目前就是用在数码管显示,在单片机使用时,我们通常是将十进制数字进行/和%运算,得到每个位置的十进制数字,在这里可能是为了节省使用存储器的量,运用的是加三移位法具体其实就是将每个数字不顾位置,各自转换为二进制形式

例如:

255 变成 0010 _0101_0101 的过程

移位的次数一定是该数字的二进制位数,加三不确定(加三也是要判断每4位的二进制大于4才加三,所以是每次移位以后都要判断)

module bcd_8421(
						input  wire sys_clk,
						input  wire  sys_rst,
						input  wire [19:0] data,
						
						output reg [3:0] ge,
						output reg [3:0] shi,
						output reg [3:0] bai,
						output reg [3:0] qian,
						output reg [3:0] wan,
						output reg [3:0] shi_wan

    );
	 
reg [4:0]  cnt_shift;  //移位判断计数器
reg [43:0] data_shift;  //移位判断数据寄存器
reg shift_flag;          //移位判断标志信号

always @(posedge sys_clk or negedge sys_rst) //0到21的循环计数(移位加三的方式实现的话,首位各加一个,999_999十进制换算到二进制有20位)
	if(!sys_rst )
		cnt_shift <= 5'd0;
	else if ((cnt_shift==5'd21) && (shift_flag == 1'b1))
		cnt_shift <= 5'd0;
	else if (shift_flag == 1'b1)
		cnt_shift <= cnt_shift + 1'b1;
	else 
		cnt_shift <= cnt_shift;
	
always @(posedge sys_clk or negedge sys_rst) //移位判断标志信号,控制移位判断的先后顺序
	if(!sys_rst )
		shift_flag <= 1'b0;
	else 
		shift_flag <= ~shift_flag;
	
always @(posedge sys_clk or negedge sys_rst) //data_shift有44位,其中高24位是999_999形成的BCD码需要24位,低20位是999_999的二进制形式是20位
	if(!sys_rst )
		data_shift <=44'b0;
	else if (cnt_shift == 5'd0)
		data_shift <= {24'b0, data };	
		else if ((cnt_shift <= 5'd20)&&(shift_flag==1'b0))   //cnt_shift=0时,还是上次的,因为六位数最大变成二进制有20位,所以考虑有20次判断和移位操作,21次稳定,将它输出,
		begin
			data_shift[23:20] <= (data_shift[23:20]>4) ? (data_shift[23:20]+2'd3) : (data_shift[23:20]);
			data_shift[27:24] <= (data_shift[27:24]>4) ? (data_shift[27:24]+2'd3) : (data_shift[27:24]);
			data_shift[31:28] <= (data_shift[31:28]>4) ? (data_shift[31:28]+2'd3) : (data_shift[31:28]);
			data_shift[35:32] <= (data_shift[35:32]>4) ? (data_shift[35:32]+2'd3) : (data_shift[35:32]);
			data_shift[39:36] <= (data_shift[39:36]>4) ? (data_shift[39:36]+2'd3) : (data_shift[39:36]);
			data_shift[43:40] <= (data_shift[43:40]>4) ? (data_shift[43:40]+2'd3) : (data_shift[43:40]);
		end 
	else if ((cnt_shift <= 5'd20)&&(shift_flag==1'b1))
		data_shift <= data_shift << 1;
	else 		
		data_shift <= data_shift;
always @(posedge sys_clk or negedge sys_rst) //当计数器等于20时,对各位置的赋值(BCD)
	if(!sys_rst )
		begin 
			ge		  <= 4'b0;
			shi       <= 4'b0;
			bai       <= 4'b0;
			qian      <= 4'b0;
			wan       <= 4'b0;
			shi_wan   <= 4'b0;
		end
	else if (cnt_shift == 5'd21)
		begin
			ge		  <= data_shift[23:20];
		    shi       <= data_shift[27:24];
	        bai       <= data_shift[31:28];
		    qian      <= data_shift[35:32];
	        wan       <= data_shift[39:36];
	        shi_wan   <= data_shift[43:40];
		end 
	else
		begin
			    ge		  <=  ge		     ;
		       shi       <=  shi        ;
			    bai       <=  bai        ;
             qian      <=  qian       ;
             wan       <=  wan        ;
             shi_wan   <=  shi_wan    ;
		end 	
			
endmodule

 

module vtf;

	// Inputs
	reg sys_clk;
	reg sys_rst;
	reg [19:0] data;

	// Outputs
	wire [3:0] ge;
	wire [3:0] shi;
	wire [3:0] bai;
	wire [3:0] qian;
	wire [3:0] wan;
	wire [3:0] shi_wan;

	// Instantiate the Unit Under Test (UUT)
	bcd_8421 uut (
		.sys_clk(sys_clk), 
		.sys_rst(sys_rst), 
		.data(data), 
		.ge(ge), 
		.shi(shi), 
		.bai(bai), 
		.qian(qian), 
		.wan(wan), 
		.shi_wan(shi_wan)
	);

	initial begin
		// Initialize Inputs
		sys_clk = 0;
		sys_rst = 0;
		data = 0;

		// Wait 100 ns for global reset to finish
		#100;
        sys_rst <= 1'b1;
		data <= 20'd0;
		#100000;
		data <= 20'd123_456;
		#100000;
		data <= 20'd999_999;
		#100000;
		data <= 20'd123_895;
		#100000;
		data <= 20'd456_789;
		#100000;
		data <= 20'd999_999;
		#100000;
		data <= 20'd456_789;
		
		// Add stimulus here

	end
	always # 10 sys_clk = ~sys_clk;
      
endmodule

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值