137 timerm cap

#include "bat32g137.h"
#include "userdefine.h"
#include "clk.h"
#include "tmm.h"

/***********************************************************************************************************************
* Function Name: TMM0_Init
* Description  : This function initializes the TMM0 module.
* Arguments    : None
* Return Value : None
***********************************************************************************************************************/
void TMM0_Init(void)
{
	// 开启时钟
    CGC->PER1 |= CGC_PER1_TMMEN_Msk;     /* enables input clock supply */
	// 匹配后不清除定时器
    TMM->TMSTR |= _04_TMM_TM0_COUNT_CONTINUES;
	// 停止定时器
    TMM->TMSTR &= (uint8_t)~_01_TMM_TM0_COUNT_START;
	// D作为B的缓冲区 
	// C作为A的缓冲区
    TMM->TMMR |= _10_TMM_TMGRC0_BUFFER | _20_TMM_TMGRD0_BUFFER;
	// 时钟源是 FHOCO
    TMM->TMCR0 = _00_TMM_COUNTER_CLEAR_DISABLE | _00_TMM_INETNAL_CLOCK_FCLK_FHOCO;
	// 捕获模式 上升沿
    TMM->TMIORA0 = _40_TMM_TMGRB_CAPTURE | _00_TMM_TMGRB_CAPTURE_RISING | _04_TMM_TMGRA_CAPTURE | _00_TMM_TMGRA_CAPTURE_RISING;
    TMM->TMIORC0 |= _40_TMM_TMGRD_CAPTURE | _04_TMM_TMGRC_CAPTURE;
	// 开启对应的中断
    TMM->TMIER0 = _10_TMM_OVIE_ENABLE | _08_TMM_IMID_ENABLE | _02_TMM_IMIB_ENABLE | _01_TMM_IMIA_ENABLE;
    TMM->TMPOCR0 = _00_TMIOD_OUTPUT_ACTIVE_L | _00_TMIOC_OUTPUT_ACTIVE_L | _00_TMIOB_OUTPUT_ACTIVE_L;
	// 初始化IO为输入模式
    /* Set TMIOA0 pin */
    PORT->PM1 |= 0x80U; // P17
    /* Set TMIOB0 pin */
    PORT->PM1 |= 0x10U; // P14
}
/***********************************************************************************************************************
* Function Name: TMM0_Start
* Description  : This function starts TMM0 counter.
* Arguments    : None
* Return Value : None
***********************************************************************************************************************/
void TMM0_Start(void)
{
    volatile uint8_t tmsr_dummy;
	// 清除挂起
    INTC_ClearPendingIRQ(TMM0_IRQn);/* clear INTTMM0 interrupt flag */
	// 读取状态寄存器 读取清除状态寄存器数据
    tmsr_dummy = TMM->TMSR0; /* read TMSR0 before write 0 */
    TMM->TMSR0 = 0x00U; /* clear TM0 each interrupt request */
	// 开启使能
    INTC_EnableIRQ(TMM0_IRQn);/* enable INTTMM0 interrupt */
	// 启动定时器
    TMM->TMSTR |= _01_TMM_TM0_COUNT_START;
}


/***********************************************************************************************************************
* Function Name: pulse_out_init
* Description  : This function initializes the pulse out module.
* Arguments    : None
* Return Value : None
***********************************************************************************************************************/
static void pulse_out_init(void)
{
	//禁止输出
	PCBZ->CKS0 &= (uint8_t)~0x80;
    PCBZ->CKS0 = 0x07; // 5.86K 170us
    /* Set CLKBUZ0 pin */
    PORT->P14 &= 0xFEU;
    PORT->PM14 &= 0xFEU; // P140
	// 使能输出
	PCBZ->CKS0 |= 0x80;
}

// beep 功能产生方波
int main(void)
{
	TMM0_Init();
	TMM0_Start();
	pulse_out_init();
	while(1)
	{
		
	}
}

void IRQ27_Handler(void) __attribute__((alias("tmm0_interrupt")));
volatile uint32_t g_tmm0_active_width_a = 0UL;
volatile uint32_t g_tmm0_inactive_width_a = 0UL;
volatile uint32_t g_tmm0_active_width_b = 0UL;
volatile uint32_t g_tmm0_inactive_width_b = 0UL;
volatile uint32_t g_tmm0_active_width_c = 0UL;
volatile uint32_t g_tmm0_inactive_width_c = 0UL;
volatile uint32_t g_tmm0_active_width_d = 0UL;
volatile uint32_t g_tmm0_inactive_width_d = 0UL;
volatile uint32_t g_tmm0_active_width_elc = 0UL;
volatile uint32_t g_tmm0_inactive_width_elc = 0UL;
volatile uint16_t g_tmm0_tmgra_old = 0U;
volatile uint16_t g_tmm0_tmgrb_old = 0U;
volatile uint8_t  g_tmm0_ovf_a = 0U;
volatile uint8_t  g_tmm0_ovf_b = 0U;

/***********************************************************************************************************************
* Function Name: tmm0_interrupt
* Description  : None
* Arguments    : None
* Return Value : None
***********************************************************************************************************************/
static void tmm0_interrupt(void)
{
	// 首先清除挂起
    INTC_ClearPendingIRQ(TMM0_IRQn); /* clear INTTMM0 interrupt flag */
    uint8_t  tmsr0_temp = TMM->TMSR0;
	// 读取数据
    uint16_t tmm_pul_a_cur = TMM->TMGRA0;
    uint16_t tmm_pul_b_cur = TMM->TMGRB0;
    uint8_t  tmier0_temp = TMM->TMIER0;

	// 关闭中断
    TMM->TMIER0 = 0x00U;

    if ((TMM->TMSR0 & _10_TMM0_INTOV_GENERATE_FLAG) == _10_TMM0_INTOV_GENERATE_FLAG)
    {
        TMM->TMSR0 = tmsr0_temp & (uint8_t)~_10_TMM0_INTOV_GENERATE_FLAG;
		// 记录溢出次数
        g_tmm0_ovf_a += 1U;
        g_tmm0_ovf_b += 1U;
    }

    if ((TMM->TMSR0 & _01_TMM0_INTA_GENERATE_FLAG) == _01_TMM0_INTA_GENERATE_FLAG)
    {
		// 清状态
        TMM->TMSR0 = tmsr0_temp & (uint8_t)~_01_TMM0_INTA_GENERATE_FLAG;

        if (g_tmm0_ovf_a == 0U)
        {
            //g_tmm0_active_width_a = (uint32_t)((uint32_t)tmm_pul_a_cur - (uint32_t)g_tmm0_tmgra_old);
			g_tmm0_active_width_a = (uint32_t)((uint32_t)tmm_pul_a_cur - (uint32_t)TMM->TMGRC0);
        }
        else
        {
           // g_tmm0_active_width_a = (uint32_t)(0x10000UL * (uint32_t)g_tmm0_ovf_a - (uint32_t)g_tmm0_tmgra_old + 
                                       //  (uint32_t)tmm_pul_a_cur);
			g_tmm0_active_width_a = (uint32_t)(0x10000UL * (uint32_t)g_tmm0_ovf_a - (uint32_t)TMM->TMGRC0 + 
                                         (uint32_t)tmm_pul_a_cur);
            g_tmm0_ovf_a = 0U;
        }

        g_tmm0_inactive_width_a = 0UL;
        g_tmm0_tmgra_old = tmm_pul_a_cur;
    }

    if ((TMM->TMSR0 & _02_TMM0_INTB_GENERATE_FLAG) == _02_TMM0_INTB_GENERATE_FLAG)
    {
        TMM->TMSR0 = tmsr0_temp & (uint8_t)~(_02_TMM0_INTB_GENERATE_FLAG);

        if (g_tmm0_ovf_b == 0U)
        {
            g_tmm0_active_width_b = (uint32_t)((uint32_t)tmm_pul_b_cur - (uint32_t)g_tmm0_tmgrb_old);
        }
        else
        {
            g_tmm0_active_width_b = (uint32_t)(0x10000UL * (uint32_t)g_tmm0_ovf_b - (uint32_t)g_tmm0_tmgrb_old + 
                                         (uint32_t)tmm_pul_b_cur);
            g_tmm0_ovf_b = 0U;
        }

        g_tmm0_inactive_width_b = 0UL;
        g_tmm0_tmgrb_old = tmm_pul_b_cur;
    }

    TMM->TMIER0 = tmier0_temp;

}

尝试两种用缓冲区不用缓冲区,测试时间都很准确,170u的数据。

8192/48 = 170us.

开启缓冲区,缓冲区和timerb一样,缓冲区的数据可以理解就是上一次的数据。

程序中有一个用了读缓冲来提取的有一个没有,测试都很准确,其中很重要的一点,进入中断过后,程序立马读取了数据。因为这些寄存器会一直在变。开缓冲的意义就在这里。

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值