开发环境:Quartus II 12 64bit,语言verilog hdl
主要功能:EPM570T144作为
STM32的FSMC总线上的设备,为MCU提供接口扩展和一些简单的逻辑功能。
问题:
1. sensor模块中读取几个IO口数据的时候,若在判断中添加对地址的判断,则无**常读取数据。(传感器就是普通的光电对管,经过施密特)
由于我是第一次写CPLD代码,有可能是某些基础知识不了解,低级问题导致,请大家帮忙查出来予以指教!
2. 奇怪的问题:如果我将led_beeper模块中的代码添加了一些逻辑功能,甚至仅仅删除一小部分代码,就会导致sensor模块中的数据读出为全0。
具体添加的逻辑功能,在led_beeper -new.v中。
具体删除的小部分代码,在下文led_beeper.v中有标识描述,删除这一段,重新下载以后STM32读取sensor模块的数据就是全0了。
硬件没问题,其他功能完全正常,设备总线读写正常(USB、LCD),通过CPLD控制的电机等设备也运行正常。传感器的信号用示波器看过没有任何问题。
我现在是给公司开发一个项目,用到CPLD临时学的,由于时间紧迫也就没能从头到尾系统地学习,希望大家能不吝赐教!!
下面贴代码(只贴了几个模块,其他的在附件中,包括CPLD其他全部代码、STM32对应的FSMC设置代码等):
CPLD 顶层模块:
- module amrp1250c
- (
- CLK48M,CPLD_INT,MCU_IO,
- BUS_WR,BUS_RD,BUS_NE,BUS_A_L,BUS_A_H,BUS_D,
- BUS_CS_CH375,BUS_CS_FLASH,BUS_CS_LCD,BUS_CS_RAM,
- BEEP,LED,
- SM1_MONI,SM1_EMO, SM2_MONI,SM2_EMO, SM3_MONI,SM3_EMO, SM4_MONI,SM4_EMO,
- SM_ST, SM4_OE,SM4_FR,SM4_ATT, SM3_OE,SM3_FR,SM3_ATT, SM2_OE,SM2_FR,SM2_ATT, SM1_OE,SM1_FR,SM1_ATT,
- DM2_EN,DM1_EN,DM1_IN,DM2_IN,
- SEN_DOOR,SEN_PRESS,SEN_CARVE,SEN_TAPE_B,SEN_TAPE_F,SEN_CUT_R,SEN_CUT_L,SEN_RESERVE,
- PH_PWR, PH_LATCH,PH_CLK, PH_DAT,PH_STR
- );
- /*********************************************************************************************************/
- //接口定义
- //晶振时钟
- input CLK48M;
- //发送至MCU的中断信号
- output CPLD_INT;
- //与MCU连接的预留IO口
- output[3:0] MCU_IO;
- //数据总线
- input BUS_WR,BUS_RD;
- input[4:1] BUS_NE;
- input[19:0] BUS_A_L;
- input[25:22] BUS_A_H;
- inout[15:0] BUS_D;
- output BUS_CS_CH375,BUS_CS_FLASH,BUS_CS_LCD;
- output[2:1] BUS_CS_RAM;
- //蜂鸣器
- output BEEP;
- //LED0--绿,LED1--红
- output[1:0] LED;
- //步进电机
- input SM1_MONI,SM1_EMO, SM2_MONI,SM2_EMO, SM3_MONI,SM3_EMO, SM4_MONI,SM4_EMO;
- output SM_ST, SM4_OE,SM4_FR,SM4_ATT, SM3_OE,SM3_FR,SM3_ATT, SM2_OE,SM2_FR,SM2_ATT, SM1_OE,SM1_FR,SM1_ATT;
- //直流电机
- output DM2_EN,DM1_EN;
- output[2:1] DM1_IN,DM2_IN;
- //传感器接口
- input SEN_DOOR,SEN_PRESS,SEN_CARVE,SEN_TAPE_B,SEN_TAPE_F,SEN_CUT_R,SEN_CUT_L,SEN_RESERVE;
- //打印头接口
- output PH_PWR, PH_LATCH,PH_CLK;
- output[4:1] PH_DAT,PH_STR;
- /*********************************************************************************************************/
- //双向总线数据口
- reg[15:0] BUS_D_OUT_REG;
- wire[15:0] BUS_D_OUT;
- wire[15:0] BUS_D;
- wire[15:0] BUS_D_IN;
- assign BUS_D[15:0] = ((BUS_RD == 1'b0) && (BUS_CS_CPLD == 0))? BUS_D_OUT_REG : 16'bzzzz_zzzz_zzzz_zzzz;
- assign BUS_D_IN = BUS_D;
- always
- begin
- BUS_D_OUT_REG = BUS_D_OUT;
- end
- /*********************************************************************************************************/
- //模拟上电复位
- wire RST_n;
- sim_rst mod_sim_rst(CLK48M,1'b1,RST_n);
- /*********************************************************************************************************/
- //时钟分频
- wire clk_1k;
- defparam Gen_ClkLed.divdWIDTH=15,Gen_ClkLed.divdFACTOR=24000;
- gen_divd Gen_ClkLed(.reset(RST_n),.clkin(CLK48M),.clkout(clk_1k));
- assign CPLD_INT = clk_1k;
- /*********************************************************************************************************/
- wire BUS_CS_CPLD;
- logic_cs mod_logic_cs(BUS_NE,BUS_A_H, BUS_CS_CH375,BUS_CS_LCD,BUS_CS_FLASH,BUS_CS_RAM,BUS_CS_CPLD);
- led_beeper mod_led_beeper(clk_1k,RST_n,BUS_CS_CPLD,BUS_WR,BUS_D_IN,BUS_A_L,LED,BEEP);
- /*********************************************************************************************************/
- //传感器读取
- sensor mod_sensor(clk_1k,BUS_CS_CPLD,BUS_RD,BUS_D_OUT[7:0],BUS_A_L, MCU_IO[0],
- SEN_DOOR,SEN_PRESS,SEN_CARVE,SEN_TAPE_B,SEN_TAPE_F,SEN_CUT_R,SEN_CUT_L,SEN_RESERVE);
- //assign MCU_IO[0] = SEN_CUT_L;
- /*********************************************************************************************************/
- dc_motor mod_dc_motor(clk_1k,RST_n,BUS_CS_CPLD,BUS_WR,BUS_D_IN,BUS_A_L,DM1_EN,DM1_IN,DM2_EN,DM2_IN);
- /*********************************************************************************************************/
- step_motor mod_step_motor
- (
- clk_1k,RST_n,
- BUS_CS_CPLD,BUS_WR,BUS_D,BUS_A_L,
- SM_ST, SM4_OE,SM4_FR,SM4_ATT, SM3_OE,SM3_FR,SM3_ATT, SM2_OE,SM2_FR,SM2_ATT, SM1_OE,SM1_FR,SM1_ATT
- );
- /*********************************************************************************************************/
- print_head mod_print_head
- (
- CLK48M,clk_1k,RST_n,
- BUS_CS_CPLD,BUS_WR,BUS_D,BUS_A_L,
- PH_PWR, PH_LATCH,PH_CLK, PH_DAT,PH_STR,
- MCU_IO[1]
- );
- endmodule
复制代码
CPLD sensor模块:
- module sensor
- (
- inClk1K,
- BUS_CS_CPLD,BUS_RD,BUS_D_OUT,BUS_A_L, MCU_IO,
- SEN_DOOR,SEN_PRESS,SEN_CARVE,SEN_TAPE_B,SEN_TAPE_F,SEN_CUT_R,SEN_CUT_L,SEN_RESERVE
- );
- input inClk1K;
- input BUS_CS_CPLD,BUS_RD;
- input[19:0] BUS_A_L;
- input SEN_DOOR,SEN_PRESS,SEN_CARVE,SEN_TAPE_B,SEN_TAPE_F,SEN_CUT_R,SEN_CUT_L,SEN_RESERVE;
- output[7:0] BUS_D_OUT;
- output MCU_IO;
- reg[7:0] BUS_D_OUT;
- reg MCU_IO;
- parameter ADDR_SENSOR = 16'h2000;
- //传感器有光(未挡住)
- //parameter STATE_BRIGHT = 1'b1;
- //传感无光(挡住)
- //parameter STATE_DARK = 1'b0;
- always@(negedge BUS_RD)
- begin
- if ((BUS_CS_CPLD == 0))// && (BUS_A_L[15:0] == ADDR_SENSOR))
- begin
- // 7 6 5 4 3 2 1 0
- BUS_D_OUT[7:0] = {SEN_DOOR,SEN_PRESS,SEN_CARVE,SEN_TAPE_B,SEN_TAPE_F,SEN_CUT_R,SEN_CUT_L,SEN_RESERVE};
- //出现读取数据为全0的情况时,将上句替换为 BUS_D_OUT[7:0] = 8'h23; 则可以正常读出数据,怀疑是总线上挂的设备太多了,驱动能力不足?
- end
- end
- endmodule
复制代码
CPLD led_beeper模块:
- module led_beeper
- (
- clk_1k,rst_n,
- BUS_CS_CPLD,BUS_WR,BUS_D,BUS_A_L,
- outLed,outBeeper
- );
- /* 输入信号数据格式
- [7:0] -- 蜂鸣器
- [11:8] -- LED0
- [15:12]-- LED1
- */
- input clk_1k,rst_n;
- input BUS_CS_CPLD, BUS_WR;
- input[15:0] BUS_D;
- input[19:0] BUS_A_L;
- output[1:0] outLed;
- output outBeeper;
- //寄存器定义
- reg[1:0] outLed;
- reg outBeeper;
- reg [3:0]rStateLed0,rStateLed1,rStateBeeper;
- reg [9:1]rCntLed0,rCntLed1,rCntBeeper;
- //定义使能信号数据
- //注意:该地址为16位数据地址,即对应到MCU中的地址为0x1000<<1 (MCU中的地址为8位数据地址)
- parameter ADDR_LED_BEEPER = 16'h1000;
- parameter STATE_ON = 4'h1;
- parameter STATE_OFF = 4'h2;
- parameter STATE_1HZ = 4'hA;
- parameter STATE_3HZ = 4'hB;
- parameter STATE_10HZ = 4'hC;
- parameter OUT_ON = 1'b0;
- parameter OUT_OFF = 1'b1;
- //总线数据接收
- always @(negedge BUS_WR or negedge rst_n)
- begin
- if (rst_n == 1'b0)
- begin
- rStateLed1 = STATE_ON;
- rStateLed0 = STATE_ON;
- rStateBeeper = STATE_OFF;
- end
- else if ((BUS_CS_CPLD == 0) && (BUS_A_L == ADDR_LED_BEEPER))
- begin
- if (BUS_D[7:4] != 4'h0)
- begin
- rStateLed1 = BUS_D[7:4];
- end
- if (BUS_D[3:0] != 4'h0)
- begin
- rStateLed0 = BUS_D[3:0];
- end
- if (BUS_D[11:8] != 4'h0)
- begin
- rStateBeeper = BUS_D[11:8];
- end
- end
- end
- //LED0
- always @(posedge clk_1k)
- begin
- case(rStateLed0)
- STATE_ON:
- begin
- outLed[0] = OUT_ON;
- rCntLed0 = 1'b0;
- end
- STATE_OFF:
- begin
- outLed[0] = OUT_OFF;
- rCntLed0 = 1'b0;
- end
- STATE_1HZ:
- begin
- if (rCntLed0 >= 500)
- begin
- outLed[0] = ~outLed[0];
- rCntLed0 = 1'b0;
- end
- rCntLed0 = rCntLed0 + 1'b1;
- end
- STATE_3HZ:
- begin
- if (rCntLed0 >= 166)
- begin
- outLed[0] = ~outLed[0];
- rCntLed0 = 1'b0;
- end
- rCntLed0 = rCntLed0 + 1'b1;
- end
- STATE_10HZ:
- begin
- if (rCntLed0 >= 50)
- begin
- outLed[0] = ~outLed[0];
- rCntLed0 = 1'b0;
- end
- rCntLed0 = rCntLed0 + 1'b1;
- end
- default: outLed[0] = OUT_ON;
- endcase
- end
- //LED1
- always @(posedge clk_1k)
- begin
- case(rStateLed1)
- STATE_ON:
- begin
- outLed[1] = OUT_ON;
- rCntLed1 = 1'b0;
- end
- STATE_OFF:
- begin
- outLed[1] = OUT_OFF;
- rCntLed1 = 1'b0;
- end
- STATE_1HZ:
- begin
- if (rCntLed1 >= 500)
- begin
- outLed[1] = ~outLed[1];
- rCntLed1 = 1'b0;
- end
- rCntLed1 = rCntLed1 + 1'b1;
- end
- STATE_3HZ:
- begin
- if (rCntLed1 >= 166)
- begin
- outLed[1] = ~outLed[1];
- rCntLed1 = 1'b0;
- end
- rCntLed1 = rCntLed1 + 1'b1;
- end
- default: outLed[1] = OUT_ON;
- endcase
- end
- //BEEPER
- always @(posedge clk_1k)
- begin
- case(rStateBeeper)
- STATE_ON:
- begin
- outBeeper = OUT_ON;
- rCntBeeper = 1'b0;
- end
- STATE_OFF:
- begin
- outBeeper = OUT_OFF;
- rCntBeeper = 1'b0;
- end
- STATE_1HZ:
- begin
- if (rCntBeeper >= 500)
- begin
- outBeeper = ~outBeeper;
- rCntBeeper = 1'b0;
- end
- rCntBeeper = rCntBeeper + 1'b1;
- end
- STATE_3HZ:
- begin
- if (rCntBeeper >= 166)
- begin
- outBeeper = ~outBeeper;
- rCntBeeper = 1'b0;
- end
- rCntBeeper = rCntBeeper + 1'b1;
- end
- /*STATE_10HZ:
- begin
- if (rCntBeeper >= 50)
- begin
- outBeeper = ~outBeeper;
- rCntBeeper = 1'b0;
- end
- rCntBeeper = rCntBeeper + 1'b1;
- end*/
- //上面这段代码删除以后,会导致sensor模块的数据通过总线读出来是全0,再添加这段代码回来,就恢复了。。奇怪的问题
- default: outBeeper = OUT_OFF;
- endcase
- end
- endmodule
复制代码
0
-
-
MCU.zip
122.03 KB , 阅读权限:10, 下载次数: 5
-
-
CPLD.rar
845.36 KB , 阅读权限:10, 下载次数: 12
已退回20积分
|