952|0

3376

帖子

0

资源

纯净的硅(高级)

CPLD驱动MAX7219传送8位参数的问题 [复制链接]

我用CPLD驱动MAX7219传送16位参数的方法成功了。

我看单片机里都是一次传送8位数据,我也想用CPLD传送8位数据。

但是有个问题,就是MAX7219的LOAD引脚也就是片选,需要传送两次8位数据才锁存。

我传送一次8位数据锁存一次,仿真没问题。

代码如下:

module MAX7219
				(
					input clk_i,
					input rst_i,					
					
					output reg sdin_o,//串行输出数据
					output reg sclk_o,//串行时钟
					output reg load_o,//更新da寄存器
					output reg [7:0] data
				
				 );



reg [7:0] olddata;
reg [22:0] currentstate;
parameter s1 = 23'b000_0000_0000_0000_0000_0001;
parameter s2 = 23'b000_0000_0000_0000_0000_0010;//s1和S2状态设置译码寄存器		 
parameter s3 = 23'b000_0000_0000_0000_0000_0100;
parameter s4 = 23'b000_0000_0000_0000_0000_1000;//S3和S4状态设置亮度寄存器
parameter s5 = 23'b000_0000_0000_0000_0001_0000;//


//reg sclk_o;
reg [5:0]counter;

parameter	
			seg1 = 8'h01,				//1.
			seg2 = 8'h81,				//2
			seg3 = 8'h02,				//3
			seg4 = 8'h02,				//4
			seg5 = 8'h03,				//1.
			seg6 = 8'h03,				//2
			seg7 = 8'h04,				//3
			seg8 = 8'h09;				//4
reg [2:0]cnt;			

	//产生时钟
always @(posedge clk_i)
begin
  if(!rst_i) begin
		counter<=6'd0;
		sclk_o <= 1'b1;
    end
  else begin
    if(counter==6'd9) begin
      sclk_o <= ~sclk_o;
      counter<=6'd0;
      end
    else counter<=counter+6'd1;
    end
end

reg [2:0] sclk_cnt;//同步时钟计数器,7
//reg [4:0] sclk_cnt;//同步时钟计数器,7
always @(posedge sclk_o or negedge rst_i)
begin
	if(!rst_i) sclk_cnt <= 3'b0;
	else 
	case(currentstate)
		s2,s4: 
			if(3'd7 == sclk_cnt) 
					sclk_cnt <= 3'b0;
			else 	sclk_cnt <= sclk_cnt + 3'b1;
		default: sclk_cnt <= 3'b0;
	endcase
end
//主状态机
always @(posedge sclk_o or negedge rst_i)
begin
	if(!rst_i) begin currentstate <=s1; cnt = 3'b0; end
	else
	case(currentstate)
	
	s1: currentstate <= s2;  //s1和S2状态设置译码寄存器	
	s2:begin 
			if(3'd7 == sclk_cnt) //8个时钟周期将数据送出去
				currentstate <= s3;
			else
				currentstate <= s2;
		end
	s3: currentstate <= s4;  //s1和S2状态设置译码寄存器	
	s4:begin 
			if(3'd7 == sclk_cnt) //8个时钟周期将数据送出去
				currentstate <= s5;
			else
				currentstate <= s4;
		end
	s5: currentstate <= s1;  //s1和S2状态设置译码寄存器
	
	endcase
end
//各状态的处理

always @(posedge sclk_o or negedge rst_i)
begin
	if(!rst_i)begin  data <= 8'h00; olddata <= 8'h00; end
	else case(currentstate)
		
		s1:begin  data <= 8'h0a; end  //正常显示模式
		s3:begin  data <= 8'h04; end  //正常显示模式
		
		s2,s4: begin data <= data << 1;	olddata <= olddata; end//循环移位 将高位送出
		default: begin data <= 8'h00; olddata <= olddata; end
	endcase
end
//----------数据串行---------
always @(posedge sclk_o or negedge rst_i)
begin
	if(!rst_i) sdin_o <= 1'b0;
	else case(currentstate)
		s2,s4: sdin_o <= data[7];
		default: sdin_o <= 1'b0;
	endcase
end
//----------串行数据写有效LOAD----------
always @(posedge sclk_o or negedge rst_i)
begin
	if(!rst_i) load_o <= 1'b1;
	else case(currentstate)
		s2,s4: begin  load_o <= 1'b0;  end //送数的时候处于低
		default: load_o <= 1'b1; //非送数时候,拉高 锁存数据
	endcase
end


endmodule

仿真波形如下:

12.jpg

可见传送一次8位数据,我传了两个8位数据0x0a,0x04,都是8个脉冲,但是都是传送之前LOAD拉低,传送完8位数据,LOAD拉高。

我想实现连续传送两次8位数据,16个时钟周期,代码如下

module MAX7219
				(
					input clk_i,
					input rst_i,					
					
					output reg sdin_o,//串行输出数据
					output reg sclk_o,//串行时钟
					output reg load_o,//更新da寄存器
					output reg [7:0] data
				
				 );



reg [7:0] olddata;
reg [22:0] currentstate;
parameter s1 = 23'b000_0000_0000_0000_0000_0001;
parameter s2 = 23'b000_0000_0000_0000_0000_0010;//s1和S2状态设置译码寄存器		 
parameter s3 = 23'b000_0000_0000_0000_0000_0100;
parameter s4 = 23'b000_0000_0000_0000_0000_1000;//S3和S4状态设置亮度寄存器
parameter s5 = 23'b000_0000_0000_0000_0001_0000;//


//reg sclk_o;
reg [5:0]counter;

parameter	
			seg1 = 8'h01,				//1.
			seg2 = 8'h81,				//2
			seg3 = 8'h02,				//3
			seg4 = 8'h02,				//4
			seg5 = 8'h03,				//1.
			seg6 = 8'h03,				//2
			seg7 = 8'h04,				//3
			seg8 = 8'h09;				//4
reg [2:0]cnt;			

	//产生时钟
always @(posedge clk_i)
begin
  if(!rst_i) begin
		counter<=6'd0;
		sclk_o <= 1'b1;
    end
  else begin
    if(counter==6'd9) begin
      sclk_o <= ~sclk_o;
      counter<=6'd0;
      end
    else counter<=counter+6'd1;
    end
end

reg [2:0] sclk_cnt;//同步时钟计数器,7
//reg [4:0] sclk_cnt;//同步时钟计数器,7
always @(posedge sclk_o or negedge rst_i)
begin
	if(!rst_i) sclk_cnt <= 3'b0;
	else 
	case(currentstate)
		s2,s4: 
			if(3'd7 == sclk_cnt) 
					sclk_cnt <= 3'b0;
			else 	sclk_cnt <= sclk_cnt + 3'b1;
		default: sclk_cnt <= 3'b0;
	endcase
end
//主状态机
always @(posedge sclk_o or negedge rst_i)
begin
	if(!rst_i) begin currentstate <=s1; cnt = 3'b0; end
	else
	case(currentstate)
	
	s1: currentstate <= s2;  //s1和S2状态设置译码寄存器	
	s2:begin 
			if(3'd7 == sclk_cnt) //8个时钟周期将数据送出去
				currentstate <= s3;
			else
				currentstate <= s2;
		end
	s3: currentstate <= s4;  //s1和S2状态设置译码寄存器	
	s4:begin 
			if(3'd7 == sclk_cnt) //8个时钟周期将数据送出去
				currentstate <= s5;
			else
				currentstate <= s4;
		end
	s5: currentstate <= s1;  //s1和S2状态设置译码寄存器
	
	endcase
end
//各状态的处理

always @(posedge sclk_o or negedge rst_i)
begin
	if(!rst_i)begin  data <= 8'h00; olddata <= 8'h00; end
	else case(currentstate)
		
		s1:begin  data <= 8'h0a; end  //正常显示模式
		s3:begin  data <= 8'h04; end  //正常显示模式
		
		s2,s4: begin data <= data << 1;	olddata <= olddata; end//循环移位 将高位送出
		default: begin data <= 8'h00; olddata <= olddata; end
	endcase
end
//----------数据串行---------
always @(posedge sclk_o or negedge rst_i)
begin
	if(!rst_i) sdin_o <= 1'b0;
	else case(currentstate)
		s2,s4: sdin_o <= data[7];
		default: sdin_o <= 1'b0;
	endcase
end
//----------串行数据写有效LOAD----------
always @(posedge sclk_o or negedge rst_i)
begin
	if(!rst_i) load_o <= 1'b1;
	else case(currentstate)
		s2,s3,s4: begin  load_o <= 1'b0;  end //送数的时候处于低
		default: load_o <= 1'b1; //非送数时候,拉高 锁存数据
	endcase
end


endmodule

仿真结果如下

13.jpg

可以看到多了一个时钟周期,一共17个时钟周期。

请问高手,有什么办法让它凑够16个时钟周期。谢谢!

个人签名为江山踏坏了乌骓马,为社稷拉断了宝雕弓。

回复
您需要登录后才可以回帖 登录 | 注册

相关帖子
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
    推荐帖子
    FM1702sl终于调通小结

    先发个牢骚前段时间着手调试fm1702sl的刷卡器,真是费了好一番功夫,首先对于这款芯片其实不应该算很难的,但是拿到fm1702sl的 ...

    徐琪、李东:单片机音乐频谱

    摘要随着时代的进步,电子信息技术被广泛运用于生活的各方面,人们越来越重视视觉、听觉以及音质的享受。音乐信号频谱因其自身有 ...

    【GD32F350 都市青年家庭安防卫士 】第六贴 国庆感悟贴与后续分享预告贴

    本帖最后由 传媒学子 于 2018-10-7 19:36 编辑 【GD32F350 都市青年家庭安防卫士 】第六贴 国庆感悟贴与后续分享预告贴 有 ...

    晒货(2) - 坑王intel

    2013年Intel为IoT推出了基于夸克处理器的伽利略开发板后,又依次推出了爱迪生、居里等开发板。虽然Intel在处理器方面实力很强, ...

    【ATmega4809 Curiosity Nano测评】串口应用初步:通过串口打印正弦字符串

    最近一直在忙CAN总线的项目,所以没有及时更新对ATMEGA4809的相关更新,现在把一些基础的东西更新的论坛里面来,希望能对大家有 ...

    Altium Designer19.1.6,Reports BOM 不生成BOM表,还会让AD19卡死,请问什么原因?

    本帖最后由 oyhprince 于 2021-3-27 17:55 编辑 软件:Altium Designer,版本19.1.6 问题:不管是原理图还是PCB界面,Repo ...

    关闭
    站长推荐上一条 1/5 下一条

    About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

    站点相关: 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

    北京市海淀区知春路23号集成电路设计园量子银座1305 电话:(010)82350740 邮编:100191

    电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2022 EEWORLD.com.cn, Inc. All rights reserved
    快速回复 返回顶部 返回列表