网站公告列表

  没有公告

加入收藏
设为首页
联系站长
您现在的位置: 61IC中国电子在线 >> EDA >> Altera >> 文章正文
  FPGA核NIOS全面接触(1)           ★★★ 【字体:
FPGA核NIOS全面接触(1)
作者:Free    文章来源:Free    点击数:    更新时间:2008-1-3    

NIOS II UART

NIOS IIUART 与通用串口兼容,用于可以设置自己的需求通信模式,比如波特率 奇偶校验 停止位 数据位和其他控制信号

主要的寄存器有: 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.hPTF文件中找到原型.

 

#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,,计时器重载preiodlpreiodh,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 从固定地址写入

读数据的地址每次访问递增1.2.4个字节,具体是几取决去传输的是字节、字、或者半字,若rcon置1,则地址不递增。

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条。评论内容只代表网友观点,与本站立场无关!)
    站长:61IC 湘ICP备05002478号