PWM原理说明
DS600遥控器说明
DS600遥控器的默认高电平是1.5ms
1通道 左右
2通道 前后
3通道 接管 上电后是1ms ,按一下是2ms,1ms和2ms切换
DS600接收机说明
*/
#include "ps2.h"
#include "common.h"
#define LEFT_RIGHT_CHANNEL 0 //DS600 Channel1
#define FORWARD_BACKWARD_CHANNEL 1 //DS600 Channel2
#define TAKE_OVER_CHANNEL 2 //DS600 Channel3
uint32_t DS600_PWM_Start_Channel[5] = {0};
uint32_t DS600_PWM_End_Channel[5] = {0};
uint32_t DS600_H_level_Value_Channel[5] = {0};
uint16_t DS600_PWM_Value_Mid_High = 1600;
uint16_t DS600_PWM_Value_Mid_Low = 1400;
int16_t DS600_PWM_Value_Channel[5] = {0};
uint16_t DS600_Loss_Messege_Countnum_Channel[5] = {0};
uint8_t DS600_Offline_Alarmflag_Channel[5] = {0};
void Initial_flysky( uint32_t period, uint32_t scale )
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure;
TIM_ICInitTypeDef TIM12_ICInitStructure_w;
RCC_APB1PeriphClockCmd( RCC_APB1Periph_TIM12, ENABLE );
RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_GPIOB, ENABLE );
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
GPIO_Init( GPIOB, &GPIO_InitStructure );
GPIO_PinAFConfig( GPIOB, GPIO_PinSource14, GPIO_AF_TIM12 );
TIM_TimeBaseStructure.TIM_Prescaler = scale;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseStructure.TIM_Period = period;
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseInit( TIM12, &TIM_TimeBaseStructure );
TIM12_ICInitStructure_w.TIM_Channel = TIM_Channel_1;
TIM12_ICInitStructure_w.TIM_ICPolarity = TIM_ICPolarity_BothEdge;
TIM12_ICInitStructure_w.TIM_ICSelection = TIM_ICSelection_DirectTI;
TIM12_ICInitStructure_w.TIM_ICPrescaler = TIM_ICPSC_DIV1;
TIM12_ICInitStructure_w.TIM_ICFilter = 0x00;
TIM_ICInit( TIM12, &TIM12_ICInitStructure_w );
TIM_ITConfig( TIM12, TIM_IT_CC1, ENABLE );
TIM_Cmd( TIM12, ENABLE );
//Sonar12_NVIC_Configuration();
/* Enable the DMA1_Stream4_TX(UART4_TX) Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = TIM8_BRK_TIM12_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;//1
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init( &NVIC_InitStructure );
}
void Flysky_DeInit( void )
{
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd( RCC_APB1Periph_TIM12, DISABLE ); //½ûÖ¹TIM12ʱÖÓ
TIM_ITConfig( TIM12, TIM_IT_CC1 | TIM_IT_Update, DISABLE ); //½ûÖ¹¶¨Ê±Æ÷12¸üÐÂÖжÏ
TIM_Cmd( TIM12, DISABLE ); //½ûÖ¹¶¨Ê±Æ÷12
NVIC_InitStructure.NVIC_IRQChannel = TIM8_BRK_TIM12_IRQn; //¶¨Ê±Æ÷12ÖжÏ
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //ÇÀÕ¼ÓÅÏȼ¶1
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; //×ÓÓÅÏȼ¶0
NVIC_InitStructure.NVIC_IRQChannelCmd = DISABLE;
NVIC_Init( &NVIC_InitStructure );
}
uint16_t PPM_Sample_Cnt=0;
uint32_t PPM_Time=0;
uint16_t PPM_Okay=0;
uint16_t PPM_Databuf[8]={0};
uint8_t TIM12_CH1_CAPTURE_STA=0;
void TIM8_BRK_TIM12_IRQHandler(void)
{
if(TIM_GetITStatus(TIM12,TIM_IT_CC1)==!RESET)//
{
if(TIM12_CH1_CAPTURE_STA&0x01)//
{
PPM_Time=TIM_GetCapture1(TIM12);
if(PPM_Time>0)
PPM_Time++;
if(PPM_Okay==1)
{
PPM_Databuf[PPM_Sample_Cnt]=PPM_Time;
if( PPM_Databuf[4] < 800 )
{
PPM_Databuf[0] = 0;PPM_Databuf[1] = 0;
}
PPM_Sample_Cnt++;
if(PPM_Sample_Cnt>8)
PPM_Okay=0;
}
if(PPM_Time>3000)//
{
PPM_Okay=1;
PPM_Sample_Cnt=0;
}
TIM_OC1PolarityConfig(TIM12,TIM_ICPolarity_Rising);
TIM12_CH1_CAPTURE_STA=0;//
}
else
{
TIM_SetCounter(TIM12,0);//
TIM12_CH1_CAPTURE_STA|=0x01;//
TIM_OC1PolarityConfig(TIM12,TIM_ICPolarity_Falling);
}
}
TIM_ClearITPendingBit(TIM12, TIM_IT_CC1|TIM_IT_Update);
}
void Init_DS600(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
EXTI_InitTypeDef EXTI_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_GPIOB, ENABLE ); //ʹÄÜGPIOBʱÖÓ
RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_GPIOC, ENABLE ); //ʹÄÜGPIOCʱÖÓ
RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_GPIOE, ENABLE ); //ʹÄÜGPIOEʱÖÓ
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);//ʹÄÜSYSCFGʱÖÓ
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;//ÆÕͨÊä³öģʽ
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//ÉÏÀ
GPIO_Init(GPIOB, &GPIO_InitStructure);//³õʼ»¯
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;//ÆÕͨÊä³öģʽ
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//ÉÏÀ
GPIO_Init(GPIOC, &GPIO_InitStructure);//³õʼ»¯
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;//ÆÕͨÊä³öģʽ
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//ÉÏÀ
GPIO_Init(GPIOE, &GPIO_InitStructure);//³õʼ»¯
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOB, EXTI_PinSource14);//PF6 Á¬½Óµ½ÖжÏÏß6
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOC, EXTI_PinSource9);//PF6 Á¬½Óµ½ÖжÏÏß6
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOE, EXTI_PinSource11);//PF6 Á¬½Óµ½ÖжÏÏß6
EXTI_InitStructure.EXTI_Line = EXTI_Line14 | EXTI_Line9 | EXTI_Line11;//LINE14
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;//ÖжÏʼþ
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling; //shangϽµÑØ´¥·¢
EXTI_InitStructure.EXTI_LineCmd = ENABLE;//ʹÄÜLINE6
EXTI_Init(&EXTI_InitStructure);//ÅäÖÃ
NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;//ÍⲿÖжÏ5
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x00;//ÇÀÕ¼ÓÅÏȼ¶3
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00;//×ÓÓÅÏȼ¶2
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//ʹÄÜÍⲿÖжÏͨµÀ
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;//ÍⲿÖжÏ5
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x00;//ÇÀÕ¼ÓÅÏȼ¶3
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00;//×ÓÓÅÏȼ¶2
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//ʹÄÜÍⲿÖжÏͨµÀ
NVIC_Init(&NVIC_InitStructure);
}
//ÍⲿÖжϷþÎñº¯Êý
void EXTI9_5_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line9) != RESET)
{
if(GPIOC->IDR & GPIO_Pin_9)
{
DS600_PWM_Start_Channel[TAKE_OVER_CHANNEL] = micros();
}
else
{
DS600_PWM_End_Channel[TAKE_OVER_CHANNEL]= micros();
DS600_H_level_Value_Channel[TAKE_OVER_CHANNEL] = DS600_PWM_End_Channel[TAKE_OVER_CHANNEL] - DS600_PWM_Start_Channel[TAKE_OVER_CHANNEL];
if(DS600_H_level_Value_Channel[TAKE_OVER_CHANNEL]>900 && DS600_H_level_Value_Channel[TAKE_OVER_CHANNEL]<2100)
{
//stop
DS600_PWM_Value_Channel[TAKE_OVER_CHANNEL] = DS600_H_level_Value_Channel[TAKE_OVER_CHANNEL];
DS600_Loss_Messege_Countnum_Channel[TAKE_OVER_CHANNEL] = 0;
DS600_Offline_Alarmflag_Channel[TAKE_OVER_CHANNEL] = 0;
}
else
{
DS600_PWM_Value_Channel[TAKE_OVER_CHANNEL] = 1500;
}
}
EXTI_ClearITPendingBit(EXTI_Line9);
}
}
//ÍⲿÖжϷþÎñº¯Êý
void EXTI15_10_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line11) != RESET)
{
if(GPIOE->IDR & GPIO_Pin_11)
{
DS600_PWM_Start_Channel[FORWARD_BACKWARD_CHANNEL] = micros();
}
else
{
DS600_PWM_End_Channel[FORWARD_BACKWARD_CHANNEL]= micros();
DS600_H_level_Value_Channel[FORWARD_BACKWARD_CHANNEL] = DS600_PWM_End_Channel[FORWARD_BACKWARD_CHANNEL] - DS600_PWM_Start_Channel[FORWARD_BACKWARD_CHANNEL];
if(DS600_H_level_Value_Channel[FORWARD_BACKWARD_CHANNEL]>900 && DS600_H_level_Value_Channel[FORWARD_BACKWARD_CHANNEL]<2100)
{
//PPMINF[5]=PPM_end[5]-INF_DAT[PPM_mid5];
if( (DS600_H_level_Value_Channel[FORWARD_BACKWARD_CHANNEL] > DS600_PWM_Value_Mid_Low) && (DS600_H_level_Value_Channel[FORWARD_BACKWARD_CHANNEL] < DS600_PWM_Value_Mid_High) )
{
//stop
DS600_PWM_Value_Channel[FORWARD_BACKWARD_CHANNEL] = 0;
}
else
{
//move
if(DS600_H_level_Value_Channel[FORWARD_BACKWARD_CHANNEL] >= DS600_PWM_Value_Mid_High)
{
DS600_PWM_Value_Channel[FORWARD_BACKWARD_CHANNEL] = DS600_H_level_Value_Channel[FORWARD_BACKWARD_CHANNEL] - DS600_PWM_Value_Mid_High;
}
else
{
DS600_PWM_Value_Channel[FORWARD_BACKWARD_CHANNEL] = DS600_H_level_Value_Channel[FORWARD_BACKWARD_CHANNEL] - DS600_PWM_Value_Mid_Low;
}
}
DS600_Loss_Messege_Countnum_Channel[FORWARD_BACKWARD_CHANNEL] = 0;
DS600_Offline_Alarmflag_Channel[FORWARD_BACKWARD_CHANNEL] = 0;
}
else
{
DS600_PWM_Value_Channel[FORWARD_BACKWARD_CHANNEL] = 0;
}
}
EXTI_ClearITPendingBit(EXTI_Line11);
}
if(EXTI_GetITStatus(EXTI_Line14) != RESET)
{
if(GPIOB->IDR & GPIO_Pin_14)
{
DS600_PWM_Start_Channel[LEFT_RIGHT_CHANNEL] = micros();
}
else
{
DS600_PWM_End_Channel[LEFT_RIGHT_CHANNEL]= micros();
DS600_H_level_Value_Channel[LEFT_RIGHT_CHANNEL] = DS600_PWM_End_Channel[LEFT_RIGHT_CHANNEL] - DS600_PWM_Start_Channel[LEFT_RIGHT_CHANNEL];
if(DS600_H_level_Value_Channel[LEFT_RIGHT_CHANNEL]>900 && DS600_H_level_Value_Channel[LEFT_RIGHT_CHANNEL]<2100)
{
//PPMINF[5]=PPM_end[5]-INF_DAT[PPM_mid5];
if( (DS600_H_level_Value_Channel[LEFT_RIGHT_CHANNEL] > DS600_PWM_Value_Mid_Low) && (DS600_H_level_Value_Channel[LEFT_RIGHT_CHANNEL] < DS600_PWM_Value_Mid_High) )
{
//stop
DS600_PWM_Value_Channel[LEFT_RIGHT_CHANNEL] = 0;
}
else
{
//move
if(DS600_H_level_Value_Channel[LEFT_RIGHT_CHANNEL] >= DS600_PWM_Value_Mid_High)
{
DS600_PWM_Value_Channel[LEFT_RIGHT_CHANNEL] = DS600_H_level_Value_Channel[LEFT_RIGHT_CHANNEL] - DS600_PWM_Value_Mid_High;
}
else
{
DS600_PWM_Value_Channel[LEFT_RIGHT_CHANNEL] = DS600_H_level_Value_Channel[LEFT_RIGHT_CHANNEL] - DS600_PWM_Value_Mid_Low;
}
}
DS600_Loss_Messege_Countnum_Channel[LEFT_RIGHT_CHANNEL] = 0;
DS600_Offline_Alarmflag_Channel[LEFT_RIGHT_CHANNEL] = 0;
}
else
{
DS600_PWM_Value_Channel[LEFT_RIGHT_CHANNEL] = 0;
}
}
EXTI_ClearITPendingBit(EXTI_Line14);
}
}
void DS600_online_check(void)
{
DS600_Loss_Messege_Countnum_Channel[LEFT_RIGHT_CHANNEL]++;
DS600_Loss_Messege_Countnum_Channel[FORWARD_BACKWARD_CHANNEL]++;
DS600_Loss_Messege_Countnum_Channel[2]++;
if(DS600_Loss_Messege_Countnum_Channel[LEFT_RIGHT_CHANNEL] > 10)
{
DS600_Loss_Messege_Countnum_Channel[LEFT_RIGHT_CHANNEL] = 0;
DS600_Offline_Alarmflag_Channel[LEFT_RIGHT_CHANNEL] = 1;
DS600_PWM_Value_Channel[LEFT_RIGHT_CHANNEL] = 0;
}
if(DS600_Loss_Messege_Countnum_Channel[FORWARD_BACKWARD_CHANNEL] > 10)
{
DS600_Loss_Messege_Countnum_Channel[FORWARD_BACKWARD_CHANNEL] = 0;
DS600_Offline_Alarmflag_Channel[FORWARD_BACKWARD_CHANNEL] = 1;
DS600_PWM_Value_Channel[FORWARD_BACKWARD_CHANNEL] = 0;
}
if(DS600_Loss_Messege_Countnum_Channel[TAKE_OVER_CHANNEL] > 10)
{
DS600_Loss_Messege_Countnum_Channel[TAKE_OVER_CHANNEL] = 0;
DS600_Offline_Alarmflag_Channel[TAKE_OVER_CHANNEL] = 1;
DS600_PWM_Value_Channel[TAKE_OVER_CHANNEL] = 1500;
}
}