eew_VHNtMb 发表于 2021-3-1 23:02

【RISC-V MCU CH32V103测评】+ TIM定时器的使用

<p><span style="font-size:20px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></p>

<p>&nbsp;</p>

<p><span style="font-size:20px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CH32V103有7个定时器,&nbsp; </span></p>

<p><span style="font-size:20px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1个16位高级定时器,包含通用定时器功能,并自带死区控制和紧急刹车,提供用于电机控制的PWM,&nbsp; </span></p>

<p><span style="font-size:20px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;3个16位通用定时器,提供多达4个用于输入捕获/输出比较/PWM/脉冲计数的通道和增量编码器输入,&nbsp; </span></p>

<p><span style="font-size:20px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2个看门狗定时器(独立和窗口型),&nbsp; </span></p>

<p><span style="font-size:20px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;系统时间定时器:64位自增型计数器.</span></p>

<p><span style="font-size:20px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;我手中的DHT11温湿度传感器要一秒以上才能读取一次,所以就要用一个定时器来定时1.3秒读取一次,详细配置如下:</span></p>

<pre>
<code>/*
* TIM2用作DHT11更新时基
* 1.3秒更新一次
*/
void TIM2_Base_Init(void)
{
    TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE );

    TIM_TimeBaseInitStructure.TIM_Period = 13000-1;//计数值
    TIM_TimeBaseInitStructure.TIM_Prescaler = 7200-1;//分频值
    TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
    TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInit( TIM2, &amp;TIM_TimeBaseInitStructure);

    TIM_ITConfig(TIM2,TIM_IT_Update, ENABLE);//配置更新中断

    NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn ;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&amp;NVIC_InitStructure);

    TIM_ClearITPendingBit(TIM2, TIM_IT_Update);

}
</code></pre>

<p><span style="font-size:20px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;配置起来不难和ST差不多,不同点在中断控制器上.对比如下:</span></p>

<p><span style="font-size:20px;"><span style="color:#e74c3c;">CH32V103C8T6</span>,沁恒微电子的<span style="color:#e74c3c;">RSIC-V</span>架构32位通用型MCU,支持IMAC指令集,内置快速可编程中断控制器(PFIC&ndash; Programmable Fast Interrupt Controller)。PFIC是该公司自研设计的结构,所以用法上有独自的特色。</span><br />
<br />
<span style="font-size:20px;"><span style="color:#9b59b6;">&nbsp;PFIC 控制器</span><br />
&nbsp;44+3个可单独屏蔽中断,每个中断请求都有独立的触发和屏蔽位、状态位<br />
&nbsp;提供一个不可屏蔽中断NMI<br />
&nbsp;2级嵌套中断进入和退出硬件自动压栈和恢复,无需指令开销<br />
&nbsp;4路可编程快速中断通道,自定义中断向量地址</span><br />
&nbsp;</p>

<p>&nbsp;</p>

<p><span style="font-size:20px;"><span style="color:#e74c3c;">CH32V103C8T6</span>在中断写法上,书写一个中断服务函数时,需要为其声明中断属性,即在函数名前添加<code>__attribute__((interrupt()))</code>,这样IDE在进行编译时,会将此函数体识别为中断服务函数,主动添加&ldquo;压栈出栈&rdquo;处理及中断返回指令。例如:在ch32v10x_it.c的顶部有如下写法.</span></p>

<pre>
<code>void NMI_Handler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
void HardFault_Handler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
void EXTI0_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
void TIM2_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));</code></pre>

<p><span style="font-size:20px;">中断服务函数中只要置位即可,处理交给while.</span></p>

<pre>
<code>/*******************************************************************************
* Function Name: TIM2_IRQHandler
* Description    : This function handles TIM2 Handler.
* Input          : None
* Return         : None
*******************************************************************************/
void TIM2_IRQHandler(void)
{
    if(TIM_GetFlagStatus(TIM2, TIM_IT_Update)!= RESET){
      DHT11_Updata = 1;
    }
    TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
}</code></pre>

<p><span style="font-size:20px;">然后主程序去处理就好了</span></p>

<pre>
<code>/*******************************************************************************
* Function Name: main
* Description    : Main program.
* Input          : None
* Return         : None
*******************************************************************************/
int main(void)
{
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
    Delay_Init();
        USART_Printf_Init(115200);
        printf("SystemClk:%d\r\n",SystemCoreClock);

        //初始化
        GPIO_Toggle_INIT();
        EXTI0_INT_INIT();
        SPI1_Init();
        DHT11_Init();
        ADC_Function_Init();
        DMA_Tx_Init();
        OLED_Init();
        TIM2_Base_Init();


        Opening_page();//启动页
        OLED_Clear();

        ADC_SoftwareStartConvCmd(ADC1, ENABLE);             //启动ADC转换
        TIM_Cmd(TIM2,ENABLE);         //使能定时器,1.3秒中断一次
        while(1)
{
                // GPIO_WriteBit(GPIOA, GPIO_Pin_0, (i==0) ? (i=Bit_SET):(i=Bit_RESET));
          if(exti0_status == 0)       //光敏电阻感到光
          {
                OLED_DisPlay_On();      //开启OLED
                TIM_Cmd(TIM2,ENABLE);
                if(DHT11_Updata == 1)
                {    /*调用DHT11_Read_TempAndHumidity读取温湿度,若成功则输出该信息*/
                    if( DHT11_Read_TempAndHumidity ( &amp; DHT11_Data ) == SUCCESS)
                    {
                      Main_page();      //成功显示温湿度,ADC电压值
                    }else
                    {
                      OLED_Clear();
                      DHT_ERR();          //失败显示错误
                    }
                    DHT11_Updata = 0;
                }
                MQ_7_Vol();
          }else
          {
                OLED_DisPlay_Off();   //关闭oled
                TIM_Cmd(TIM2,DISABLE);//关闭定时器
          }
          Delay_Ms(150);
}
}</code></pre>

<p><br />
<span style="font-size:20px;">这里TIM2只是用作了DHT11更新时基,其他神马和ST差不多,唯一不同点便是这中断的写法了.</span></p>

火辣西米秀 发表于 2021-3-1 23:09

<p>PFIC 这种结构的优势是什么</p>

<p>&nbsp;</p>

w494143467 发表于 2021-3-2 13:33

<p>感谢分享!</p>

littleshrimp 发表于 2021-3-4 15:58

<p>如果代码结构基本相同是不是可以使用ST的cubemx生产配置代码 然后再加入到CH32V103的工程里来</p>

eew_VHNtMb 发表于 2021-3-7 09:47

littleshrimp 发表于 2021-3-4 15:58
如果代码结构基本相同是不是可以使用ST的cubemx生产配置代码 然后再加入到CH32V103的工程里来

<p>要更换驱动文件,还要对比st的寄存器是否相同,另外中断管理器用的不一样需要更改.但可以和自家的ch32f103共用一套程序.</p>

eew_VHNtMb 发表于 2021-3-7 10:06

火辣西米秀 发表于 2021-3-1 23:09
PFIC 这种结构的优势是什么

&nbsp;

<p>沁恒加入了硬件压栈出栈,其他和nvic差不多,大概GPS和GNSS的区别吧!</p>

火辣西米秀 发表于 2021-3-13 18:56

eew_VHNtMb 发表于 2021-3-7 10:06
沁恒加入了硬件压栈出栈,其他和nvic差不多,大概GPS和GNSS的区别吧!

<p>主要就是硬件压栈出栈</p>

<p>明白一些了,谢谢</p>
页: [1]
查看完整版本: 【RISC-V MCU CH32V103测评】+ TIM定时器的使用