完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
电子发烧友论坛|
|
|
相关推荐
1个回答
|
|
Sifive Learn Inventor是Sifive的一款基于RISC-V内核的开发板,具体见官网的Hifive Rev b 的文档一,硬件连接 芯片的gpio11连接到buttonA,如下,可见,按键按下是低电平,所以我们可以设置gpio11为下降沿中断来实现按键中断。 二,代码编写 首先是button初始化 /** *buttona初始化为下降沿触发中断 */ void ButtonA_init(int *flag) { struct metal_gpio *gpio0;//声明一个gpio对象 int buttonA_id=12;//根据芯片手册查询到gpio11的中断id的为12 gpio0=metal_gpio_get_device(0);//实例化gpio对象 //获得gpio控制器,其实就是plic buttonA_intr=metal_gpio_interrupt_controller(gpio0); metal_interrupt_init(buttonA_intr); //注册回调函数 buttonA_isr是回调函数的函数名,最后传递的flag是一个指针,是传递给回调函数的参数 metal_interrupt_register_handler(buttonA_intr,buttonA_id,buttonA_isr,flag); //设置优先级为3 metal_interrupt_set_priority(buttonA_intr,buttonA_id,3); //enable gpio metal_gpio_disable_output(gpio0,11); metal_gpio_enable_input(gpio0,11); //禁止gpio功能复用 metal_gpio_disable_pinmux(gpio0,11); //先关闭一下中断 metal_gpio_config_interrupt(gpio0,11,METAL_GPIO_INT_DISABLE); //清楚gpio中断的所有标志位 metal_gpio_clear_interrupt(gpio0,11, METAL_GPIO_INT_MAX); //配置为下降沿中断 metal_gpio_config_interrupt(gpio0,11,METAL_GPIO_INT_FALLING); //使能gpio11 metal_interrupt_enable(buttonA_intr,buttonA_id); } 2,中断服务函数中,改变全局变量flag的值,随后在主函数中判断flag的值,再进入处理函数; 这里的中断函数的名称是可以随意取的,但是传递的参数必须是固定的int id, void data,voiddata 是由初始化注册回调函数的传递过来的无类型的一个指针。在回调函数中,先拿到gpio对象,然后清楚gpio11的下降沿中断的标志位。然后从data里拿到flag的地址,从而改变flag的值。 /** *buttona回调函数 清除下降沿中断标志位,将flag置2 */ void buttonA_isr (int id, void *data){ struct metal_gpio *gpio0=metal_gpio_get_device(0); metal_gpio_clear_interrupt(gpio0, 11,METAL_GPIO_INT_FALLING); int *flag=(int *)data; *flag=2; } 3,在main()函数中检测flag的值 while(1){ if(flag==2){ fun(); } } 三,小结 这是一个简单的gpio中断的配置,从这个例子出发,来讨论一下sifive的中断是如何完成的。然后就可以依样画葫芦,其他外设的中断也可以相对容易的去理解。 中断产生的过程大概是这样的: inturrpt就是我们的中断源,当我们的按键按下时,gpio11就产生了一个中断请求,中断信号先来到plic控制器,plic根据请求的优先级来给中断请求排队,根据中断的id来找到中断服务程序的入口,随后进入中断服务函数,当完成中断服务函数后,plic相应的id的中断标志位会被置0 根据手册可以知道plic负责管理所有外设的中断请求,从下表可以知道外设对应的中断id。 其实上面代码中的buttonA_intr=metal_gpio_interrupt_controller(gpio0);这个函数就是把plic控制器的对象负责给buttonA_intr,这样通过操作buttonA_intr,其实也就是对plic的操作。 综上,要初始化一个外设中断,我们需要配置外设的中断寄存器,同时还要拿到plic对象,中断id,接下来就是配置plic,设置回调函数和中断优先级。这时候再来看初始化代码 这两个语句就是获取中断id和plic; int buttonA_id=12;初始化一下plic,主要是把plic对象里的一些参数赋值为0或null metal_interrupt_init(buttonA_intr);这个函数就是配置plic的作用,在plic的中断表里id=12的地方写入中断回调函数的地址和传递的参数 metal_interrupt_register_handler(buttonA_intr,buttonA_id,buttonA_isr,flag);设置一下优先级,使能这个中断 metal_interrupt_set_priority(buttonA_intr,buttonA_id,3);至此,一个中断初始化的plic部分就设置完成了,另一部分,外设的中断寄存器配置就要根据手册的说明或者库函数去相应的配置 可以根据下面的图片理解plic,其实初始化一个外设中断就像是给下面的表格填写对应的内容,我们需要的就是plic对象,id,回调函数地址,优先级,传递参数。更多的plic内容查看芯片手册。 |
|
|
|
|
只有小组成员才能发言,加入小组>>
1934 浏览 0 评论
imx6ull 和 lan8742 工作起来不正常, ping 老是丢包
4776 浏览 0 评论
4256 浏览 9 评论
3845 浏览 16 评论
4419 浏览 1 评论
4244浏览 3评论
2405浏览 0评论
3423浏览 0评论
1184浏览 0评论
2873浏览 0评论
/9
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2025-12-11 03:17 , Processed in 0.783896 second(s), Total 74, Slave 54 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191

淘帖
2668