使用C++来写NiosII[2]-GPIO

先看看效果

比如我们现在要实现点亮一个灯的操作,采用了C++进行封装之后,在主程序中就会非常的简洁。
main.cpp

GNios::Gpio Led(LED_BASE);
int main() {
	//Hello world to jtag
	printf("Hello from Nios II!\n");

	//led
	int i;
	while (1)
	{
			for (i = 0; i < 4; i++) 
			{
				//IOWR_ALTERA_AVALON_PIO_DATA(LED_BASE, 1<<i);
				Led.WriteData(1<<i);
				usleep(100000);
			}
		}
	}
	return 0;
}

自定义类型

在实际开始写之前,将一些类型名称进行个性化的定制,这样保持整个工程中的不同长度大小的类型定义不混乱。
gnios_types.h

#ifndef GNIOS_TYPES_H_
#define GNIOS_TYPES_H_

#include "system.h"

typedef alt_8  int8;		//有符号8位整数
typedef alt_u8  uint8;		//无符号8位整数
typedef alt_16 int16;		//有符号16位整数
typedef alt_u16 uint16;		//无符号16位整数
typedef alt_32 int32;
typedef alt_u32 uint32;
typedef alt_64 int64;
typedef alt_u64 uint64;

typedef void(*gnios_func)(void* context);		//定义一个通用的函数指针类型gnios_func,返回类型为void,参数为void* context

//定义一个泛型类(模板类?),以便之后规范数据传输。
template<class T>
class EventArgs
{
public:
	T Content;
	EventArgs(T content)
	{
		this->Content=content;
	}
};


#endif /* GNIOS_TYPES_H_ */

GPIO

gnios_gpio.h

#ifndef GNIOS_GPIO_H_
#define GNIOS_GPIO_H_

#include "system.h"
#include "altera_avalon_pio_regs.h"
#include "gnios_types.h"

#define GpioInput 0
#define GpioOutput 1
//PIO核支持最多32个IO,这里都定义出来
#define GpioPin0  ((uint32)0x00000001)
#define GpioPin1  ((uint32)0x00000002)
#define GpioPin2  ((uint32)0x00000004)
#define GpioPin3  ((uint32)0x00000008)
#define GpioPin4  ((uint32)0x00000010)
#define GpioPin5  ((uint32)0x00000020)
#define GpioPin6  ((uint32)0x00000040)
#define GpioPin7  ((uint32)0x00000080)
#define GpioPin8  ((uint32)0x00000100)
#define GpioPin9  ((uint32)0x00000200)
#define GpioPin10 ((uint32)0x00000400)
#define GpioPin11 ((uint32)0x00000800)
#define GpioPin12 ((uint32)0x00001000)
#define GpioPin13 ((uint32)0x00002000)
#define GpioPin14 ((uint32)0x00004000)
#define GpioPin15 ((uint32)0x00008000)
#define GpioPin16 ((uint32)0x00010000)
#define GpioPin17 ((uint32)0x00020000)
#define GpioPin18 ((uint32)0x00040000)
#define GpioPin19 ((uint32)0x00080000)
#define GpioPin20 ((uint32)0x00100000)
#define GpioPin21 ((uint32)0x00200000)
#define GpioPin22 ((uint32)0x00400000)
#define GpioPin23 ((uint32)0x00800000)
#define GpioPin24 ((uint32)0x01000000)
#define GpioPin25 ((uint32)0x02000000)
#define GpioPin26 ((uint32)0x04000000)
#define GpioPin27 ((uint32)0x08000000)
#define GpioPin28 ((uint32)0x10000000)
#define GpioPin29 ((uint32)0x20000000)
#define GpioPin30 ((uint32)0x40000000)
#define GpioPin31 ((uint32)0x80000000)
#define GpioPinAll ((uint32)0xFFFFFFFF)

namespace GNios
{
   class Gpio
   {
   protected:
      /* GPIO register PIO核的寄存器映射*/ 
      typedef struct RegStruct
      {
         volatile uint32 DATA;
         volatile uint32 DIRECTION;
         volatile uint32 INTERRUPT_MASK;
         volatile uint32 EDGE_CAPTURE;
      }RegStruct;

      /* GPIO Arguments*/
      typedef struct GpioArgs
      {
    	  RegStruct* Reg; //寄存器映射
    	  uint32 base;    //PIO核的基地址
      }GpioArgs;

      GpioArgs Instance; //GPIO核实例

   public:
      Gpio(uint32 base);  //使用基地址实例化

      uint32 ReadData();
      void WriteData(uint32 data);

      uint32 ReadDirection();
      void WriteDirection(uint32 data);

      uint32 ReadIrqMask();
      void WriteIrqMask(uint32 data);

      uint32 ReadEdgeCapture();
      void WriteEdggeCapture(uint32 data);

      uint32 ReadSetBits();
      void WriteSetBits(uint32 data);

      uint32 ReadClearBits();
      void WriteClearBits(uint32 data);


      ~Gpio();
   };


}



#endif /* GNIOS_GPIO_H_ */

这里要说明一下,虽然这里使用了寄存器映射的办法将IP核的寄存器映射到了RegStruct上,但是实际使用的时候,并不推荐使用寄存器赋值的办法来做,还是推荐使用API来操作。具体原因是采用API的话,调用的是内建的函数,而使用寄存器赋值,在NiosII的F核情况下就会遇到DataCache的问题。所以寄存器赋值的定义那里置位了第31位,第31位是DataCache bypassing位
在这里插入图片描述


gnios_gpio.cpp

#include "../inc/gnios_gpio.h"
namespace GNios
{

   Gpio::Gpio(uint32 base)
   {
      Instance.Reg=((RegStruct*)(base|(1<<31)));
      Instance.base=base;
   }

   uint32 Gpio::ReadData()
   {
      return (uint32)IORD_ALTERA_AVALON_PIO_DATA(Instance.base);
   }
   void Gpio::WriteData(uint32 data)
   {
      //Reg->DATA=data;  //using Register
	  IOWR_ALTERA_AVALON_PIO_DATA(Instance.base, data);  //using api
   }


   uint32 Gpio::ReadDirection()
   {
      return (uint32)IORD_ALTERA_AVALON_PIO_DIRECTION(Instance.base);
   }
   void Gpio::WriteDirection(uint32 data)
   {
      IOWR_ALTERA_AVALON_PIO_DIRECTION(Instance.base,data);
   }

   uint32 Gpio::ReadIrqMask()
   {
      return (uint32)IORD_ALTERA_AVALON_PIO_IRQ_MASK(Instance.base);
   }

   void Gpio::WriteIrqMask(uint32 data)
   {
      IOWR_ALTERA_AVALON_PIO_IRQ_MASK(Instance.base,data);
   }
   
   uint32 Gpio::ReadEdgeCapture()
   {
      return (uint32)IORD_ALTERA_AVALON_PIO_EDGE_CAP(Instance.base);
   }

   void Gpio::WriteEdggeCapture(uint32 data)
   {
      IOWR_ALTERA_AVALON_PIO_EDGE_CAP(Instance.base,data);
   }


   uint32 Gpio::ReadSetBits()
   {
      return (uint32)IORD_ALTERA_AVALON_PIO_SET_BITS(Instance.base);
   }
   void Gpio::WriteSetBits(uint32 data)
   {
      IOWR_ALTERA_AVALON_PIO_SET_BITS(Instance.base,data);
   }

   uint32 Gpio::ReadClearBits()
   {
      return (uint32)IORD_ALTERA_AVALON_PIO_CLEAR_BITS(Instance.base);
   }
   void Gpio::WriteClearBits(uint32 data)
   {
      IOWR_ALTERA_AVALON_PIO_CLEAR_BITS(Instance.base,data);
   }



   Gpio::~Gpio()
   {
   }
   

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值