我是靠谱客的博主 忧伤棒棒糖,最近开发中收集的这篇文章主要介绍nios自学笔记三:nios常用外设C函数整理一、PIO读写二、寄存器读写 三、PIO中断处理 四、定时器中断处理五、uart收发处理 六、延时函数,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

该文章为Nios II学习中的外设C函数收集整理笔记,长期更新。


提示:以下是本篇文章正文内容,下面案例可供参考

一、PIO读写

1.1 对PIO进行写操作

(1)利用给定的宏定义函数,函数原型如下:

IOWR_ALTERA_AVALON_PIO_DATA(base, data);    //base是要访问的IO口的基地址,data是所要写入的数据

(2)直接调用内部函数,函数原型如下:

IOWR(BASE, REGNUM, DATA);    //BASE为寄存器的基地址,REGNUM为寄存器的偏移量,DATA为要写入的数据。对于PIO来说,REGNUM为0

1.2 对PIO进行读操作

(1)利用给定的宏定义函数,函数原型如下:

value = IORD_ALTERA_AVALON_PIO_DATA(base);   //base是要访问的IO口的基地址,value为函数返回的读到的值

(2)直接调用内部函数,函数原型如下:

value = IORD(BASE, REGNUM);    //BASE为是要访问的IO口的基地址,REGNUM为寄存器的偏移量,value为函数返回的读到的值。对于PIO来说,REGNUM为0

二、寄存器读写 

用于对momory地址内数据直接进行多bit读写,比如对RAM的读写之类的。

2.1 多位寄存器写操作

IOWR_8DIRECT(BASE, OFFSET, DATA);     //往地址为BASE+OFFSET的寄存器中直接写入8Bit的数据DATA
IOWR_16DIRECT(BASE, OFFSET, DATA);    //往地址为BASE+OFFSET的寄存器中直接写入16Bit的数据DATA
IOWR_32DIRECT(BASE, OFFSET, DATA);   //往地址为BASE+OFFSET的寄存器中直接写入32Bit的数据DATA

2.2 多位寄存器读操作 

value = IORD_8DIRECT(BASE, OFFSET);     //从地址为BASE+OFFSET的寄存器中直接读8Bit的数据到value中
value = IORD_16DIRECT(BASE, OFFSET);    //从地址为BASE+OFFSET的寄存器中直接读16Bit的数据到value中
value = IORD_32DIRECT(BASE, OFFSET);    //从地址为BASE+OFFSET的寄存器中直接读32Bit的数据到value中

三、PIO中断处理 

//需要添加的头文件
#include "system.h"                   // 系统
#include "altera_avalon_pio_regs.h"   // PIO,ads_nIRQ
#include "alt_types.h"
#include "sys/alt_irq.h"              // 中断


//相关声明
unsigned int nirq_isr_context; // 定义全局变量以储存isr_context指针
void nIRQ_Initial(void);
void nIRQ_ISR(void* isr_context);


//main函数
int main(void)
{
  nIRQ_Initial(); // 初始化PIO中断
  while(1)
  {
  }  
}


// nIRQ中断初始化
void nIRQ_Initial(void)
{
  
  void* isr_context_ptr = (void*) &nirq_isr_context;  // 改写timer_isr_context指针以匹配alt_irq_register()函数原型

  IOWR_ALTERA_AVALON_PIO_IRQ_MASK(ADS_NIRQ_BASE, 1); // 使能中断
  IOWR_ALTERA_AVALON_PIO_EDGE_CAP(ADS_NIRQ_BASE, 1); // 清中断边沿捕获寄存器

  // 注册ISR
  alt_ic_isr_register(
      ADS_NIRQ_IRQ_INTERRUPT_CONTROLLER_ID, // 中断控制器标号,从system.h复制
      ADS_NIRQ_IRQ,     // 硬件中断号,从system.h复制
      nIRQ_ISR,         // 中断服务子函数
      isr_context_ptr,  // 指向与设备驱动实例相关的数据结构体
      0x0);             // flags,保留未用
}


// 中断服务子函数
void nIRQ_ISR(void* nirq_isr_context)
{
  IOWR_ALTERA_AVALON_PIO_EDGE_CAP(ADS_NIRQ_BASE, 1); // 清中断边沿捕获寄存器
 
  // 用户中断代码


}

四、定时器中断处理

//需要添加的头文件
#include "system.h"                   // 系统
#include "altera_avalon_timer_regs.h" // 定时器
#include "alt_types.h"
#include "sys/alt_irq.h"              // 中断


//相关声明
unsigned int timer_isr_context; // 定义全局变量以储存isr_context指针
void Timer_Initial(void);
void Timer_ISR(void* isr_context);


//main函数
int main(void)
{
  Timer_Initial(); // 初始化定时器中断
  while(1)
  {
  }  
}


// 定时器中断初始化
void Timer_Initial(void)
{
  
    void* isr_context_ptr = (void*) &timer_isr_context;    // 改写timer_isr_context指针以匹配alt_irq_register()函数原型
  
    // 设置PERIOD寄存器
    // PERIODH << 16 | PERIODL = 计数器周期因子 * 系统时钟频率因子 - 1
    // PERIODH << 16 | PERIODL = 5m*100M - 1 = 499999 = 0x7A11F
    IOWR_ALTERA_AVALON_TIMER_PERIODH(HIGH_RES_TIMER_BASE, 0x0007);
    IOWR_ALTERA_AVALON_TIMER_PERIODL(HIGH_RES_TIMER_BASE, 0xA11F);
 
    // 设置CONTROL寄存器
    //    位数 |  3   |  2   |  1   |  0  |
    // CONTROL | STOP | START| CONT | ITO |
    // ITO   1,产生IRO;                      0,不产生IRQ
    // CONT  1,计数器连续运行直到STOP被置一;   0,计数到0停止
    // START 1,计数器开始运行;                0,无影响
    // STOP  1,计数器停止运行;                0,无影响
    IOWR_ALTERA_AVALON_TIMER_CONTROL(
        HIGH_RES_TIMER_BASE,
        ALTERA_AVALON_TIMER_CONTROL_START_MSK |     // START = 1
        ALTERA_AVALON_TIMER_CONTROL_CONT_MSK  |     // CONT  = 1
        ALTERA_AVALON_TIMER_CONTROL_ITO_MSK);       // ITO   = 1
      
    // 注册定时器中断
    alt_ic_isr_register(
        HIGH_RES_TIMER_IRQ_INTERRUPT_CONTROLLER_ID, // 中断控制器标号,从system.h复制
        HIGH_RES_TIMER_IRQ,     // 硬件中断号,从system.h复制
        Timer_ISR,              // 中断服务子函数
        isr_context_ptr,        // 指向与设备驱动实例相关的数据结构体
        0x0);                   // flags,保留未用
}


// 定时器中断服务子函数
void Timer_ISR(void* timer_isr_context)
{
  // 应答中断,将STATUS寄存器清零
    IOWR_ALTERA_AVALON_TIMER_STATUS(
        HIGH_RES_TIMER_BASE,
        ~ ALTERA_AVALON_TIMER_STATUS_TO_MSK);   // TO = 0
 
    // 用户中断代码

}

五、uart收发处理

uart接收有查询方式和中断方式。我这里的uart接收采用中断处理方式,发送利用单独的函数实时处理。

5.1 uart发送函数

//查询发送准备好信号,如果没有准备好,则等待
while(!((IORD_ALTERA_AVALON_UART_STATUS(UART_0_BASE)&ALTERA_AVALON_UART_STATUS_TRDY_MSK)));
//发送准备好,发送txbyte
IOWR_ALTERA_AVALON_UART_TXDATA(UART_0_BASE,txbyte);

5.2 uart中断接收

//相关头文件
#include "system.h"    //系统硬件信息的宏定义文件
#include "alt_types.h"    //与Nios II相关的数据类型
#include "altera_avalon_uart_regs.h"    //提供相应内核寄存器访问宏定义
#include "sysalt_irq.h"    //中断相关宏定义


//相关声明
unsigned int uart_isr_context; //定义全局变量以储存isr_context指针
void uart_init();
static void uart_isr(void * p_uart_isr_context);


//main函数
int main(void)
{
  uart_init(); // 初始化uart中断
  while(1)
  {
  }  
}

//uart中断初始化
void uart_init()
{

	// 改写pack_uart_isr_context指针以匹配alt_irq_register()函数原型
	  void *isr_context_ptr = (void*) & uart_isr_context;

	//清除状态寄存器
    IOWR_ALTERA_AVALON_UART_STATUS(UART_0_BASE,0);
    //使能接受准备好中断
    IOWR_ALTERA_AVALON_UART_CONTROL(UART_0_BASE,0X80);

    // 注册ISR
    alt_ic_isr_register(
        UART_0_IRQ_INTERRUPT_CONTROLLER_ID,  // 中断控制器标号,从system.h复制
        UART_0_IRQ,     					 // 硬件中断号,从system.h复制
        uart_isr,         					 // 中断服务子函数
        isr_context_ptr,  					 // 指向与设备驱动实例相关的数据结构体
        0x0);             					 // flags,保留未用

}


//uart中断接收服务子函数
static void uart_isr(void * p_uart_isr_context)

{
	//清除状态寄存器
	IOWR_ALTERA_AVALON_UART_STATUS(UART_0_BASE,0);

    //用户逻辑

    //rxdata = IORD_ALTERA_AVALON_UART_RXDATA(UART_0_BASE);//UART 接收

    /*
    //查询发送准备好信号,如果没有准备好,则等待
    while(!((IORD_ALTERA_AVALON_UART_STATUS(UART_0_BASE)&ALTERA_AVALON_UART_STATUS_TRDY_MSK)));
  	//发送准备好,发送txdata
    IOWR_ALTERA_AVALON_UART_TXDATA(UART_0_BASE,txdata);

    */

}


 六、延时函数

//所需头文件
#include "unistd.h"    

//us延时函数 usleep()
usleep(200*1000); //延时200ms

注:usleep()函数做ms级别及以上的延时的确很准,但是us级别就有点捉襟见肘了。如果是us级别的延时可以用for()循环做空语句延时,但是这样也只是粗略的延时。

最后

以上就是忧伤棒棒糖为你收集整理的nios自学笔记三:nios常用外设C函数整理一、PIO读写二、寄存器读写 三、PIO中断处理 四、定时器中断处理五、uart收发处理 六、延时函数的全部内容,希望文章能够帮你解决nios自学笔记三:nios常用外设C函数整理一、PIO读写二、寄存器读写 三、PIO中断处理 四、定时器中断处理五、uart收发处理 六、延时函数所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(77)

评论列表共有 0 条评论

立即
投稿
返回
顶部