![]() |
|
||||||||||||||
| . 网站首页 . 新闻 . 新品 . 方案 . 专访 . 活动 . DSP . EDA . 评测室 . 技术文库 . 会员区 . 商城 . 服务导航 . 邮购 . 资源 . | ||
|
||
|
|||||
| FPGA核NIOS全面接触(1) | |||||
作者:Free 文章来源:Free 点击数: 更新时间:2008-1-3 ![]() |
|||||
|
NIOS II的 UART NIOS II的UART 与通用串口兼容,用于可以设置自己的需求通信模式,比如波特率 奇偶校验 停止位 数据位和其他控制信号 主要的寄存器有: txdata,rxdata,status control divisor endof packet,串口要说的东西其实不是很多,但是其确有很多很多的位定义,比如irrdy itrdy等等发送接受传输和错误检测等控制位,这里就不一一列出了,太多了,用的东西在NIOS中看名字大概也能看出来.具体见头文件 #i nclude "altera_avalon_uart_regs.h" 下面是我曾经用过的一个UART通信中断程序 int handle_uart_interrupts(void* context, alt_u32 id) { FILE *uart_file; uart_file=fopen("/dev/uart_0","r+"); if (uart_file == NULL) { printf("can't open uart_device!"); return 0 ; } uart_buf[k++]=IORD_ALTERA_AVALON_UART_RXDATA(UART_0_BASE); if(uart_buf[k-1]=='f') { char search[20] = "s "; uart_buf[k-1]='\0'; k=0; //printf("串口%s ", uart_buf); if (cur_panel.id == 0) { search[0] = 'c'; if (strlen(uart_buf) == 2) { search[2] = '0'; search[3] = '\0'; } } if (strlen(uart_buf) == 6) { search[2] = '9'; search[3] = '\0'; } strcat(search, uart_buf); strcpy(sendbuf, search); } fclose(uart_file); return 0; } 仔细看看上面的程序,并与头文件 #i nclude "altera_avalon_uart_regs.h"中所定义的可用寄存器比较一下会发现,上述写法并不可取,上述程序接受数据是字符的依次读入,其实可以在控制位和发送接受寄存器的配合下,则可以很高效的写出通信程序,而不必像上面那样显得有点"笨". NIOS II的 PIO PIO模块也作为SOPC Builder库中的一个组件,可以是1-32位的并行接口,有多种配置选项,比如输入\输出\双向\触发方式(若用于中断的话) 其相关的寄存器如下: 数据寄存器 data 方向寄存器 direction 中断允许寄存器 interruptmask 边沿捕获寄存器(edgecapture) (RISING.FALLING.ANY) PIO的应用还是比较简单的,一般作为NIOS 与外部电路(还是FPGA内)的接口,比如数据\中断控制等等,下面贴上PIO的一些设置项,同样在system.h头文件中,几乎所有的设置都可以在 system.h和PTF文件中找到原型. #define PIO_NAME "/dev/pio" #define PIO_TYPE "altera_avalon_pio" #define PIO_BASE 0x00001000 #define PIO_SPAN 16 #define PIO_DO_TEST_BENCH_WIRING 0 #define PIO_DRIVEN_SIM_VALUE 0x0000 #define PIO_HAS_TRI 0 #define PIO_HAS_OUT 1 #define PIO_HAS_IN 0 #define PIO_CAPTURE 0 #define PIO_EDGE_TYPE "NONE" #define PIO_IRQ_TYPE "NONE" #define PIO_FREQ 50000000 我想上述各个选项的含义就不多说了,应该很好理解,下面贴一个当时写过的一个PIO中断控制程序,求大家批评. #i nclude "altera_avalon_pio_regs.h" IOWR_ALTERA_AVALON_PIO_IRQ_MASK(BUTTON_PIO_BASE, 0xf); alt_irq_register(BUTTON_PIO_IRQ,edge_capture_ptr,handle_button_interrupts); void handle_button_interrupts() {} 大概好象是这个样子的,不是记得很清楚了,仅供参考 NIOS II 的定时器 如果你对单片机熟悉的话,那么NIOS II的定时器会很简单的理解,并很好的应用.定时器模块是NIOS 开发工具包的一个库组件,其可用于周期脉冲发生器或看门狗定时器.记得当时参加NIOS 竞赛的时候发现很多的资料不仅老,而且少,所以我这里先把一些关键寄存器说一下(想到哪,说到哪,有点乱) NIOS 定时器模块是32位的内部定时器,以下寄存器均为16位. 寄存器名 status 位0 : to位,内部计时器为0时,to 位置1 位1: run位,内部计时器运行时,run位置1,否则0 control 位0: ito 位,如果该位置1,则当状态寄存器的to 位置1(定时器溢出),计时器发出中断请求.若其置0,则不产生中断. 位1: cont 位 内部计时器为0时,,计时器重载preiodl和preiodh,若cont 为1,则定时器连续计时,只有写stop位停止,若cont 为0,则重载初值后,停止计时. 位2: start 见名知意 位3: stop 见名知意 periodl 计数器低16位 periodh 计数器高16位 snapl 计数器捕捉寄存器(读地位状态) snaph 计数器捕捉寄存器(读高位状态) 对nios中的定时器的具体功能设定可以通过SOPC中进行相应勾选 若需要watch dog的话,则在SOPC中选择Timer,在Preset configration选择 watch dog 关于对看门狗的具体设置,则在头文件system.h中加以修改,具体如下: #define WATCH_DOG_NAME "/dev/watch_dog" #define WATCH_DOG_TYPE "altera_avalon_timer" #define WATCH_DOG_BASE 0x00001020 #define WATCH_DOG_SPAN 32 #define WATCH_DOG_IRQ 0 #define WATCH_DOG_ALWAYS_RUN 1 #define WATCH_DOG_FIXED_PERIOD 1 #define WATCH_DOG_SNAPSHOT 0 #define WATCH_DOG_PERIOD 1 #define WATCH_DOG_PERIOD_UNITS "ms" #define WATCH_DOG_RESET_OUTPUT 1 #define WATCH_DOG_TIMEOUT_PULSE_OUTPUT 0 #define WATCH_DOG_MULT 0.001 #define WATCH_DOG_FREQ 50000000 若应用为计时器的话,则关于在NIOS IDE中的具体编程,在头文件 include "altera_avalon_timer_regs.h"中定义了所有的寄存器的地址,通过IOWR IORD等指令可以很方面的进行定时器的设计 /****************************************************************************** * * * ****** Agreement * * * * Copyright (c) 2003 Altera Corporation, San Jose, California, USA. * * All rights reserved. * * * * Permission is hereby granted, free of charge, to any person obtaining a * * copy of this software and associated documentation files (the "Software"), * * to deal in the Software without restriction, including without limitation * * the rights to use, copy, modify, merge, publish, distribute, sub******, * * and/or sell copies of the Software, and to permit persons to whom the * * Software is furnished to do so, subject to the following conditions: * * * * The above copyright notice and this permission notice shall be included in * * all copies or substantial portions of the Software. * * * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * * DEALINGS IN THE SOFTWARE. * * * * This agreement shall be governed in all respects by the laws of the State * * of California and by the laws of the United States of America. * * * ******************************************************************************/ #ifndef __ALTERA_AVALON_TIMER_REGS_H__ #define __ALTERA_AVALON_TIMER_REGS_H__ #i nclude <io.h> /* STATUS register */ #define ALTERA_AVALON_TIMER_STATUS_REG 0 #define IOADDR_ALTERA_AVALON_TIMER_STATUS(base) \ __IO_CALC_ADDRESS_NATIVE(base, ALTERA_AVALON_TIMER_STATUS_REG) #define IORD_ALTERA_AVALON_TIMER_STATUS(base) \ IORD(base, ALTERA_AVALON_TIMER_STATUS_REG) #define IOWR_ALTERA_AVALON_TIMER_STATUS(base, data) \ IOWR(base, ALTERA_AVALON_TIMER_STATUS_REG, data) #define ALTERA_AVALON_TIMER_STATUS_TO_MSK (0x1) #define ALTERA_AVALON_TIMER_STATUS_TO_OFST (0) #define ALTERA_AVALON_TIMER_STATUS_RUN_MSK (0x2) #define ALTERA_AVALON_TIMER_STATUS_RUN_OFST (1) /* CONTROL register */ #define ALTERA_AVALON_TIMER_CONTROL_REG 1 #define IOADDR_ALTERA_AVALON_TIMER_CONTROL(base) \ __IO_CALC_ADDRESS_NATIVE(base, ALTERA_AVALON_TIMER_CONTROL_REG) #define IORD_ALTERA_AVALON_TIMER_CONTROL(base) \ IORD(base, ALTERA_AVALON_TIMER_CONTROL_REG) #define IOWR_ALTERA_AVALON_TIMER_CONTROL(base, data) \ IOWR(base, ALTERA_AVALON_TIMER_CONTROL_REG, data) #define ALTERA_AVALON_TIMER_CONTROL_ITO_MSK (0x1) #define ALTERA_AVALON_TIMER_CONTROL_ITO_OFST (0) #define ALTERA_AVALON_TIMER_CONTROL_CONT_MSK (0x2) #define ALTERA_AVALON_TIMER_CONTROL_CONT_OFST (1) #define ALTERA_AVALON_TIMER_CONTROL_START_MSK (0x4) #define ALTERA_AVALON_TIMER_CONTROL_START_OFST (2) #define ALTERA_AVALON_TIMER_CONTROL_STOP_MSK (0x8) #define ALTERA_AVALON_TIMER_CONTROL_STOP_OFST (3) /* PERIODL register */ #define ALTERA_AVALON_TIMER_PERIODL_REG 2 #define IOADDR_ALTERA_AVALON_TIMER_PERIODL(base) \ __IO_CALC_ADDRESS_NATIVE(base, ALTERA_AVALON_TIMER_PERIODL_REG) #define IORD_ALTERA_AVALON_TIMER_PERIODL(base) \ IORD(base, ALTERA_AVALON_TIMER_PERIODL_REG) #define IOWR_ALTERA_AVALON_TIMER_PERIODL(base, data) \ IOWR(base, ALTERA_AVALON_TIMER_PERIODL_REG, data) #define ALTERA_AVALON_TIMER_PERIODL_MSK (0xFFFF) #define ALTERA_AVALON_TIMER_PERIODL_OFST (0) /* PERIODH register */ #define ALTERA_AVALON_TIMER_PERIODH_REG 3 #define IOADDR_ALTERA_AVALON_TIMER_PERIODH(base) \ __IO_CALC_ADDRESS_NATIVE(base, ALTERA_AVALON_TIMER_PERIODH_REG) #define IORD_ALTERA_AVALON_TIMER_PERIODH(base) \ IORD(base, ALTERA_AVALON_TIMER_PERIODH_REG) #define IOWR_ALTERA_AVALON_TIMER_PERIODH(base, data) \ IOWR(base, ALTERA_AVALON_TIMER_PERIODH_REG, data) #define ALTERA_AVALON_TIMER_PERIODH_MSK (0xFFFF) #define ALTERA_AVALON_TIMER_PERIODH_OFST (0) /* SNAPL register */ #define ALTERA_AVALON_TIMER_SNAPL_REG 4 #define IOADDR_ALTERA_AVALON_TIMER_SNAPL(base) \ __IO_CALC_ADDRESS_NATIVE(base, ALTERA_AVALON_TIMER_SNAPL_REG) #define IORD_ALTERA_AVALON_TIMER_SNAPL(base) \ IORD(base, ALTERA_AVALON_TIMER_SNAPL_REG) #define IOWR_ALTERA_AVALON_TIMER_SNAPL(base, data) \ IOWR(base, ALTERA_AVALON_TIMER_SNAPL_REG, data) #define ALTERA_AVALON_TIMER_SNAPL_MSK (0xFFFF) #define ALTERA_AVALON_TIMER_SNAPL_OFST (0) /* SNAPH register */ #define ALTERA_AVALON_TIMER_SNAPH_REG 5 #define IOADDR_ALTERA_AVALON_TIMER_SNAPH(base) \ __IO_CALC_ADDRESS_NATIVE(base, ALTERA_AVALON_TIMER_SNAPH_REG) #define IORD_ALTERA_AVALON_TIMER_SNAPH(base) \ IORD(base, ALTERA_AVALON_TIMER_SNAPH_REG) #define IOWR_ALTERA_AVALON_TIMER_SNAPH(base, data) \ IOWR(base, ALTERA_AVALON_TIMER_SNAPH_REG, data) #define ALTERA_AVALON_TIMER_SNAPH_MSK (0xFFFF) #define ALTERA_AVALON_TIMER_SNAPH_OFST (0) #endif /* __ALTERA_AVALON_TIMER_REGS_H__ */ NIOS II DMA NIOS DMA同样是Altera SOPC Builder库组件 DMA可用于存储器之间、存储器与外设、外设之间的数据传输,允许没有CPU干预,完成固定长度或者可变长度的数据传输 DMA外设通过两个Avalon主端口(一读一写)和一从端口控制。 典型DMA传递过程如下: 1。通过写控制端口设置DMA的数据传输方式 2。启动DMA外设,实施数据传输(CPU不干预) 3。DMA读传输主端口从目标地址(内存或者外设)读取数据,写端口向目的地址(内存或者外设)写数据。读写之间通过FIFO进行数据缓冲。 4。只指定字节数的数据传输完成或者传输了一个包结束(EOP)时,DMA将结束传输。DMA外设可以在传输结束时发出中断请求。 5。传输当中或者结束后,都可以通过查看DMA的状态寄存器来判断传输在进行还是已经结束 主要寄存器: status 第0位:done 第1位:busy 第2位:reop(读取当前数据包结束) 第3位:weop(写当前数据包结束) 第4位:len(完成一次DMA传输,len置1) readaddress(主读取起始地址),存放的是传输数据的源地址,其宽度由用户在SOPC中自己定义。(与外设匹配) writeaddress(主写入起始地址),与上类似 length ,存放读写端口之间需要传输的字节数,长度寄存器宽度由系统生成时的设置决定,DMA每完成一次写传输,length寄存器值减一,当减为0时,len位使能。其寄存器的值按照字节数计算,双字传输,必须是4的倍数,字的传输,当然是2的倍数啦!! control 寄存器: 位0: byte 字节传输 位1: hw 字传输 位2: word 双字传输 位3: go DMA 使能 位4: i_en 中断使能 位5:reen 读数据包使能 位6:ween写数据包使能 位7:leen ,置1时,DMA在传输完length数目数据的时候结束传输(已经知道传输数据量),若设置0,则不会停止,使用于数据量不确定的场合。 位8:rcon 从固定地址读取 位9:wcon 从固定地址写入 读数据的地址每次访问递增 当done&&i_en == 1时候,dma向外设发出中断请求,典型的中断处理程序首先读取状态寄存器的len,reop,weop位来判断中断原因。然后,写转台寄存器清除中断,处理后,进行下一次DMA传输。 |
|||||
| 欢迎点击进入:TI德州中文网 (国内唯一针对TI应用的中文技术网站) 文章录入:admin 责任编辑:admin | |||||
| 【发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口】 | |||||
| 最新热点 | 最新推荐 | 相关文章 | ||
| FFT实现的参考文献 FPGA核NIOS全面接触(2) Quartus II 7.2正式版和crac… 一种用VHDL语言实现的帧同步… 二进制格雷码与自然二进制码… HDL其他相关资料 HDL软件培训资料 Verilog HDL参考资料 VHDL语法参考资料 其他设计举例:布斯乘法器 |
| 网友评论:(只显示最新10条。评论内容只代表网友观点,与本站立场无关!) |
| | 设为首页 | 加入收藏 | 联系站长 | 友情链接 | 版权申明 | 网站公告 | 管理登录 | | |||
|
|