|
本帖最后由 do335maomao 于 2015-2-23 20:18 编辑
之前研究了MultiWii PID部分的代码(http://bbs.5imx.com/bbs/forum.ph ... &page=1#pid15434975)
计算PID需要两方面的信息,一是传感器的信息,二是遥控接收机的信息
今天就来看看遥控接收方面的源代码,依然是2.2版本的源代码
原始的代码很长,有800多行,但是包括了PPM,SBUS,还有一些开源遥控信号
但是这次我们只看最传统的也是目前被广泛使用的PWM遥控信号,只有大概200行代码(就是一个通道要接一根线那种,对,天地飞就是)
虽然我没有看过APM的代码,但是APM与MWC用的都是AVR单片机,APM用的是mega2560,mwc也可以用在2560上,所以相信对以后学习APM也会是有帮助的
好,下面开始分析代码
volatile uint16_t rcValue[RC_CHANS] = {1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502}
static uint8_t rcChannel[RC_CHANS] = {ROLLPIN, PITCHPIN, YAWPIN, THROTTLEPIN, AUX1PIN,AUX2PIN,AUX3PIN,AUX4PIN};
static uint8_t PCInt_RX_Pins[PCINT_PIN_COUNT] = {PCINT_RX_BITS};
#define FAILSAFE_DETECT_TRESHOLD 985
最开始定义了一些要用到的变量,都可以顾名思义
我们知道,遥控信号是从1000 到 2000,中位是1502
第二行定义了八个通道分别是什么
第三行一会儿要用到
这个FAILSAFE_DETECT_TRESHOLD的意思是,若遥控信号低于这个值,就判定失控,因为遥控信号正常的时候,最低值基本在1000左右
/***********设置接收遥控信号的引脚***********/
void configureReceiver()
{
for(uint8_t i = 0; i < PCINT_PIN_COUNT; i++)
{
PCINT_RX_PORT |= PCInt_RX_Pins;
PCINT_RX_MASK |= PCInt_RX_Pins;
}
PCICR = PCIR_PORT_BIT;
#if defined(RCAUXPIN)
PCICR |= (1 << 0) ;
#if defined(RCAUXPIN8)
PCMSK0 = (1 << 0);
#endif
#if defined(RCAUXPIN12)
PCMSK0 = (1 << 4);
#endif
#endif
}
这个函数的工作是:设置Arduino上的2,4,5,6,7号口 接收前五个通道的信号
以中断的方式读取遥控信号,初始化核心工作是要设置中断 (此处以Atmega328p为例,其他芯片类似)
for循环逐一设置引,这里PCINT_RX_PORT 即 Arduino Nano上的PORTD,即数字0-7引脚
PCInt_RX_Pins = {(1<<2),(1<<4),(1<<5),(1<<6),(1<<7)}
因此i=0时, PCINT_RX_PORT |= PCInt_RX_Pins 即为 PORTD |= 0000 0100 (设置2号引脚为高)依次类推
PCINT_RX_MASK 在此处为 PCMSK2 ,即为PORTD的 Pin Change Mask Register 2
设置这个寄存器的某一位为高,即为设置相对应的引脚的中断
因此i=0时,PCINT_RX_MASK |= PCInt_RX_Pins 即为 PCMSK2 |= 0000 0100 (设置2号引脚中断)依次类推
PCICR = PCIR_PORT_BIT;
最后,设置PCICR寄存器,此处PCIR_PORT_BIT 为 (1<<2) 即允许整个PORTD的中断
循环的后半部分为设置第六个通道,在8号口,或者,12号口上方法与前面的雷同,就不赘述了
(待更新)
|
欢迎继续阅读楼主其他信息
|