[ pepsiredstar @ 16.05.2009. 22:51 ] @
Pozdrav svima!

Imam jedan problem. Naime treba da napravim program koji ce simulirati bacanje kocke (1,2,3,4,5,6). Koristim CCS Compiler za Microchip-ove PIC-ove i PICC Simulator (radi se o PIC 16f877 mikrokontroleru). Preko tastera koji je povezan na pinu RB7 treba da okinem program i da mi on na portu B (pinovi od 0 do 6) mikrokontrolera setuje odredjene pinove na "1".
Problem je u sledecem kodu koji sam napravio, preveo i kompajlirao, a koji kada simuliram ne radi posao koji treba da radi.
Jel moze neko da mi pomogne da prepravim ovaj kod?

#include <16F877.h>
#fuses HS,NOWDT,PROTECT,NOLVP,PUT
#use delay (clock=20000000)
#include <stdlib.h>

#byte port_b=0x06

byte const SEG_MAP[6] = {0x08,0x22,0x2A,0x55,0x9D,0x77};

unsigned int i, n;

int x;

void display_digits() {

port_b=SEG_MAP[x];
delay_us(1);
}

void main() {

set_tris_b(0x80);
port_b=0;
i=0;

Loop:

while(input(PIN_B7))
{
i=i+1;
if (i==255)
i=0;
}

srand(i);
n=rand();

switch (n)
{
case '1':
{
x=1;
if ((n>0) & (n<42))
display_digits();
break;
}
case '2':
{
x=2;
if ((n>42) & (n<84))
display_digits();
break;
}
case '3':
{
x=3;
if ((n>84) & (n<126))
display_digits();
break;
}
case '4':
{
x=4;
if ((n>126) & (n<168))
display_digits();
break;
}
case '5':
{
x=5;
if ((n>168) & (n<210))
display_digits();
break;
}
case '6':
{
x=6;
if ((n>210) & (n<255))
display_digits();
break;
}

};

while(!input(PIN_B7))
delay_us(1);

goto Loop;
}

[ bogdan.kecman @ 17.05.2009. 00:56 ] @
evo ovako radi:

Code:


#include <16F877.h>



#device adc=8

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES HS                       //High speed Osc (> 4mhz)
#FUSES NOPUT                    //No Power Up Timer
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD                    //No EE protection
#FUSES NOWRT                    //Program memory not write protected
#FUSES NODEBUG                  //No Debug mode for ICD

#use delay(clock=20000000)

#byte port_b=0x06

#include <stdlib.h>

unsigned int8 const SEG_MAP[6] = {0x08, 0x41, 0x1C, 0x55, 0x5D,0x77};

unsigned int8 i, x;
int r;

void display_digits() {
  port_b=SEG_MAP[x];
  delay_us(1);
}


void main()
{
   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_OFF);
   setup_psp(PSP_DISABLED);
   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);

   set_tris_b(0x80);
   port_b=0;
   i=0;
   
   /* vrti u krug dok ne pritisne dugme */
   while(!input(PIN_B7)){
     i++; if (i>6) i=1;
     x = i-1;
     display_digits();
     delay_ms(100);
   }
   
   /* obrisi kocku */
   port_b = 0;


Loop:

   while(input(PIN_B7)) i++;
   srand(i);
   r=rand();
   x = r%5;
   display_digits();
   while(!input(PIN_B7)) delay_us(1);

   goto Loop;
}


i primer sema:

[ pepsiredstar @ 17.05.2009. 09:02 ] @
E hvala Bogdane. Imam jos jedno pitanje. Kako da prepravim kod tako da ako se taster prilikom izbora broja ne otpusti u roku od 5 sekundi, sve diode upale i svetle permanentno do otpustanja tastera? Nakon otpustanja diode treba da se ugase, a pale se tek nakon novog pritiska na taster.
[ bogdan.kecman @ 17.05.2009. 09:55 ] @
ne kontam pitanje :(

ovaj kod kada upalis masinu vrti u krug 1-6 dok ne pritisnes taster ... ako to neces, izbaci ovaj deo:

Code:

   /* vrti u krug dok ne pritisne dugme */
   while(!input(PIN_B7)){
     i++; if (i>6) i=1;
     x = i-1;
     display_digits();
     delay_ms(100);
   }


citam ponovo ovo sto si trazio .. mozda hoces nesto ovako?

Code:

#include <16F877.h>
#device adc=8
#FUSES NOWDT                    //No Watch Dog Timer
#FUSES HS                       //High speed Osc (> 4mhz)
#FUSES NOPUT                    //No Power Up Timer
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD                    //No EE protection
#FUSES NOWRT                    //Program memory not write protected
#FUSES NODEBUG                  //No Debug mode for ICD
#use delay(clock=20000000)
#byte port_b=0x06
#include <stdlib.h>

unsigned int8 const SEG_MAP[6] = {0x08, 0x41, 0x1C, 0x55, 0x5D,0x77};

unsigned int8 i, x;
int r;
unsigned intt16 l;
unsigned int8 h;

void display_digits() {
  port_b=SEG_MAP[x];
  delay_us(1);
}


void main()
{
   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_OFF);
   setup_psp(PSP_DISABLED);
   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);

   set_tris_b(0x80);
   port_b=0;
   i=0;


   /* vrti u krug dok ne pritisne dugme (zakomentarisan ceo blok)
   while(!input(PIN_B7)){
     i++; if (i>6) i=1;
     x = i-1;
     display_digits();
     delay_ms(100);
   }
   */   

   /* obrisi kocku */
   port_b = 0;


Loop:


// pusten taster je "low"
   while(!input(PIN_B7)); // cekaj da stisne taster
   h=0;
   l=0;
   while(input(PIN_B7)){ // ~40 taktova traje ovaj while, dakle 40/5M sec, ako nam treba 5sec to znaci 625000 puta da obrnemo ovu petlju
      i++;
      if(++l == 0) if(++h>9) { // 625000/65535 = 9.3 - ne verujem da nam je bas ultra bitno da bude 5sec okruglo .. ali mozes ovde to da stelujes
         port_b = 0xff;        // upali sve ledare
         while(input(PIN_B7)); // cekaj da pusti taster
         port_b = 0;           // ugasi sve ledare
         goto Loop;            // aj sve jovo nanovo
      }       
   }

   srand(i);
   r=rand();
   x = r%5;
   display_digits();
   while(!input(PIN_B7)) delay_us(1);

   goto Loop;
}



mrzi me da palim lap sa windozom da proverim ovo, trebalo bi da sljaka .. probaj pa reci ako nesto nije jasno ili ako nije to to
[ pepsiredstar @ 17.05.2009. 13:35 ] @
Evo da pojasnim:

Sledeci kod sam prilagodio mojim potrebama:

#include <16F877.h>
#fuses NOWDT,HS,NOPUT,NOPROTECT,NOBROWNOUT,NOLVP,NOWRT,NODEBUG
#use delay(clock=20000000)
#include <stdlib.h>

#byte port_b=0x06

unsigned int8 const SEG_MAP[6] = {0x08, 0x22, 0x2A, 0x55, 0x5D,0x77};

unsigned int8 i, x;
int r;

void display_digits()
{
port_b=SEG_MAP[x];
delay_us(5);
}

void main()
{

set_tris_b(0x80);
port_b=0;
i=0;

/* vrti u krug dok ne pritisne dugme */
while(input(PIN_B7))
{
i++;
if (i>6)
i=1;
x = i-1;
}

/* obrisi kocku */
port_b = 0;


Loop:

while(input(PIN_B7))
i++;
srand(i);
r=rand();
x = r%6;
display_digits();
while(!input(PIN_B7))
delay_us(1);

goto Loop;
}

U funkciji display_digits drzim LED-ove upaljene tokom 5 sekundi. Ako je za to vreme taster pritisnut (znaci tokom svih 5 sekundi), treba da upalim svih 7 LED-ova i da ih drzim upaljene sve dok se taster ne otpusti. Kada se taster otpusti sve LED-ove treba da ugasim, i da ponovo krenem sa izborom broja.
[ bogdan.kecman @ 17.05.2009. 13:54 ] @
Code:

void display_digits(){
  port_b=SEG_MAP[x];
  delay_us(5);
}


u ovoj funkciji drzis ledare upaljene prema SEG_MAP[6] nizu (cifre 1-6) 5 mikro sekundi .. ne 5 sekundi !!! 5 sekundi bi bilo ovako:

Code:

void display_digits(){
  port_b=SEG_MAP[x];
  delay_ms(5000);
}


tokom trajanja delay_ funkcije ne radis nista .. niti proveravas da li je pritisnut niti bilo sta drugo ..

Code:

while(input(PIN_B7)) i++;


dok je pritisnut taster - povecavaj i .. (kada dodje do 255 sam ce se i rotirati na 0)

Code:

srand(i);
r=rand();


setuj random seed na i pa pokupi random vrednost u r ... ovo je moglo da bude i preskoceno .. posto je svejedno I zavisno od toga koliko dugo drzis taster ceo random je potpuno nepotreban ...

Code:

x = r%6;


ovo dodeljuje X-u vrednost 0-5

Code:

display_digits();


ovde prikazes X+1 na kocki i sacekas 5 mikro sekundi

Code:

while(!input(PIN_B7)) delay_us(1);


cekaj dok neko ne pritisne taster

dakle ... ja i dalje ne kapiram sta hoces, ali evo ti objasnjenje sta se desava posto mi se cini da ti nije jasno ...
sto se tice tih 5 sekundi ... ovaj drugi kod ce ti pomoci .. samo onu cifru 9 promeni na manje/vise koliko oces da traje taj interval
[ pepsiredstar @ 17.05.2009. 14:46 ] @
Vazi. Slazem se sa tobom u vezi drzanja ledara upaljenih, ja sam to stavio cisto da bih skratio vreme simulacije. Javicu se ako budem imao nekih problema.
[ pepsiredstar @ 28.05.2009. 12:57 ] @
Evo cisto da se javim da sam resio problem koji sam imao.
Postoje dve mogucnosti, i to sa led diodama i 7 segmentnim displejom. Pa rekoh ajde da to ovde okacim.

Prva varijanta:

#include <16F877.h>
#fuses NOWDT,HS,NOPUT,NOPROTECT,NOBROWNOUT,NOLVP,NOWRT,NODEBUG
#use delay(clock=20000000)
#use rs232(baud=19200, xmit=PIN_C6, rcv=PIN_C7)
#include <stdlib.h>

#byte port_b=0x06

unsigned int8 const SEG_MAP[6] = {0x08, 0x22, 0x2A, 0x55, 0x5D,0x77};

unsigned int8 i, x;

void display_digits()
{
port_b=SEG_MAP[x];
printf("Slucajan broj je: %u\n", i);
delay_ms(5000);
}

void main()
{

set_tris_b(0x80);
port_b=0;
i=0;

Loop:
/* vrti u krug dok ne pritisne dugme */
while(input(PIN_B7))
{
i++;
if (i>6)
i=1;
x = i-1;
}

display_digits();



while(!input(PIN_B7));

port_b=0; //iskljucenje dioda
delay_ms(50);
goto Loop;

}

Druga varijanta:

#include <16F877.h>
#fuses NOWDT,HS,NOPUT,NOPROTECT,NOBROWNOUT,NOLVP,NOWRT,NODEBUG
#use delay(clock=20000000)
#use rs232(baud=19200, xmit=PIN_C6, rcv=PIN_C7)
#include <stdlib.h>

#byte port_b=0x06

unsigned int8 const SEG_MAP[6] = {0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D};

unsigned int8 i, x, n;

void display_digits()
{
port_b=SEG_MAP[x];
delay_ms(5000);
}

void main()
{

set_tris_b(0x80);
port_b=0;
setup_timer_0 (RTCC_INTERNAL);
set_timer0(0);

Loop:

while(input(PIN_B7)) // petlja broji dok je taster otpusten (high)

STR:
i=get_timer0();
srand(i); // f-ja promene pocetnih uslova za novu sekvencu pss. brojeva
n=rand(); // f-ja generisanja sekvence pseudoslucajnih int brojeva

n=(n & 0x07);

if ((n==0)|(n==7))
goto STR;

x=n-1;
display_digits();


while(!input(PIN_B7)); // cekaj dok taster ne otpusti

port_b=0; //iskljucenje dioda
delay_ms(50);

goto Loop;
}

Pozdrav.