Atomowa aparatura zdalnego sterowania.rar

Prosta "aparatura" modelarska.

Obiecane źródła i schematy. Układ korzysta z taktowania z modułów. Więc źródło taktowania procesorów oczywiście trzeba ustawić na zewnętrzne. Komunikacja idzie po UARCie. PWM na razie jest jeden i powiela kanał SERVO7. Normalnie jak się chce PWMa to trzeba zrezygnować z jednego serva. Albo wydłużyć długość ramki komunikacyjnej żeby przesłać więcej danych. A jak się tam zastosuje ATMegę88 to będą jeszcze 2 dodatkowe PWMy z Timera0.

  • Atomowa aparatura zdalnego sterowania.rar
    • TX.pdf
    • Array
    • RX.pdf
    • Array


Pobierz plik - link do postu


Atomowa aparatura zdalnego sterowania.rar > main.c

#include & lt; avr\io.h & gt;
#include & lt; avr\delay.h & gt;
#include & lt; inttypes.h & gt;
#include & lt; math.h & gt;
#include & lt; avr\pgmspace.h & gt;
#include & lt; avr\interrupt.h & gt;
#include & lt; avr\stdlib.h & gt;


uint16_t RFXX_WRT_CMD(uint16_t aCmd);
static uint8_t crc8_calc(uint8_t *data, uint8_t size);
static void RFM_Init(void);
static void Servo_all_0(void);
static void Servo_0_1(void);
static void Servo_1_1(void);
static void Servo_2_1(void);
static void Servo_3_1(void);
static void Servo_4_1(void);
static void Servo_5_1(void);
static void Servo_6_1(void);
static void Servo_7_1(void);


#define PORT_SEL PORTD
#define PORT_SDI PORTD
#define PORT_SCK PORTD

#define RFXX_SCK 2
#define RFXX_SDI 3
#define RFXX_SEL 4

#define DDR_IN 0
#define DDR_OUT 1

#define HI_SEL() PORT_SEL|= (1 & lt; & lt; RFXX_SEL)
#define LOW_SEL() PORT_SEL & =~(1 & lt; & lt; RFXX_SEL)
#define HI_SDI() PORT_SDI|= (1 & lt; & lt; RFXX_SDI)
#define LOW_SDI() PORT_SDI & =~(1 & lt; & lt; RFXX_SDI)
#define HI_SCK() PORT_SCK|= (1 & lt; & lt; RFXX_SCK)
#define LOW_SCK() PORT_SCK & =~(1 & lt; & lt; RFXX_SCK)



/*union int16_t_LSB_MSB
{
struct
{
uint8_t LSB;
uint8_t MSB;
};

int16_t XSB;
};*/



uint8_t Axis[8];
uint16_t Adc_value;

uint8_t Axis_2[8];

uint8_t i;

volatile uint8_t RX_Buffer[32];
volatile uint8_t RX_Buf_Pos;

float Float;


volatile uint8_t TimeOut;

volatile uint16_t Servo_Time[16] = {15000, 10000, 15000, 10000, 15000, 10000, 15000, 10000, 15000, 10000, 15000, 10000, 15000, 10000, 15000, 10000};


void (*Servo_function_addr[])(void) PROGMEM =
{
Servo_0_1,
Servo_all_0,
Servo_1_1,
Servo_all_0,
Servo_2_1,
Servo_all_0,
Servo_3_1,
Servo_all_0,
Servo_4_1,
Servo_all_0,
Servo_5_1,
Servo_all_0,
Servo_6_1,
Servo_all_0,
Servo_7_1,
Servo_all_0
};

void (*Servo_function)(void);




int main(void)
{
PORTB = 0x00;
PORTC = 0x00;
PORTD = (1 & lt; & lt; RFXX_SEL);

DDRB = (1 & lt; & lt; 3); //PWM
DDRC = (1 & lt; & lt; 0) | (1 & lt; & lt; 1) | (1 & lt; & lt; 2) | (1 & lt; & lt; 3) | (1 & lt; & lt; 4) | (1 & lt; & lt; 5); //SERVO0...SERVO5
DDRD = (1 & lt; & lt; RFXX_SCK) | (1 & lt; & lt; RFXX_SDI) | (1 & lt; & lt; RFXX_SEL) | (1 & lt; & lt; 6) | (1 & lt; & lt; 7); //SERVO6, SERVO7


UCSRA = 0x00;
UCSRB = (1 & lt; & lt; 4) | (1 & lt; & lt; RXCIE);
UCSRC = (1 & lt; & lt; 1) | (1 & lt; & lt; 2) | (1 & lt; & lt; 3) | (1 & lt; & lt; 4) | (1 & lt; & lt; 5);
UBRRH = 0;
UBRRL = 129; //4800baud




TCCR1A = 0;
TCCR1B = 0x01 | (1 & lt; & lt; 3); //Prescaler = 1 Mode = CTC
TIMSK = (1 & lt; & lt; OCIE1A); //Enable Compare1A


TCCR2 = (1 & lt; & lt; WGM20) | (1 & lt; & lt; COM21) | (1 & lt; & lt; CS21) | (1 & lt; & lt; CS20); //Mode = PWM, Phase Correct. PWM = 1kHz.



_delay_ms(10); //To póŸnienie trwa 100ms bo tutaj zegar ma 1MHz.

RFM_Init();

_delay_ms(30); //TO ju? ma 30ms bo zegar ma 10MHz.

RFM_Init();



sei();



while(1)
{
}

return 0;
}
//-------------------------------------------------------------------------
uint8_t crc8_calc(uint8_t *data, uint8_t size)
{
/* Calculate CRC-8 value; uses The CCITT-8 polynomial,
expressed as X^8 + X^5 + X^4 + 1 */

uint8_t crc = 0xFF;
uint8_t index;
uint8_t b;

for(index=0; index & lt; size; index++)
{
crc ^= data[index];
for(b=0; b & lt; 8; ++b)
{
if(crc & 0x80)
crc = (crc & lt; & lt; 1) ^ 0x31;
else
crc = (crc & lt; & lt; 1);
}
}

return crc;
}
//-------------------------------------------------------------------------
static void RFM_Init(void)
{
RFXX_WRT_CMD(0x0000); //Status Read Command
RFXX_WRT_CMD(0x918A); //868BAND,134kHz
//RFXX_WRT_CMD(0x898A); //433BAND,134kHz
RFXX_WRT_CMD(0xA640); //434MHz
RFXX_WRT_CMD(0xC847); //4.8kbps
RFXX_WRT_CMD(0xC69B); //AFC setting
RFXX_WRT_CMD(0xC42A); //Clock recovery manual control,Digital filter,DQD=4
RFXX_WRT_CMD(0xC2E0); //output 10MHz
RFXX_WRT_CMD(0xC080); //Receiver Setting Command
RFXX_WRT_CMD(0xCE88); //use FIFO
RFXX_WRT_CMD(0xCE8A); //no Use FIFO
RFXX_WRT_CMD(0xC081); //OPEN RX
}
//-------------------------------------------------------------------------
uint16_t RFXX_WRT_CMD(uint16_t aCmd)
{
uint8_t i;
uint16_t temp;

LOW_SCK();
LOW_SEL();

for(i=0; i & lt; 16; i++)
{
/*temp & lt; & lt; = 1;
if(SDO_HI())
{
temp|=0x0001;
}*/
LOW_SCK();
if(aCmd & 0x8000)
{
HI_SDI();
}
else
{
LOW_SDI();
}
HI_SCK();
aCmd & lt; & lt; = 1;
};

LOW_SCK();
HI_SEL();

return(temp);
}
//-------------------------------------------------------------------------
static void Servo_all_0(void)
{
PORTC = 0x00;
PORTD & = ~((1 & lt; & lt; 0) | (1 & lt; & lt; 0));
}
//-------------------------------------------------------------------------
static void Servo_0_1(void)
{
PORTC |= (1 & lt; & lt; 0);
}
//-------------------------------------------------------------------------
static void Servo_1_1(void)
{
PORTC |= (1 & lt; & lt; 1);
}
//-------------------------------------------------------------------------
static void Servo_2_1(void)
{
PORTC |= (1 & lt; & lt; 2);
}
//-------------------------------------------------------------------------
static void Servo_3_1(void)
{
PORTC |= (1 & lt; & lt; 3);
}
//-------------------------------------------------------------------------
static void Servo_4_1(void)
{
PORTC |= (1 & lt; & lt; 4);
}
//-------------------------------------------------------------------------
static void Servo_5_1(void)
{
PORTC |= (1 & lt; & lt; 5);
}
//-------------------------------------------------------------------------
static void Servo_6_1(void)
{
PORTD |= (1 & lt; & lt; 6);
}
//-------------------------------------------------------------------------
static void Servo_7_1(void)
{
PORTD |= (1 & lt; & lt; 7);
}
//-------------------------------------------------------------------------
ISR(SIG_UART_RECV)
{
#define Liczba_bajtow 10

uint8_t i;

sei();

RX_Buffer[RX_Buf_Pos] = UDR;
RX_Buf_Pos++;

if (RX_Buf_Pos & gt; = Liczba_bajtow)
{
if (RX_Buffer[0] == 55)
{
if (crc8_calc((uint8_t*)(RX_Buffer), (Liczba_bajtow-1)) == RX_Buffer[Liczba_bajtow-1])
{
Axis[0] = RX_Buffer[1];
Axis[1] = RX_Buffer[2];
Axis[2] = RX_Buffer[3];
Axis[3] = RX_Buffer[4];
Axis[4] = RX_Buffer[5];
Axis[5] = RX_Buffer[6];
Axis[6] = RX_Buffer[7];
Axis[7] = RX_Buffer[8];

//Tutaj mo?na mixowaae osie.


Servo_Time[0] = Axis[0]*40 + 10000; //10000...20000
Servo_Time[1] = 25000 - Servo_Time[0];
Servo_Time[2] = Axis[1]*40 + 10000; //10000...20000
Servo_Time[3] = 25000 - Servo_Time[2];
Servo_Time[4] = Axis[2]*40 + 10000; //10000...20000
Servo_Time[5] = 25000 - Servo_Time[4];
Servo_Time[6] = Axis[3]*40 + 10000; //10000...20000
Servo_Time[7] = 25000 - Servo_Time[6];
Servo_Time[8] = Axis[4]*40 + 10000; //10000...20000
Servo_Time[9] = 25000 - Servo_Time[8];
Servo_Time[10] = Axis[5]*40 + 10000; //10000...20000
Servo_Time[11] = 25000 - Servo_Time[10];
Servo_Time[12] = Axis[6]*40 + 10000; //10000...20000
Servo_Time[13] = 25000 - Servo_Time[12];
Servo_Time[14] = Axis[7]*40 + 10000; //10000...20000
Servo_Time[15] = 25000 - Servo_Time[14];

OCR2 = Axis[7]; //Powiela kana? SERVO7.


TimeOut = 0;

RX_Buf_Pos = 0;
}
else
{
for(i=0;i & lt; (Liczba_bajtow-1);i++)
RX_Buffer[i] = RX_Buffer[i+1];

RX_Buf_Pos = Liczba_bajtow-1;
}
}
else
{
for(i=0;i & lt; (Liczba_bajtow-1);i++)
RX_Buffer[i] = RX_Buffer[i+1];

RX_Buf_Pos = Liczba_bajtow-1;
}
}
}
//-------------------------------------------------------------------------
ISR(SIG_OUTPUT_COMPARE1A)
{
TimeOut++;

if (TimeOut & gt; = 160) //16 przerwa? = 20ms. 160 = 200ms = TimeOut.
{
TimeOut = 160;

Servo_Time[0] = 15000;
Servo_Time[1] = 10000;
Servo_Time[2] = 15000;
Servo_Time[3] = 10000;
Servo_Time[4] = 15000;
Servo_Time[5] = 10000;
Servo_Time[6] = 15000;
Servo_Time[7] = 10000;
Servo_Time[8] = 15000;
Servo_Time[9] = 10000;
Servo_Time[10] = 15000;
Servo_Time[11] = 10000;
Servo_Time[12] = 15000;
Servo_Time[13] = 10000;
Servo_Time[14] = 15000;
Servo_Time[15] = 10000;
}


static uint8_t Servo_state = 0;

OCR1A = Servo_Time[Servo_state];

Servo_function = (void*)(pgm_read_word( & (Servo_function_addr[Servo_state])));
Servo_function();


Servo_state++;
Servo_state & = 0x0F;
}
//-------------------------------------------------------------------------



Atomowa aparatura zdalnego sterowania.rar > main.c

#include & lt; avr\io.h & gt;
#include & lt; avr\delay.h & gt;
#include & lt; inttypes.h & gt;
#include & lt; math.h & gt;
#include & lt; avr\pgmspace.h & gt;
#include & lt; avr\interrupt.h & gt;
#include & lt; avr\stdlib.h & gt;


uint16_t RFXX_WRT_CMD(uint16_t aCmd);
static uint16_t get_adc(uint8_t adc_channel);
static void USART_Transmit(uint8_t data);
static uint8_t crc8_calc(uint8_t *data, uint8_t size);
static void RFM_Init(void);


#define PORT_SEL PORTD
#define PORT_SDI PORTD
#define PORT_SCK PORTD

#define RFXX_SCK 2
#define RFXX_SDI 3
#define RFXX_SEL 4

#define DDR_IN 0
#define DDR_OUT 1

#define HI_SEL() PORT_SEL|= (1 & lt; & lt; RFXX_SEL)
#define LOW_SEL() PORT_SEL & =~(1 & lt; & lt; RFXX_SEL)
#define HI_SDI() PORT_SDI|= (1 & lt; & lt; RFXX_SDI)
#define LOW_SDI() PORT_SDI & =~(1 & lt; & lt; RFXX_SDI)
#define HI_SCK() PORT_SCK|= (1 & lt; & lt; RFXX_SCK)
#define LOW_SCK() PORT_SCK & =~(1 & lt; & lt; RFXX_SCK)



/*union int16_t_LSB_MSB
{
struct
{
uint8_t LSB;
uint8_t MSB;
};

int16_t XSB;
};*/


uint8_t Axis[8];

uint16_t Adc_value;


int main(void)
{
uint8_t i;
uint8_t TX_Buffer[32];


PORTB = 0x00;
PORTC = 0x00;
PORTD = (1 & lt; & lt; RFXX_SEL);

DDRB = 0x00;
DDRC = 0x00;
DDRD = (1 & lt; & lt; RFXX_SEL) | (1 & lt; & lt; RFXX_SDI) | (1 & lt; & lt; RFXX_SCK) | (1 & lt; & lt; 1);




ADMUX = _BV(REFS0);
ADCSRA = _BV(ADEN) | 0x06;


UCSRA = 0x00;
UCSRB = (1 & lt; & lt; 3);
UCSRC = (1 & lt; & lt; 1) | (1 & lt; & lt; 2) | (1 & lt; & lt; 3) | (1 & lt; & lt; 4) | (1 & lt; & lt; 5);
UBRRH = 0;
UBRRL = 129; //4800baud



_delay_ms(10); //To póŸnienie trwa 100ms bo tutaj zegar ma 1MHz.

RFM_Init();

_delay_ms(30); //TO ju? ma 30ms bo zegar ma 10MHz.

RFM_Init();


while(1)
{
Axis[0] = get_adc(0) & gt; & gt; 2;
Axis[1] = get_adc(1) & gt; & gt; 2;
Axis[2] = get_adc(2) & gt; & gt; 2;
Axis[3] = get_adc(3) & gt; & gt; 2;
Axis[4] = get_adc(4) & gt; & gt; 2;
Axis[5] = get_adc(5) & gt; & gt; 2;
Axis[6] = get_adc(6) & gt; & gt; 2;
Axis[7] = get_adc(7) & gt; & gt; 2;


//Tutaj mo?na mixowaae osie.


TX_Buffer[0] = 55; //ID

TX_Buffer[1] = Axis[0]; //Data
TX_Buffer[2] = Axis[1];
TX_Buffer[3] = Axis[2];
TX_Buffer[4] = Axis[3];
TX_Buffer[5] = Axis[4];
TX_Buffer[6] = Axis[5];
TX_Buffer[7] = Axis[6];
TX_Buffer[8] = Axis[7]; //Data

TX_Buffer[9] = crc8_calc((uint8_t*)(TX_Buffer), 9); //CRC8 CCITT

for (i=0; i & lt; 10; i++)
{
USART_Transmit(TX_Buffer[i]);
}


_delay_ms(30);
}


return 0;
}
//-------------------------------------------------------------------------
static uint16_t get_adc(uint8_t adc_channel)
{
ADMUX = _BV(REFS0) | adc_channel;
ADCSRA = _BV(ADEN) | 0x06;
ADCSRA |= _BV(ADSC);
while (ADCSRA & _BV(ADSC));

return ADCW;
}
//-------------------------------------------------------------------------
static void USART_Transmit(uint8_t data)
{
while (!(UCSRA & (1 & lt; & lt; UDRE)));

UDR = data;
}
//-------------------------------------------------------------------------
uint8_t crc8_calc(uint8_t *data, uint8_t size)
{
/* Calculate CRC-8 value; uses The CCITT-8 polynomial,
expressed as X^8 + X^5 + X^4 + 1 */

uint8_t crc = 0xFF;
uint8_t index;
uint8_t b;

for(index=0; index & lt; size; index++)
{
crc ^= data[index];
for(b=0; b & lt; 8; ++b)
{
if(crc & 0x80)
crc = (crc & lt; & lt; 1) ^ 0x31;
else
crc = (crc & lt; & lt; 1);
}
}

return crc;
}
//-------------------------------------------------------------------------
static void RFM_Init(void)
{
RFXX_WRT_CMD(0xCC00); //Status Register Read Command
RFXX_WRT_CMD(0x9761); //868BAND,+/-90kHz, CLK = 10MHz
//RFXX_WRT_CMD(0x8F61); //433BAND,+/-90kHz, CLK = 10MHz
RFXX_WRT_CMD(0xA640); //868MHz
RFXX_WRT_CMD(0xD040); //RATE/2
RFXX_WRT_CMD(0xC823); //4.8kbps
RFXX_WRT_CMD(0xC210); //DISABLE BIT SYNC
RFXX_WRT_CMD(0xC038); //A0,A1 = 0, EX,ES,EA = 1
}
//-------------------------------------------------------------------------
uint16_t RFXX_WRT_CMD(uint16_t aCmd)
{
uint8_t i;
uint16_t temp;

LOW_SCK();
LOW_SEL();

for(i=0; i & lt; 16; i++)
{
/*temp & lt; & lt; = 1;
if(SDO_HI())
{
temp|=0x0001;
}*/
LOW_SCK();
if(aCmd & 0x8000)
{
HI_SDI();
}
else
{
LOW_SDI();
}
HI_SCK();
aCmd & lt; & lt; = 1;
};

LOW_SCK();
HI_SEL();

return(temp);
}
//-------------------------------------------------------------------------