2035|0

3183

帖子

0

TA的资源

纯净的硅(高级)

楼主
 

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

仿真波形如下:

可见传送一次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

仿真结果如下

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

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

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

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
推荐帖子
【赛题大汇总】选录09及往年各省、地区竞赛题目

【赛题大汇总】选录09及往年各省地区竞赛题目,各位有兴趣可以拿来练习预热哦~~ 2008年广西省大学生电子设计竞赛试题 A题:宽带 ...

ZT:电子毕业生如何规划你的人生

一、 怎样规划你的毕业后的人生     我今年39岁了, 25岁研究生毕业,工作14年,回头看看,应该说走了不少的弯路,有一些 ...

ADC10实验例程(含C#上位机)

C#上位机学习资料 https://bbs.eeworld.com.cn/viewthread.php?tid=308129&page=1#pid1198878上周逛论坛看到上面的C#串口教程 ...

添加并美化SEED-EXP430F5529 LCD背光(TPS75105DSKR正常工作!)

在Ti申请的TPS75105DSKR器件今天到了! 花了点时间其焊接上了! 112980 为了测试TPS75105DSKR器件是否正常工作! 我自己添 ...

【晒方案】纯手工仅100克的四轴飞行器“她”仍在努力飞行中

本帖最后由 paulhyde 于 2014-9-15 03:20 编辑 我们组在2013年全国电子设计大赛中选择的题目是自主四轴飞行器,为什么要选择这 ...

工程人员安全黑匣子之ESP8266连接OneNet云平台的方法

本帖最后由 sipower 于 2020-5-28 23:05 编辑 前面几个帖子分享了我的准备工作和系统框图,这次我分享点跟传感器关系不大,但 ...

刚装的AD17,Keep-OutLayer设置不了

刚装的AD17,Keep-OutLayer设置不了,不能批量和单个修改成机械层或其他层,有没有知道在哪里设置的,十万火急,谢谢!

电力电子变换器:PWM 策略与电流控制技术

《电力电子变换器:PWM 策略与电流控制技术》系统地介绍了现代电力电子变换装置及其PWM控制策略,具有内容系统全面、范例丰富详 ...

《控制之美(卷2)》--最优控制、线性二次规划与模型预测控制

本帖最后由 dirty 于 2024-2-25 18:00 编辑 本篇讲述第三至五章节 最优控制的基本概念,动态规划与线性二次型调节器 和模型预 ...

#AI挑战营第一站#PC上完成手写数字模型训练

model.py import torch.nn as nn import torch.nn.functional as F class Net(nn.Module): class Net(nn.Module ...

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

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

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

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

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

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