我想用一個Zybo板上的4個LED指示計數從0到15的計數器。另外我希望板的4個按鍵對應不同的頻率用於改變LED(0.5Hz,1Hz,2Hz,4Hz)。我已經實現了固定頻率的簡單計數器,但沒有按鈕頻率改變的第二部分。不同頻率的LED計數器編程(0 - 15)
在模塊設計中,我有一個Zynq處理系統,一個讀取按鈕數據的AXI GPIO以及一個用作LED驅動器,時鐘分頻器和變頻器的自定義IP。
自定義IP
的時鐘分頻模塊代碼。
module Clock_Divider(
input clk,
input rst,
input reg0,
output reg clk_out
);
reg [31:0] count;
reg constantNumber;
always @ (reg0)
begin
if(reg0 == 0000)
constantNumber = 50000000;
else if(reg0 == 0001)
constantNumber = 100000000;
else if(reg0 == 0010)
constantNumber = 50000000;
else if(reg0 == 0100)
constantNumber = 25000000;
else if(reg0 == 1000)
constantNumber = 12500000;
else
constantNumber = 50000000;
end
always @ (posedge(clk), posedge(rst))
begin
if (rst == 1'b1)
begin
count <= 32'b0;
end
else if (count == constantNumber - 1)
begin
count <= 32'b0;
end
else
begin
count <= count + 1;
end
end
always @ (posedge(clk), posedge(rst))
begin
if (rst == 1'b1)
clk_out <= 1'b0;
else if (count == constantNumber - 1)
clk_out <= ~clk_out;
else
clk_out <= clk_out;
end
endmodule
寄存器constantNumber取對應的值以改變時鐘頻率。
其餘的定製IP邏輯。
Clock_Divider UIP (.clk(S_AXI_ACLK), .rst(), .reg0(slv_reg0), .clk_out(clk_out));
reg [3:0] counter = 0;
always @(posedge clk_out)
begin
if(counter < PWM_COUNTER_MAX-1)
begin
counter <= counter + 1;
end
else
counter <= 0;
end
assign PWM0 = counter[0];
assign PWM1 = counter[1];
assign PWM2 = counter[2];
assign PWM3 = counter[3];
數據被髮送到定製IP(slv_reg0),其反過來將它們發送到所述REG0模塊Clock_Divider中的所述第一寄存器中的按鈕。
主C程序
#include <stdio.h>
#include "platform.h"
#include <xgpio.h>
#include "xparameters.h"
#include "sleep.h"
#include "xil_io.h"
//#define MY_PWM XPAR_MY_PWM_CORE_0_S00_AXI_BASEADDR //Because of a bug in Vivado 2015.3 and 2015.4, this value is not correct.
#define MY_PWM 0x43C00000 //This value is found in the Address editor tab in Vivado (next to Diagram tab)
int main(){
XGpio input;
int button_data = 0;
XGpio_Initialize(&input, XPAR_AXI_GPIO_0_DEVICE_ID); //initialize input XGpio variable
XGpio_SetDataDirection(&input, 1, 0xF); //set first channel tristate buffer to input
init_platform();
while(1){
button_data = XGpio_DiscreteRead(&input, 1); //get button data
if(button_data == 0b0000){
Xil_Out32(MY_PWM, button_data);
}
else if(button_data == 0b0001){
xil_printf("button 0 pressed\n\r");
Xil_Out32(MY_PWM, button_data);
}
else if(button_data == 0b0010){
xil_printf("button 1 pressed\n\r");
Xil_Out32((MY_PWM), button_data);
}
else if(button_data == 0b0100){
xil_printf("button 2 pressed\n\r");
Xil_Out32((MY_PWM), button_data);
}
else if(button_data == 0b1000){
xil_printf("button 3 pressed\n\r");
Xil_Out32((MY_PWM), button_data);
}
else{
xil_printf("multiple buttons pressed\n\r");
Xil_Out32(MY_PWM, 0b0000);
}
}
cleanup_platform();
return 0;
}
我可以確認按鍵數據被正確地由AXI GPIO讀因爲當按下他們正確的線在終端打印。但是當我按下按鈕時,頻率不會改變。此外,它的運行頻率非常慢,比即使按鈕數據未發送到自定義IP時默認值爲1Hz的頻率慢得多。
問題必須存在於自定義IP中的reg0案例邏輯或從cpu發送到自定義IP的寄存器的按鈕數據的某處。
在Verilog'0010'中是十個,而不是二進制二。我想你想'4'b0010' – Greg
我改變了它,仍然以非常低的頻率運行。但即使與前值不應該constantNumber總是採取值50000000和計數器運行在1Hz? – vic
許多嘗試後仍然存在的問題是,即使按鈕數據沒有傳輸到時鐘分頻器邏輯,constantNumber也應該是50000000,並且無論按下哪個按鈕,計數器都應以1Hz運行。但現在它運行非常緩慢,LED每85秒就會改變一次狀況。 – vic