nios
我就是想要实现这样的功能:
学过51单片机的都知道,每一个8位IO口都有单独每一位的读取或者赋值方式,这个在LCD等外设的驱动引脚控制中至关重要,这里我举个例:
lcd1602主要有如下引脚,
LCD1602_DB,8位
LCD1602_RS,一位
LCD1602_RW,一位
LCD1602_E,一位
比如我们想要单独控制使能引脚LCD1602_E
51单片机中我可以这样写:sbit LCD1602_E = P1`0;
LCD1602_E = 1;即可实现这个引脚为高电平
但是在FPGA niOS中,没有单独取某一位的指令(只能一次性读完或者写完,FPGA nios结构决定的),那么怎么办呢,我百度了好多,基本上都是说,把每个需要单独控制的引脚用一个pio核来实现,这样当然是没有问题,但是很麻烦,比如某些场合需要单独控制几十个引脚,那么是不是得添加几十个pio核,这样你的FPGA的宏单元也不一定够用,而且,添加太多IP核可能容易出错,这里我想到一种方法来实现这个功能:
添加一个pio核即可,但是位宽设为你需要的引脚数,比如8位,而且设置为双向IO
这样这8个IO和51单片机的IO结构就是一样的了,也比较符合我们操作的习惯
比如我们需要读某一位的值,我们可以先读出这8位的值(只能一次性读完或者写完,FPGA nios结构决定的),
然后再通过c语言的一些与或等运算取出其中我们想要的那一位即可
比如需要写某一位的值,我们可以先读出这8个io的值,然后通过与或等c语言运算方式写进读出的这个数中,最后一次性8位全部写进去即可
以上就实现了用一个IP核实现多个引脚单独控制的问题,具体代码看如下:这是我自己写的,因为我最近搞LCD2864的程序:
// 只有pio_bid_db是双向的,需要控制方向
void pio_bid_db_write8bits(unsigned char value)
{
IOWR (PIO_BID_DB_BASE,1,0Xff); // 设置这个双向io的方向为全部io输出
IOWR_ALTERA_AVALON_PIO_DATA (PIO_BID_DB_BASE, value);
}
unsigned char pio_bid_db_read8bits()
{
IOWR (PIO_BID_DB_BASE,1,0X00);
return IORD_ALTERA_AVALON_PIO_DATA (PIO_BID_DB_BASE);
}
void pio_bid_db_write1bit(unsigned char position,unsigned char value)
{
unsigned char tmp;
tmp = pio_bid_db_read8bits();
tmp &= ~(1<<position); //将tmp的第pos位设置为0
tmp |= value<<position;
pio_bid_db_write8bits(tmp);
}
// 0-7
unsigned char pio_bid_db_read1bit(unsigned char position)
{
unsigned char tmp;
tmp = pio_bid_db_read8bits();
if((tmp & (1 << position)) > 0)
return 1;
else
return 0;
}
经过我的测试,完全ok