23. C
main.c
#include <msp430x44x.h>
#include "veze.h"
float D1,D2; //brojaci pozicije:
int count1; // ocitana pozicija
int count2;
int posref1; // zadata pozicija
int posref2;
int mode; // sluzi u inicijalizaciji i prekidnoj rutini
void main(void)
{
init();
}
init.c
/*************************/
/* Inicijalizacija */
/*************************/
// U toku inicijalizacije, na P2.7 trepce led dioda sa periodom oko 100/100ms,
// kada se inicijalizacija zavrsi, dioda sija stalno
#include <msp430x44x.h>
#include "veze.h"
void init()
{
//stabilizacija oscilatora
volatile unsigned int i;
WDTCTL = WDTPW + WDTHOLD; // Stop WDT
SCFI0 |= FN_4; // x2 DCO frequency, 8MHz nominal DCO
SCFQCTL = 121; // (121+1) x 32768 x 2 = 7.99 Mhz
FLL_CTL0 |= DCOPLUS + XCAP18PF; // DCO+ set so freq = xtal x D x N+1
for(i=0; i<10; i++) ; // Delay for FLL to lock, only needed at
// initial power up
// Port 1:
P1DIR = 0xF0; // P1(0..3 ulazi enc)
P1SEL = 0x00;
P1OUT = 0x00; // Resetovan pin za WDT
// Port 2:
P2DIR = 0xC0; // 0..5 (c1,c2,l1,d1,l2,d2)
P2SEL = 0x00;
P2OUT |=0x80; // Ukljucena signalizaciona dioda
P2IFG = 0x00;
P2IES = 0xFF; // Stavili smo pull-up, silazna ivica int
// Port 3:
P3DIR = 0xFF; //4..7 izlazi PWM, timerB, out3,4,5,6
23
24. P3SEL = 0xF0;
// Port 4:
P4DIR = 0xFD; //USART1, P4.0 TX, P4.1 RX
P4SEL = 0x03;
// Kasnije cemo ukljuciti interapte
//podesiti interrupt edge select prema potrebama
// inicijalizacija USART:
ME2 |= UTXE1; // Enabled USART1 TXD
UCTL1 |= CHAR+PENA; // 8-bit character, parity enabled
UTCTL1 |= SSEL1; // UCLK = SMCLK
URCTL1 |= URXEIE;
// ukljucen prijem podataka sa greskom
UBR01 = 0x45; // 8MHz 115200
UBR11 = 0x00; // 8MHz 115200
UMCTL1 = 0x00; // 8MHz 115200 modulation
UCTL1 &= ~SWRST; // Initalize USART state machine UKLJUCITI TEK POSLE INIT
// I JAVITI SE RACUNARU
posref1 = 1024; //obavezno iskljuciti prekide kada menjamo vrednosti posref i count
posref2 = 1024; //tj. u prekidnoj rutini menjamo vrednosti i ne dozvoljavamo prekide
count1 = 1024;
count2 = 1024;
D1=0;
D2=0;
TBCCR0 = PEAK; // PWM Period/2
//prvi motor
TBCCTL3 = OUTMOD_6; // TBCCR3 toggle/set
TBCCR3 = (PEAK*(1-D1)+TD)/2; // TBCCR3 PWM set
TBCCTL4 = OUTMOD_2; // TBCCR4 /* PWM output mode: 2 - PWM toggle/reset
TBCCR4 = TBCCR3-TD; // TBCCR4 PWM reset
//drugi motor
TBCCTL5 = OUTMOD_6; // TBCCR5 toggle/set
TBCCR5 = (PEAK*(1-D2)+TD)/2; // TBCCR5 PWM set
TBCCTL6 = OUTMOD_2; // TBCCR6 /* PWM output mode: 2 - PWM toggle/reset */
TBCCR6 = TBCCR5-TD; // TBCCR6 PWM reset
TBCTL = TBSSEL_2 + MC_3 + TBIE; // ACLK, up-down mode, ukljuceni prekidi
_BIS_SR(GIE); // GIE
P2IE = 0x0C; // Ukljuceni su samo za prvi motor
P3OUT |=0x01; // Ukljucujemo energetsku elektroniku,
// ovaj bit u spoljnjem hardveru blokira
// izlazne tranzistore motora
mode=1;
if (P2IN & 0x04) mode=2; //U slucaju da je motor vec u krajnjoj levoj poziciji
//krecemo inicijalizaciju na desno
while (mode==1) //cekamo prekid na P2;
{
delay();
posref1-=5;
P2OUT ^= 0x80; // toggle dioda za treptanje
}
while (mode==2) //ako se obrnuo smer u rutini, inace skip this
{
delay();
posref1+=5;
P2OUT ^= 0x80; // toggle dioda za treptanje
24
25. }
P2IE = 0x32; //ukljuceni su samo za drugi motor
if (P2IN & 0x10) mode=4; //U slucaju da je motor vec u krajnjoj levoj poziciji
//krecemo inicijalizaciju na desno
while (mode==3)
{
delay();
posref2-=5;
P2OUT ^= 0x80; // toggle dioda za treptanje
}
while (mode==4)
{
delay();
posref1+=5;
P2OUT ^= 0x80; // toggle dioda za treptanje
}
P2IE = 0;
P2OUT |= 0x80; // dioda ukljucena, init zavrsena
// u prekidu TA se ocitava poz, i racuna upravljanje svaki 100 put
//ukljuciti prekide p2
//konst brzinom init 1 motor, dok drugi radi poziciono
//cekati prekid
//2 motor
//cekati prekid
//poslati poruku racunaru da moze da krene sa radom
ME2 |= URXE1; // Enabled USART1 RX
IE2 |= URXIE1; // Enabled USART1 RX interrupt
while (!(IFG2 & UTXIFG1)); // USART1 TX buffer ready?
TXBUF1 = 0xCC; //inicijalizacija uspela
}
delay.c
long del;
void delay(void)
{
del = 40000; // Delay treba da bude oko 100ms
do (del--);
while (del != 0);
}
position_init.c
// Kodovi za signaliziranje:
// 0xBC - prvi motor init failed
// 0xEC - drugi motor init failed
// 0xCC - inicijalizacija uspela
#include <msp430x44x.h>
#include "veze.h"
25
26. #pragma vector = PORT2_VECTOR
__interrupt void position_init()
{
int flagreg = P2IFG;
//prvi motor init
if (flagreg & 0x04)
{
mode = 2;
P2IFG &= ~0x04;
}
if (flagreg & 0x08)
{
P3OUT &= ~0x01; //Iskljucujemo energetsku elektroniku
while (!(IFG2 & UTXIFG1)); // USART1 TX buffer ready?
TXBUF1 = 0xBC; //Kod za prvi motor init failed
P2IFG &= ~0x08;
}
if (flagreg & 0x01)
{
mode = 3;
posref1= NEUTRAL;
count1 = NEUTRAL;
P2IFG &= ~0x01;
}
//Drugi motor init
if (flagreg & 0x10)
{
mode = 4;
P2IFG &= ~0x10;
}
if (flagreg & 0x20)
{
P3OUT &= ~0x02; //Iskljucujemo energetsku elektroniku
while (!(IFG2 & UTXIFG1)); // USART0 TX buffer ready?
TXBUF1 = 0xEC; //Kod za drugi motor init failed
P2IFG &= ~0x20;
}
if (flagreg & 0x02)
{
mode = 0;
posref2= NEUTRAL;
count2 = NEUTRAL;
P2IFG &= ~0x02;
}
}
26
27. main_routine.c
#include <msp430x44x.h>
#include "veze.h"
#pragma vector = TIMERB0_VECTOR
__interrupt void mainroutine()
{
static int flag = 0, counter100 = 98; //Ovakve su vrednosti zbog prvog ulaska u
//rutinu i prvog racuna upravljanja
static int new_ccr3;
static int new_ccr4;
static int new_ccr5;
static int new_ccr6;
if (flag == 1)
{
TBCCR3 = new_ccr3;
TBCCR4 = new_ccr4;
TBCCR5 = new_ccr5;
TBCCR6 = new_ccr6;
flag = 0;
};
readEncoders();
counter100++;
if (counter100 == 99)
{
_BIS_SR(GIE); // omoguciti interapte
control_calc1(); // racunanje upravljanja za 1. motor vraca D1
new_ccr4 = (TD + (1 - D1) * PEAK) / 2;
new_ccr3 = new_ccr4 - TD;
flag = 1;
};
if (counter100 == 100)
{
counter100 = 0;
_BIS_SR(GIE); // omoguciti interapte
control_calc2(); // racunanje upravljanja za 2. motor vraca D2
new_ccr6 = (TD + (1 - D2) * PEAK) / 2;
new_ccr5 = new_ccr6 - TD;
flag = 1;
P1OUT ^= 0x80; //watchdog timer toggle
};
}
readencoders.c
/**********************************************/
/* Ocitavanje enkodera i proracun pozicije */
/**********************************************/
27