Sida 4 av 6
Postat: 2 december 2006, 00:38:10
av bearing
1. Jag hade citerat ditt inlägg och så råkade det ligga kvar i slutet.
2. Ah, tänkte fel.
3. I min kompilator för picar är int 8 bitar, i din 16 bitar tror jag, i datorer 32 bitar tror jag. Med sådana variationer verkar det bäst att du kollar själv. Det borde gå fort att googla fram manualen för din kompilator. Kanske t.o.m finns hjälp om du trycker F1,
Postat: 2 december 2006, 11:16:12
av Kalf
ja det är 16 bitar, jag borde ha skrivit det i mitt förra inlägg, då jag redan då tagit reda på det.
//Kalf
Postat: 8 december 2006, 17:08:41
av Kalf
Jag har arbetet lite med koden. Jag tillsammans med ett par lärare på skolan har försökt, nu funkar det nästan. Det verkar vara nära ett slut. Så som den beter sig för tillfället så lyser dioden om man håller handen på precis rätt avstånd. Men inte annars. Här är koden som den ser ut för tillfället:
Kod: Markera allt
/****************************************
* *
* Safety Electronics UF *
* *
* Programerad av: Karl-fredrik *
* Datum: 2006-11-30 *
* Version: V.0.3 *
* *
****************************************/
//Prototyper
void start_pulse(void);
void recive(void);
void count(void);
//Variablar
unsigned int CCP_Value_1;
unsigned int CCP_Value_2;
unsigned int CCP_Result;
void main()
{
TRISA = 0b00000000; //Porta utgång
while(1) //Evighets loop
{
TRISB = 0b00000000; //PortB utgång
start_pulse();
TRISB = 0b00001000; //Ställa om PORTB.3 till ingång
recive();
if((CCP_Result < 0x500)) //gämför värdet på CCP_result
{
PORTA = 0b00000100; //LED'en tänds
}
else
{
PORTA=0x00; //Led'en är släckt
}
}
}
void start_pulse(void)
{
PORTB = 0x00;
PORTB = 0b00001000; //1 skickar en puls till ping)))...
delay_us(5); //...Som varar i 5us
PORTB = 0x00; //0'ställer igen
}
void recive(void)
{
T1CON = 0b00110001; //startar timer 1 med prescaler 1:8
CCP1CON = 0b00000101; //Sätter igång CCP'n, positiv flank
while(PIR1.CCP1IF == 0) //Väntar på flank
{
void;
}
PIR1.CCP1IF = 0;
CCP_Value_1 = CCPR1L << 8 | CCPR1H;
CCP1CON = 0b00000100; //Ställer om för negativa flanker
while(PIR1.CCP1IF == 0) //Väntar igen
{
void;
}
PIR1.CCP1IF = 0; //Nollställer interuppt registret
CCP_Value_2 = CCPR1L << 8 | CCPR1H;
T1CON = 0x00; //Stoppar timern
count();
}
void count(void)
{
CCP_Result = CCP_Value_2 - CCP_Value_1; //Lägger ihop till en variabel
}
Men den roliga biten är att ifall jag byter ut raden:
Kod: Markera allt
if(CCP_Result < 0x500) //gämför värdet på CCP_result
Till:
Kod: Markera allt
if((CCP_Result < 0x500) || (CCP_Result == 0x500)) //gämför värdet på CCP_result
Så när det inte ligger något framför sensorn så blinkar LED'en väldigt snabbt, men ändå så långsamt så man kan uppfatta det. Men när det ligger något innom det område som det handlar om så lyser LED'en.
Om ni har glömt, eller inte läst tidigare i troden så skall LED'en lysa när det ligger ett föremål innom ett visst område. Om det är tomt så skall den vara släckt.
Vad klan felet vara?
//Kalf
Postat: 8 december 2006, 17:15:26
av Icecap
När man bytar flank på CCP ska man göra:
CCP1CON = 0x00; // To avoid false interrupts
CCP1CON = 0x04; // Make it capture falling edge
Alltså sätta den till noll först, allt enl. databladet! (heja sodjan!)
Jag använder själv denna funktion fast via interrupt och det fungerar klockrent.
Postat: 8 december 2006, 17:26:14
av bearing
Har du inte tillgång till oscilloskop eller liknande i skolan, så du kan kolla om det är signalerna det är fel på eller koden?
Det kan vara en ide' att lägga in en paus mellan varje puls, för att inte få med ev. ekon.
Jag har en avståndsmätare hemma och den sänder bara en puls varannan sekund ungefär.
Postat: 8 december 2006, 17:37:37
av Kalf
jag har idag testat med oscillioskop och signalen är det inget fel på. Jag trodde först att det inte kom någon puls alls när det inte låg någonting framför sensorn, men det gör det, det blir en puls på ca 20ms.
Visst kan jag lägga in en delay. Det skall jag testa.
Jag lade in CCP1CON = 0x00;
Men då hänger sig koden när det kommer något framför sensorn innom ett område, ganska nära till den, men när man är på "rätt" avstånd så lyser dioden.
//Kalf
Postat: 8 december 2006, 17:43:48
av bearing
Förresten, om insignalen blir hög innan du ställer in CCP-enheten så kommer ju inte den sätta flaggan. Du kanske måste ställa in den under pulsen du sänder.
Postat: 8 december 2006, 17:47:39
av Kalf
exakt vad menar du? Är det första eller andra gången jag konfiguerar CCP-enheten?
//Kalf
BTW: Jag testade med en delay på 1 sek och det hjälpte inte något.
Postat: 8 december 2006, 17:53:04
av bearing
Första. Menar att du ställer in den på triggning efter delay_us och innan PORTB = 0x00; . Det förutsättar att du låter timer1 gå hela tiden.
Postat: 8 december 2006, 18:30:13
av Icecap
Jag antar att du förstod att denna extra nollning av CCP1CON ska göras vid VARJE ändring av flanken.....
Kod: Markera allt
/****************************************
* *
* Safety Electronics UF *
* *
* Programerad av: Icecap *
* Datum: 2006-12-08 *
* Version: V.0.4 *
* *
****************************************/
//Prototyper
void start_pulse(void);
void Recieve(void);
typedef unsigned int word;
typedef unsigned char byte;
typedef union
{
word Word;
byte Byte[2];
} T_BOTH;
#define true 1
#define false 0
#define Indicator PORTA.F2 /* Giltigt för MikroC */
#define Pulse_IO PORTB.F3
#define Pulse_Dir TRISB.F3
//Variablar
T_BOTH CCP_Value_1, CCP_Value_2;
word CCP_Result;
void main()
{
PORTA = 0x00; // Known state
PORTB = 0x00; // Known state
TRISA = 0x00; // PORTA utgång
TRISB = 0x00; // PORTB utgång
T1CON = 0b00110001; // Startar timer 1 med prescaler 1:8 och låt den köra!
while(true) // Evighets loop
{
Pulse_Dir = 0; // Som utgång
Pulse_IO = true; // Skickar en puls till ping)))...
delay_us(5); //...Som varar i 5us
Pulse_IO = false; // Puls slut
Pulse_Dir = true; // Ställa om PORTB.3 till ingång
CCP1CON = 0b00000101; // Sätter igång CCP'n, positiv flank
while(PIR1.CCP1IF == 0); // Väntar på flank
CCP_Value_1.Byte[0] = CCPR1L; // Transfer low byte
CCP_Value_1.Byte[1] = CCPR1H; // Transfer high byte
PIR1.CCP1IF = 0; // Acknowledge the change
CCP1CON = 0x00; // To avoid stupidities
CCP1CON = 0b00000100; //Ställer om för negativa flanker
while(PIR1.CCP1IF == 0); // Väntar igen
CCP_Value_2.Byte[0] = CCPR1L; // Transfer low byte
CCP_Value_2.Byte[1] = CCPR1H; // Transfer high byte
PIR1.CCP1IF = 0; // Nollställer interupt flaggan
CCP1CON = 0x00; // Reset the CCP
CCP_Result = CCP_Value_2.Word - CCP_Value_1.Word; //Lägger ihop till en variabel
if(CCP_Result < 0x500) //Jämför värdet på CCP_result
{
Indicator = true; // LED'en tänds
}
else
{
Indicator = false; // LED'en släcks
}
}
}
Edit: snyggade till lite.
Postat: 8 december 2006, 19:18:09
av Kalf
Jag fick felmedelande på din kod icecap.
rad 43: ';' expected but =found
raden ser ut:
(byte*)&CCP_Value_1 + 0 = CCPR1L; // Transfer low byte
//Kalf
Postat: 8 december 2006, 19:39:49
av Icecap
OK, har ändrat lite.
Postat: 8 december 2006, 23:41:04
av Kalf
Det verkar som om din kod hänger sig. För aktivitets LED'en på sensorn blinkar bara till en gång. Denna skall lysa hela tiden om sensorn fungerar som den skall.
//Kalf
Postat: 8 december 2006, 23:44:27
av bearing
Du borde koppla in några fler lysdioder som påverkas på olika ställen i koden, tex att de tänds i de olika while-looparna, så du vet var den stannar.
Att den stannar i en while-loop måste ju betyda att CCP-enheten inte får sin flank.
Har du länk till databladet till din sensor?
Postat: 9 december 2006, 00:47:39
av Kalf
får fixa LED's imon här är länken till databladet för sensorn:
http://www.parallax.com/dl/docs/prod/ac ... G-v1.3.pdf
//Kalf