按键
LED控制
开发板 小梅哥AC620
软件 quartus 13.1
2个按键,当按键0按下时,LED灯开始闪烁;当按键1按下时,LED灯停止闪烁。
使用一个PIO 这个PIO设置为6位(4个LED+2个按键)
PIO设置为bidir型 位宽为6位
能够捕获边沿下降沿
能够产生中断、边沿中断
要求使能单独位的设置和清零
使能边沿捕获寄存器的单独位清零
顶层代码PL部分
module nios_pio_led(
clk,
rst_n,
key,
key_gnd,
led
);
input clk;
input rst_n;
output key_gnd;
inout [1:0]key;
inout [3:0]led;
assign key_gnd = 0;
mysystem u0 (
.clk_clk (clk), // clk.clk
.reset_reset_n (rst_n), // reset.reset_n
.pio_led_export ({key,led}) // pio_led.export
);
endmodule
PS部分
#include "stdio.h"
#include "system.h"
#include "alt_types.h"
#include "altera_avalon_pio_regs.h"
#include "sys/alt_irq.h"
alt_u8 led_enable=0;
alt_u32 i,data;
alt_isr_func isr(void)//中断服务函数
{
IOWR_ALTERA_AVALON_PIO_IRQ_MASK(PIO_LED_BASE, 0x00); //关闭按键中断
data=IORD_ALTERA_AVALON_PIO_EDGE_CAP(PIO_LED_BASE);
if(data&0x20) //这样写的原因是无法确定低4位的值
led_enable=0;
else if(data&0x10) //停止按键按下
led_enable=1;
else
{
led_enable=0;
}
IOWR_ALTERA_AVALON_PIO_EDGE_CAP(PIO_LED_BASE,0X30);//清除边缘捕获寄存器
IOWR_ALTERA_AVALON_PIO_IRQ_MASK(PIO_LED_BASE,0X30);//开中断
return 0;
}
int main(void)
{
char *p;
IOWR_ALTERA_AVALON_PIO_DIRECTION(PIO_LED_BASE, 0x0f); //设置低4位为输出,高2位为输入
alt_ic_isr_register( PIO_LED_IRQ_INTERRUPT_CONTROLLER_ID, PIO_LED_IRQ, isr, p, 0);//注册中断函数
IOWR_ALTERA_AVALON_PIO_EDGE_CAP(PIO_LED_BASE, 0x30); //清零所有的捕获位
IOWR_ALTERA_AVALON_PIO_IRQ_MASK(PIO_LED_BASE, 0x30); //打开按键中断
while(1)
{
if(led_enable==1)
{
while(i<=500000)
{
i++;
}
IOWR_ALTERA_AVALON_PIO_CLEAR_BITS(PIO_LED_BASE,0x8);//低电平,LED4小灯点亮,
i=0;
while(i<=500000)
{
i++;
}
i=0;
IOWR_ALTERA_AVALON_PIO_SET_BITS(PIO_LED_BASE,0x8);//第3位置位,高电平,LED4小灯熄灭
}
else if(led_enable==0)
{
IOWR_ALTERA_AVALON_PIO_SET_BITS(PIO_LED_BASE,0xF);//第3位置位,高电平,LED4小灯熄灭
}
}
return 0;
}
实验效果
- 矩阵键盘说明
矩阵键盘有两组,共有8跟信号线,其中COL每一列的四个按键的一端连接起来,而ROW则将每一行的4个按键的一端连接起来,通过4行4列的8根信号线,总共能够管理16个按键。用4个IO得到了16个按键。
可看出,我们把COL0接地,按键按下为0,不按为1.(后续再继续学习如何学习电路原理图)
中断的头文件,在sys路径下面
划线定义i,要注意了,我们下面是500000,大于了u8类型,所以这也是个坑,一定要注意自己定义的数是否够用。
定义方向,这也很是个坑,我原先就没有找出是什么原因导致错误,后来弄了半天才想到,inout的方向没有设置,默认是输出的。
然后注册中断函数,每一个元素前面,不用再次声明数据类型
这里消耗时间是while,不是if判断,if是并行的选择,不是顺序
以上分别是全速运行、step into step over step return
并且可以看到变量
还可以设置断点。
另外如果出错,记得,在run configure 里面重新refresh 一下blaster