利用FPGA输出占空比可调的方波

一开始我不太认同通过测试文件的输入值改变占空比的做法符合要求,总感觉这等同于多次不同的测试放到了一起。后来感觉手动调占空比也符合要求,可以对应开发板上一个按键,来改变占空比。

手动调的方案

module PWM(clk,rst_n,duty,PWM_wave);
	input clk;
	input [6:0] duty;
	input rst_n;
	output reg PWM_wave;

	reg [7:0] count;
	
	always@(posedge clk or negedge rst_n)
		begin
			if(!rst_n)
				begin
				PWM_wave<=0;
				count<=8'd0;
				end
			else
				begin
				if(count>=8'd100)
					count<=8'd0;
				if(count<8'd100)
					count<=count+8'd1;
					
				if(count<duty)
					PWM_wave<=1;
				if(count>=duty)
					PWM_wave<=0;
				end
		end

endmodule

测试文件

`timescale 10ns/1ns
module test();

	reg clk;
	reg rst_n;
	reg [6:0] duty;
	wire PWM_wave;
	
	PWM u1(.clk(clk),.rst_n(rst_n),.duty(duty),.PWM_wave(PWM_wave));
	
	initial 
		begin
	     clk<=0;
		 rst_n=0;
		 duty=7'd10;
		 #10 rst_n=1;
		 #100	duty=7'd30;
		 #100	duty=7'd50;
		 #100	duty=7'd70;
		 end
		 
	always #10 clk<=~clk;
	
endmodule

自动改变占空比的程序可对应呼吸灯实例,代码如下

顶层文件

module top_pwm(CLK_50M,RST_N,pwm_out);

	input CLK_50M;
	input RST_N;
	output  pwm_out;
	wire 	CLK_1M;
	
	fenpin i1(.CLK_50M(CLK_50M),.RST_N(RST_N),.CLK_1M(CLK_1M));
	PWM    i2(.CLK_1M(CLK_1M),.RST_N(RST_N),.pwm_out(pwm_out));
	
endmodule

PWM程序

module PWM(CLK_1M,RST_N,pwm_out);

	input CLK_1M;
	input RST_N;
	output  pwm_out;
		
	reg [6:0]  time_cnt;
	reg [6:0]  turn_reg;//翻转寄存器
	reg  pwm_reg;//输出寄存器
	reg  flag;
//---------------------------------------------
	parameter   period=7'd50;//周期
	parameter   turn=7'd30;//最大占空比
//---------------------------------------------------

	always  @ (posedge CLK_1M or negedge RST_N)
		begin
			if(!RST_N)
				begin
				time_cnt <= 7'd0;
				pwm_reg<= 1'b0;
				turn_reg<=turn;
				end
			else
				begin
				time_cnt<=time_cnt+7'd1;
				
				if(turn_reg==turn)
					flag=1'b0;
				if(turn_reg==7'd1)
					flag=1'b1;
					
				if ( time_cnt <= turn_reg-1) 
					pwm_reg <= 1'b0;
				if (( time_cnt > turn_reg-1) && (time_cnt<period-1))
					pwm_reg <= 1'b1;
					
				if(time_cnt==period-1)
					begin
					time_cnt <= 7'd0;
					if(flag==1'b1)//改变占空比
						turn_reg<=turn_reg+7'd1;	
					if(flag==1'b0)
						turn_reg<=turn_reg-7'd1;
					end
				end
		end
 
   assign  pwm_out= pwm_reg;
	
 endmodule

分频产生1MHz时钟

module fenpin(CLK_50M,RST_N,CLK_1M);

	input CLK_50M ;
	input RST_N;
	output CLK_1M;
	
	reg [6:0] time_cnt;
	reg  CLK_1M;
	parameter period=7'd25;
	
	always@(posedge CLK_50M or negedge RST_N)
		begin
			if(!RST_N)
				begin
				time_cnt<=7'd0;
				CLK_1M<=1'b0;
				end
			else
				begin
				time_cnt<=time_cnt+7'd1;
				if(time_cnt==period-1)
					begin
					CLK_1M<=~CLK_1M;
					time_cnt<=7'd0;
					end
				end
		end
endmodule
	

测试文件

`timescale 1ns/1ns

module pwm_test();
	
	reg CLK_50M;
	reg RST_N;
	wire pwm_out;
	
	top_pwm  u1 (.CLK_50M(CLK_50M),.RST_N(RST_N),.pwm_out(pwm_out));
	
	initial 
		begin
		
		RST_N=0;
		CLK_50M=0;
		#10 RST_N=1;
		#10 RST_N=0;
		#10 RST_N=1;
		
		end
		
	always  #10 CLK_50M=~CLK_50M;
	
endmodule

仿真波形
在这里插入图片描述

  • 9
    点赞
  • 66
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
要让STM32的P2.3口输出72MHz比为80%的方波,可以使用定时器来实现。首先,需要将P2.3口配置为定时器的输出引脚,然后配置定时器的时钟源和分频器,使得定时器的时钟频率为72MHz。接着,配置定时器的计数器和自动重载寄存器,使得定时器的周期为1个周期。然后,再配置定时器的比,使得高电平的时间为一个周期的80%。最后,启动定时器,并在定时器中断中翻转P2.3口的输出电平,就可以输出72MHz比为80%的方波了。以下是一个简单的示例代码: ```c #include "stm32f10x.h" void TIM2_IRQHandler(void) { if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) { TIM_ClearITPendingBit(TIM2, TIM_IT_Update); GPIO_WriteBit(GPIOB, GPIO_Pin_3, (BitAction)(1 - GPIO_ReadOutputDataBit(GPIOB, GPIO_Pin_3))); } } int main(void) { GPIO_InitTypeDef GPIO_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); TIM_TimeBaseStructure.TIM_Period = 1; TIM_TimeBaseStructure.TIM_Prescaler = 0; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = 1 * 0.8; // 80% duty cycle TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OC1Init(TIM2, &TIM_OCInitStructure); TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE); NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); TIM_Cmd(TIM2, ENABLE); while (1) { } } ```
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值