最近看过Intel的大学计划课程《嵌入式设计》,lab2 的 part III 实验要求是:在DE1-SOC开发板上通过 FPGA定时器中断实现秒表倒计时,且能通过按键中断 设定时钟,具体操作是按key0 暂停,按key1 设置 百分秒,按key2 设置 秒钟,按key3设置 分钟。百分秒、秒、分 分别在6个数码管上显示。这里面会用到PIO的寄存器Edgecapture,有人可能会对这个寄存器的使用存在疑问,觉得中断初始化的时候设置:
*(KEY_ptr + 0x3) = 0xF; // clear Edgecapture register
那么后面,在中断处理函数 irq_handler_KEY中 读出来的时候 edgecapture 变量也应该是1111才对:
如果是这样,那么无论按键是否被按,edgecapture 变量一直都是1111了。
其实不是这样,Edgecapture 寄存器不能当作一般的变量来看。write和read分别有不一样的定义。 read不会读回write的值。根据edgecapture 的定义:
所以 *(KEY_ptr + 0x3) = 0xF; 代码只是将寄存器清零了,也就是写1 将寄存器清零,如果没有按键按下, 寄存器read的时候应该是 0000。 如果有按键按下了,就会产生中断,进入中断处理函数 irq_handler_KEY:
所以这里两行代码 读出来又写进去,不是吃了没事干哈, 第一行(38行)是读出寄存器的值看是哪个按键按下了,第二行(39行)是将某个按键对应位写1进行寄存器对应位的清零操作。
(更多PIO寄存器的说明参考intel手册 :