manhuami2007 发表于 2022-2-28 17:43

【沁恒RISC-V内核 CH582】3- IO外部中断的使用

<div class="parsedown-markdown">
<p>CH582的中断也有一个中断控制器,缩写是PFIC。应该和ARM里的NVIC有点相似,管理中断的优先级和使能。</p>

<p>本次只用最基本的外部中断功能。使用按键触发中断,控制LED等的翻转。</p>

<p>包括2个部分:</p>

<ol>
        <li>中断源的设置</li>
        <li>中断函数的编写</li>
</ol>

<h2>中断源的设置</h2>

<p>同ARM一样,中断源的使能是由2部分共同控制的:外设本身和中断管理器。</p>

<h3>IO输入端口的中断设置</h3>

<pre>
<code>GPIOB_ModeCfg(GPIO_Pin_4,GPIO_ModeIN_PU);
GPIOB_ITModeCfg(GPIO_Pin_4,GPIO_ITMode_RiseEdge);</code></pre>

<p>首先将IO设置成输入模式,然后配置中断类型,可配置的类型包括:高电平、低电平、上升沿和下降沿。</p>

<h3>PFIC中断控制器的设置</h3>

<pre>
<code>PFIC_EnableIRQ(GPIO_B_IRQn);</code></pre>

<p>上面这个函数出现在&quot;core_riscv.h&quot;文件中,这个文件里类似于ARM里的&quot;cm3.h&quot;那个头文件。包括了全局中断的使能和关闭,中断优先级的设置,快速中断设置,重启等指令。</p>

<h2>中断函数的编写</h2>

<p>我是参考工程中uart的中断函数写的,其中断函数的上部有2个预编译指令(见下面的两行指令)不清楚是做什么用的,百度了一下,大概是为了在编译的时候把中断统一放在某个代码区里。</p>

<pre>
<code>__INTERRUPT
__HIGH_CODE</code></pre>

<p>按键触发中断翻转LED的中断函数如下:</p>

<pre>
<code>__INTERRUPT
__HIGH_CODE
void GPIOB_IRQHandler()
{
    if(GPIOB_ReadITFlagBit(GPIO_Pin_4) != 0){
      GPIOB_InverseBits(GPIO_Pin_19);
      GPIOB_ClearITFlagBit(GPIO_Pin_4);
    }
}</code></pre>

<p>中断函数的函数名可以在&quot;startup_CH583.S&quot;里找到。</p>

<h2>一些疑问</h2>

<ol>
        <li><code>__INTERRUPT</code>和<code>__HIGH_CODE</code>的作用还不知道。</li>
        <li>手册中提到了 ,对这个不是很理解,手册上也没有细说。猜测可能是有4个可配置的通道,能够连接其它的中断源,然后能够更快速的跳转到中断执行函数里。</li>
</ol>

<p>手册写的有些简单,而且例程上也没有体现中断的用法。这个希望后期官方能够补充一下。</p>
</div>

<p>&nbsp;</p>

lugl4313820 发表于 2022-2-28 22:09

楼主很有思想,我就没有想到这么,能用就好,顶你一个!

WCH_Risc5 发表于 2022-3-8 10:04

<p>_HIGH_CODE是将代码放到RAM里去跑,速度会大大提高,所以我们的例程中关于中断就会这么写,gpio中断在BLE目录下的PM中有使用gpio中断唤醒,可参考。</p>

<p>&mdash;INTERRUPT是必须得有的,他可以提醒编译器这是中断服务函数,另外还可以提醒编译器硬件压栈已经开启,不需要开启软件压栈。</p>

manhuami2007 发表于 2022-3-8 15:47

WCH_Risc5 发表于 2022-3-8 10:04
_HIGH_CODE是将代码放到RAM里去跑,速度会大大提高,所以我们的例程中关于中断就会这么写,gpio中断在BLE目 ...

<p>感谢解惑<img height="48" src="https://bbs.eeworld.com.cn/static/editor/plugins/hkemoji/sticker/facebook/wanwan88.gif" width="59" /></p>
页: [1]
查看完整版本: 【沁恒RISC-V内核 CH582】3- IO外部中断的使用