Заключение
Таким образом, во время проектирования было разработано устройство, способное контролировать и управлять движением шести независимых двигателей в автоматическом манипуляторе. Устройство управления спроектировано на основе современной элементной базы, может быть легко и недорого изготовлено, может применяться с широким спектром автоматических манипуляторов. Также спроектированное устройство может быть легко адаптировано и к другим, схожим, применениям благодаря гибкости аппаратной части и простой организации программного кода.
Также был разработан пакет конструкторской документации и представлен исходный код управляющей программы.
Приложение А
Сюды вставится листег с заданием.
А тут будет страничка календарного плана
Приложение Б
Листинг управляющей программы
/*****************************************************
Project : Manipulator6_AVR
Version : 0.1
Date : 30.03.2008
Author : Yashin V.
Company : acts
Comments:
Chip type : ATmega64
Program type : Application
Clock frequency : 16,000000 MHz
Memory model : Small
External SRAM size : 0
Data Stack size : 1024
*****************************************************/
#define DEBUG 1
//*************//
#include
#include
#define RXB8 1
#define TXB8 0
#define UPE 2
#define OVR 3
#define FE 4
#define UDRE 5
#define RXC 7
#define FRAMING_ERROR (1<
#define PARITY_ERROR (1<
#define DATA_OVERRUN (1<
#define DATA_REGISTER_EMPTY (1<
#define RX_COMPLETE (1<
// USART0 Receiver buffer
#define RX_BUFFER_SIZE 8
char rx_buffer[RX_BUFFER_SIZE];
#if RX_BUFFER_SIZE<256
unsigned char rx_wr_index,rx_rd_index,rx_counter;
#else
unsigned int rx_wr_index,rx_rd_index,rx_counter;
#endif
// This flag is set on USART0 Receiver buffer overflow
bit rx_buffer_overflow;
// USART0 Receiver interrupt service routine
interrupt [USART0_RXC] void usart_rx_isr(void)
{
char status,data;
status=UCSR0A;
data=UDR0;
if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN)) == 0)
{
rx_buffer[rx_wr_index] = data;
if (++rx_wr_index == RX_BUFFER_SIZE) rx_wr_index = 0;
if (++rx_counter == RX_BUFFER_SIZE)
{
rx_counter = 0;
rx_buffer_overflow = 1;
};
};
}
#ifndef _DEBUG_TERMINAL_IO_
// Get a character from the USART0 Receiver buffer
#define _ALTERNATE_GETCHAR_
#pragma used+
char getchar(void)
{
char data;
while (rx_counter == 0);
data=rx_buffer[rx_rd_index];
if (++rx_rd_index == RX_BUFFER_SIZE) rx_rd_index = 0;
#asm("cli")
--rx_counter;
#asm("sei")
return data;
}
#pragma used-
#endif
// Standard Input/Output functions
#include
//GLOBAL VARS
//pwm[] - set by computer through USART, enc[] - measured angles
char pwm[6] = {0, 20, 50, 100, 130, 190};
signed char enc[6] = {0, 0, 0, 0, 0, 0};
const int CLEAR_INTERVAL = 100;
#ifdef DEBUG
const int REPORT_INTERVAL = 1;
#else
const int REPORT_INTERVAL = 100;
#endif
void delay_5u(int us)
{
while(us--)
delay_us(5);
delay_us(900);
}
//Produce PWM signal out on PORTA
void updateServo()
{
PORTA.0 = 1; delay_5u(pwm[0]); PORTA.0 = 0;
PORTA.1 = 1; delay_5u(pwm[1]); PORTA.1 = 0;
PORTA.2 = 1; delay_5u(pwm[2]); PORTA.2 = 0;
PORTA.3 = 1; delay_5u(pwm[3]); PORTA.3 = 0;
PORTA.4 = 1; delay_5u(pwm[4]); PORTA.4 = 0;
PORTA.5 = 1; delay_5u(pwm[5]); PORTA.5 = 0;
delay_ms(1);
}
//Send status info to USARTA (PE1-TX)
void reportStatus()
{
int i;
putchar('B');
for (i = 0; i < 6; i++)
{
#ifdef DEBUG
putchar('a'+enc[i]);
#else
putchar(enc[i]);
#endif
}
putchar('E');
putchar('\r');
putchar('\n');
}
//Sometimes we need to clear rx_buffer
void clearBuffer()
{
rx_buffer[0] = rx_buffer[7] = 0; //Clear 'B' and 'E'
rx_counter = rx_wr_index = rx_buffer_overflow = rx_rd_index = 0;
}
//Reads b[] from USART, if computer sent us new values
void updateTask()
{
//Computer sends us "B******E", where * -> b[i] and RX_BUFFER_SIZE=8(!)
if(rx_buffer[0] == 'B' && rx_buffer[7] == 'E')
{
int i;
for (i = 0; i < 6; i++)
{
char val = rx_buffer[i+1]; //must be: 0 < rx_buffer[i+1] < 200
if(val > 200) val = 190; //+90
pwm[i] = val;
}
clearBuffer();
}
}
void updateEncoders()
{
/*
Q1 , IDX, Q2
PB0, PB1, PB2 - ENC1
PB3, PB4, PB5 - ENC2
PC0, PC1, PC2 - ENC3
PC3, PC4, PC5 - ENC4
PD0, PD1, PD2 - ENC5
PD3, PD4, PD5 - ENC6
We hold state of each encoder in enc[]
When motor rotates clockwise(Q1=1 while Q2=0), increment enc[i]. Otherwise - decrement
If IDX=1, then enc[i] = 0 (IDX==1 when encoder goes through zero position)
*/
int i;
static char q1[6], q2[6], idx[6];
char n_q1[6], n_q2[6], n_idx[6];
n_q1[0] = PINB.0;
n_idx[0] = PINB.1;
n_q2[0] = PINB.2;
n_q1[1] = PINB.3;
n_idx[1] = PINB.4;
n_q2[1] = PINB.5;
n_q1[2] = PINC.0;
n_idx[2] = PINC.1;
n_q2[2] = PINC.2;
n_q1[3] = PINC.3;
n_idx[3] = PINC.4;
n_q2[3] = PINC.5;
n_q1[4] = PIND.0;
n_idx[4] = PIND.1;
n_q2[4] = PIND.2;
n_q1[5] = PIND.3;
n_idx[5] = PIND.4;
n_q2[5] = PIND.5;
for (i = 0; i < 6; i++)
{
if (idx[i] == 1 && n_idx[i] == 0)
{
enc[i] = 0;
} else if (q1[i] == 1 && n_q1[i] == 0)
{
if(n_q2[i] == 1)
{
enc[i]++;
}
else
{
enc[i]--;
}
}
q1[i] = n_q1[i];
q2[i] = n_q2[i];
idx[i] = n_idx[i];
}
}
void main(void)
{
// Declare your local variables here
long int time = 0;
// Input/Output Ports initialization
// Port A initialization
// Func7=In Func6=In Func5=Out Func4=Out Func3=Out Func2=Out Func1=Out Func0=Out
// State7=P State6=P State5=0 State4=0 State3=0 State2=0 State1=0 State0=0
PORTA=0xC0;
DDRA=0x3F;
// Port B initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=P State6=P State5=T State4=T State3=T State2=T State1=T State0=T
PORTB=0xC0;
DDRB=0x00;
// Port C initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=P State6=P State5=T State4=T State3=T State2=T State1=T State0=T
PORTC=0xC0;
DDRC=0x00;
// Port D initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=P State6=P State5=T State4=T State3=T State2=T State1=T State0=T
PORTD=0xC0;
DDRD=0x00;
// Port E initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTE=0x00;
DDRE=0x00;
// Port F initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTF=0x00;
DDRF=0x00;
// Port G initialization
// Func4=In Func3=In Func2=In Func1=In Func0=In
// State4=T State3=T State2=T State1=T State0=T
PORTG=0x00;
DDRG=0x00;
// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
// Mode: Normal top=FFh
// OC0 output: Disconnected
ASSR=0x00;
TCCR0=0x00;
TCNT0=0x00;
OCR0=0x00;
// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer 1 Stopped
// Mode: Normal top=FFFFh
// OC1A output: Discon.
// OC1B output: Discon.
// OC1C output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer 1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
// Compare C Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;
OCR1CH=0x00;
OCR1CL=0x00;
// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer 2 Stopped
// Mode: Normal top=FFh
// OC2 output: Disconnected
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;
// Timer/Counter 3 initialization
// Clock source: System Clock
// Clock value: Timer 3 Stopped
// Mode: Normal top=FFFFh
// Noise Canceler: Off
// Input Capture on Falling Edge
// OC3A output: Discon.
// OC3B output: Discon.
// OC3C output: Discon.
// Timer 3 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
// Compare C Match Interrupt: Off
TCCR3A=0x00;
TCCR3B=0x00;
TCNT3H=0x00;
TCNT3L=0x00;
ICR3H=0x00;
ICR3L=0x00;
OCR3AH=0x00;
OCR3AL=0x00;
OCR3BH=0x00;
OCR3BL=0x00;
OCR3CH=0x00;
OCR3CL=0x00;
// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
// INT2: Off
// INT3: Off
// INT4: Off
// INT5: Off
// INT6: Off
// INT7: Off
EICRA=0x00;
EICRB=0x00;
EIMSK=0x00;
// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x00;
ETIMSK=0x00;
// USART0 initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART0 Receiver: On
// USART0 Transmitter: On
// USART0 Mode: Asynchronous
// USART0 Baud Rate: 9600
UCSR0A=0x00;
UCSR0B=0x98;
UCSR0C=0x06;
UBRR0H=0x00;
UBRR0L=0x67;
// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;
// Global enable interrupts
#asm("sei")
while (1)
{
time++;
if(!(time % CLEAR_INTERVAL)) clearBuffer();
if(!(time % REPORT_INTERVAL)) reportStatus();
updateTask();
updateEncoders();
updateServo();
};
}
Приложение В
Список литературы
Новацкий А.А Электронный конспект по курсу «Компьютерная электроника».
П. Андре, Ж-М. Кофман Конструирование роботов. Перевод с французского Москва, «Мир», 1986
С. Ф. Бурдаков Проектирование манипуляторов промышленных роботов и роботизированных комплексов Москва «Высшая школа», 1986г.
А. В. Тимофеев Адаптивные робототехнические комплексы, Ленинград, «Машиностроение», 1988г.
Дж. Ф. Янг Робототехника Ленинград, «Машиностроение», 1979г.
Под ред. К. В. Фролова, Е. И. Воробьёва Механика промышленных роботов, книга 3 Основы конструирования Москва «Высшая школа», 1989г.
Под ред. В. Ф. Шаньгина Промышленные роботы для миниатюрных изделий Москва, «Машиностроение», 1985г.
Под ред. проф.. А. Пью Техническое зрение роботов, Москва, «Машиностроение», 1987г.
А. А. Краснопрошина Электроника и микросхемотехника Киев, «Высшая школа», 1989г.
Денисенко Т.А, Тихончук С.Т Методические указания по применению контроллеров семейства SIMATIC S5, ОГПУ, 1998г.
Ямпольский Л.С, Мельничук П.П, Самоткин Б.Б Гибкие компьютеризированные системы, Житомир, 2005 г.
|