九齐NY8BE62D学习笔记2-CCP捕获PWM输入

参考文章: PIC单片机捕捉模块的设计思路-EDA365

#include <ny8.h>
#include "ny8_constant.h"
#define UPDATE_REG(x)	__asm__("MOVR _" #x ",F")

#define C_TIMER_VALUE	0xFFFF

unsigned char R_COUNT;
unsigned char signal_period;
unsigned char signal_width;
// unsigned int signal_duty;
// unsigned int signal_freq;
// 存储定时器值
unsigned char H1;
unsigned char L1;
unsigned char H2;
unsigned char L2;
unsigned char H3;
unsigned char L3;
unsigned char H4;
unsigned char L4;
unsigned char time_array[5];
unsigned char time_index;

void main(void)
{
	DISI();

// Initialize GPIO
	IOSTB = C_PB2_Input;						// Set PB2 as input pin
	PORTB = 0xFF;								// PortB Data Register = 0xFF
	BPHCONbits.PHPB2 = 0;						// Set PB2 with Pull-High

// Step1: Set Timer5 operating mode
	T5CR1 = C_TMR5_Reload;
// Step2: Set Timer4 clock source, prescaler
	T4CR2 = C_PS4_Dis;
// Step3: Set 16-bit-timer reload value
	TMR4 = C_TIMER_VALUE&0x00FF;
	TMR5 = (C_TIMER_VALUE&0xFF00)>>8;
// Step4: Set capture mode
	CCPCON = C_CCP_Capt_RiseEdge;

	R_COUNT = 0;
	INTE3 = C_INT_CCP;							// Enable CCP interrupt
	INTF3 = 0;	 								// Clear CCP interrupt
	ENI();

	time_index = 0;
	signal_period = 0;
	signal_width = 0;
	// signal_duty = 0;
	// signal_freq = 0;
	// 存储定时器值
	H1 = 0;	L1 = 0;	H2 = 0;	L2 = 0;	H3 = 0;	L3 = 0;	H4 = 0;	L4 = 0;


	while(1)
	{
		CLRWDT();								// Clear WatchDog
	}
}

void isr(void) __interrupt(0)
{
	if(INTF3)
	{ 
		if(R_COUNT == 0) // 第一次上升沿
		{
			H1 = PWM5DUTY;
			L1 = PWM4DUTY;
			R_COUNT = 1;
		}
		else if(R_COUNT == 1) // 第二次上升沿
		{
			H2 = PWM5DUTY;
			L2 = PWM4DUTY;
			R_COUNT = 2;
			
		}
		else if(R_COUNT == 2) // 第三次上升沿
		{
			H3 = PWM5DUTY;
			L3 = PWM4DUTY;
			
			CCPCON = C_CCP_Capt_FallEdge; // CCP模式改为下降沿触发
			R_COUNT = 3;
		}
		else if(R_COUNT == 3) // 第四次下降沿
		{
			H4 = PWM5DUTY;
			L4 = PWM4DUTY;
			
			unsigned int time1 = (0xFF - H1) * 0x100 + 0xFF - L1;
			unsigned int time2 = (0xFF - H2) * 0x100 + 0xFF - L2;
			unsigned int time3 = (0xFF - H3) * 0x100 + 0xFF - L3;
			unsigned int time4 = (0xFF - H4) * 0x100 + 0xFF - L4;
			
			if(time4 > time3 && time3 > time2 && time2 > time1) // 略过定时器下溢
			{
				signal_period = (time3 - time1) / 2;
				signal_width = time4 - time3;
				if(signal_width > signal_period)  // 切换下降沿,可能会多出1个周期才读到下降沿,需要减去
				{
					if(signal_width > signal_period + signal_period / 100)
						signal_width -= signal_period;
					else
						signal_width = signal_period;
				}
				time_array[time_index++] = signal_width;
				// 筛掉异常的数值,取平均值
				if(time_index == 5)
				{
					unsigned char pwm_num = 0;
					unsigned char avg = (time_array[0] + time_array[1] + time_array[2] + time_array[3] + time_array[4]) / 5;
					for(char i = 0; i < 5; i++)
					{
						if(time_array[i] < (avg + avg / 10) && time_array[i] > (avg - avg / 10))
                        {
						    if(pwm_num == 0)
							    pwm_num = time_array[i];
						    else
							    pwm_num = (pwm_num + time_array[i]) / 2;
                        }
					}
					signal_width = pwm_num;
					time_index = 0;
				}
				
				/*
				signal_freq = 1 / signal_period;
				signal_duty = signal_width / signal_period;
				*/
			}
			
			CCPCON = C_CCP_Capt_RiseEdge;  // 恢复上升沿触发
			R_COUNT = 0;
			ccp_heart = 100;
		}
		INTF3 = 0;	 								// Clear CCP interrupt
	}
	
}

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值