去年测试分频器写法的玩具,呼吸得比较喘,所以不叫呼吸灯了,调整占空比区域可以转换成正常呼吸灯。
assign r_LED_pwn = (switch)?(LED_pwn_2):(LED_pwn);//控制亮灭
1.assign r_LED_pwn = (switch)?(LED_pwn_2):(LED_pwn);
LED_pwn是led_cnt == div_cnt时反转的灯,
led_cnt每个时钟周期增加一次的计数器;
div_cnt则是每毫秒增加一次的计数器;
随着时间的增加,反转速度会越来越慢。
2.LED_pwn_2是led_cnt_2 == (div_max - div_cnt)时反转的灯,
随着时间的增加,反转速度会越来越慢。
3.
module breatheled
#(
parameter time_period = 20,
parameter div_max = 1000_000,
parameter one_route = 2_000_000_000,
parameter cnt_max = ((one_route/time_period)/div_max),
parameter div_width = $clog2(div_max),
parameter cnt_width = $clog2(cnt_max)
)
(
input wire Sys_clk,
input wire Rst_n ,
output wire r_LED_pwn
);
reg [cnt_width-1:0] Change_cnt ;
reg Change_flag;
reg [div_width-1:0] div_cnt ;
reg [div_width-1:0] led_cnt ;
reg [div_width-1:0] led_cnt_2 ;
reg LED_pwn ;
reg LED_pwn_2 ;
reg switch ;
assign r_LED_pwn = (switch)?(LED_pwn_2):(LED_pwn);
//switch
always @(posedge Sys_clk or negedge Rst_n)
begin
if(!Rst_n)
switch <= 1'b0;
else if(div_cnt == div_max -1'b1)
switch <= ~switch;
else
switch <= switch;
end
//change
always @(posedge Sys_clk or negedge Rst_n)
begin
if(!Rst_n)
Change_cnt <= 0;
else if(Change_cnt == cnt_max -1'b1)
Change_cnt <= 0;
else
Change_cnt <= Change_cnt + 1'b1;
end
//flag
always @(posedge Sys_clk or negedge Rst_n)
begin
if(!Rst_n)
Change_flag <= 1'b0;
else if(Change_cnt == cnt_max -1'b1)
Change_flag <= 1'b1;
else
Change_flag <= 1'b0;
end
//div_cnt
always @(posedge Sys_clk or negedge Rst_n)
begin
if(!Rst_n)
div_cnt <= 1'b0;
else if(div_cnt == div_max -1'b1)
div_cnt <= 1'b0;
else if(Change_flag)
div_cnt <= div_cnt + 1'b1;
end
//led_cnt
always @(posedge Sys_clk or negedge Rst_n)
begin
if(!Rst_n)
led_cnt <= 1'b0;
else if(led_cnt == div_cnt)
led_cnt <= 1'b0;
else
led_cnt <= led_cnt + 1'b1;
end
//led
always @(posedge Sys_clk or negedge Rst_n)
begin
if(!Rst_n)
LED_pwn <= 1'b0;
else if(led_cnt == div_cnt)
LED_pwn <= ~LED_pwn;
else
LED_pwn <= LED_pwn ;
end
//led_cnt_2
always @(posedge Sys_clk or negedge Rst_n)
begin
if(!Rst_n)
led_cnt_2 <= 1'b0;
else if(led_cnt_2 == (div_max - div_cnt))
led_cnt_2 <= 1'b0;
else
led_cnt_2 <= led_cnt_2 + 1'b1;
end
//led_2
always @(posedge Sys_clk or negedge Rst_n)
begin
if(!Rst_n)
LED_pwn_2 <= 1'b0;
else if(led_cnt_2 == (div_max - div_cnt))
LED_pwn_2 <= ~LED_pwn_2;
else
LED_pwn_2 <= LED_pwn_2 ;
end
endmodule
真呼吸灯
assign r_LED_pwn = (pwn_flag == 0)?
((pwn_cnt > div_1000_cnt)?1'b0:1'b1):
((pwn_cnt > div_1000_cnt)?1'b1:1'b0);
div_1000_cnt 100ns计数器,100周期增加一次。
pwn_cnt 1000*100即100000周期增加一次
pwn_flag 1000*1000*100 100周期反转一次
pwn_flag = 0 随着时间增加,闪烁越来越快。
pwn_flag = 1随着时间增加,闪烁越来越慢。
module pwm_breathe_led
#(
parameter time_period = 20,
parameter div_1000 = 1000,
parameter div_1000_100= 100 ,
parameter div_width = $clog2(div_1000),
parameter cnt_width = $clog2(div_1000_100)
)
(
input wire Sys_clk,
input wire Rst_n ,
output wire r_LED_pwn
);
reg [div_width-1:0] div_1000_cnt;
reg [div_width-1:0] pwn_cnt ;
reg [cnt_width-1:0] div_1000_100_cnt;
reg pwn_flag;
assign r_LED_pwn = (pwn_flag == 0)?
((pwn_cnt > div_1000_cnt)?1'b0:1'b1):
((pwn_cnt > div_1000_cnt)?1'b1:1'b0);
//cnt
always @(posedge Sys_clk or negedge Rst_n)
begin
if(!Rst_n)
div_1000_100_cnt <= 0;
else if(div_1000_100_cnt == div_1000_100 - 1'b1)
div_1000_100_cnt <= 0;
else
div_1000_100_cnt <= div_1000_100_cnt + 1'b1;
end
always @(posedge Sys_clk or negedge Rst_n)
begin
if(!Rst_n)
div_1000_cnt <= 0;
else if((div_1000_cnt == div_1000 - 1'b1)
&&(div_1000_100_cnt == div_1000_100 - 1'b1))
div_1000_cnt <= 0;
else if(div_1000_100_cnt == div_1000_100 - 1'b1)
div_1000_cnt <= div_1000_cnt + 1'b1;
else
div_1000_cnt <= div_1000_cnt;
end
always @(posedge Sys_clk or negedge Rst_n)
begin
if(!Rst_n)
pwn_cnt <= 0;
else if((pwn_cnt == div_1000 - 1'b1)
&&(div_1000_cnt == div_1000 - 1'b1)
&&(div_1000_100_cnt == div_1000_100 - 1'b1))
pwn_cnt <= 0;
else if((div_1000_cnt == div_1000 - 1'b1)
&&(div_1000_100_cnt == div_1000_100 - 1'b1))
pwn_cnt <= pwn_cnt + 1'b1;
else
pwn_cnt <= pwn_cnt;
end
//flag
always @(posedge Sys_clk or negedge Rst_n)
begin
if(!Rst_n)
pwn_flag <= 1'b0;
else if((pwn_cnt == div_1000 - 1'b1)
&&(div_1000_cnt == div_1000 - 1'b1)
&&(div_1000_100_cnt == div_1000_100 - 1'b1))
pwn_flag <= ~pwn_flag;
else
pwn_flag <= pwn_flag;
end
endmodule
PS呼吸灯
/******************************************************************************
*
* Copyright (C) 2009 - 2014 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*
* helloworld.c: simple test application
*
* This application configures UART 16550 to baud rate 9600.
* PS7 UART (Zynq) is not initialized by this application, since
* bootrom/bsp configures it to baud rate 115200
*
* ------------------------------------------------
* | UART TYPE BAUD RATE |
* ------------------------------------------------
* uartns550 9600
* uartlite Configurable only in HW design
* ps7_uart 115200 (configured by bootrom/bsp)
*/
#include <stdio.h>
#include "platform.h"
#include "xil_printf.h"
#include "xparameters.h"
#include "xgpiops.h"
#define GPIO_DEVICE_ID XPAR_XGPIOPS_0_DEVICE_ID
u32 LED0 = 54;
u32 LED1 = 55;
u32 Bottom = 56;
static XGpioPs GPIO_Decive;
static XGpioPs_Config *GPIO_Device_ConFig;
int GPIO_init_TEST(void);
int main()
{
int LED = 0;
int i;
int j;
int k = 0;
init_platform();
GPIO_init_TEST();
while (1)
{
switch(k)
{
case 0:
for(i=0;i<500;i++){
for(j=0;j<500;j++){
usleep(1);
if(j>i){
XGpioPs_WritePin(&GPIO_Decive,LED0,0x00);}
else{
XGpioPs_WritePin(&GPIO_Decive,LED0,0x01);}}}
k = 1;
break;
case 1:
for(i=0;i<500;i++){
for(j=0;j<500;j++){
usleep(1);
if(j>i){
XGpioPs_WritePin(&GPIO_Decive,LED0,0x01);}
else{
XGpioPs_WritePin(&GPIO_Decive,LED0,0x00);}}}
k = 0;
break;
}
}
cleanup_platform();
return 0;
}
int GPIO_init_TEST(void)
{
int Status;
GPIO_Device_ConFig = XGpioPs_LookupConfig(GPIO_DEVICE_ID);
if (GPIO_Device_ConFig == NULL) {
return XST_FAILURE;
}
Status = XGpioPs_CfgInitialize(&GPIO_Decive,
GPIO_Device_ConFig,
GPIO_Device_ConFig->BaseAddr);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
//LED0
XGpioPs_SetDirectionPin(&GPIO_Decive,
LED0,
0x01);
XGpioPs_SetOutputEnablePin(&GPIO_Decive,
LED0,
0x01);
//LED1
XGpioPs_SetDirectionPin(&GPIO_Decive,
LED1,
0x01);
XGpioPs_SetOutputEnablePin(&GPIO_Decive,
LED1,
0x01);
//Bottom
XGpioPs_SetDirectionPin(&GPIO_Decive,
Bottom,
0x0);
XGpioPs_SetOutputEnablePin(&GPIO_Decive,
Bottom,
0x01);
}