项目介绍
使用WebIDE的图形化编程,使用常规的74系列元器件,构建交通灯控制系统:
1、在数码管上显示计时信息-图形化
2、蜂鸣器报警-图形化
3、接近传感器检测人员走进-Verilog
4、环境光感知,自动点亮路灯(小脚丫核心板上的单色LED)-Verilog
硬件资源介绍
本次项目使用苏州思德普信息科技公司的STEP-MXO2-LPC及其扩展板,只需要一根Type C数据线和电脑相连,就可以完成供电和编程功能,免去其他仿真器。采用U盘方式下载程序,当数据线与PC端相连时,PC端自动弹出烧录程序的磁盘,此时将生成的JED文件拷贝到StepFPGA盘即可完成烧录。STEP-MXO2-LPC及其扩展板的外设资源如图1,图2所示。
本项目所使用到的硬件资源有STEP-MXO2-LPC板的2个数码管、2个三色LED、8个单色LED和1个按键;STEP-Baseboard-V4.0扩展板的环境光和接近传感器、蜂鸣器和由74HC595驱动的数码管。
图1 STEP-MXO2-LPC核心板资源图 |
图2 STEP-Baseboard-V4.0扩展板 |
环境光和接近传感器:
接近传感器 (PS)通过对IrLED发射光线的接近物产生的反射光,检测出人及物体的接近;照度传感器(ALS)可测量从昏暗光线到直射日光的广泛照度。该传感器在STEP-Baseboard-V4.0扩展板中通过IIC总线与STEP-MXO2-LPC核心板相连,如图3所示。
图3 环境光和接近传感器 |
74HC595是一款8 位串行输入/串行输出或并行输出移位寄存器,该器件集成了一个 8 位移位寄存器和一个8位D型存储寄存器。当输出使能输入 (OE) 保持在低电平时,存储寄存器中的数据将出现在输出端。当OE保持在高电平时,所有并行输出都处于高阻抗状态。在STEP-Baseboard-V4.0扩展板中通过2片级联实现对8个8段数码管实现控制。如图4所示。595_DIN为串行数据输入引脚,595_SCK引脚上升沿时移位寄存器数据整体后移,595_RCK上升沿时,数据从移位寄存器转移到存储寄存器。
图4 74HC595驱动数码管电路图 |
方案框图和设计思路
项目为2部分实现,红绿灯倒计时部分与环境光感知和检测人员走近部分。
图5 红绿灯倒计时部分方案框图 |
红绿灯倒计时部分方案框图如图5所示。交通灯主路上绿灯持续15s的时间,黄灯3s的时间,红灯10s的时间;交通灯支路上绿灯持续7s的时间,黄灯持续3秒的时间,红灯18秒的时间;当交通信号灯的状态发生改变时,通过蜂鸣器辅助提示。
环境光感知和检测人员走近方案框图如图6所示。通过传感器检测亮度并显示在扩展板数码管,当亮度小于一定值时,由板载单色LED代替路灯亮起;当有物体靠近时,蜂鸣器提示报警。
图6 环境光感知和检测人员走近方案框图 |
软件流程图和关键代码介绍
软件流程图如图7所示。红绿灯倒计时部分,使用2个时钟分频器,一个用来提供蜂鸣器的驱动,另一个定时1s用来判断红绿灯的状态转移。通过状态机实现,此状态机共有4种状态,状态1:主路绿灯15s,支路红灯15s;状态2:主路黄灯3秒,支路红灯3s;状态3:主路红灯7s,支路绿灯7s;状态4:主路红灯3s,支路黄灯3s。每次状态转移完成后,驱动声光显示部分,蜂鸣器响1s,通过控制IO口的电平状态控制LED的颜色,并将寄存器内的数据进行BCD转码显示到数码管上,完成整个流程。
环境光感知和检测人员走近部分,通过IIC协议读取传感器的数据,进行量化处理,将量化后的数据进行BCD转码驱动74HC5954芯片显示并设定阈值判断蜂鸣器和路灯。当光照度过小时,路灯亮起;有物体或人靠近则蜂鸣器响起。
图7 软件流程图 |
图8 WebIDE实现红绿灯倒计时部分 |
红绿灯倒计时部分采用WebIDE实现,如图8所示,此部分完全使用自定义模块实现,下面展示图形化和状态机部分。
divide模块为红绿灯定时分频,state为状态转移模块,ge_shi为BCD转码模块,seg为核心板数码管显示模块,beep为蜂鸣器驱动模块。
状态机模块代码:
wire clk1;
wire rst_n;
reg beep_en;
reg [7:0]timecont;
localparam red = 3'b011;
localparam green = 3'b101;
localparam yellow = 3'b001;
localparam S1 = 4'b1000;
localparam S2 = 4'b0100;
localparam S3 = 4'b0010;
localparam S4 = 4'b0001;
reg[5:0] rgbout;
reg[3:0] state;
reg [7:0]cnt_ge ;
reg [7:0]cnt_shi ;
wire [7:0]cont;
always@(posedge clk1 or negedge rst_n)
begin
if(rst_n == 0)
begin
timecont<=0;
state <= S1;
rgbout<={red,green};
end
else if(timecont==0)
begin
if(state==S1)
begin
timecont<=15;
state <= S2;
beep_en <= 1'b1;
rgbout<={red,green};//红绿
end
else if(state==S2)
begin
timecont<=3;
state <= S3;
beep_en <= 1'b1;
rgbout<={red,yellow};//红黄
end
else if(state==S3)
begin
timecont<=7;
state <= S4;
beep_en <= 1'b1;
rgbout<={green,red};//绿红
end
else if(state==S4)
begin
timecont<=3;
state <= S1;
beep_en <= 1'b1;
rgbout<={yellow,red};//黄红
end
end
else
begin
beep_en <= 1'b0;
timecont <= timecont -1;
end
end
assign cont[7:0] = timecont[7:0];
环境光感知和检测人员走近部分在lattice diamond中使用verilog实现。下面展示最顶层设计部分代码
module prox_detect(
input clk,
input rst_n,
output i2c_scl, //I2C时钟总线
inout i2c_sda, //I2C数据总线
output seg_rck, // 74HC595的RCK管脚
output seg_sck, // 74HC595的SCK管脚
output seg_din, // 74HC595的SER管脚
output [7:0] led, //led灯
output beep_out
);
wire dat_valid;
wire [15:0] ch0_dat, ch1_dat, prox_dat;
wire [31:0] lux_data;
rpr0521rs_driver u1(
.clk (clk ), //系统时钟
.rst_n (rst_n ), //系统复位,低有效
.i2c_scl (i2c_scl ), //I2C总线SCL
.i2c_sda (i2c_sda ), //I2C总线SDA
.dat_valid (dat_valid ), //数据有效脉冲
.ch0_dat (ch0_dat ), //ALS数据
.ch1_dat (ch1_dat ), //IR数据
.prox_dat (prox_dat ) //Prox数据
);
wire beep_en;
wire [31:0] JJ_dat;
decoder u2(
.rst_n (rst_n),
.dat_valid (dat_valid ),
.ch0_dat (ch0_dat ),
.ch1_dat (ch1_dat ),
.JJ_dat(JJ_dat),
.prox_dat (prox_dat ),
.lux_data (lux_data ),
.beep_en(beep_en)
);
//进行BCD转码处理
wire [3:0] transcode1;
wire [3:0] transcode2;
wire [3:0] transcode3;
wire [3:0] transcode4;
wire [3:0] transcode5;
wire [3:0] transcode6;
wire [3:0] transcode7;
wire [3:0] transcode8;
bin_to_bcd u3
(
.rst_n (rst_n ), //系统复位,低有效
.code (lux_data ), //显示照度
.transcode1 (transcode1 ), //转码后的BCD码型数据输出
.transcode2 (transcode2 ), //转码后的BCD码型数据输出
.transcode3 (transcode3 ), //转码后的BCD码型数据输出
.transcode4 (transcode4 ), //转码后的BCD码型数据输出
.transcode5 (transcode5 ), //转码后的BCD码型数据输出
.transcode6 (transcode6 ), //转码后的BCD码型数据输出
.transcode7 (transcode7 ), //转码后的BCD码型数据输出
.transcode8 (transcode8) //转码后的BCD码型数据输出
);
segment_scan u4(
.clk(clk), //系统时钟 12MHz
.rst_n(rst_n), //系统复位 低有效
.dat_1(transcode1 ), //SEG1 显示的数据输入
.dat_2(transcode2 ), //SEG2 显示的数据输入
.dat_3(transcode3 ), //SEG3 显示的数据输入
.dat_4(transcode4 ), //SEG4 显示的数据输入
.dat_5(transcode5 ), //SEG5 显示的数据输入
.dat_6(transcode6 ), //SEG6 显示的数据输入
.dat_7(transcode7 ), //SEG7 显示的数据输入
.dat_8(transcode8 ), //SEG8 显示的数据输入
.seg_rck(seg_rck ), //74HC595的RCK管脚
.seg_sck(seg_sck ), //74HC595的SCK管脚
.seg_din(seg_din ) //74HC595的SER管脚
);
beep u5(
.clk(clk),
.rst_n(rst_n),
.beep_en(beep_en),
.beep_out(beep_out)
);
led u6(
.rst_n(rst_n),
.transcode1(transcode1),
.transcode2(transcode2),
.transcode3(transcode3),
.transcode4(transcode4),
.transcode5(transcode5),
.transcode6(transcode6),
.transcode7(transcode7),
.transcode8(transcode8),
.Y_out(led)
);
endmodule
功能展示图及说明
图9 路灯未开启 |
图10 路灯开启 |
图11 交通灯倒计时 |
逻辑资源使用情况
红绿灯倒计时部分:
Design Summary:
Number of registers: 68 out of 4635 (1%)
PFU registers: 68 out of 4320 (2%)
PIO registers: 0 out of 315 (0%)
Number of SLICEs: 80 out of 2160 (4%)
SLICEs as Logic/ROM: 80 out of 2160 (4%)
SLICEs as RAM: 0 out of 1620 (0%)
SLICEs as Carry: 31 out of 2160 (1%)
Number of LUT4s: 160 out of 4320 (4%)
Number used as logic LUTs: 98
Number used as distributed RAM: 0
Number used as ripple logic: 62
Number used as shift registers: 0
Number of PIO sites used: 27 + 4(JTAG) out of 105 (30%)
Number of block RAMs: 0 out of 10 (0%)
Number of GSRs: 1 out of 1 (100%)
EFB used : No
JTAG used : No
Readback used : No
Oscillator used : No
Startup used : No
POR : On
Bandgap : On
Number of Power Controller: 0 out of 1 (0%)
Number of Dynamic Bank Controller (BCINRD): 0 out of 6 (0%)
Number of Dynamic Bank Controller (BCLVDSO): 0 out of 1 (0%)
Number of DCCA: 0 out of 8 (0%)
Number of DCMA: 0 out of 2 (0%)
Number of PLLs: 0 out of 2 (0%)
Number of DQSDLLs: 0 out of 2 (0%)
Number of CLKDIVC: 0 out of 4 (0%)
Number of ECLKSYNCA: 0 out of 4 (0%)
Number of ECLKBRIDGECS: 0 out of 2 (0%)
环境光感知和检测人员走近部分
Design Summary
Number of registers: 577 out of 4635 (12%)
PFU registers: 572 out of 4320 (13%)
PIO registers: 5 out of 315 (2%)
Number of SLICEs: 1258 out of 2160 (58%)
SLICEs as Logic/ROM: 1258 out of 2160 (58%)
SLICEs as RAM: 0 out of 1620 (0%)
SLICEs as Carry: 509 out of 2160 (24%)
Number of LUT4s: 2516 out of 4320 (58%)
Number used as logic LUTs: 1498
Number used as distributed RAM: 0
Number used as ripple logic: 1018
Number used as shift registers: 0
Number of PIO sites used: 16 + 4(JTAG) out of 105 (19%)
Number of block RAMs: 0 out of 10 (0%)
Number of GSRs: 1 out of 1 (100%)
EFB used : No
JTAG used : No
Readback used : No
Oscillator used : No
Startup used : No
POR : On
Bandgap : On
Number of Power Controller: 0 out of 1 (0%)
Number of Dynamic Bank Controller (BCINRD): 0 out of 6 (0%)
Number of Dynamic Bank Controller (BCLVDSO): 0 out of 1 (0%)
Number of DCCA: 0 out of 8 (0%)
Number of DCMA: 0 out of 2 (0%)
Number of PLLs: 0 out of 2 (0%)
Number of DQSDLLs: 0 out of 2 (0%)
Number of CLKDIVC: 0 out of 4 (0%)
Number of ECLKSYNCA: 0 out of 4 (0%)
Number of ECLKBRIDGECS: 0 out of 2 (0%)
项目中遇到的难题和解决方法
在设计红绿灯倒计时部分时,采用取余和除法的方式取出数据的十位和百位出现显示错误的问题,之后将取余和除法的方式改为转换BCD码后再进行显示,问题解决。
对本次活动的心得体会(包括意见或建议)
WebIDE功能让我对FPGA这种类似搭积木的设计方式有了更深入的理解,每一个自定义模块就是一块单独的数字电路,比如分频器,更好的理解FPGA的并行执行方式与MCU顺序执行的控制过程不同点。