完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
核心功能(基于EGO1)
1.Verilog测距传感(利用HC-SR04测距传感器) 2.Verilog四位数码管显示 3.Verilog伺服电机驱动(包含维护模式) 4.蜂鸣报警、及各种传感器维护模式 主函数 // module onic_detect(clk_100m, rst, Trig, Echo,kaiguan, an,bn,code_out,code_out2, q,q2,LED2,LED1,LED0,fengmingqi);//主模块输入输出 input clk_100m, rst, Echo; input [2:0]kaiguan; output Trig; output [3:0]an; output [3:0]bn; output [7:0]code_out;/* out */ output [7:0]code_out2; output q,q2; output LED2; output LED1; output LED0; output fengmingqi; reg fengmingqi; wire [15:0]N; reg [50:0]high; wire [50:0]low; reg [50:0]cnt = 0; reg [50:0]cnt2 = 0; reg [15:0]dis; reg [3:0]an; reg [3:0]bn; reg [7:0]code_out; //控制右边四位数码管显示的数字 reg [7:0]code_out2; //控制左边四位数码管显示的数字 reg [50:0] count=0; reg q; //输出不同占空比控制台灯的升降 reg q2; reg LED2; reg LED1; reg LED0; reg led; //控制呼吸灯有强到弱再由弱到强 reg [10:0]cntus=0; reg [10:0]cntms=0; reg [10:0]cnts=0; reg [2:0]cnt2s=0; wire clk_1m; wire[15:0] dis0; // 回波高电平持续时间us wire[15:0] d; // 距离(单位cm),5位十进制,包括两位小数 ##为HC-SR04测距传感器(50分频) Clk_1M u0(.clk_out(clk_1m),.clk_in(clk_100m), .rst(rst)); // 50分频 TrigSignal u1(.clk_1m(clk_1m),.trig(Trig)); PosCounter u2(.clk_1m(clk_1m), .rst(rst), .echo(Echo), .dis_count(dis0)); assign low = 2000000-high; assign d[15:12] = dis0/1000%10; // 十位 assign d[11:8] = dis0/100%10; // 个位 assign d[7:4] = dis0/10%10; // 0.1 assign d[3:0] = dis0%10; // 0.01 parameter T1US = 8‘d100; parameter T1MS = 10’d1000; parameter T1S = 10‘d1000; always @ (posedge clk_100m) begin q2《=q; end ##伺服电机维护模式 拨动三个开关 分别控制电机三种工作模式 always @ (posedge clk_100m or negedge rst) if(kaiguan==3’b001) //维护模式中使电机降到最低位置 begin code_out2 《= code_out; bn 《= an; if(!rst) begin cnt 《= 0; end else if(cnt2==100000000) begin cnt2 《=0; end else if(cnt==400000) begin cnt《=0; end else begin cnt=cnt+1; cnt2=cnt2+1; end if ((cnt2《=50000000)&&(cnt2》=1)) begin dis 《=16‘b1011101110111011; end else if((cnt2》50000000)&&(cnt2《100000000)) begin dis 《=16’b1010101010101010; end end else if(kaiguan==3‘b010) //维护模式中使电机降到中间位置 begin bn 《= an; code_out2 《= code_out; if(!rst) begin cnt 《= 0; end else if(cnt2==100000000) begin cnt2 《=0; end else if(cnt==400000) begin cnt《=0; end else begin cnt=cnt+1; cnt2=cnt2+1; end if ((cnt2《=50000000)&&(cnt2》=1)) begin dis 《=16’b1100110011001100; end else if((cnt2》50000000)&&(cnt2《100000000)) begin dis 《=16‘b1010101010101010; end end else if(kaiguan==3’b100) //维护模式中使电机降到最高位置 begin bn 《= an; code_out2 《= code_out; if(!rst) begin cnt 《= 0; end else if(cnt2==100000000) begin cnt2 《=0; end else if(cnt==400000) begin cnt《=0; end else begin cnt=cnt+1; cnt2=cnt2+1; end if ((cnt2《=50000000)&&(cnt2》=1)) begin dis 《=16‘b1101110111011101; end else if((cnt2》50000000)&&(cnt2《100000000)) begin dis 《=16’b1010101010101010; end end else//数码管部分维护 begin bn 《= an; code_out2《=8‘b00111111; if(!rst) begin cnt 《= 0; end else if(cnt==400000) begin cnt《=0; end else begin cnt=cnt+1; dis《=d; end end ##四位数码管显示 always @ (posedge clk_100m) //通过数码管显示出距离 if ((1《cnt)&(cnt《=100000)) begin an 《= 4’b0001; case(dis[15:12]) 0 :code_out《= 8‘b00111111; 1 :code_out《= 8’b00000110; 2 :code_out 《=8‘b01011011; 3 : code_out《=8’b01001111; 4 : code_out《=8‘b01100110; 5 : code_out《=8’b01101101; 6 :code_out《= 8‘b01111101; 7 : code_out《=8’b00000111; 8 :code_out《= 8‘b01111111; 9 : code_out《=8’b01101111; 10 : code_out《=8‘b0; 11 : code_out《=8’b00001000; 12 : code_out《=8‘b01000000; 13 : code_out《=8’b00000001; endcase end else if ((100000《cnt)&(cnt《=200000)) begin an《=4‘b0010; case(dis[11:8]) 0 :code_out《= 8’b10111111; 1 :code_out《= 8‘b10000110; 2 :code_out 《=8’b11011011; 3 : code_out《=8‘b11001111; 4 : code_out《=8’b11100110; 5 : code_out《=8‘b01101101; 6 :code_out《= 8’b11111101; 7 : code_out《=8‘b10000111; 8 :code_out《= 8’b11111111; 9 : code_out《=8‘b11101111; 10 : code_out《=8’b0; 11 : code_out《=8‘b00001000; 12 : code_out《=8’b01000000; 13 : code_out《=8‘b00000001; endcase end else if ((200000《cnt)&(cnt《=300000)) begin an《=4’b0100; case(dis[7:4]) 0 :code_out《= 8‘b00111111; 1 :code_out《= 8’b00000110; 2 :code_out 《=8‘b01011011; 3 : code_out《=8’b01001111; 4 : code_out《=8‘b01100110; 5 : code_out《=8’b01101101; 6 :code_out《= 8‘b01111101; 7 : code_out《=8’b00000111; 8 :code_out《= 8‘b01111111; 9 : code_out《=8’b01101111; 10 : code_out《=8‘b0; 11 : code_out《=8’b00001000; 12 : code_out《=8‘b01000000; 13 : code_out《=8’b00000001; endcase end else if ((300000《cnt)&(cnt《400000)) begin an《=4‘b1000; case(dis[3:0]) 0 :code_out《= 8’b00111111; 1 :code_out《= 8‘b00000110; 2 :code_out 《=8’b01011011; 3 : code_out《=8‘b01001111; 4 : code_out《=8’b01100110; 5 : code_out《=8‘b01101101; 6 :code_out《= 8’b01111101; 7 : code_out《=8‘b00000111; 8 :code_out《= 8’b01111111; 9 : code_out《=8‘b01101111; 10 : code_out《=8’b0; 11 : code_out《=8‘b00001000; 12 : code_out《=8’b01000000; 13 : code_out《=8‘b00000001; endcase end ##四位数码管显示 always @ (posedge clk_100m) //通过数码管显示出距离 if ((1《cnt)&(cnt《=100000)) begin an 《= 4’b0001; case(dis[15:12]) 0 :code_out《= 8‘b00111111; 1 :code_out《= 8’b00000110; 2 :code_out 《=8‘b01011011; 3 : code_out《=8’b01001111; 4 : code_out《=8‘b01100110; 5 : code_out《=8’b01101101; 6 :code_out《= 8‘b01111101; 7 : code_out《=8’b00000111; 8 :code_out《= 8‘b01111111; 9 : code_out《=8’b01101111; 10 : code_out《=8‘b0; 11 : code_out《=8’b00001000; 12 : code_out《=8‘b01000000; 13 : code_out《=8’b00000001; endcase end else if ((100000《cnt)&(cnt《=200000)) begin an《=4‘b0010; case(dis[11:8]) 0 :code_out《= 8’b10111111; 1 :code_out《= 8‘b10000110; 2 :code_out 《=8’b11011011; 3 : code_out《=8‘b11001111; 4 : code_out《=8’b11100110; 5 : code_out《=8‘b01101101; 6 :code_out《= 8’b11111101; 7 : code_out《=8‘b10000111; 8 :code_out《= 8’b11111111; 9 : code_out《=8‘b11101111; 10 : code_out《=8’b0; 11 : code_out《=8‘b00001000; 12 : code_out《=8’b01000000; 13 : code_out《=8‘b00000001; endcase end else if ((200000《cnt)&(cnt《=300000)) begin an《=4’b0100; case(dis[7:4]) 0 :code_out《= 8‘b00111111; 1 :code_out《= 8’b00000110; 2 :code_out 《=8‘b01011011; 3 : code_out《=8’b01001111; 4 : code_out《=8‘b01100110; 5 : code_out《=8’b01101101; 6 :code_out《= 8‘b01111101; 7 : code_out《=8’b00000111; 8 :code_out《= 8‘b01111111; 9 : code_out《=8’b01101111; 10 : code_out《=8‘b0; 11 : code_out《=8’b00001000; 12 : code_out《=8‘b01000000; 13 : code_out《=8’b00000001; endcase end else if ((300000《cnt)&(cnt《400000)) begin an《=4‘b1000; case(dis[3:0]) 0 :code_out《= 8’b00111111; 1 :code_out《= 8‘b00000110; 2 :code_out 《=8’b01011011; 3 : code_out《=8‘b01001111; 4 : code_out《=8’b01100110; 5 : code_out《=8‘b01101101; 6 :code_out《= 8’b01111101; 7 : code_out《=8‘b00000111; 8 :code_out《= 8’b01111111; 9 : code_out《=8‘b01101111; 10 : code_out《=8’b0; 11 : code_out《=8‘b00001000; 12 : code_out《=8’b01000000; 13 : code_out《=8‘b00000001; endcase end ##目前看不懂。。。 #always @ (posedge clk_100m) begin if(kaiguan==3’b001) begin high《=60000; end else if(kaiguan==3‘b010) begin high《=150000; end else if(kaiguan==3’b100) begin high《=250000; end else begin if(d[15:12]》=4) high《=250000; else if(d[15:12]》=2) high《=150000; else begin fengmingqi《=(high《=150000)?1:0; high《=60000; end end if (rst) begin if (count 《high) begin count 《= count+1‘b1; q 《= 1; end if (count 》= high) begin count 《= count+1’b1; q 《= 0; end if (count == high+low) begin q 《= 0; count 《= 1‘b0; end end end #呼吸灯相关。。。 always @ ( posedge clk_100m) //呼吸灯控制程序 begin if (!rst) begin cntus 《= 10’d0; cntms 《= 10‘d0; cnts 《= 10’d0; end else if (cntus 《 100 ) cntus 《= cntus + 1‘b1; else cntus《= 6’d1; if(cntms《1000) begin if(cntus==100) cntms 《= cntms + 1‘b1; end else cntms《=10’d0; if(cnts《1000) begin if(cntms==1000) cnts 《= cnts+1‘b1; end else cnts《=0; if(cnt2s《2) begin if(cnts==1000) cnt2s《=cnt2s+1; end else cnt2s《=0; led《=(cnt2s==0)?((cntms《=cnts)?1:0):((cntms《=cnts)?0:1); end always @ ( posedge clk_100m) //维护模式中呼吸灯模块 if (kaiguan[2]==0) LED2=0; else LED2=led; always @ ( posedge clk_100m) if (kaiguan[1]==0) LED1=0; else LED1=led; always @ ( posedge clk_100m) if (kaiguan[0]==0) LED0=0; else LED0=led; Endmodule ##测距传感器控制部分(三个主要控制部分) module Clk_1M (clk_in, rst, clk_out); //进行分频(1Mhz)程序 input clk_in; input rst; output reg clk_out; parameter high = 50, low =100-high; reg [50:0] count=0; always @ (posedge clk_in) begin if (rst) begin if (count 《high) begin count 《= count+1’b1; clk_out 《= 1; end if (count 》= high) begin count 《= count+1‘b1; clk_out《= 0; end if (count == high+low) begin clk_out 《= 0; count 《= 1’b0; end end end endmodule module TrigSignal(clk_1m, trig); //产生10us的触发信号 input clk_1m; output reg trig; parameter high = 10, low =1000000-high; reg [50:0] count=0; always @ (posedge clk_1m) begin if (count 《high) begin count 《= count+1‘d1; trig 《= 1; end if (count 》= high) begin count 《= count+1’d1; trig《= 0; end if (count == high+low) begin trig 《= 0; count 《= 1‘d0; end end module PosCounter(clk_1m, rst, echo, dis_count); // 检测回波高电平持续时间 input clk_1m, rst, echo; output[15:0] dis_count; parameter S0 = 2’b00, S1 = 2‘b01, S2 = 2’b10; // 状态定义 S0:闲置, S1:开始测距计数, S2:结束测距计数 reg[1:0] curr_state, next_state; reg echo_reg1, echo_reg2; wire start; wire finish; assign start = echo_reg1&~echo_reg2; //检测posedge assign finish = ~echo_reg1&echo_reg2; //检测negedge reg[15:0] count, dis_reg; wire[15:0] dis_count; //测距计数 always@(posedge clk_1m, posedge rst) begin if(!rst) begin echo_reg1 《= 0; echo_reg2 《= 0; count 《= 0; dis_reg 《= 0; curr_state 《= S0; end else begin echo_reg1 《= echo; // 当前 echo_reg2 《= echo_reg1; // 后一个 case(curr_state) S0:begin if (start) // 检测到上升沿 curr_state 《= next_state; //S1 else count 《= 0; end S1:begin if (finish) // 检测到下降沿 curr_state 《= next_state; //S2 else begin count 《= count + 1; end end S2:begin dis_reg 《= count; // 缓存计数结果 count 《= 0; curr_state 《= next_state; //S0 end endcase end end always@(curr_state) begin case(curr_state) S0:next_state 《= S1; S1:next_state 《= S2; S2:next_state 《= S0; endcase end assign dis_count = dis_reg * 100 / 58; // 距离,乘100取小数部分 endmodule ##数码管显示 module cnt2=cnt2+1; end if ((cnt2《=50000000)&&(cnt2》=1)) begin dis 《=16‘b1011101110111011; end else if((cnt2》50000000)&&(cnt2《100000000)) begin dis 《=16’b1010101010101010; end end else if(kaiguan==3‘b010) begin bn 《= an; code_out2 《= code_out; if(!rst) begin cnt 《= 0; end else if(cnt2==100000000) begin cnt2 《=0; end else if(cnt==400000) begin cnt《=0; end else begin cnt=cnt+1; cnt2=cnt2+1; end if ((cnt2《=50000000)&&(cnt2》=1)) begin dis 《=16’b1100110011001100; end else if((cnt2》50000000)&&(cnt2《100000000)) begin dis 《=16‘b1010101010101010; end end else if(kaiguan==3’b100) begin bn 《= an; code_out2 《= code_out; if(!rst) begin cnt 《= 0; end else if(cnt2==100000000) begin cnt2 《=0; end else if(cnt==400000) begin cnt《=0; end else begin cnt=cnt+1; cnt2=cnt2+1; end if ((cnt2《=50000000)&&(cnt2》=1)) begin dis 《=16‘b1101110111011101; end else if((cnt2》50000000)&&(cnt2《100000000)) begin dis 《=16’b1010101010101010; end end else begin bn 《= an; code_out2《=8‘b00111111; if(!rst) begin cnt 《= 0; end else if(cnt==400000) begin cnt《=0; end else begin cnt=cnt+1; dis《=d; end end always @ (posedge clk_1m) if ((1《cnt)&(cnt《=100000)) begin an 《= 4’b0001; case(dis[15:12]) 0 :code_out《= 8‘b00111111; 1 :code_out《= 8’b00000110; 2 :code_out 《=8‘b01011011; 3 : code_out《=8’b01001111; 4 : code_out《=8‘b01100110; 5 : code_out《=8’b01101101; 6 :code_out《= 8‘b01111101; 7 : code_out《=8’b00000111; 8 :code_out《= 8‘b01111111; 9 : code_out《=8’b01101111; 10 : code_out《=8‘b0; 11 : code_out《=8’b00001000; 12 : code_out《=8‘b01000000; 13 : code_out《=8’b00000001; endcase end else if ((100000《cnt)&(cnt《=200000)) begin an《=4‘b0010; case(dis[11:8]) 0 :code_out《= 8’b10111111; 1 :code_out《= 8‘b10000110; 2 :code_out 《=8’b11011011; 3 : code_out《=8‘b11001111; 4 : code_out《=8’b11100110; 5 : code_out《=8‘b01101101; 6 :code_out《= 8’b11111101; 7 : code_out《=8‘b10000111; 8 :code_out《= 8’b11111111; 9 : code_out《=8‘b11101111; 10 : code_out《=8’b0; 11 : code_out《=8‘b00001000; 12 : code_out《=8’b01000000; 13 : code_out《=8‘b00000001; endcase end else if ((200000《cnt)&(cnt《=300000)) begin an《=4’b0100; case(dis[7:4]) 0 :code_out《= 8‘b00111111; 1 :code_out《= 8’b00000110; 2 :code_out 《=8‘b01011011; 3 : code_out《=8’b01001111; 4 : code_out《=8‘b01100110; 5 : code_out《=8’b01101101; 6 :code_out《= 8‘b01111101; 7 : code_out《=8’b00000111; 8 :code_out《= 8‘b01111111; 9 : code_out《=8’b01101111; 10 : code_out《=8‘b0; 11 : code_out《=8’b00001000; 12 : code_out《=8‘b01000000; 13 : code_out《=8’b00000001; endcase end else if ((300000《cnt)&(cnt《400000)) begin an《=4‘b1000; case(dis[3:0]) 0 :code_out《= 8’b00111111; 1 :code_out《= 8‘b00000110; 2 :code_out 《=8’b01011011; 3 : code_out《=8‘b01001111; 4 : code_out《=8’b01100110; 5 : code_out《=8‘b01101101; 6 :code_out《= 8’b01111101; 7 : code_out《=8‘b00000111; 8 :code_out《= 8’b01111111; 9 : code_out《=8‘b01101111; 10 : code_out《=8’b0; 11 : code_out《=8‘b00001000; 12 : code_out《=8’b01000000; 13 : code_out《=8‘b00000001; endcase end always @ (posedge clk_1m) begin if(kaiguan==3’b001) begin high《=60000; end else if(kaiguan==3‘b010) begin high《=150000; end else if(kaiguan==3’b100) begin high《=250000; end else begin if(d》=35) high《=250000; else if(d》=20) high《=150000; else begin fengmingqi《=1; high《=60000; end end if (rst) begin if (count 《high) begin count 《= count+1‘b1; q 《= 1; end if (count 》= high) begin count 《= count+1’b1; q 《= 0; end if (count == high+low) begin q 《= 0; count 《= 1‘b0; end end end always @ ( posedge clk_1m) begin if (!rst) begin cntus 《= 10’d0; cntms 《= 10‘d0; cnts 《= 10’d0; end else if (cntus 《 100 ) cntus 《= cntus + 1‘b1; else cntus《= 6’d1; if(cntms《1000) begin if(cntus==100) cntms 《= cntms + 1‘b1; end else cntms《=10’d0; if(cnts《1000) begin if(cntms==1000) cnts 《= cnts+1‘b1; end else cnts《=0; if(cnt2s《2) begin if(cnts==1000) cnt2s《=cnt2s+1; end else cnt2s《=0; led《=(cnt2s==0)?((cntms《=cnts)?1:0):((cntms《=cnts)?0:1); end |
|
|
|
只有小组成员才能发言,加入小组>>
2434 浏览 0 评论
9099 浏览 4 评论
36771 浏览 19 评论
5025 浏览 0 评论
24743 浏览 34 评论
1527浏览 2评论
1742浏览 1评论
2192浏览 1评论
1552浏览 0评论
523浏览 0评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-22 13:41 , Processed in 1.259219 second(s), Total 75, Slave 59 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号