zoukankan      html  css  js  c++  java
  • 实验:PIO外部中断

     转自:http://www.cnblogs.com/chentuo/articles/1427402.html

     

    实验:PIO外部中断

    AuthorChen Tuo

    Copyright © Chen Tuo, 2008-2009. All rights reserved.

    200831日创建

    2009326日修改

    1.      实验目的

    熟悉NiosII PIO设备的访问方法。学习边沿触发中断。

    2.      实验设备

    硬件:PC机,EP1C3EP1C12核心板,MyEpx3实验版。

    软件:Quartus II 7.2MagaCore 7.2Nios II IDE 7.2

    3.      实验内容

    用一个按键控制一个LED灯显示。

    4.      实验预习要求

    熟悉PIO外设的访问和控制和PIO的中断控制机制。

    5.      实验步骤

    (1)    创建一个Quartus II项目PIOEINT

    (2)    如下图,定制一个Nios II CPU,命名为myniosii

    其中:

    l         onchip_mem8K。启动向量和异常向量配置如下:

    l         KEY_PIO1位输入,如下图设置为下降沿触发中断。

    l         LED_PIO1位输出。

    (3)    Quartus II中创建一个原理图,放置一个上面定制好的Nios IImyniosii,并如图设置引脚。编译、下载硬件配置到FPGA

    (4)    启动Nios II IDE,新建一个空白Nios II C/C++ Application项目,并命名为pio_eint

    (5)    pio_eint项目中添加一个C文件pio_eint.c

    (6)    设置pio_eint项目Properties属性,对该项目的代码编译进行优化:

    C/C++ Build > Tool Settings > General > Optimize size (-Os)

    (7)    设置pio_eint_syslib项目Properties属性,对该项目的代码编译进行优化:

    a)       C/C++ Build > Tool Settings > General > Optimize size (-Os)

    b)      System library属性页面,清除Support C++Clean exit (flush buffers);选上ProgramLightWeight device driver APIReduced device driversSmall C library

    (8)    编译、调试、运行。

           从上面的编译、链接信息看到,优化后,pio_eint.elf文件代码加指令总共只有1728字节,这样实验就完全可以在低成本的EP1C3系列芯片上进行。

    6.      程序清单

    PIO外部中断实验程序

    /*************************************************************

     * 文件名:pio_eint.c

     *  能:用按键以中断方式控制LED。每当有一次按键中断时,取反LED一次

     *  明:按下KEY1观察LED1的状态

     ************************************************************/

    #include <stdio.h>

    #include "system.h"

    #include "altera_avalon_pio_regs.h"

    #include "alt_types.h"

    #include "sys/alt_irq.h"

    #include "priv/alt_busy_sleep.h"

     

    #define LEDCON 0x01

    #define KEYCON 0x01

    volatile alt_u32 done = 0;     //信号量:通知中断事件发生

    /*************************************************************

     *     称:KeyDown_interrupts()

     *     能:键按下事件中断服务子程序,当键按下时,通过down标志告知外界

     * 入口参数:context,一般用于传递中断状态寄存器的值,这里未使用

     *         id,中断号,这里未使用

     * 出口参数:无

     ************************************************************/

    static void KeyDown_interrupts(void* context, alt_u32 id)

    {

        /* 清中断捕获寄存器 */

        IOWR_ALTERA_AVALON_PIO_EDGE_CAP(PIO_KEY_BASE, ~KEYCON);

        /* 通知外部有中断事件发生 */

        done++;

    }

    /*************************************************************

     *     称:InitPIO()

     *     能:初始化PIO_KEY为输入,PIO_LED为输出,开中断,清边沿捕获寄存器

     * 入口参数:无

     * 出口参数:无

     ************************************************************/

    void InitPIO(void)

    {

        /* 初始化PIO_KEY为输入,PIO_LED为输出 */  

        IOWR_ALTERA_AVALON_PIO_DIRECTION(PIO_KEY_BASE, ~KEYCON); //0为输入

        IOWR_ALTERA_AVALON_PIO_DIRECTION(PIO_LED_BASE, LEDCON); //1为输出

        /* PIO_KEY中断 */

        IOWR_ALTERA_AVALON_PIO_IRQ_MASK(PIO_KEY_BASE, KEYCON);

        /* 清边沿捕获寄存器 */

        IOWR_ALTERA_AVALON_PIO_EDGE_CAP(PIO_KEY_BASE, ~KEYCON);

        /* 注册中断服务子程序 */

        alt_irq_register(PIO_KEY_IRQ, NULL, KeyDown_interrupts);

    }

    /*************************************************************

     *     称:main()

     *     能:等待按键中断,并输出控制LED

     ************************************************************/

    int main(void)

    {

        volatile alt_u32 key_state, old_state, new_state;

        old_state = KEYCON;

        IOWR_ALTERA_AVALON_PIO_DATA(PIO_LED_BASE, old_state); //初始化LED熄灭

        InitPIO();

        while(1)

        {

            if(0 != done)

            {

                done--;                          //中断事件数量减1

                alt_busy_sleep(5000);          //延时5ms

                key_state = IORD_ALTERA_AVALON_PIO_DATA(PIO_KEY_BASE)&KEYCON;

                if(key_state == 0xFF)          //如果是由短暂脉冲引起的中断,则忽略

                    continue;                   //消除键盘抖动

                new_state = ~(old_state^key_state); //按键按下时LED取反。

                old_state = new_state;         //保存LED的状态

                IOWR_ALTERA_AVALON_PIO_DATA(PIO_LED_BASE, new_state);

            }

        }

        return(0);

    }

           注意:不要在中断服务程序中进行等待或者其他阻塞性操作。

    7.      中断服务程序的调试

    l         在中断服务程序内设置断点。当中断发生后,处理器会在断点处停下,用户可以单步调试中断服务程序。

    l         使用spintf()函数把关键数据写到内存中,然后触发外部分析程序。在中断服务程序中,不可调用printf()函数,因为它可能引起阻塞且运行时间无法预知,但可以调用sprintf()

    8.      键盘去抖动

           由于按键的按下与抬起都会有1020ms的抖动毛刺存在,如下图所示。因此,为了获取稳定的按键信息,须要避开这段抖动期。

           去抖动的方法有很多种,如使用R-S触发器的硬件方法、运用不同算法的各种软件方法等。硬件方法会增加成本和体积,对于按键较多的矩阵式键盘,一般会使用硬件方法;一般情况下软件方法用的比较普遍,但加固定延时的去抖动法效率最低,它以无谓地耗费机时来实现去抖动。本例采用短延时加异或算法消除键盘抖动。

    9.      system.h

           system.h文件在路径"PIOEINT"software"pio_eint_syslib"Debug"system_description下。注意:system.h要编译以后才有。system.h头文件是根据SOPC Builder生成的myniosii.ptf文件产生的系统硬件信息的宏定义文件,清单如下:

    /* system.h

     *

     * Machine generated for a CPU named "cpu" as defined in:

     * d:"lecture"embed"FPGA"SOPCExample1C12"PIO"PIOEINT"software"pio_eint_syslib"..".."myniosii.ptf

     *

     * Generated: 2009-03-31 07:55:41.873

     *

     */

     

    #ifndef __SYSTEM_H_

    #define __SYSTEM_H_

     

    /*

     * system configuration

     *

     */

     

    #define ALT_SYSTEM_NAME "myniosii"

    #define ALT_CPU_NAME "cpu"

    #define ALT_CPU_ARCHITECTURE "altera_nios2"

    #define ALT_DEVICE_FAMILY "CYCLONE"

    #define ALT_STDIN "/dev/null"

    #define ALT_STDIN_TYPE ""

    #define ALT_STDIN_BASE UNDEFINED VARIABLE %BASE_ADDRESS%

    #define ALT_STDIN_DEV null

    #define ALT_STDOUT "/dev/null"

    #define ALT_STDOUT_TYPE ""

    #define ALT_STDOUT_BASE UNDEFINED VARIABLE %BASE_ADDRESS%

    #define ALT_STDOUT_DEV null

    #define ALT_STDERR "/dev/null"

    #define ALT_STDERR_TYPE ""

    #define ALT_STDERR_BASE UNDEFINED VARIABLE %BASE_ADDRESS%

    #define ALT_STDERR_DEV null

    #define ALT_CPU_FREQ 50000000

    #define ALT_IRQ_BASE NULL

     

    /*

     * processor configuration

     *

     */

     

    #define NIOS2_CPU_IMPLEMENTATION "tiny"

    #define NIOS2_BIG_ENDIAN 0

     

    #define NIOS2_ICACHE_SIZE 0

    #define NIOS2_DCACHE_SIZE 0

    #define NIOS2_ICACHE_LINE_SIZE 0

    #define NIOS2_ICACHE_LINE_SIZE_LOG2 0

    #define NIOS2_DCACHE_LINE_SIZE 0

    #define NIOS2_DCACHE_LINE_SIZE_LOG2 0

    #define NIOS2_FLUSHDA_SUPPORTED

     

    #define NIOS2_EXCEPTION_ADDR 0x00002020

    #define NIOS2_RESET_ADDR 0x00002000

    #define NIOS2_BREAK_ADDR 0x00004820

     

    #define NIOS2_HAS_DEBUG_STUB

     

    #define NIOS2_CPU_ID_SIZE 1

    #define NIOS2_CPU_ID_VALUE 0

     

    /*

     * A define for each class of peripheral

     *

     */

     

    #define __ALTERA_AVALON_ONCHIP_MEMORY2

    #define __ALTERA_AVALON_PIO

     

    /*

     * onchip_mem configuration

     *

     */

     

    #define ONCHIP_MEM_NAME "/dev/onchip_mem"

    #define ONCHIP_MEM_TYPE "altera_avalon_onchip_memory2"

    #define ONCHIP_MEM_BASE 0x00002000

    #define ONCHIP_MEM_SPAN 8192

    #define ONCHIP_MEM_ALLOW_MRAM_SIM_CONTENTS_ONLY_FILE 0

    #define ONCHIP_MEM_RAM_BLOCK_TYPE "M4K"

    #define ONCHIP_MEM_INIT_CONTENTS_FILE "onchip_mem"

    #define ONCHIP_MEM_NON_DEFAULT_INIT_FILE_ENABLED 0

    #define ONCHIP_MEM_GUI_RAM_BLOCK_TYPE "Automatic"

    #define ONCHIP_MEM_WRITEABLE 1

    #define ONCHIP_MEM_DUAL_PORT 0

    #define ONCHIP_MEM_SIZE_VALUE 8192

    #define ONCHIP_MEM_SIZE_MULTIPLE 1

    #define ONCHIP_MEM_USE_SHALLOW_MEM_BLOCKS 0

    #define ONCHIP_MEM_INIT_MEM_CONTENT 1

    #define ONCHIP_MEM_ALLOW_IN_SYSTEM_MEMORY_CONTENT_EDITOR 0

    #define ONCHIP_MEM_INSTANCE_ID "NONE"

    #define ONCHIP_MEM_IGNORE_AUTO_BLOCK_TYPE_ASSIGNMENT 1

    #define ONCHIP_MEM_CONTENTS_INFO "QUARTUS_PROJECT_DIR/onchip_mem.hex 1238111903"

    #define ALT_MODULE_CLASS_onchip_mem altera_avalon_onchip_memory2

     

    /*

     * pio_key configuration

     *

     */

     

    #define PIO_KEY_NAME "/dev/pio_key"

    #define PIO_KEY_TYPE "altera_avalon_pio"

    #define PIO_KEY_BASE 0x00005000

    #define PIO_KEY_SPAN 16

    #define PIO_KEY_IRQ 0

    #define PIO_KEY_DO_TEST_BENCH_WIRING 0

    #define PIO_KEY_DRIVEN_SIM_VALUE 0

    #define PIO_KEY_HAS_TRI 0

    #define PIO_KEY_HAS_OUT 0

    #define PIO_KEY_HAS_IN 1

    #define PIO_KEY_CAPTURE 1

    #define PIO_KEY_DATA_WIDTH 1

    #define PIO_KEY_EDGE_TYPE "RISING"

    #define PIO_KEY_IRQ_TYPE "EDGE"

    #define PIO_KEY_BIT_CLEARING_EDGE_REGISTER 0

    #define PIO_KEY_FREQ 50000000

    #define ALT_MODULE_CLASS_pio_key altera_avalon_pio

     

    /*

     * pio_led configuration

     *

     */

     

    #define PIO_LED_NAME "/dev/pio_led"

    #define PIO_LED_TYPE "altera_avalon_pio"

    #define PIO_LED_BASE 0x00005010

    #define PIO_LED_SPAN 16

    #define PIO_LED_DO_TEST_BENCH_WIRING 0

    #define PIO_LED_DRIVEN_SIM_VALUE 0

    #define PIO_LED_HAS_TRI 0

    #define PIO_LED_HAS_OUT 1

    #define PIO_LED_HAS_IN 0

    #define PIO_LED_CAPTURE 0

    #define PIO_LED_DATA_WIDTH 1

    #define PIO_LED_EDGE_TYPE "NONE"

    #define PIO_LED_IRQ_TYPE "NONE"

    #define PIO_LED_BIT_CLEARING_EDGE_REGISTER 0

    #define PIO_LED_FREQ 50000000

    #define ALT_MODULE_CLASS_pio_led altera_avalon_pio

     

    /*

     * system library configuration

     *

     */

     

    #define ALT_MAX_FD 32

    #define ALT_SYS_CLK none

    #define ALT_TIMESTAMP_CLK none

     

    /*

     * Devices associated with code sections.

     *

     */

     

    #define ALT_TEXT_DEVICE       ONCHIP_MEM

    #define ALT_RODATA_DEVICE     ONCHIP_MEM

    #define ALT_RWDATA_DEVICE     ONCHIP_MEM

    #define ALT_EXCEPTIONS_DEVICE ONCHIP_MEM

    #define ALT_RESET_DEVICE      ONCHIP_MEM

     

    /*

     * The text section is initialised so no bootloader will be required.

     * Set a variable to tell crt0.S to provide code at the reset address and

     * to initialise rwdata if appropriate.

     */

     

    #define ALT_NO_BOOTLOADER

     

     

    #endif /* __SYSTEM_H_ */

    10.altera_avalon_pio_regs.h

           altera_avalon_pio_regs.h位于路径C:"altera"72"ip"sopc_builder_ip"altera_avalon_pio"inc下。该头文件提供PIO内核寄存器访问宏定义,程序中对I/O端口操作的宏定义都在该文件中。其清单如下:

    #ifndef __ALTERA_AVALON_PIO_REGS_H__

    #define __ALTERA_AVALON_PIO_REGS_H__

     

    #include <io.h>

     

    #define IOADDR_ALTERA_AVALON_PIO_DATA(base)           __IO_CALC_ADDRESS_NATIVE(base, 0)

    #define IORD_ALTERA_AVALON_PIO_DATA(base)             IORD(base, 0)

    #define IOWR_ALTERA_AVALON_PIO_DATA(base, data)       IOWR(base, 0, data)

     

    #define IOADDR_ALTERA_AVALON_PIO_DIRECTION(base)      __IO_CALC_ADDRESS_NATIVE(base, 1)

    #define IORD_ALTERA_AVALON_PIO_DIRECTION(base)        IORD(base, 1)

    #define IOWR_ALTERA_AVALON_PIO_DIRECTION(base, data) IOWR(base, 1, data)

     

    #define IOADDR_ALTERA_AVALON_PIO_IRQ_MASK(base)       __IO_CALC_ADDRESS_NATIVE(base, 2)

    #define IORD_ALTERA_AVALON_PIO_IRQ_MASK(base)         IORD(base, 2)

    #define IOWR_ALTERA_AVALON_PIO_IRQ_MASK(base, data)   IOWR(base, 2, data)

     

    #define IOADDR_ALTERA_AVALON_PIO_EDGE_CAP(base)       __IO_CALC_ADDRESS_NATIVE(base, 3)

    #define IORD_ALTERA_AVALON_PIO_EDGE_CAP(base)         IORD(base, 3)

    #define IOWR_ALTERA_AVALON_PIO_EDGE_CAP(base, data)   IOWR(base, 3, data)

     

    /* Defintions for direction-register operation with bi-directional PIOs */

    #define ALTERA_AVALON_PIO_DIRECTION_INPUT 0

    #define ALTERA_AVALON_PIO_DIRECTION_OUTPUT 1

     

    #endif /* __ALTERA_AVALON_PIO_REGS_H__ */

           下面是与中断屏蔽寄存器相关的宏定义说明。

    中断屏蔽寄存器访问宏定义

    宏定义

    意义

    IOADDR_ALTERA_AVALON_PIO_IRQ_MASK(base)

    计算中断屏蔽寄存器的物理地址。参数basePIO内核的基地址

    IORD_ALTERA_AVALON_PIO_IRQ_MASK(base)

    读取中断屏蔽寄存器的内容

    IOWR_ALTERA_AVALON_PIO_IRQ_MASK(base, data)

    写中断屏蔽寄存器。参数data为向中断屏蔽寄存器写入的数据

    11.alt_types.h

           alt_types.h位于路径C:"altera"72"nios2eds"components"altera_nios2"HAL"inc下。它定义与altera Nios II自己的与编译器无关的数据类型。其清单如下:

    #ifndef __ALT_TYPES_H__

    #define __ALT_TYPES_H__

     

    /*

     * Don't declare these typedefs if this file is included by assembly source.

     */

    #ifndef ALT_ASM_SRC

    typedef signed char alt_8;

    typedef unsigned char alt_u8;

    typedef signed short alt_16;

    typedef unsigned short alt_u16;

    typedef signed long alt_32;

    typedef unsigned long alt_u32;

    typedef long long alt_64;

    typedef unsigned long long alt_u64;

    #endif

     

    #define ALT_INLINE        __inline__

    #define ALT_ALWAYS_INLINE __attribute__ ((always_inline))

    #define ALT_WEAK          __attribute__((weak))

     

    #endif /* __ALT_TYPES_H__ */

    12.sys/alt_irq.h

           sys/alt_irq.h位于路径C:"altera"72"nios2eds"components"altera_nios2"HAL"inc"sys下。它定义了与中断相关的函数(参见定时器实验),如alt_irq_register()。其清单如下:

    #endif /* __ALT_TYPES_H__ */

     

    #ifndef __ALT_IRQ_H__

    #define __ALT_IRQ_H__

     

    /*

     * alt_irq.h is the nios2 specific implementation of the interrupt controller

     * interface.

     */

     

    #include <errno.h>

     

    #include "nios2.h"

    #include "alt_types.h"

     

    #ifdef __cplusplus

    extern "C"

    {

    #endif /* __cplusplus */

     

    /*

     * Macros used by alt_irq_enabled

     */

     

    #define ALT_IRQ_ENABLED 1

    #define ALT_IRQ_DISABLED 0 

     

    /*

     * number of available interrupts

     */

     

    #define ALT_NIRQ NIOS2_NIRQ

     

    /*

     * Used by alt_irq_disable_all() and alt_irq_enable_all().

     */

     

    typedef int alt_irq_context;

     

    /*

     * alt_irq_enabled can be called to determine if interrupts are enabled. The

     * return value is zero if interrupts are disabled, and non-zero otherwise.

     */

     

    static ALT_INLINE int ALT_ALWAYS_INLINE alt_irq_enabled (void)

    {

     int status;

     

     NIOS2_READ_STATUS (status);

     

     return status & NIOS2_STATUS_PIE_MSK;

    }

     

    /*

     * alt_irq_init() is the device initialisation function. This is called at

     * config time, before any other driver is initialised.

     */

     

    static ALT_INLINE void ALT_ALWAYS_INLINE

           alt_irq_init (const void* base)

    {

     NIOS2_WRITE_IENABLE (0);

     NIOS2_WRITE_STATUS (NIOS2_STATUS_PIE_MSK);

    }

     

    /*

     * alt_irq_register() can be used to register an interrupt handler. If the

     * function is succesful, then the requested interrupt will be enabled upon

     * return.

     */

     

    extern int alt_irq_register (alt_u32 id,

                                 void*   context,

                                 void (*irq_handler)(void*, alt_u32));

     

    /*

     * alt_irq_disable_all() inhibits all interrupts.

     */

     

    static ALT_INLINE alt_irq_context ALT_ALWAYS_INLINE

           alt_irq_disable_all (void)

    {

     alt_irq_context context;

     

     NIOS2_READ_STATUS (context);

     NIOS2_WRITE_STATUS (0);

     

     return context;

    }

     

    /*

     * alt_irq_enable_all() re-enable all interrupts that currently have registered

     * interrupt handlers (and which have not been masked by a call to

     * alt_irq_disable()).

     */

     

    static ALT_INLINE void ALT_ALWAYS_INLINE

           alt_irq_enable_all (alt_irq_context context)

    {

     NIOS2_WRITE_STATUS (context);

    }

     

    /*

     * alt_irq_disable() disables the individual interrupt indicated by "id".

     */

     

    static ALT_INLINE int ALT_ALWAYS_INLINE alt_irq_disable (alt_u32 id)

    {

     alt_irq_context status;

     extern volatile alt_u32 alt_irq_active;

     

     status = alt_irq_disable_all ();

     

     alt_irq_active &= ~(1 << id);

     NIOS2_WRITE_IENABLE (alt_irq_active);

     

     alt_irq_enable_all(status);

     

     return 0;

    }

     

    /*

     * alt_irq_enable() enables the individual interrupt indicated by "id".

     * 

     */

     

    static ALT_INLINE int ALT_ALWAYS_INLINE alt_irq_enable (alt_u32 id)

    {

     alt_irq_context status;

     extern volatile alt_u32 alt_irq_active;

     

     status = alt_irq_disable_all ();

     

     alt_irq_active |= (1 << id);

     NIOS2_WRITE_IENABLE (alt_irq_active);

     

     alt_irq_enable_all(status);

     

     return 0;

    }

     

    #ifndef ALT_EXCEPTION_STACK

     

    /*

     * alt_irq_initerruptable() should only be called from within an ISR. It is used

     * to allow higer priority interrupts to interrupt the current ISR. The input

     * argument, "priority", is the priority, i.e. interrupt number of the current

     * interrupt.

     *

     * If this function is called, then the ISR is required to make a call to

     * alt_irq_non_interruptible() before returning. The input argument to

     * alt_irq_non_interruptible() is the return value from alt_irq_interruptible().

     *

     * Care should be taken when using this pair of functions, since they increasing

     * the system overhead associated with interrupt handling.

     *

     * If you are using an exception stack then nested interrupts won't work, so

     * these functions are not available in that case.

     */

     

    static ALT_INLINE alt_u32 ALT_ALWAYS_INLINE alt_irq_interruptible (alt_u32 priority)

    {

     extern volatile alt_u32 alt_priority_mask;

     extern volatile alt_u32 alt_irq_active;

     

     alt_u32 old_priority;

     

     old_priority      = alt_priority_mask;

     alt_priority_mask = (1 << priority) - 1;

     

     NIOS2_WRITE_IENABLE (alt_irq_active & alt_priority_mask);

     

     NIOS2_WRITE_STATUS (1);

     

     return old_priority;

    }

     

    /*

     * See Comments above for alt_irq_interruptible() for an explanation of the use of this

     * function.

     */

     

    static ALT_INLINE void ALT_ALWAYS_INLINE alt_irq_non_interruptible (alt_u32 mask)

    {

     extern volatile alt_u32 alt_priority_mask;

     extern volatile alt_u32 alt_irq_active;

     

     NIOS2_WRITE_STATUS (0); 

     

     alt_priority_mask = mask;

     

     NIOS2_WRITE_IENABLE (mask & alt_irq_active); 

    }

     

    #endif

     

    /*

     * alt_irq_pending() returns a bit list of the current pending interrupts.

     * This is used by alt_irq_handler() to determine which registered interrupt

     * handlers should be called.

     */

     

    static ALT_INLINE alt_u32 ALT_ALWAYS_INLINE alt_irq_pending (void)

    {

     alt_u32 active;

     

     NIOS2_READ_IPENDING (active);

     

     return active;

    }

     

    #ifdef __cplusplus

    }

    #endif /* __cplusplus */

     

    #endif /* __ALT_IRQ_H__ */

    13.priv/alt_busy_sleep.h

           priv/alt_busy_sleep.h位于路径C:"altera"72"nios2eds"components"altera_nios2"HAL"inc"priv下。它定义了延时函数alt_busy_sleep。其清单如下:

    #ifndef __ALT_BUSY_SLEEP_H

    #define __ALT_BUSY_SLEEP_H

     

    /*

     * The function alt_busy_sleep provides a busy loop implementation of usleep.

     * This is used to provide usleep for the standalone HAL, or when the timer is

     * unavailable in uC/OS-II.

     */

     

    extern unsigned int alt_busy_sleep (unsigned int us);

     

    #endif /* __ALT_BUSY_SLEEP_H */

    14.参考文献

    [1] 周立功,等. SOPC嵌入式系统实验教程()[M]. 北京:北京航空航天大学出版社,2006.

    [2] 李兰英,等. Nios II 嵌入式软核 SOPC设计原理及应用[M]. 北京:北京航空航天大学出版社,2006.

    [3] http://www.altera.com.cn/.

    [4] http://www.icembed.com/info-16530.htm 一种软件去除键抖动的方法.

  • 相关阅读:
    《编程人生》的书评
    目前流行的源程序版本管理软件和项目管理软件都有哪些, 各有什么优缺点?
    知识思考
    自我介绍
    使用my exclipse对数据库进行操作(3)
    猜数字简洁版
    SQL语句
    使用my exclipse对数据库进行操作(1)
    使用my exclipse对数据库进行操作(2)
    建筑平面图, 建筑设计图, 家具摆放图, 制作, 开发, 软件, VC++, 源代码组件库
  • 原文地址:https://www.cnblogs.com/xinjie/p/1536174.html
Copyright © 2011-2022 走看看