跟着视频慢慢的学习,现在学习到蜂鸣器篇。
蜂鸣器的作业:
程序如下:
module fmq(clk,rst,beep);
input clk;
input rst;
output beep;
reg beep;
reg[24:0] divcnt;
reg[15:0] delay_cnt;
wire[15:0] delay_end;
parameter driver0=16320;
parameter driver1=8192;//警车的声音
/*parameter driver0=8333;
parameter driver1=3333;*/ //消防车的声音
assign delay_end=divcnt[24] ? driver0:driver1;
always @(posedge clk or negedge rst)
begin
if(!rst)
divcnt<=25'd0;
else
divcnt<=divcnt+1'b1;
end
always @ (posedge clk or negedge rst)
begin
if(!rst)
begin
beep<=1'b0;
delay_cnt<=delay_end;
end
else if(delay_cnt==16'd0)
begin
beep<=~beep;
delay_cnt<=delay_end;
end
else
delay_cnt<=delay_cnt-1'b1;
end
endmodule
由于当时听完数码管的动态显示没有明白数码管的扫描显示,导致现在才完成动态显示的课后作业,这个程序是产生60秒的计数器,每过1秒数码管显示的数自动加1。明白了这个原理之后就可以做个基于CPLD的时钟显示的设计。程序如下,
module smg(sys_clk,sys_rstn,sm_seg,sm_bit);
input sys_clk;
input sys_rstn;
output [8:1]sm_seg;
output [8:1]sm_bit;
reg [8:1]sm_seg;
reg [8:1]sm_bit;
reg [1:0]diap_dat;
reg [9:0]num;
reg[3:0]gwei;
reg[2:0]swei;
reg [4:0]dataout_buf;
reg [15:0]delay_cnt;
always @(posedge sys_clk or negedge sys_rstn)
begin
if(!sys_rstn)
delay_cnt<=16'd0;
else if(delay_cnt==16'd49999)
delay_cnt<=16'd0;
else
delay_cnt<=delay_cnt+1'b1;
end
always @(posedge sys_clk or negedge sys_rstn)
begin
if(!sys_rstn)
begin
num<=10'd0;
diap_dat<=2'd0;
end
else if(delay_cnt==16'd49999)
begin
diap_dat<=diap_dat+1'b1;
num<=num+1'b1;
if(diap_dat>=2'd2)
diap_dat<=2'd0;
if(num>10'd999)
begin
gwei<=gwei+1'b1;
if(gwei>=4'b1001)
begin
gwei<=4'b0000;
swei<=swei+1'b1;
if(swei>=3'b101)
begin
gwei<=4'b0000;
swei<=3'b000;
end
end
num<=10'd0;
end
end
else
diap_dat<=diap_dat;
end
always @(diap_dat)
begin
case(diap_dat)
2'b00 : sm_bit=8'b11111110;
2'b01 : sm_bit=8'b11111101;
default :
sm_bit=8'b11111110;
endcase
end
always@(sm_bit)
begin
case(sm_bit)
8'b11111110 : dataout_buf<=gwei;
8'b11111101 : dataout_buf<=swei;
endcase
end
always @(dataout_buf)
begin
case(dataout_buf)
4'h0:sm_seg=8'hc0; //"0"
4'h1:sm_seg=8'hf9; //"1"
4'h2:sm_seg=8'ha4; //"2"
4'h3:sm_seg=8'hb0; //"3"
4'h4:sm_seg=8'h99; //"4"
4'h5:sm_seg=8'h92; //"5"
4'h6:sm_seg=8'h82; //"6"
4'h7:sm_seg=8'hf8; //"7"
4'h8:sm_seg=8'h80; //"8"
4'h9:sm_seg=8'h90; //"9"
4'ha:sm_seg=8'h88; //"a"
4'hb:sm_seg=8'h83; //"b"
4'hc:sm_seg=8'hc6; //"c"
4'hd:sm_seg=8'ha1; //"d"
4'he:sm_seg=8'h86; //"e"
4'hf:sm_seg=8'h8e; //"f"
default:
sm_seg=8'hc0;
endcase
end
endmodule
本实验为利用CPLD来产生2KHZ的波形,并利用key1,key2,key3来选择25%,75%,40%,50%的占空比。利用这些不同的占空比可以用来控制电机。由于实验室条件的限制,只能用示波器来观察波形。附件里面是关于波形产生的实验结果。
module pwm(sys_clk,sys_rst,button,wave);
//端口配置input sys_clk;
input sys_rst;
input[3:1]button;
output wave;
//参数配置
wire [3:1] button;
reg [14:0] delay_cnt;
reg [13:0] duty;
reg wave;
always @(posedge sys_clk or negedge sys_rst)
begin
if(!sys_rst)
delay_cnt<=15'd0;
else if(delay_cnt==15'd24999) //产生2000HZ的波形
delay_cnt<=15'd0;
else
delay_cnt<=delay_cnt+1'b1;
end
always @(posedge sys_clk or negedge sys_rst)
begin
case(button)
3'b111:duty<=14'd12499; //占空比为50%;
3'b110:duty<=14'd6250; //占空比为25%;
3'b101:duty<=14'd1875; //占空比为75%;
3'b011:duty<=14'd10000; //占空比为40%;
default :duty<=14'd12499;
endcaseif(!sys_rst)
duty<=14'd12499;
else if(delay_cnt
wave<=1'b1;
else
wave<=1'b0;
end
endmodule
今天调了uart程序,本实验采用波特率为14400bps。发送的数据帧格式为:1bit起始位(从高电平到低电平保持一个bit周期),8bit数据,1bit停止位,无校验位。
波特率设置模块如下:
`timescale 1ns / 1ps
module baud(sys_clk,sys_rstn,bps_start,clk_bps);
input sys_clk;
input sys_rstn;
input bps_start;
output clk_bps;
`define BPS_PARA 5207
`define BPS_PARA_2 2603
reg[12:0] cnt;
reg clk_bps_r;
always @ (posedge sys_clk or negedge sys_rstn)
begin
if(!sys_rstn)
cnt <= 13'd0;
else if((cnt == `BPS_PARA) || !bps_start)
cnt <= 13'd0;
else
cnt <= cnt+1'b1;
end
always @ (posedge sys_clk or negedge sys_rstn)
begin
if(!sys_rstn)
clk_bps_r <= 1'b0;
else if(cnt == `BPS_PARA_2)
clk_bps_r <= 1'b1;
else
clk_bps_r <= 1'b0;
end
assign clk_bps = clk_bps_r;
endmodule
下面是调试UART时的收发的实验现象VID_20131102_231849.rar
对于PS/2键盘来说,可通过扫描编码来识别按键输入。扫描编码与物理按键相关联。当按下键盘时,Make扫描编码被发送到PS/2 接口;当释放按键时,Break扫描编码被发送到PS/2接口。 对所有的字母和数字来说,Make扫描编码是一个单字节,而其Break扫描编码则是在相同的单字节前面加上F0。 键盘中的扫描编码和键值的ASCII码没有任何联系。对于字母的大小写形式对应不同的ASCII码。而在键盘上区分大小写输入,必须使用【Shift】或【CAPSLOCK】键。
PS2模块程序如下:
module ps_keyboard(sys_clk,sys_rst,PS2C,PS2D,xkey);
input sys_clk;
input sys_rst;
input PS2C;
input PS2D;
output [15:0] xkey;
reg PS2Cf,PS2Df;
reg[7:0]ps2c_filter,ps2d_filter;
reg[10:0]shift1,shift2;
assign xkey={shift2[8:1],shift1[8:1]};
always @(posedge sys_clk or negedge sys_rst)
begin
if(!sys_rst)
begin
ps2c_filter<=0;
ps2d_filter<=0;
PS2Cf<=1;
PS2Df<=1;
end
else
begin
ps2c_filter[7]<=PS2C;
ps2c_filter[6:0]<=ps2c_filter[7:1];
ps2d_filter[7]<=PS2D;
ps2d_filter[6:0]<=ps2d_filter[7:1];
if(ps2c_filter==8'b11111111)
PS2Cf<=1;
else if(ps2c_filter==8'b00000000)
PS2Cf<=0;
if(ps2d_filter==8'b11111111)
PS2Df<=1;
else if(ps2d_filter==8'b00000000)
PS2Df<=0;
end
end
always@(negedge PS2Cf or negedge sys_rst)
begin
if(!sys_rst)
begin
shift1<=0;
shift2<=1;
end
else
begin
shift1<={PS2Df,shift1[10:0]};
shift2<={shift1[0],shift2[10:1]};
end
end
endmodule
这一段时间忙着调试lcd1602,1602液晶模块内部的字符发生存储器(CGROM)已经存储了160个不同的点阵字符图形,这些字符有:阿拉伯数字、英文字母的大小写、常用的符号、和日文假名等,每一个字符都有一个固定的代码,比如大写的英文字母“A”的代码是01000001B(41H),显示时模块把地址41H中的点阵字符图形显示出来,我们就能看到字母“A”。
1602的指令集:
1602通过D0~D7的8位数据端传输数据和指令。
显示模式设置: (初始化)
0011 0000 [0x38] 设置16×2显示,5×7点阵,8位数据接口;
显示开关及光标设置: (初始化)
0000 1DCB D显示(1有效)、C光标显示(1有效)、B光标闪烁(1有效)
0000 01NS N=1(读或写一个字符后地址指针加1 &光标加1),
N=0(读或写一个字符后地址指针减1 &光标减1),
S=1 且 N=1 (当写一个字符后,整屏显示左移)
s=0 当写一个字符后,整屏显示不移动
数据指针设置:
数据首地址为80H,所以数据地址为80H+地址码(0-27H,40-67H)
其他设置:
01H(显示清屏,数据指针=0,所有显示=0);02H(显示回车,数据指针=0)。
lcd1602的模块例程:
回复
有奖活动 | |
---|---|
【有奖活动】分享技术经验,兑换京东卡 | |
话不多说,快进群! | |
请大声喊出:我要开发板! | |
【有奖活动】EEPW网站征稿正在进行时,欢迎踊跃投稿啦 | |
奖!发布技术笔记,技术评测贴换取您心仪的礼品 | |
打赏了!打赏了!打赏了! |