CH582使用SysTick滴答定时器

参考:

CH579 CH5573 CH582 嘀嗒定时器使用

SysTick就是一个定时器而已,只是它放在了NVIC中,主要的目的是为了给操作系统提供一个硬件上的中断(号称滴答中断)。只要不把它在SysTick控制及状态寄存器中的使能位清除,就永不停息。

使用SysTick的方法其实很简单,只需要在main.c的初始化中添加SysTick_Config()函数,设定嘀嗒时间,并在对应的中断函数中清除对应的标志即可。

SysTick_Config()函数在core_riscv.h中:

#define SysTick_LOAD_RELOAD_Msk    (0xFFFFFFFFFFFFFFFF)
#define SysTick_CTLR_INIT          (1 << 5)
#define SysTick_CTLR_MODE          (1 << 4)
#define SysTick_CTLR_STRE          (1 << 3)
#define SysTick_CTLR_STCLK         (1 << 2)
#define SysTick_CTLR_STIE          (1 << 1)
#define SysTick_CTLR_STE           (1 << 0)

#define SysTick_SR_CNTIF           (1 << 0)

RV_STATIC_INLINE uint32_t SysTick_Config(uint64_t ticks)
{
    if((ticks - 1) > SysTick_LOAD_RELOAD_Msk)
        return (1); /* Reload value impossible */

    SysTick->CMP = ticks - 1; /* set reload register */
    PFIC_EnableIRQ(SysTick_IRQn);
    SysTick->CTLR = SysTick_CTLR_INIT |
                    SysTick_CTLR_STRE |
                    SysTick_CTLR_STCLK |
                    SysTick_CTLR_STIE |
                    SysTick_CTLR_STE; /* Enable SysTick IRQ and SysTick Timer */
    return (0);                       /* Function successful */
}

这里在初始化时,通过设置系统计数控制寄存器SysTick->CTLRSysTick设置为了向上计数从0开始,并使能了自动重载计数,计数器时钟源为HCLK,同时使能了计数器中断,启动计数器。

关于SysTick计数时间的计算很简单,看下面就行:

// 设定嘀嗒时间 1000ms
#define SYSTICK_INTERVAL (1000)

//  自动重新加载计数值,计数时钟60M的话,以1ms为例,参数是60000
SysTick_Config( GetSysClock() / 1000 * SYSTICK_INTERVAL);  //设定嘀嗒时间1000ms

在这里插入图片描述

在这里插入图片描述

这里我是在新建工程的串口模板工程中修改的:


#include "CH58x_common.h"

uint8_t TxBuff[] = "This is a tx exam\r\n";
uint8_t RxBuff[100];
uint8_t trigB;

// 设定嘀嗒时间 1000 ms
#define SYSTICK_INTERVAL 	(1000)

// SysTick完成一次计时中断的标志
volatile uint8_t systick_flag = 0;

/*********************************************************************
 * @fn      main
 *
 * @brief   主函数
 *
 * @return  none
 */
int main()
{
    SetSysClock(CLK_SOURCE_PLL_60MHz);

    //  自动重新加载计数值,计数时钟60M,以1ms为例,参数是60000
    SysTick_Config( GetSysClock() / 1000 * SYSTICK_INTERVAL);  //设定嘀嗒时间1000ms

    /* 配置串口1:先配置IO口模式,再配置串口 */
    GPIOA_SetBits(GPIO_Pin_9);
    GPIOA_ModeCfg(GPIO_Pin_8, GPIO_ModeIN_PU);      // RXD-配置上拉输入
    GPIOA_ModeCfg(GPIO_Pin_9, GPIO_ModeOut_PP_5mA); // TXD-配置推挽输出,注意先让IO口输出高电平
    UART1_DefInit();

 // 中断方式:接收数据后发送出去
    UART1_ByteTrigCfg(UART_7BYTE_TRIG);
    trigB = 7;
    UART1_INTCfg(ENABLE, RB_IER_RECV_RDY | RB_IER_LINE_STAT);
    PFIC_EnableIRQ(UART1_IRQn);

    PRINT("GetSysClock: %d\n", GetSysClock());

    while(1)
    {
        if(systick_flag)
        {
            systick_flag = 0;
            UART1_SendString("SysTick_Handler\n", strlen("SysTick_Handler\n"));
        }
    }

}

// SysTick中断函数
__INTERRUPT
__HIGH_CODE
void SysTick_Handler()
{
    systick_flag = 1;
    SysTick->SR = 0;    // 清除中断标志
//    UART1_SendString("SysTick_Handler\r\n", strlen("SysTick_Handler\r\n"));
}

/*********************************************************************
 * @fn      UART1_IRQHandler
 *
 * @brief   UART1中断函数
 *
 * @return  none
 */
__INTERRUPT
__HIGH_CODE
void UART1_IRQHandler(void)
{
    volatile uint8_t i;

    switch(UART1_GetITFlag())
    {
        case UART_II_LINE_STAT: // 线路状态错误
        {
//            UART1_GetLinSTA();
            break;
        }

        case UART_II_RECV_RDY: // 数据达到设置触发点
            for(i = 0; i != trigB; i++)
            {
                RxBuff[i] = UART1_RecvByte();
                UART1_SendByte(RxBuff[i]);
            }
            break;

        case UART_II_RECV_TOUT: // 接收超时,暂时一帧数据接收完成
            i = UART1_RecvString(RxBuff);
            UART1_SendString(RxBuff, i);
            break;

        case UART_II_THR_EMPTY: // 发送缓存区空,可继续发送
            break;

        case UART_II_MODEM_CHG: // 只支持串口0
            break;

        default:
            break;
    }
}

测试效果如下:

在这里插入图片描述

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值