www.pudn.com > buzzer.rar > buzzer.v, change:2005-12-14,size:2729b


/* 
向蜂鸣器发送一定频率的方波可以使蜂鸣器发出相应的音调,该实验通过设计一个状态机和分频 
器使蜂鸣器发出"多来咪发梭拉西多"的音调。 
*/ 
 
module buzzer(clk,rst,out); 
 
input clk,rst; 
output out; 
reg out; 
 
reg[3:0] clk_div1; //基频分频计数器,基频为4M 
reg[12:0] clk_div2;//音阶分频计数器,由基频分频产生各个音阶 
reg[21:0] cnt;//各音阶发声时间长短计数器 
reg[2:0] state; 
 
parameter   duo=3822,   //各个音调的分频系数 
		    lai=3405, 
			mi=3034, 
			fa=2865, 
			suo=2551, 
			la=2273, 
			xi=2024, 
			duo1=1911; 
 
 
always@(posedge clk or negedge rst) 
begin 
	if(!rst) begin 
		clk_div1<=0; 
	 end 
	else begin 
		if(clk_div1!=9) 
			clk_div1<=clk_div1+1; 
		else 
			clk_div1<=0; 
	 end 
end 
 
always@(posedge clk or negedge rst) 
begin 
	if(!rst) begin 
		clk_div2<=0; 
		state<=0; 
		cnt<=0; 
		out<=0; 
	 end 
	else if(clk_div1==9) begin 
		case(state) 
			3'b000: begin               //发“多” 
				cnt<=cnt+1; 
				if(cnt==22'h3fffff)  
					state<=3'b001; 
				if(clk_div2!=duo) 
					clk_div2<=clk_div2+1; 
				else begin 
					clk_div2<=0; 
					out<=~out; 
				end 
			 end 
			3'b001: begin				//发“来” 
				cnt<=cnt+1; 
				if(cnt==22'h3fffff)  
					state<=3'b010; 
				if(clk_div2!=lai) 
					clk_div2<=clk_div2+1; 
				else begin 
					clk_div2<=0; 
					out<=~out; 
				end 
			 end 
			3'b010:begin                //发"米“ 
				cnt<=cnt+1; 
				if(cnt==22'h3fffff)  
					state<=3'b011; 
				if(clk_div2!=mi) 
					clk_div2<=clk_div2+1; 
				else begin 
					clk_div2<=0; 
					out<=~out; 
				end 
			 end 
			3'b011: begin				 //发"法“ 
				cnt<=cnt+1; 
				if(cnt==22'h3fffff)  
					state<=3'b100; 
				if(clk_div2!=fa) 
					clk_div2<=clk_div2+1; 
				else begin 
					clk_div2<=0; 
					out<=~out; 
				end 
			 end 
			3'b100: begin               //发"梭“    
				cnt<=cnt+1; 
				if(cnt==22'h3fffff)  
					state<=3'b101; 
				if(clk_div2!=suo) 
					clk_div2<=clk_div2+1; 
				else begin 
					clk_div2<=0; 
					out<=~out; 
				end 
			 end 
			3'b101: begin                  //发"拉“ 
				cnt<=cnt+1; 
				if(cnt==22'h3fffff)  
					state<=3'b110; 
				if(clk_div2!=la) 
					clk_div2<=clk_div2+1; 
				else begin 
					clk_div2<=0; 
					out<=~out; 
				end 
			 end 
			3'b110: begin                   //发"西“ 
				cnt<=cnt+1; 
				if(cnt==22'h3fffff)  
					state<=3'b111; 
				if(clk_div2!=xi) 
					clk_div2<=clk_div2+1; 
				else begin 
					clk_div2<=0; 
					out<=~out; 
				end 
			 end 
			3'b111: begin                   //发"多“(高音) 
				cnt<=cnt+1; 
				if(cnt==22'h3fffff)  
					state<=3'b000; 
				if(clk_div2!=duo1) 
					clk_div2<=clk_div2+1; 
				else begin 
					clk_div2<=0; 
					out<=~out; 
				end 
			 end 
		 endcase 
	 end 
end 
 
endmodule