Archive for 'PIC primeri'

I got me a bunch of 7seg LED boards from sureelectronics and I expected them to have some “smarts” on them even as they are fairly cheap. Now, the nasty buggers come without any documentation so it took me a bit to figure out how they are connected and how to drive them.

The modules take 12V and 3 inputs, data, clock and something called DIMM. After bit of checking out the schematic it looks like this:

DE-DP22811 2.3" Two Digits 7-Segment LED Information Board MTO schematic

DE-DP22811 2.3" Two Digits 7-Segment LED Information Board MTO schematic

So, the data line goes directly into data input of the 74HC164 (it is one from NXP on the boards I have) shift register, clock for some reason goes trough a double NAND and finally the DIMM goes also trough double NAND and then controls the current trough modules. When DIMM line is high the 7segment led will be dimmed (almost off).

For some reason, who ever designed this board decided to go with 74HC164 instead with 74HC595 and to add DIMM instead of latch… donno what to say, I really like latch more then this dimm solution, but it works like this too..

Note that schematic is just something I drawn (at 6am so don’t be too rush on me, I know that according to this schematic dimm low would dimm the segments but it is really not important). What is not on the schematic is “irrelevant” for driving the bastard, the 7seg’s are not connected directly too 12V and to shift register but shift register drives the ULN2003 that then sinks the current for the 7segs, of course there are some current limiting resistors and also a 5V regulator for the onboard electronics. There is also some circuitry (4 transistors plus some extra passive components) that gets the dimm line high dimms the segments but it is too early/late and I really need sleep and is not important really “how” it works… important is “what it does” and how to control it.

Here is also a sample code (for pic16F690 – chosen this one as I had it on the table from some manual I made for a friend yesterday) :

#include <16F690.h>
#device adc=8
#case
#use fast_io(C)

#FUSES NOWDT
#FUSES INTRC_IO
#FUSES NOPROTECT
#FUSES NOBROWNOUT
#FUSES NOMCLR
#FUSES NOCPD
#FUSES NOPUT
#FUSES NOIESO
#FUSES NOFCMEN  

#use delay(clock=8000000)

//define data, clock and blank pin
#define DATAPIN PIN_C0
#define CLOCKPIN PIN_C1
#define BLANKPIN PIN_C2

//define clock delay routine. the display comes with
//NXP 74HC164 so minimal pulse width at 5V is 24ns
//a single nop takes much longer at 8MHz clock (500ns)
#define clkdelay() #asm ASIS nop #endasm

//   0
// 5   1
//   6
// 4   2
//   3    7

unsigned int8 digit[10] = {
  0x3F,
  0x06,
  0x5B,
  0x4F,
  0x66,
  0x6D,
  0x7D,
  0x07,
  0x7F,
  0x6F
};

void clean(){
  int8 i;
  output_low(DATAPIN);
  for(i=0;i<100;i++){
    output_high(CLOCKPIN);
    clkdelay();
    output_low(CLOCKPIN);
    clkdelay();
  }
}

void sendDigit(signed int8 d){
  int8 x;

  if (d<0){
    output_high(DATAPIN);
    d = -d;
  }else{
    output_low(DATAPIN);
  }
  if (d > 9) d=0;
  x = digit[d];

  //send DP
  output_high(CLOCKPIN);
  clkdelay();
  output_low(CLOCKPIN);

  if (x & 0x40){
     output_high(DATAPIN);
  } else {
     output_low(DATAPIN);
  }
  output_high(CLOCKPIN);
  clkdelay();
  output_low(CLOCKPIN);

  if (x & 0x20){
     output_high(DATAPIN);
  } else {
     output_low(DATAPIN);
  }
  output_high(CLOCKPIN);
  clkdelay();
  output_low(CLOCKPIN);

  if (x & 0x10){
     output_high(DATAPIN);
  } else {
     output_low(DATAPIN);
  }
  output_high(CLOCKPIN);
  clkdelay();
  output_low(CLOCKPIN);

  if (x & 0x08){
     output_high(DATAPIN);
  } else {
     output_low(DATAPIN);
  }
  output_high(CLOCKPIN);
  clkdelay();
  output_low(CLOCKPIN);

  if (x & 0x04){
     output_high(DATAPIN);
  } else {
     output_low(DATAPIN);
  }
  output_high(CLOCKPIN);
  clkdelay();
  output_low(CLOCKPIN);

  if (x & 0x02){
     output_high(DATAPIN);
  } else {
     output_low(DATAPIN);
  }
  output_high(CLOCKPIN);
  clkdelay();
  output_low(CLOCKPIN);

  if (x & 0x01){
     output_high(DATAPIN);
  } else {
     output_low(DATAPIN);
  }
  output_high(CLOCKPIN);
  clkdelay();
  output_low(CLOCKPIN);
}

void main()
{
   int16 i;
   int8 a,b,c,d;

   setup_adc_ports(NO_ANALOGS|VSS_VDD);
   setup_adc(ADC_OFF);
   setup_spi(SPI_SS_DISABLED);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_comparator(NC_NC_NC_NC);
   setup_oscillator(OSC_8MHZ);

   set_tris_c(0);
   clean();   

   while(1){

     //single module
     for (i=0;i<100;i++){
       output_high(BLANKPIN);
       sendDigit(i%10);
       sendDigit(i/10);
       output_low(BLANKPIN);
       delay_ms(100);
     }

     for (i=0;i<10000;i++){
       a = i%10;
       b = (i/10)%10;
       c = (i/100)%10;
       d = (i/1000)%10;
       output_high(BLANKPIN);
       sendDigit(a);
       sendDigit(b);
       sendDigit(c);
       sendDigit(d);
       output_low(BLANKPIN);
       delay_ms(100);
     }
   }
}

I hope you use it well :)

Another interesting thing is the power consumption. The two modules take up to 750mA when powered from 12V. The brightness is great but so is the power consumption. Depending on how many segments are shown (600mA exactly with 12 source and 8584 on display)  the consumption goes down (for e.g. for 1413 on display the usage is 360mA). What I found is that when I power it from 9V the brightness is still great (almost as strong as with 12V) but the power consumption almost drops 50% so the same settings only 9V the power draw when 8584 is on display is 330mA (when 1413 is on display the power usage is 200mA). As you are “dimming” the display while updating it it the current draw drops a bit but so does the brightness. After some testing I believe 9V is perfect psu for this board.

Tags: , ,

Termostat sa 5 zona

Thermostat mcu segment

Termostat - MCU

Pojavila se potreba za jednog klijenta da održava temperaturu u velikom prostoru, koji ima različite termički izolovane zone, konzistentno kroz ceo prostor. Pregledom objekta (dugacka peć je u pitanju) zaključeno je da postoji 5 segmenata sa različitom izolacijom te svaki segment gubi energiju različitom brzinom te jedan termostat za celu peć nije u stanju da održi kvalitetno temperaturu na celoj dužini peći i razlike između extrema može da bude i do 40C. Kako se peć koristi za “osetljiv materijal” nemoguće je u peć staviti ventilator koji bi mešao vazduh i na taj način održavao konzistentnu temperaturu u celoj peći. Kako je klijent već odvojio 5 grupa grejača u tih 5 različitih zona pokušavajući da reši problem tako što je na mesta sa većim gubitcima stavio jače grejače rešio sam da napravim običan digitalni termostat za 5 zona. Prvo pitanje je bilo da li da idem na termokaplere koji su profi senzori za peći i idu do 700C odnosno 1300C zavisno od toga da li se koristi termokapler J ili K tipa. Ono što je problem sa termokaplerima je

Termostat - IO

Termostat - IO

  • koštaju dosta para
  • ja nemam nijedan za testiranje
  • daju napon u milivoltima i nikakvu struju tako da ih je potrebno zakačiti preko drajvera koji onda daje uglavno 10mV po stepenu

Uglavnom iz razloga što nemam nijedan za test, i što peć nikad nema potrebu da ide preko 250C rešio sam da kao senzor koristim dobro isprobani NTC (0.5$ po komadu, 100K RT16 honeywell NTC, farnell code 1383986). Njih je vrlo lako vezati, poštuju svoju RT krivu, daju ponovljive rezultate i rade odlično do 300C.

Termostat - PSU

Termostat - PSU

Za srce termostata je odabran pic16F690. Ima interni oscilator, dovoljno ADC ulaza (12 10 bitnih)… idealno za ovu priliku. 5 termistora je vezano na 5 adc ulaza sa 10K otpornikom prema VDD u razdelniku napona tako da je lako detektovati ako nema termistora ili ako je termistor u kratkom spoju. Komande se unose preko tastature vezane na sesti analogni ulaz (na pločici je 12 tastera ali se ne koriste svi tasteri za rad uređaja).

Termostat - Relays

Termostat - Relays

Grejači se kontrolišu preko 5 releja koje pali i gasi ULN2003A) a vezan je dodatno šesti rele za potrebe alarma (ako je temperatura nekog dela peći mnogo različita od prosečne temperature u peći). Interface prema korisniku je spi display 84×48 pixela (5×8 pixela font daje 5 linija teksta na njemu) sa nokia 3310 telefona. Software je napisan u CSC C-u. U “normalnom” režimu rada, termostat daje mogućnost promene željene temperature sa +10, -10, +1 i -1 tasterima. Prikazuje željenu temperaturu, temperaturu na svim senzorima (ne prikazuje senzore koji nisu zakačeni) i prikazuje srednju temperaturu peći (propuštenu kroz low pass filter). Ako duže od 1sec držite taster “menu” prelazite u setup mode u kome se definiše hysteresis za grejače i razlika u temperaturi između temperature segmenta i prosečne temperature koja aktivira alarm. Izlaskom iz setup moda (pritiskom na menu taster 1sec) trenutna željena temperatura, hysteresis i alarm vrednosti se snimaju u eeprom 16F690 i te vrednosti se automatski učitavaju po sledećem resetu / paljenju uređaja.

HEX file

Pravih za rodjaka neki dan neki primer pa reko mozda bi bilo zgodno podeliti ga.

Shema - klikni za celu semu

Shema - klikni za celu semu

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();
    }
  }
}
Tags: , , , , ,

Nigel pocinje svoju seriju tutorijala sa tipicnim “hello world” programom za mikrokontrolere – tj “blinkanjem ledara”.

Za prvi deo ovog tutorijala bice nam potrebna GLAVNA1 plocica sa ledarom. sa J1 postavljenim, ili mozemo koristiti LED plocicu na portu B.

Primer 1.1

Jednostavan program koji sve io portove setuje na na 1 a onda na 0 (pisan u MikroC-u):

void main(){
   CMCON = 0x07;    // TURN COMPARATORS OFF (make it like a 16F84)
   TRISA = 0;       // Set port A all output
   TRISB = 0;       // Set port B all output
   
Loop:
     PORTA = 0xFF;  // Set all port A bits high
     PORTB = 0xFF;  // Set all port B bits high
     asm nop        // The nop's make up the time taken by the goto
     asm nop        // giving square wave output
     PORTA = 0;     // Set all port A bits low
     PORTB = 0;     // Set all port B bits low
     goto Loop;     // go back and do it again
}

Prva linija definise pocetak “glavne” funkcije, druga iskljucuje komparatore, naredne dve setuju “pravac” portova A i B. Na PIC mikrokontrolerima, digitalni IO port moze biti “ulaz” ili “izlaz”, da li je port ulazni ili izlazni podesava se registrom TRISx gde za je svaki bit tog registra vezan za bit porta i 0 predstavlja “output” a 1 “input”.

U petlji dizemo sve bitove oba porta na 1, pravimo pauzu od 2 takta (sa nop sto znaci no operation) spustamo vrednost na 0 i skacemo na pocetak petlje (ovaj skok takodje traje 2 takta tako da nam je izlaz simetrican).

Primer 1.2
Ako ste probali primer 1.1 primetili ste da ne primecujete kako LED trepce. Ne mozete primetiti treptanje posto ledare trepcu velikom brzinom (upaljene su 2-3 mikro sekunde i onda su ugasene 2-3 mikro sekunde ako uzmemo u obzir da mikrokontroler radi na 4MHz) sto je prebrzo da bi bilo detektovane golim okom. Kako bi mogli da “vidimo” promene, ubacicemo pauzu izmedju paljenja i gasenje le dioda.

void main(){
   CMCON = 0x07;    // TURN COMPARATORS OFF (make it like a 16F84)
   TRISA = 0;       // Set port A all output
   TRISB = 0;       // Set port B all output
   
Loop:
     PORTA = 0xFF;  // Set all port A bits high
     PORTB = 0xFF;  // Set all port B bits high
     asm nop        // The nop's make up the time taken by the goto
     asm nop        // giving square wave output
     Delay_ms(500); // Half a second pause
     PORTA = 0;     // Set all port A bits low
     PORTB = 0;     // Set all port B bits low
     Delay_ms(500); // Half a second pause
     goto Loop;     // go back and do it again
}

MikroC compiler koristen u ovom primeru koristi funkciju Delay_ms(x) koja sluzi da pauzira program na X milisekundi. Mi smo dodali Delay_ms(500) sto pravi pauzu od 500ms iliti pola sekunde. MikroC takodje ima funkcije Delay_us() (pauza u mikro sekundama), VDelay_ms() (pauza u mili sekundama koja nije “apsolutno tacna” ali zauzima manje prostora od Delay_us()) kao i Delay_Cyc(x) funkciju koja pravi pauzu u “taktovima”. 1 takt na PIC mikro kontroleru je na svake 4 oscilacije glavnog instrukcijskog oscilatora tako da ako nam je oscilator na 4MHz 1 takt je na svake 4 oscilacije, dakle na 1 mikro sekundu. Neki C kompajleri nude delay funkciju samo na nivou “taktova” tako da sami morate u odnosu na to kolika je brzina procesora da racunate koliko taktova vam je potrebno za vremesku pauzu od X milisekundi.

Primer 1.3
Prethodni primeri menjaju vrednost “svih” pinova jednog porta. Cesto zelimo da menjamo vrednost samo jednog pina. Razliciti C kompajleri nam dozvoljavaju da pristupimo pinovima porta na razlicite nacine. MikroC sintaksa ja PORTx.Fn gde je x – ime porta a n bit dakle, PORTA.F0 je najnizi bit porta A, PORTC.F7 je najvisi bit porta C; neke ceste sintakse su: PORTAbits.RA0, PORTA.A0, PORTA.0 i slicno. Neki kompajleri van daju mogucnost da sami kreirate strukturu i imenujete svaki pin, neki daju mogucnost da setujete pojedinacne pinove kroz funkciju (na primer – output_high(porta, 0); ) i slicno.

Ovaj primer pali i gasi RB7 (PORTB MSB – tj. najvisi bit porta B):

void main(){
   CMCON = 0x07;    // TURN COMPARATORS OFF (make it like a 16F84)
   TRISA = 0;       // Set port A all output
   TRISB = 0;       // Set port B all output
   PORTA = 0;       // Set port A all bits low
   PORTB = 0;       // Set port B all bits low

   
Loop:
     PORTB.F7 = 1;  // Set RB7 high
     asm nop        // The nop's make up the time taken by the goto
     asm nop        // giving square wave output
     Delay_ms(500); // Half a second pause
     PORTB.F7 = 0;  // Set RB7 low
     Delay_ms(500); // Half a second pause
     goto Loop;     // go back and do it again
}

Primer 1.4
Ako zelimo da umesto RB7 iz prethodnog posta palimo i gasimo LED na RB4 moramo da nadjemo svuda gde se spominje PORTB.F7 i promenimo u PORTB.F4 .. C jezik nam daje mogucnost definisanja makro-a tako da na pocetku programa mozemo da definisemo makro LED koji ce kompajler sam zameniti sa PORTB.F7 a mi ako zelimo da promenimo port/pin to cinimo samo na jednom mestu te nam je kasnije mnogo lakse da razumemo i administriramo program:

#define LED PORTB.F7
void main(){
   CMCON = 0x07;    // TURN COMPARATORS OFF (make it like a 16F84)
   TRISA = 0;       // Set port A all output
   TRISB = 0;       // Set port B all output
   PORTA = 0;       // Set port A all bits low
   PORTB = 0;       // Set port B all bits low

   
Loop:
     LED      = 1;  // Set RB7 high
     asm nop        // The nop's make up the time taken by the goto
     asm nop        // giving square wave output
     Delay_ms(500); // Half a second pause
     LED      = 0;  // Set RB7 low
     Delay_ms(500); // Half a second pause
     goto Loop;     // go back and do it again
}

Dakle ako sada u prvoj liniji umesto #define LED PORTB.F7 stavimo #define LED PORTB.F4 LED na RB4 ce se paliti i gasiti.

Primer 1.5
Sada cemo “prosetati” svetlo po redu od 8 ledara na portu B

#define LEDPORT PORTB
#define LEDTRIS TRISB

void main(){
   CMCON = 0x07;    // TURN COMPARATORS OFF (make it like a 16F84)
   LEDTRIS = 0;     // Macro points to right TRIS register, set them to output
   LEDPORT = 0;     // Macro points to right PORT, set it all low
Loop:
     LEDPORT = 0x80;// 10000000
     Delay_ms(500); // Half a second pause
     LEDPORT = 0x40;// 01000000
     Delay_ms(500); // Half a second pause
     LEDPORT = 0x20;// 00100000
     Delay_ms(500); // Half a second pause
     LEDPORT = 0x10;// 00010000
     Delay_ms(500); // Half a second pause
     LEDPORT = 0x08;// 00001000
     Delay_ms(500); // Half a second pause
     LEDPORT = 0x04;// 00000100
     Delay_ms(500); // Half a second pause
     LEDPORT = 0x02;// 00000010
     Delay_ms(500); // Half a second pause
     LEDPORT = 0x01;// 00000001
     Delay_ms(500); // Half a second pause
     goto Loop;     // go back and do it again
}

Primer 1.6
Vrlo lako mozemo da napravimo da se svetlo “odbija” od krajeve:

#define LEDPORT PORTB
#define LEDTRIS TRISB

void main(){
   CMCON = 0x07;    // TURN COMPARATORS OFF (make it like a 16F84)
   LEDTRIS = 0;     // Macro points to right TRIS register, set them to output
   LEDPORT = 0;     // Macro points to right PORT, set it all low
Loop:
     LEDPORT = 0x80;// 10000000
     Delay_ms(500); // Half a second pause
     LEDPORT = 0x40;// 01000000
     Delay_ms(500); // Half a second pause
     LEDPORT = 0x20;// 00100000
     Delay_ms(500); // Half a second pause
     LEDPORT = 0x10;// 00010000
     Delay_ms(500); // Half a second pause
     LEDPORT = 0x08;// 00001000
     Delay_ms(500); // Half a second pause
     LEDPORT = 0x04;// 00000100
     Delay_ms(500); // Half a second pause
     LEDPORT = 0x02;// 00000010
     Delay_ms(500); // Half a second pause
     LEDPORT = 0x01;// 00000001
     Delay_ms(500); // Half a second pause


     LEDPORT = 0x02;// 00000010
     Delay_ms(500); // Half a second pause
     LEDPORT = 0x04;// 00000100
     Delay_ms(500); // Half a second pause
     LEDPORT = 0x08;// 00001000
     Delay_ms(500); // Half a second pause
     LEDPORT = 0x10;// 00010000
     Delay_ms(500); // Half a second pause
     LEDPORT = 0x20;// 00100000
     Delay_ms(500); // Half a second pause
     LEDPORT = 0x40;// 01000000
     Delay_ms(500); // Half a second pause

     goto Loop;     // go back and do it again
}
Tags: , , ,

Keypad Plocica

keypada Keypad Plocica je vrlo jednostavan interface prema 4×4 tastaturi.

keypad - gore

keypad - gore

keypad - dole

keypad - dole

keypad - keypad

keypad - keypad

Tags: , , , ,

Stepper Plocica

stepperStepper Plocica sluzi da pokrece unipolarni stepper motor. Ima 4 tranzistora koji sluze da obezbede potrebnu struju. Tranzistori se napajaju preko 470R otpornika da si limitira bazna struja a 8 dioda sluze da absorbuju EMF posto je stepper induktivni potrosac.

J1 sluzi da odredi kako ce se motori napajati, da li sa 5V ili sa externog napajanja.

Stepper - gore

Stepper - gore

Stepper - dole

Stepper - dole

Tags: , , , ,

RS232 Plocica

serialRS232 Plocica koristi MAX232 5V -> RS232 converter chip. On konvertuje 0-5V TTL nivoe sa pinova mikrokontrolera na +/- 12V nivoe potrebne za RS232. Kao sto je uobicajeno za ovakve chipove, invertuje podatke prilikom shiftovanja nivoa. PIC USART je dizajniran da to kompenzije ali ako pravite seriski port softwerski, morate na to da obratite paznju.

RS232 - gore

RS232 - gore

RS232 - dole

RS232 - dole

Tags: , , , ,

I2C Switch Board

i2csw

I2C Switch Board ne koristi I2C uopste ali je Nigel ovu plocicu nazvao I2C posto je koristi u primerima sa I2C protokolom.

I2C switch board - gore

I2C switch board - gore

I2C switch board - dole

I2C switch board - dole

Tags: , , ,

I2C ADC Pločica

i2c_a2dI2C ADC Pločica koristi Philips PCF8591P, to je I2C chip sa 4 analogna ulaza i 1 analognim izlazom – svi sa osmobinom rezolucijom. Tu je i EEPROM kako bi mogli da snimimo semplove.

I2C ADC - gore

I2C ADC - dole

Tags: , , , , ,

I2C SAT Pločica

i2ctut2

I2C SAT Pločica koristi PCF8583P chip koji pamti i racuna vreme, ima bekap bateriju koja mu daje mogucnost da cuva tacno vreme i kada nije prikljucen na napajanje.

Ova sema je prilicno slicna prethodnoj plocica sa I2C EEPROM chipom sa par dodataka. 32KHz kristal, izlaz za alarm. 12K pull-up otpornik i komponente za bateriju (izolacione diode). Trimer sluzi da se podesi “tacnost sata” a jedna “dugmetara” od 3V bi trebalo da traje oko 5 godina.

I2C RTC gore

I2C RTC gore

I2C RTC dole

I2C RTC dole

Tags: , , , , ,
« Previous posts Back to top