第一次使用学习单片机编程, 使用了n76e003, 主要在检测pwm的信号问题上花了比较多的时间,最后是使用了timer2的0通道来捕捉上升缘,1通道来捕捉下降缘来检测pwm的宽度。
接收机是0-2000us pwm输出,500-1000是基础的pwm, 就是说没有信号也定期输出500(舵机)或1000(油门),这样单片机可以检测到有无信号.
timer0来控制led的开关和闪烁,timer0使用10khz, timer2使用16m的时钟.
#include "N76E003.h"
#include "Common.h"
#include "Delay.h"
#include "SFR_Macro.h"
#include "Function_define.h"
unsigned int pulse_width = 0;
unsigned char rising_cap=1;
#define LED_OFF 0
#define LED_FLASH_SLOW 1
#define LED_FLASH_NORMAL 2
#define LED_FLASH_FAST 3
#define LED_FLASH_ALL_FAST 4
unsigned char led_mod =0;
unsigned int tick;
UINT8 u8TH0_Tmp,u8TL0_Tmp;
/************************************************************************************************************
* TIMER 0 interrupt subroutine
************************************************************************************************************/
void Timer0_ISR (void) interrupt 1 //interrupt address is 0x000B
{
// interrupt every 10ms
//clr_TF0;
TH0 = u8TH0_Tmp;
TL0 = u8TL0_Tmp;
tick++;
switch(led_mod)
{
case LED_FLASH_SLOW:
//one 1/4 second
if(tick < 25)
{
set_P01;
}
else
{
clr_P01;
}
set_P00;
set_P02;
break;
/*
case LED_FLASH_NORMAL:
break;
case LED_FLASH_FAST:
break;
case LED_FLASH_ALL_FAST:
break;*/
default:
{
clr_P00;
clr_P01;
clr_P02;
}
break;
}
if(tick>150)
{
tick = 0;
}
}
/************************************************************************************************************
* Timer2 Capture interrupt subroutine
************************************************************************************************************/
void Capture_ISR (void) interrupt 12
{
if(CAPCON0 & 0x01)
{
clr_CAPF0;
}
if(CAPCON0 & 0x02)
{
clr_CAPF1;
pulse_width = C1H;
pulse_width <<= 8;
pulse_width |= C1L;
if(pulse_width>24000) //1/16m = 0.0000000625 * 24000 ==1500
{
led_mod = LED_FLASH_SLOW;
//set_P00;
}
else
{
led_mod = LED_OFF;
// clr_P00;
}
}
}
/************************************************************************************************************
* Main function
************************************************************************************************************/
void main (void)
{
Set_All_GPIO_Quasi_Mode;
// InitialUART0_Timer3(115200);
P05_Input_Mode; //PWM Input
P00_PushPull_Mode;
P01_PushPull_Mode;
P02_PushPull_Mode;
clr_P00;
clr_P01;
clr_P02;
TIMER0_MODE1_ENABLE;
clr_T0M; //set div 12 10khz mode;
u8TH0_Tmp = TIMER_DIV12_VALUE_10ms/256; //every 10 ms
u8TL0_Tmp = TIMER_DIV12_VALUE_10ms%256; //every 10 ms
TH0 = u8TH0_Tmp; //set time out
TL0 = u8TL0_Tmp;
TIMER2_CAP0_Capture_Mode;
IC6_P05_CAP0_RisingEdge_Capture;
IC6_P05_CAP1_FallingEdge_Capture;
set_ET0; //enable Timer0 interrupt
set_ECAP; //Enable Capture interrupt
set_EA;
set_TR0; //Timer0 run
set_TR2; //Triger Timer2
while(1);
}