Mäta en puls med ccp och timer

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

> jag har klippt lite, tyvärr och efter det har nog kommentaren hamnat fel bara.

"Bara" ??

Men men, vad har du gjort för att debugga ?
Har du kollat om koden hänger sig (t.ex på while(PIR1.CCP1IF == 0)) ?
Har du hängt på lite LEDs så att du vet var processorn befinner sig i koden ?
bearing
Inlägg: 11677
Blev medlem: 2 mars 2006, 01:01:45
Ort: Ängelholm

Inlägg av bearing »

Kalf skrev:Såg inte ditt tilläg färens nu. Det är en ultraljuds modul. Det finns bara en signalpine på den. Så det är så man skall göra.
Aha, ok. Men du har fortfarande en bugg i koden, för TRISB=1 sätter inte RB3 till ingång. Kommentaren är rätt, men inte koden.

Jag föreslår att överallt som du bara ska ändra en pinne i TRIS- eller PORT-register använder du REGISTER.BIT = 0/1. Det är också säkrare att bara använda pinnar som måste vara utgångar till utgångar, resten ingångar. Portarna är ingångar efter reset.

TRISB = 0; //TRISB.3=0
TRISB = 8; //PORTB.3 blir ingång //TRISB.3=1

PORTB = 0b00001000; //PORTB.3=1
PORTB = 0; //PORTB.3=0
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

> Det är också säkrare att bara använda pinnar som måste vara utgångar
> till utgångar, resten ingångar. Portarna är ingångar efter reset.

Notera bara att man inte ska ha "öppna" ingångar. De kommer att plocka
upp störningar och ställa till det. Antingen lägger man dom som utgångar.
Eller som ingångar med pull up/down motstånd. Men minst job blir det
att lägga oanvända pinnar som utgångar...
bearing
Inlägg: 11677
Blev medlem: 2 mars 2006, 01:01:45
Ort: Ängelholm

Inlägg av bearing »

Det visste jag inte. Var kan man läsa om det?
Min tanke var att när man håller på på labplattan och råkar koppla något fel är det förmodligen bättre om felkopplingen hamnar på en ingång.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

Läsa och läsa, det är väl allmän kunskap. :-)

Det har alltid varit så sedan CMOS tekniken kom för en massa
år sedan, att man inte ska lämna CMOS ingångar "öppna". Spelar ingen
roll om det är en processor eller en valig 74HCxx eller 4xxx krets...
bearing
Inlägg: 11677
Blev medlem: 2 mars 2006, 01:01:45
Ort: Ängelholm

Inlägg av bearing »

Användarvisningsbild
Kalf
Inlägg: 249
Blev medlem: 5 november 2005, 09:59:45

Inlägg av Kalf »

Nu verkar det fungera bättre, men inte helt. Nu lyser aktivitetslampan på sensorn amt man hör ett väldigt högfrekvent ljud om man lyssnar riktigt noga. Men min utgångs LED lyser hela tiden. Här är koden igen.

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_L;
unsigned int CCP_Value_1_H;
unsigned int CCP_Value_2_L;
unsigned int CCP_Value_2_H;
unsigned int CCP_Result_L;
unsigned int CCP_Result_H;
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 <= 0x908)                   //Inställd på max avtåndet
                 {
                 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_L = CCPR1L;                            //Stoppar in värdet på CCPR1L i en varabel...
     CCP_Value_1_H = CCPR1H;                            //Samma med 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_L = CCPR1L;                            //Stoppar in i varablar
     CCP_Value_2_H = CCPR1H;
     T1CON = 0x00;                                      //Stoppar timern
     count();
     }
     
void count(void)
     {
     CCP_Result_L = CCP_Value_2_L - CCP_Value_1_L;      //Subtraherar andra värdet med det första
     CCP_Result_H = CCP_Value_2_H - CCP_Value_1_H;
     CCP_Result = CCP_Result_H << 8 + CCP_Result_L;     //Lägger ihop till en variabel
     }
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

Kod: Markera allt

     CCP_Result_L = CCP_Value_2_L - CCP_Value_1_L;      //Subtraherar andra värdet med det första
     CCP_Result_H = CCP_Value_2_H - CCP_Value_1_H;
     CCP_Result = CCP_Result_H << 8 + CCP_Result_L;     //Lägger ihop till en variabel
Fungerar det där ?
Har du provat med papper och penna med några olika värden ?
Prova t.ex med Value1 = 500 och Value2 = 1000. CCP_Result borde bli 500,
eller hur ?

Blir det det ???
Användarvisningsbild
vfr
EF Sponsor
Inlägg: 3515
Blev medlem: 31 mars 2005, 17:55:45
Ort: Kungsbacka

Inlägg av vfr »

Hehe. Det är det som kallas ledande fråga.

Fast det är helt ok. Det är ju liksom det som är meningen, att vägleda. :D
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

Ja, jag hade hela uträkningen steg-för-steg med från början, men så tänke jag,
va fan!, och plockade bort det igen... :roll:

Men svaret på frågan är "Nej".
Utan hantering av carry ("lånesiffra") blir det inte rätt, utom ibland, med "rätt" invärden...
bearing
Inlägg: 11677
Blev medlem: 2 mars 2006, 01:01:45
Ort: Ängelholm

Inlägg av bearing »

Jo, jag har ju skrivit att han måste ta hänsyn till carry, eller göra subtraktionen med 16-bitarstal istället, så att kompliatorn sköter det hela.

Ok, jag tar väl bort min uträkning också...

Kod: Markera allt

             if(CCP_Result <= 0x908)                   //Inställd på max avtåndet
                 {
                 PORTA = 0b00000100;                    //LED'en tänds 
Detta gör väl att LED:en alltid tänds?


För övrigt, mängder med globala variabler är inte god sed att använda när man programmerar. I ditt fall behövs inte en enda, men om du hade använt interrupts hade du behövt en/två stycken att kommunicera med huvudprogrammet med.
Användarvisningsbild
Kalf
Inlägg: 249
Blev medlem: 5 november 2005, 09:59:45

Inlägg av Kalf »

Bearing: Ja, det gör så att LED'en tänds. Men den skall ju inte alltid vara tänd utan enbart då CCP_Result är mindre än ett visst värde. Men jag fattade inte det där med carry. Är det ett register? Känns som jag skall läsa ännu mer datablad, *suck*. Jag trodde att jag hade stappat in den i en 16bitars varabel när jag skrev unsigned innan? Du sa nämligen: "Antagligen skriver man: unsigned int variabelnamn."

Detta var det sättet som jag tyckte var lättast, men vad skall ändras då?

Sedan, fungerar denna raden ordenkligt?

Kod: Markera allt

CCP_Result = CCP_Result_H << 8 + CCP_Result_L;
om result_h är 16 och result_l 47 bilr result 1647?

//Kalf
Användarvisningsbild
vfr
EF Sponsor
Inlägg: 3515
Blev medlem: 31 mars 2005, 17:55:45
Ort: Kungsbacka

Inlägg av vfr »

Javisst funkar den raden! Fast personligen hade jag bytt ut "+"-tecknet mot "|" (d.v.s bitwise OR) istället. Resutatet blir detsamma för den här operationen men det är mer "rätt" att använda antingen två logiska operatorer "<<" och "|", eller två aritmetiska "*" och "+". Själv tycker jag att logiska operatorer känns bäst.

Vad gäller carry så är det en flagga i registerbanken till processorn. Tänkt tillbaka på hur du subtraherade tal som är större än en siffra när man gick i skolan. Alltså lånesiffra som Sodjan säger. Tänk en byte = en siffra och gör en uppställning på papper precis som i skolan. Använder du sedan processorns instruktioner för carry så löser du det!

Ett annat alternativ kan vara att slå ihop hög och lågbyte av båda resulten först och sedan göra en 16-bitars subtraktion.
bearing
Inlägg: 11677
Blev medlem: 2 mars 2006, 01:01:45
Ort: Ängelholm

Inlägg av bearing »

>Bearing: Ja, det gör så att LED'en tänds. Men den skall ju inte alltid vara tänd utan enbart då CCP_Result är mindre än ett visst värde.

Aha, nu förstår jag vad du gör. Har hela tiden trott att du har en IR-modul av någon anledning.
18,5 ms, dvs ca 6 meter gäller bara när det är ett ganska tomt mellan sensorn och väggen. Så du kommer nog få kortare pulser om du är i ett rum med möbler.

>Jag trodde att jag hade stappat in den i en 16bitars varabel när jag skrev unsigned innan? Du sa nämligen: "Antagligen skriver man: unsigned int variabelnamn."

Unsigned gör bara att kompilatorn betraktar värdena i registret som endast positiva. Det är int, char, long osv som definierar storleken. Om en int är 8 eller 16 bitar kan du läsa i manualen för kompilatorn.

Jag föreslår att du byter ut:
CCP_Value_1_L = CCPR1L;
CCP_Value_1_H = CCPR1H;
mot:
CCP_Value_1 = CCPR1H<<8 | CCPR1L; //och motsvarande få CCP_Value_2
(Förutsatt att CCP_Value_x är 16-bitars unsigned.)

Sedan kan du göra enkel subtraktion mellan två variabler.

>om result_h är 16 och result_l 47 bilr result 1647?
Om result_h är 0x16 och result_l 0x47 bilr result 0x1647.

Du borde läsa på om hur digitala register funkar. Det bör stå i digitalteknikboken. "Carry" är inte ett begrepp som gäller PICar endast, det är generellt.
Senast redigerad av bearing 2 december 2006, 00:27:00, redigerad totalt 1 gång.
Användarvisningsbild
Kalf
Inlägg: 249
Blev medlem: 5 november 2005, 09:59:45

Inlägg av Kalf »

1. Varför har du, bearing, undertecknat med kalf?

2. Om du tänker lite till så är det faktiskt 3m, för det är ett eko, altså fram och tillbaka, som sensorn mäter.

3. Jag visste, igentligen, att unsigned betyder posetivt tal. Men blev förvirrad när du skrev "Unsigned in varabelnamn".

4. Jag skall genast ta och ändra koden till ditt förslag, bearing, så jag blir av med några variablar.

5. Jag skall läsa på om digitala register, men jag har, tyvärr, inte någon lärobok i den kursen. Detta beror på att läroböker blir så snabbt omodärna så skolan skulle behöva köpa in nya böcker varje år.
BTW: Det gick bra på provet idag, det var så himla enkelt, bara läsa av databladen man fick ut och skriva ner svaren. Men så är kursen väldigt basic. Blir bättre i B kursen senare, om jag väljer den.

6. Får ta och läsa i databladet om carry då.

//Kalf
Skriv svar