avalon总线与接口Word格式文档下载.docx
- 文档编号:4698059
- 上传时间:2023-05-03
- 格式:DOCX
- 页数:23
- 大小:485.46KB
avalon总线与接口Word格式文档下载.docx
《avalon总线与接口Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《avalon总线与接口Word格式文档下载.docx(23页珍藏版)》请在冰点文库上搜索。
此外,程序中还包括一个PWM_out信号,这个信号是PWM输出,不属于Avalon接口信号。
PWM内部还包括使能控制寄存器、周期设定寄存器以及占空比设置寄存器。
设计中将各寄存器映射成AvalonSlave端口地址空间内一个单独的偏移地址。
没个寄存器都可以进行读写访问,软件可以读回寄存器中的当前值。
寄存器及偏移地址如下:
寄存器名
偏移量
访问属性
clock_divide_reg
00
读/写
设定PWM输出周期的时钟数
duty_cycle_reg
01
设定一个周期内PWM输出低电平的始终个数
control_reg
10
使能和关闭PWM输出,为1时使能PWM输出
程序如下:
viewsource
print?
001
modulePWM(
002
clk,
003
reset_n,
004
chipselect,
005
address,
006
write,
007
writedata,
008
read,
009
byteenable,
010
readdata,
011
PWM_out);
012
013
inputclk;
014
inputreset_n;
015
inputchipselect;
016
input[1:
0]address;
017
inputwrite;
018
input[31:
0]writedata;
019
inputread;
020
input[3:
0]byteenable;
021
output[31:
0]readdata;
022
outputPWM_out;
023
024
reg[31:
0]clock_divide_reg;
025
0]duty_cycle_reg;
026
regcontrol_reg;
027
regclock_divide_reg_selected;
028
regduty_cycle_reg_selected;
029
regcontrol_reg_selected;
030
0]PWM_counter;
031
032
regPWM_out;
033
wirepwm_enable;
034
035
//地址译码
036
always@(address)
037
begin
038
clock_divide_reg_selected<
=0;
039
duty_cycle_reg_selected<
040
control_reg_selected<
041
case(address)
042
2'
b00:
clock_divide_reg_selected<
=1;
043
b01:
duty_cycle_reg_selected<
044
b10:
control_reg_selected<
045
default:
046
begin
047
048
049
050
end
051
endcase
052
end
053
054
//写PWM输出周期的时钟数寄存器
055
always@(posedgeclkornegedgereset_n)
056
057
if(reset_n==1'
b0)
058
clock_divide_reg=0;
059
else
060
061
if(write&
chipselect&
clock_divide_reg_selected)
062
063
if(byteenable[0])
064
clock_divide_reg[7:
0]=writedata[7:
0];
065
if(byteenable[1])
066
clock_divide_reg[15:
8]=writedata[15:
8];
067
if(byteenable[2])
068
clock_divide_reg[23:
16]=writedata[23:
16];
069
if(byteenable[3])
070
clock_divide_reg[31:
24]=writedata[31:
24];
071
072
073
end
074
075
//写PWM周期占空比寄存器
076
077
078
079
duty_cycle_reg=0;
080
081
082
duty_cycle_reg_selected)
083
084
085
duty_cycle_reg[7:
086
087
duty_cycle_reg[15:
088
089
duty_cycle_reg[23:
090
091
duty_cycle_reg[31:
092
093
094
095
096
//写控制寄存器
097
098
099
100
control_reg=0;
101
102
103
control_reg_selected)
104
105
106
control_reg=writedata[0];
107
108
109
110
111
//读寄存器
112
always@(addressorreadorclock_divide_regorduty_cycle_regorcontrol_regorchipselect)
113
114
if(read&
chipselect)
115
116
readdata<
=clock_divide_reg;
117
=duty_cycle_reg;
118
=control_reg;
119
readdata=32'
h8888;
120
endcase
121
122
123
//控制寄存器
124
assignpwm_enable=control_reg;
125
126
//PWM功能部分
127
128
129
130
PWM_counter=0;
131
132
133
if(pwm_enable)
134
135
if(PWM_counter>
=clock_divide_reg)
136
PWM_counter<
137
138
=PWM_counter+1;
139
140
141
142
143
144
145
146
147
148
PWM_out<
=1'
b0;
149
150
151
152
153
if(PWM_counter<
=duty_cycle_reg)
154
b1;
155
156
157
158
159
160
161
162
163
endmodule
上面的程序保存好以后,命名为PWM.v,并将其存放到工程目录下。
硬件设置
接下来,我们就通过SOPCBuilder,来建立PWM模块了。
首先,打开Quartus软件,进入SOPCBuilder。
进入后,点击下图红圈处
点击后,如下图所示,点击Next,
点击后,如下图所示,点击下图红圈处,将我们刚才建立的PWM.v加进来。
(我将PWM。
v放到了工程目录下的pwm文件夹下)
加入后,系统会对PWM.v文件进行分析,如下图所示,出现红圈处的文字,说明分析成功,点击close,关闭对话框。
然后点击Next,如下图所示,通过下图,我们可以看到,PWM.v中的信号都出现在这里面了。
我们可以根据我们的功能要求来配置这些信号,其中,Interface是Avalon接口类型,它包括Avalon-MM、Avalon-ST、AvalonMemoryMappedTristateInterface等等。
SignalType指的是各个Avalon接口类型下的信号类型。
PWM.v中的信号我们已经在前面都介绍过了,大家按照上面的要求设置就可以了。
默认情况只有PWM_out需要改动,如下图示红圈处设置,
其中,Interface在下拉菜单中选择下图红圈处所示的选项。
上面的选项都设置好以后,点击Next,如下图所示,我们通过下图红圈处的下拉条向下拉
拉到下图所示位置停止,我们将红圈处的改选为NATIVE,这个地方就是地址对齐的选项,我们选择为静态地址对齐。
其他的地方都默认,不需要改动。
这里面还有很多选项,其中Timing部分需要说明一下,PWM的AvalonSlave端口与AvalonSlave端口时钟信号同步,读/写时的建立很保持时间为0,因为读、写寄存器仅需要一个时钟周期,所以读/写时为0等待切不需要读延时。
接着点击Next,如下图所示,其中红圈处需要注意,这个地方需要可以建立新组,然后在SOPCBuilder中体现出来。
点击Finish后,会出现下面的对话框,点击Yes,就会生成一个PWM_hw.tcl脚本文件,大家可以打开看一下,里面放置的是刚才我们配置PWM时候的配置信息。
上面都完成以后,我们回到了SOPCBuilder界面,我们在左侧边栏中可以找到下图所示的红圈处
大家看到了吧,MyIP就是我们刚才建立的group。
双击PWM,我们建立PWM模块,如下图
点击Finish,完成建立。
这里还需要设置一步,点击下图红圈处
点击后,如下图所示,点击IPSerarchPath,然后点击Add,添加PWM.v所在位置的路径
添加后,如下图所示
点击Finish完成。
设置这个选项是为了让SOPCBuilder可以找到PWM.v的位置。
不然就会出现下次你进入SOPCBuilder的时候PWM模块无效的问题。
接下来的工作就是自动分配地址,分配中断,编译,等待......
编译好以后,我们回到Quartus软件界面,我们可以看到,PWM出现了,我将它接到了一个LED上了,我们可以通过PWM改变LED的亮度,实现LED渐亮渐灭的过程。
接下来又是编译,等待.....
做好硬件部分工作以后,我们打开NIOSIDE,开始软件编程部分。
软件开发
首先对工程重新编译一次,Ctril+B,等待......
编译好以后,我们来看一下system.h的变化情况,我们可以发现,多出来PWM部分了。
下面是PWM测试代码,
#include<
unistd.h>
02
#include"
system.h"
03
04
//根据寄存器的偏移量,我们定义一个结构体PWM
05
typedefstruct{
06
volatileunsignedintdivi;
07
volatileunsignedintduty;
08
volatileunsignedintenable;
09
}PWM;
11
intmain()
12
{
13
intdir=1;
14
15
//将pwm指向PWM_0_BASE首地址
16
PWM*pwm=(PWM*)PWM_0_BASE;
17
//对pwm进行初始化,divi最大值为232-1。
18
pwm->
divi=1000;
19
duty=0;
20
enable=1;
21
22
//通过不断的改变duty值来改变LED一个周期亮灯的时间长短
23
while
(1){
24
if(dir>
0){
25
if(pwm->
duty<
divi)
26
duty+=100;
27
28
dir=0;
29
}
30
else{
31
duty>
0)
duty-=100;
33
34
dir=1;
35
36
37
usleep(100000);
38
39
40
return0;
41
}
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- avalon 总线 接口