Pravih za rodjaka neki dan neki primer pa reko mozda bi bilo zgodno podeliti ga.
Shema sadrzi
- mikrokontroler PIC16F887 koji radi na internom oscilatoru na 8MHz
- reset kolo na MCLR pinu
- primer kako kontrolisati 2 ledare preko samo jednog pina
- karakter LCD u 4-bitnom modu (zakacena su paralelno dva, jedan sa jednom linijom i jedan sa dve)
- unipolarni stepper motor vezan preko ULN2003 (koji je u stvari 7 darlingtona u jednoj kutiji)
- bipolarni stepper motor sa L297+L298 drajver kombinacijom
- servo motor
Sors je “samoobjasnjihv” tako da, evo ga:
// LCD pinovi
sbit LCD_EN at RD1_bit;
sbit LCD_RS at RD2_bit;
//sbit LCD_RW at RD3_bit; // MikroC ne koristi RW pin
sbit LCD_D4 at RD4_bit;
sbit LCD_D5 at RD5_bit;
sbit LCD_D6 at RD6_bit;
sbit LCD_D7 at RD7_bit;
sbit LCD_EN_Direction at TRISD1_bit;
sbit LCD_RS_Direction at TRISD2_bit;
//sbit LCD_RW_Direction at TRISD3_bit;
sbit LCD_D4_Direction at TRISD4_bit;
sbit LCD_D5_Direction at TRISD5_bit;
sbit LCD_D6_Direction at TRISD6_bit;
sbit LCD_D7_Direction at TRISD7_bit;
char txt1[] = "TEST TEKST";
char txt2[] = "neki tekst";
char txt3[] = "primer";
char txt4[] = "za lcd";
char txt5[] = "Vozi unapred";
char txt6[] = "UNIPOLARNI STEPP";
char txt7[] = "Vozi unazad";
char txt8[] = "STOP";
char txt9[] = "KRAJ";
// koraci stepper motora
char unipolar_step[] = {0b1100, 0b0110, 0b0011, 0b1001};
#define Move_Delay() Delay_ms(200)
unsigned char i;
void main(){
//////////////////////////////////////
// INICIJALIZACIJA //
//////////////////////////////////////
// Ugasi ADC (konfigurisi AN pinove kao digital IO)
ANSEL = 0;
ANSELH = 0;
// Ugasi komparatore
C1ON_bit = 0;
C2ON_bit = 0;
//////////////////////////////////////
// PALI, GASI LEDARU //
//////////////////////////////////////
// Na D0 su nam charlieplexed ledare
TRISD0_bit=1; //postavi D0 na imput - gasi obe ledare
for (i = 0; i < 10; i++){ //20 puta se izvrti
//upali prvu ledaru
RD0_bit=0; //D0 je GND
TRISD0_bit=0; //D0 je "izlaz"
Delay_ms(100); //sacekaj 500ms
//Ugasi ledare
TRISD0_bit=1;
Delay_ms(100); //sacekaj 500ms
//upali drugu ledaru
RD0_bit=1; //D0 je 5V
TRISD0_bit=0; //D0 je "izlaz"
Delay_ms(100); //sacekaj 500ms
//Ugasi ledare
TRISD0_bit=1;
Delay_ms(100); //sacekaj 500ms
}
//////////////////////////////////////
// LCD tekstualni //
//////////////////////////////////////
Lcd_Init();
Lcd_Cmd(_LCD_CLEAR);
Lcd_Cmd(_LCD_CURSOR_OFF);
Lcd_Out(1,6,txt3);
Lcd_Out(2,6,txt4);
Delay_ms(2000);
Lcd_Cmd(_LCD_CLEAR);
Lcd_Out(1,1,txt1);
Lcd_Out(2,5,txt2);
//iskuliraj 2 sekunde
Delay_ms(2000);
//Mrducaj malo tekst na lcd-u
for(i=0; i<4; i++) {
Lcd_Cmd(_LCD_SHIFT_RIGHT);
Move_Delay();
}
for(i=0; i<8; i++) {
Lcd_Cmd(_LCD_SHIFT_LEFT);
Move_Delay();
}
for(i=0; i<8; i++) {
Lcd_Cmd(_LCD_SHIFT_RIGHT);
Move_Delay();
}
//////////////////////////////////////
// UNIPOLARNI STEPPER MOTOR //
//////////////////////////////////////
//mrducaj malo stepper
//SPREMI RC4 - RC7 da budu izlaz
TRISC4_bit=0;
TRISC5_bit=0;
TRISC6_bit=0;
TRISC7_bit=0;
//sacekaj sekund
Delay_ms(1000);
Lcd_Cmd(_LCD_CLEAR);
Lcd_Out(1,1,txt5);
Lcd_Out(2,1,txt6);
//UNAPRED
for(i=0;i<100;i++){ // 100 koraka
RC4_bit = unipolar_step[i%4] >> 3;
RC5_bit = (unipolar_step[i%4] >> 2) & 1;
RC6_bit = (unipolar_step[i%4] >> 1) & 1;
RC7_bit = unipolar_step[i%4] & 1;
Delay_ms(80); //pauza izmedju koraka, sto manja pauza, brze se vrti stepper
}
Lcd_Cmd(_LCD_CLEAR);
Lcd_Out(1,1,txt8);
//sacekaj sekund
Delay_ms(1000);
Lcd_Cmd(_LCD_CLEAR);
Lcd_Out(1,1,txt7);
Lcd_Out(2,1,txt6);
//UNAZAD
for(i=100;i>0;i--){ // 100 koraka
RC4_bit = unipolar_step[i%4] >> 3;
RC5_bit = (unipolar_step[i%4] >> 2) & 1;
RC6_bit = (unipolar_step[i%4] >> 1) & 1;
RC7_bit = unipolar_step[i%4] & 1;
Delay_ms(80); //pauza izmedju koraka, sto manja pauza, brze se vrti stepper
}
Lcd_Cmd(_LCD_CLEAR);
Lcd_Out(1,1,txt8);
//sacekaj sekund
Delay_ms(1000);
//////////////////////////////////////
// BIPOLARNI STEPPER MOTOR //
//////////////////////////////////////
//SPREMI RC0, RC1 da budu izlaz
RC0_bit = 0;
RC1_bit = 0;
TRISC0_bit=0;
TRISC1_bit=0;
RC0_bit = 0;
//vozi unapred
Delay_ms(1000);
Lcd_Cmd(_LCD_CLEAR);
Lcd_Out(1,1,"Vozi unapred");
Lcd_Out(2,1,"BIPOLARNI STEPP");
RC1_bit = 1; // u smeru kazaljke na satu
for (i=0;i<200;i++){//200 koraka
RC0_bit = 1;
Delay_ms(20);
RC0_bit = 0;
Delay_ms(20);
}
Lcd_Cmd(_LCD_CLEAR);
Lcd_Out(1,1,txt8);
//sacekaj sekund
Delay_ms(1000);
//vozi unazad
Lcd_Cmd(_LCD_CLEAR);
Lcd_Out(1,1,"Vozi unazad");
Lcd_Out(2,1,"BIPOLARNI STEPP");
RC1_bit = 0; // suprotno smeru kazaljke na satu
for (i=0;i<200;i++){//200 koraka
RC0_bit = 1;
Delay_ms(20);
RC0_bit = 0;
Delay_ms(20);
}
//////////////////////////////////////
// SERVO MOTOR - DIREKTNA KONTROLA //
//////////////////////////////////////
TRISC2_bit = 0; //izlaz
RC2_bit = 0;
//DUZINA PULSA ODREDJUJE POZICIJU SERVO MOTORA
//STANDARD JE 1500us je "centar" 900us je "skroz levo", 2100us je "skroz desno"
//MADA TO ZAVISI OD MOTORA DO MOTORA, OBICNO PISE U DOKUMENTACIJI MOTORA ALI
//SE UVEK MOZE EXPERIMENTALNO UTVRDITI
Lcd_Cmd(_LCD_CLEAR);
Lcd_Out(1,1,"SERVO - CENTAR");
Lcd_Out(2,2,"DIREKTNO");
for (i=0;i<50;i++){
//posalji puls
RC2_bit = 1;
Delay_us(1500);
RC2_bit = 0;
//cekaj do sledeceg pulsa
Delay_ms(25);
}
Lcd_Cmd(_LCD_CLEAR);
Lcd_Out(1,1,"SERVO - -90");
Lcd_Out(2,2,"DIREKTNO");
for (i=0;i<50;i++){
//posalji puls
RC2_bit = 1;
Delay_us(900);
RC2_bit = 0;
//cekaj do sledeceg pulsa
Delay_ms(25);
}
Lcd_Cmd(_LCD_CLEAR);
Lcd_Out(1,1,"SERVO - +90");
Lcd_Out(2,2,"DIREKTNO");
for (i=0;i<50;i++){
//posalji puls
RC2_bit = 1;
Delay_us(2000);
RC2_bit = 0;
//cekaj do sledeceg pulsa
Delay_ms(25);
}
Lcd_Cmd(_LCD_CLEAR);
Lcd_Out(1,1,"SERVO - -45"); //53 1200
Lcd_Out(2,2,"DIREKTNO");
for (i=0;i<50;i++){
//posalji puls
RC2_bit = 1;
Delay_us(1250);
RC2_bit = 0;
//cekaj do sledeceg pulsa
Delay_ms(25);
}
Lcd_Cmd(_LCD_CLEAR);
Lcd_Out(1,1,"SERVO - +45"); //36 1700
Lcd_Out(2,2,"DIREKTNO");
for (i=0;i<50;i++){
//posalji puls
RC2_bit = 1;
Delay_us(1750);
RC2_bit = 0;
//cekaj do sledeceg pulsa
Delay_ms(25);
}
Lcd_Cmd(_LCD_CLEAR);
Lcd_Out(1,1,"SERVO - CENTAR");
Lcd_Out(2,2,"DIREKTNO");
for (i=0;i<50;i++){
//posalji puls
RC2_bit = 1;
Delay_us(1500);
RC2_bit = 0;
//cekaj do sledeceg pulsa
Delay_ms(25);
}
//////////////////////////////////////
// SERVO MOTOR - PWM //
// Ovaj uC je suvise brz tako da //
// ne moze da nam da dovoljno spor //
// PWM da bi imali full range od //
// min do max. minimalni PWM na //
// 8MHZ je 489Hz sto je prebrzo //
// idealan pwm bi bio negde ~100Hz //
//////////////////////////////////////
TRISC2_bit = 0; //izlaz
RC2_bit = 0;
PWM1_Init(489); //Hz
PWM1_Set_Duty(0);
PWM1_Start();
Lcd_Cmd(_LCD_CLEAR);
Lcd_Out(1,1,"SERVO - SETAJ");
Lcd_Out(2,2,"PWM");
for (i=0;i<200;i+=2){
PWM1_Set_Duty(i);
Delay_ms(100);
}
PWM1_Stop();
//KRAJ
Lcd_Cmd(_LCD_CLEAR);
Lcd_Out(1,1,txt9);
Lcd_Out(2,4,txt9);
while(1){
for(i=0; i<4; i++) {
Lcd_Cmd(_LCD_SHIFT_RIGHT);
Move_Delay();
}
for(i=0; i<4; i++) {
Lcd_Cmd(_LCD_SHIFT_LEFT);
Move_Delay();
}
}
}








