W600 PWM 捕获功能使用示例程序

使用DMA的方式来捕获输入波形中一个周期内的高低电平的持续时间,从而计算出输入频率;

捕获分辨率在这里设置到了1us;

/***************************************************************************** 
* 
* File Name : main.c
* 
* Description: main 
* 
* Copyright (c) 2014 Winner Micro Electronic Design Co., Ltd. 
* All rights reserved. 
* 
* Author : dave
* 
* Date : 2014-6-14
*****************************************************************************/ 
#include "wm_include.h"
#include "wm_type_def.h"
#include "FreeRTOS.h"
#include "task.h"
#include "wm_gpio.h"
#include "wm_pwm.h"
#include "wm_cpu.h"
#include "wm_dma.h"
#include "wm_gpio_afsel.h"
#include "wm_timer.h"


#define COUNTER_FREQ    1000000
#define ZERO_DETEC_IO	WM_IO_PB_18
#define PWM_CAP_CHANNEL 0

typedef struct _frequency_info 
{
	volatile u32 pwmDmaCap;
	volatile u32 period_ticks;
	volatile u32 frequecy;
} frequency_info;

static frequency_info f_info;

static void pwm_dma_callback(void *arg)
{
	//printf("pwmH:%d, pwmL:%d\n", (f_info.pwmDmaCap >> 16), (f_info.pwmDmaCap & 0x0000ffff));
	f_info.period_ticks = (f_info.pwmDmaCap >> 16) + (f_info.pwmDmaCap & 0x0000ffff);
}

static int pwm_capture_mode_dma(u8 channel, u32 freq)
{
    u8 dmaCh;
	int frequecy = 0, high, low;
    struct tls_dma_descriptor DmaDesc;
    tls_sys_clk sysclk;

	memset( &f_info, 0, sizeof(f_info) );
    tls_sys_clk_get(&sysclk);
	wm_pwm1_config(ZERO_DETEC_IO);
    tls_pwm_stop(channel);

    dmaCh = tls_dma_request(1, TLS_DMA_FLAGS_CHANNEL_SEL(TLS_DMA_SEL_PWM_CAP0) | TLS_DMA_FLAGS_HARD_MODE);
    DmaDesc.src_addr = HR_PWM_CAPDAT;
    DmaDesc.dest_addr = (unsigned int)&(f_info.pwmDmaCap);
    DmaDesc.dma_ctrl = TLS_DMA_DESC_CTRL_DEST_ADD_INC | TLS_DMA_DESC_CTRL_BURST_SIZE1 | TLS_DMA_DESC_CTRL_DATA_SIZE_WORD | TLS_DMA_DESC_CTRL_TOTAL_BYTES(400);
    DmaDesc.valid = TLS_DMA_DESC_VALID;
    DmaDesc.next = NULL;
    tls_dma_start(dmaCh, &DmaDesc, 0);
    tls_dma_irq_register(dmaCh, pwm_dma_callback, NULL, TLS_DMA_IRQ_TRANSFER_DONE);

    tls_pwm_cap_init(channel, sysclk.apbclk * UNIT_MHZ / freq, DISABLE, WM_PWM_CAP_DMA_INT);
    tls_pwm_start(channel);
	while(f_info.period_ticks == 0);
	tls_pwm_stop(channel);
	high = f_info.period_ticks>>16;
	low = f_info.period_ticks&0xffff;
	printf("LEVEL: H:%d, L:%d\n", high, low);
	frequecy = COUNTER_FREQ/(high + low);
	printf("input freq: %dHz\n", frequecy);
	f_info.frequecy = frequecy;
	return frequecy;
}

static int gpio_initial(void)
{
    tls_gpio_cfg(ZERO_DETEC_IO, WM_GPIO_DIR_INPUT, WM_GPIO_ATTR_PULLHIGH);

    return WM_SUCCESS;
}

void ctrl_task9(int *arg)
{

	printf("application start.\n");
	wm_pwm2_config(WM_IO_PB_17);
	tls_pwm_init(1, 60, 99, 0);
    tls_pwm_start(1);
	gpio_initial();
	
	pwm_capture_mode_dma(PWM_CAP_CHANNEL, COUNTER_FREQ);
    while(1)
    {	
		tls_os_time_delay(HZ);
    }
}



int misc_task_start(void (*func)(void *), char *task_name, 
                    u32 stack_size, void *arg, u8 uxTaskPriority)
{
    return xTaskCreate(func,          /* The function that implements the task. */
                      task_name,      /* Just a text name for the task to aid debugging. */
                      stack_size,     /* The stack size is defined in FreeRTOSIPConfig.h. */
                      arg,            /* The task parameter, not used in this case. */
                      uxTaskPriority, /* The priority assigned to the task is defined in FreeRTOSConfig.h. */
                      NULL);          /* The task handle is not used. */

}

void UserMain(void)
{
	misc_task_start(ctrl_task9, "ctr9", 256, NULL, 5);	
}

发布了63 篇原创文章 · 获赞 95 · 访问量 41万+

猜你喜欢

转载自blog.csdn.net/zwl1584671413/article/details/103127014
PWM