do not know pa0-pa7 problem?
code
#include <avr/io.h>
#include <avr/interrupt.h>
#include <string.h>
#include <stdio.h>
#include <math.h>
#include <avr/signal.h>
#include <avr/wdt.h>
#include <avr/pgmspace.h>
#include <avr/sleep.h>
#include <avr/eeprom.h>
#include <avr/wdt.h>
#include <avr/delay.h>
#include "UART/uart.h"
#include "UART/xitoa.h"
#define LED 0
#define LED_OFF PORTB &= ~_BV(LED)
#define LED_ON PORTB |= _BV(LED)
#define sbi(reg, bit) reg |= (1<<bit) // SET
#define cbi(reg, bit) reg &=~(1<<bit) // CLEAR
#define output_low(port,pin) port &= ~(1<<pin)
#define output_high(port,pin) port |= (1<<pin)
#define set_input(portdir,pin) portdir &= ~(1<<pin)
#define set_output(portdir,pin) portdir |= (1<<pin)
/**
* Receiver pulse timings
*
* Standard RC receivers output high pulses between 0.5 ms and 2.5 ms with a neutral
* position of about 1.5 ms. If your RC receiver operates with different pulse
* widths, change these constants below.
*
* The units of these constants is ticks of Timer1 which is set to tick every 3.2
* microseconds.
*
*/
const int minPulseTime = 156; // 0.5 ms
const int neutralPulseTime = 469; // 1.5 ms
const int maxPulseTime = 782; // 2.5ms
const int maxLowPulseTime = 3000; // 9.6ms
struct ChannelStruct
{
volatile unsigned int prevTime;
volatile unsigned int lowDur;
volatile unsigned int highDur;
volatile unsigned char newPulse;
unsigned int pulse;
unsigned char error;
};
struct ChannelStruct ch[7];
/*
* Pin Change interrupts
* PCI0 triggers on PCINT7..0
* PCI1 triggers on PCINT14..8
* PCI2 triggers on PCINT23..16
* PCI3 triggers on PCINT31..24
* PCMSK2, PCMSK1, PCMSK0 registers control which pins contribute.
*
* The following table is useful:
*
* AVR pin PCINT # PCI #
* --------- ----------------- -----
* PA0 - PA7 PCINT0 - PCINT7 PCO0
* PB0 - PB3 PCINT8 - PCINT11 PCI1
* PC0 - PC5 PCINT16 - PCINT23 PCI2
* PD0 - PD7 PCINT24 - PCINT31 PCI3
*
*/
// This interrupt service routine is for the channel connected to PaA0-PA5
ISR(PCINT0_vect)
{
// Save a snapshot of PINA at the current time
unsigned char pina = PINA;
unsigned int time = TCNT1;
if(pina & (1 << PORTA0))
{
// PA0 has changed to high so record the low pulse's duration
ch[0].lowDur = time - ch[0].prevTime;
}
else
{
// PA0 has changed to low so record the high pulse's duration
ch[0].highDur = time - ch[0].prevTime;
ch[0].newPulse = 1; // The high pulse just finished so we can process it now
}
ch[0].prevTime = time;
if(pina & (1 << PORTA1))
{
// PA1 has changed to high so record the low pulse's duration
ch[1].lowDur = time - ch[1].prevTime;
}
else
{
// PA1 has changed to low so record the high pulse's duration
ch[1].highDur = time - ch[1].prevTime;
ch[1].newPulse = 1; // The high pulse just finished so we can process it now
}
ch[1].prevTime = time;
if(pina & (1 << PORTA2))
{
// PA2 has changed to high so record the low pulse's duration
ch[2].lowDur = time - ch[2].prevTime;
}
else
{
// PA2 has changed to low so record the high pulse's duration
ch[2].highDur = time - ch[2].prevTime;
ch[2].newPulse = 1; // The high pulse just finished so we can process it now
}
ch[2].prevTime = time;
if(pina & (1 << PORTA3))
{
// PA3 has changed to high so record the low pulse's duration
ch[3].lowDur = time - ch[3].prevTime;
}
else
{
// PA3 has changed to low so record the high pulse's duration
ch[3].highDur = time - ch[3].prevTime;
ch[3].newPulse = 1; // The high pulse just finished so we can process it now
}
ch[3].prevTime = time;
if(pina & (1 << PORTA4))
{
// PA4 has changed to high so record the low pulse's duration
ch[4].lowDur = time - ch[4].prevTime;
}
else
{
// PA4 has changed to low so record the high pulse's duration
ch[4].highDur = time - ch[4].prevTime;
ch[4].newPulse = 1; // The high pulse just finished so we can process it now
}
ch[4].prevTime = time;
if(pina & (1 << PORTA5))
{
// PA5 has changed to high so record the low pulse's duration
ch[5].lowDur = time - ch[5].prevTime;
}
else
{
// PA5 has changed to low so record the high pulse's duration
ch[5].highDur = time - ch[5].prevTime;
ch[5].newPulse = 1; // The high pulse just finished so we can process it now
}
ch[5].prevTime = time;
if(pina & (1 << PORTA6))
{
// PA5 has changed to high so record the low pulse's duration
ch[6].lowDur = time - ch[6].prevTime;
}
else
{
// PA5 has changed to low so record the high pulse's duration
ch[6].highDur = time - ch[6].prevTime;
ch[6].newPulse = 1; // The high pulse just finished so we can process it now
}
ch[6].prevTime = time;
}
/**
* updateChannels ensures the recevied signals are valid, and if they are valid
* it stores the most recent high pulse for each channel.
*/
void updateChannels()
{
unsigned char i;
for (i = 0; i < 1; i++)
{
cli(); // Disable interrupts
if (TCNT1 - ch[i].prevTime > 35000)
{
// The pulse is too long (longer than 112 ms); register an error
// before it causes possible problems.
ch[i].error = 5; // wait for 5 good pulses before trusting the signal
}
sei(); // Enable interrupts
if (ch[i].newPulse)
{
cli(); // Disable interrupts while reading highDur and lowDur
ch[i].newPulse = 0;
unsigned int highDuration = ch[i].highDur;
unsigned int lowDuration = ch[i].lowDur;
sei(); // Enable interrupts
ch[i].pulse = 0;
if (lowDuration < maxLowPulseTime ||
highDuration < minPulseTime ||
highDuration > maxPulseTime)
{
// The low pulse was too short or the high pulse was too long or too short
ch[i].error = 5; // Wait for 5 good pulses before trusting the signal
}
else
{
// Wait for error number of good pulses
if (ch[i].error)
ch[i].error--;
else
{
// Save the duration of the high pulse for use in the channel mixing
// calculation below
ch[i].pulse = highDuration;
}
}
}
}
}
/* AVR Initialization */
static void hardwareInit( void )
{
/* PortA +--------7: In : CH[7] input */
/* |+-------6: In : CH[6] input */
/* ||+------5: In : CH[5] input */
/* |||+-----4: In : CH[4] input */
/* ||||+----3: In : CH[3] input */
/* |||||+---2: In : CH[2] input */
/* ||||||+--1: In : CH[1] input */
/* |||||||+-0: In : CH[0] input */
DDRA = 0b00000000;
PORTA = 0b11111111;
/* PortB +--------7: Pullup : non use */
/* |+-------6: Pullup : non use */
/* ||+------5: Pullup : non use */
/* |||+-----4: Pullup : non use */
/* ||||+----3: Pullup : non use */
/* |||||+---2: Pullup : non use */
/* ||||||+--1: Pullup : non use */
/* |||||||+-0: Pullup : non use */
DDRB = 0b00000000;
PORTB = 0b11111111;
/* PortC +--------7: Pullup : non use */
/* |+-------6: Pullup : non use */
/* ||+------5: Pullup : non use */
/* |||+-----4: Pullup : non use */
/* ||||+----3: Pullup : non use */
/* |||||+---2: Pullup : non use */
/* ||||||+--1: Pullup : non use */
/* |||||||+-0: Pullup : non use */
DDRC = 0b00000000;
PORTC = 0b11111111;
/* PortD +--------7: Pullup : non use */
/* |+-------6: Pullup : non use */
/* ||+------5: Pullup : non use */
/* |||+-----4: Pullup : non use */
/* ||||+----3: Pullup : non use */
/* |||||+---2: Pullup : non use */
/* ||||||+--1: Out(L) : TXD */
/* |||||||+-0: Pullup : RXD */
DDRD = 0b00000010;
PORTD = 0b11110001;
uart_init(); // initialize USART
xfunc_out = uart_putc;
sei();
}
int main( void )
{
ch[0].error = 5; // Wait for 5 good pulses before trusting the signal
ch[1].error = 5;
ch[2].error = 5;
ch[3].error = 5;
ch[4].error = 5;
ch[5].error = 5;
ch[6].error = 5;
set_sleep_mode(SLEEP_MODE_IDLE);
hardwareInit();
// PCMSK0 - Pin Change Mask Register 0
PCMSK0 = (1<<PCINT7) | (1<<PCINT6) | (1<<PCINT5) | (1<<PCINT4) | (1<<PCINT3) | (1<<PCINT2) | (1<<PCINT1) | (1<<PCINT0);
// PCIFR - Pin Change Interrupt Flag Register
PCIFR = 0xFF;
// PCICR - Pin Change Interrupt Control Register
PCICR = 0x01;
sei();
TCCR1B = 0x03; // Timer1 ticks at 20MHZ/64 = 312.5KHZ(1 tick per 3.2us)
while(1) // Loop forever
{
updateChannels();
long servo_position0 = ch[0].pulse / 10; // PA0
xprintf(PSTR("CH[0] = %4d\r\n"),servo_position0);
}
return ( 0 );
}