 |
www.elektronik.si Forum o elektrotehniki in računalništvu
|
Poglej prejšnjo temo :: Poglej naslednjo temo |
Avtor |
Sporočilo |
hocko18x Član

Pridružen-a: Pet 03 Apr 2009 23:49 Prispevkov: 46 Aktiv.: 0.23 Kraj: Pod Šmarno Goro :P
|
Objavljeno: Pon Maj 04, 2009 5:03 pm Naslov sporočila: PIC16F628A (Merjenje razdalje s pomočjo ultrazvoka) |
|
|
Živjo fantje, že dolg probavam rešiti en problem, vendar mi ne gre in ne gre.
Za seminarsko nalogo moram narediti "parkirni radar". Uporabljam PIC16F628A.
Kot razvojno okolje uporabljam EasyPIC4. Čip sem postavil v DIP18B socket. Problem je, ker mi compiler javi napako, ko hočem naložiti program na čip; "internal error". Se pravi PORTi so pravilno nastavljeni, tudi LCD_Config sem naštimal na 16x2 LCD.
Tukaj je še slika moje sheme, ki sem jo naredil v Eaglu.
Konfiguracija LCD je sledeča:
void Lcd_Config(unsigned short *port, unsigned short RS, unsigned short EN, unsigned short WR, unsigned short D7, unsigned short D6, unsigned short D5, unsigned short D4);
LCD_Config(&PORTB,0,2,1,6,5,4,3);
Vendar ko priklopim LCD na razvojno okolje, se ne zgodi nič. Prikažejo se samo default kvadratki, tako da LCD deluje pravilno.
Še kopija programa
Koda: |
temp Var Word
temperature Var Word
count_remain Var Byte
count_per_c Var Byte
DQ Var PORTA.4
cnt Var Word
mm Var Word
cm Var Word
cmd Var Word
meter Var Word
mtrd Var Word
dummy Var Word
time Var Word
preset Var Word
rb0old Var Word
OPTION_REG = %01001111
CMCON = %00000111
TRISA = %00110000
TRISB = %00100001
start:
preset = 1000 ' to give me a preset value of 2ms at a prescaler value of 1:2 for timer1
TMR1H = preset.highbyte ' loading the preset high byte into timer1 (%00000011)
TMR1L = preset.lowbyte ' loading the preset low byte into timer1 (%11101000)
T1CON = %00010000 ' prescaler value of 1:2, timer diabled
INTCON = %11000000 ' GIE & PEIE enabled
PIE1.0 = 1 ' TMR1 interrupt enabled
PIR1.0 = 0 ' TMR1 interrupt flag reset
rb0old = PORTB.0 ' set rb0old to current value of RB0
mm = 0 ' set millimeter to zero
cm = 0 ' set centimeter to zero
cmd = 0 ' set centimeter decimal to zero
meter = 0 ' set meter to zero
mtrd = 0 ' set meter decimal to zero
ON INTERRUPT GOTO timeint
gosub LCD0 ' Call LCD welcome & info meassage
pause 2000 ' Pause 2 seconds
gosub LCD1 ' Call LCD measurement display
'/Test if start button is pressed
start1:
if PORTB.5 = 0 then goto test ' if start button is pressed go to test
goto start1 ' if not pressed go back to start
'/Confirm that start button has been pressed
test:
pause 20 ' pause 20ms
if PORTB.5 = 1 then goto start1 ' if button is not pressed go back to start
gosub LCD2
'/Start & stop hardware pulse width modulation
HPWM 1,127,40000 ' 50% duty cycle 40kHz PWM (Start)
PAUSE 2 ' 2ms delay
HPWM 1,0,40000 ' 0% duty cycle 40kHz PWN (End)
'/Start timing system & check for change on RB0
changetest:
T1CON.0 = 1 ' Start Timer1
While (PORTB.0 = rb0old)
Wend
T1CON.0 = 0 ' Stop Timer1
SOUND PORTB.4, [128,84] ' Sound buzzer for a second at 10kHz
time.lowbyte = TMR1L ' Saving Timer1 value into time
time.highbyte = TMR1H ' Saving Timer1 value into time
'/Temperature calculation
tempconversion:
OWOut DQ, 1, [$CC, $44] ' Start temperature conversion
waitloop:
OWIn DQ, 4, [count_remain] ' Check for still busy converting
If count_remain = 0 Then waitloop
OWOut DQ, 1, [$CC, $BE] ' Read the temperature
OWIn DQ, 0, [temperature.LOWBYTE, temperature.HIGHBYTE, Skip 4, count_remain, count_per_c]
'Calculate temperature in degrees C to 2 decimal places (not valid for negative temperature)
temperature = (((temperature >> 1) * 100) - 25) + (((count_per_c - count_remain) * 100) / count_per_c)
temp = temperature
'/Distance calculation
DISABLE ' disable interrupts
dummy = (time((6 * temp)+ 3300)) ' calculate part of the full calculation
mm = DIV32 10000 ' dummy divided by 10k to get distance in mm
if (mm > 10) then ' if distance is greater than 10mm then
cm = (mm / 10) ' work out distance in cm and
cmd = (mm - (cm * 10)) ' work out the decimal value
endif
if (cm > 100) then ' if distance is greater than 100cm then
meter = (cm /100) ' work out distance in meters and
mtrd = (mm - (meter * 1000)) ' work out the decimal value
endif
endprog:
pause 5000 ' pause for 5 seconds
goto start ' return to the start of the program for a new measurement
'//////////////////////// SUB Routines & Interrupts/////////////////////////////
'/Display on LCD
LCD0:
LCDOUT $FE,1 ' clear display
LCDOUT "WELCOME:" ' first line information
LCDOUT $FE, $C0 ' set cursor to the start of the second line
LCDOUT "DEVICE INFORMATION" ' second line information
LCDOUT $FE, $94 ' set cursor to the start of the third line
LCDOUT "MIN RANGE: 1 METER" ' third line information
LCDOUT $FE, $D4 ' set the cursor to the start of the fourth line
LCDOUT "MAX RANGE: 15 METERS" ' fourth line information
RETURN
LCD1:
LCDOUT $FE,1 ' clear display
LCDOUT " *DISTANCE METER* " ' first line information
LCDOUT $FE, $C0 ' set cursor to the start of the second line
LCDOUT "METER = ",#meter,".",#mtrd ' second line information
LCDOUT $FE, $94 ' set cursor to the start of the third line
LCDOUT "CM = ",#cm,".",#cmd ' third line information
LCDOUT $FE, $D4 ' set the cursor to the start of the fourth line
LCDOUT "MM = ",#mm ' fourth line information
RETURN
LCD2:
LCDOUT $FE,1 ' clear display
LCDOUT " *DISTANCE METER* " ' first line information
LCDOUT $FE, $C0 ' set cursor to the start of the second line
LCDOUT "METER = CALCULATING" ' second line information
LCDOUT $FE, $94 ' set cursor to the start of the third line
LCDOUT "CM = CALCULATING" ' third line information
LCDOUT $FE, $D4 ' set the cursor to the start of the fourth line
LCDOUT "MM = CALCULATING" ' fourth line information
RETURN
LCD3:
LCDOUT $FE,1 ' clear display
LCDOUT " *DISTANCE METER* " ' first line information
LCDOUT $FE, $C0 ' set cursor to the start of the second line
LCDOUT "ERROR: NO SIGNAL" ' second line information
LCDOUT $FE, $94 ' set cursor to the start of the third line
LCDOUT "RECEIVED OR" ' third line information
LCDOUT $FE, $D4 ' set the cursor to the start of the fourth line
LCDOUT "MAX RANGE EXCEEDED" ' fourth line information
RETURN
DISABLE
timeint:
T1CON.0 = 0 ' Stop Timer1
PIR1.0 = 0 ' Reset Timer1 Flag
gosub LCD3 ' Display error
goto endprog ' Goto end of the program
RESUME ' Will not reach this point
ENABLE ' Will not reach this point
END
|
Ta program ni napisan v C-ju... verjetno moram uporabiti kakšen drugačen compiler?
|
|
Nazaj na vrh |
|
 |
bungee Član


Pridružen-a: Pon 07 Mar 2005 18:49 Prispevkov: 1479 Aktiv.: 6.24 Kraj: Ljubljana
|
Objavljeno: Pon Maj 04, 2009 8:54 pm Naslov sporočila: |
|
|
Prva napaka, ki jo opazim je to, da je tvoj"ping" dolg 2ms, kar ne bo dobro.
Najboljša dolžina pinga je bila cca 200us = 8 ciklov na oddajanju.
Poleg tega, pa je tu meritev in oddajanje časovno kritična zadeva, tako da v basicu tole verjetno ne bo šlo. Še najbolje bi bilo to naredit v assemblerju.
Internal error je običajno znak, da nekaj ni v redu s samim programom, s katerim nalagaš ti to na PIC.
Če imaš EasyPIC mislim, da ni problema uporabit njihov program samo za nalaganje firmware pa lahko napišeš v MPLAB-u
|
|
Nazaj na vrh |
|
 |
Branez Moderator


Pridružen-a: Pon 14 Apr 2003 7:21 Prispevkov: 7831 Aktiv.: 33.04 Kraj: Koprivnica HR
|
Objavljeno: Pon Maj 04, 2009 10:31 pm Naslov sporočila: |
|
|
Daj dodaj link na program, odkoder si to snel.
V programu je uporabljen štirivrstični display in nekakšen senzor temperature. Tega vsega v tvojih shemah ni.
Z nečim podobnim se ravnokar igram, ampak še nisem vsega napisal. Ko bo čas bo na tem mestu vse lepo opisano. Dela pa že (brez merjenja temperature)!
_________________ The true sign of intelligence is not knowledge but imagination.
Creativity is intelligence having fun!
Albert Einstein |
|
Nazaj na vrh |
|
 |
hocko18x Član

Pridružen-a: Pet 03 Apr 2009 23:49 Prispevkov: 46 Aktiv.: 0.23 Kraj: Pod Šmarno Goro :P
|
Objavljeno: Tor Maj 05, 2009 10:56 am Naslov sporočila: |
|
|
Program je samo copy/paste iz strani, na začetku sem zbrisal te ukaze, ker sem po svoje iniciliaziral LCD;
Koda: |
DEFINE LCD_DREG PORTA ' Set LCD Data port
DEFINE LCD_DBIT 0 ' Set starting Data bit (0 or 4) if 4-bit bus
DEFINE LCD_RSREG PORTB ' Set LCD Register Select port
DEFINE LCD_RSBIT 6 ' Set LCD Register Select bit
DEFINE LCD_EREG PORTB ' Set LCD Enable port
DEFINE LCD_EBIT 7 ' Set LCD Enable bit
DEFINE LCD_BITS 4 ' Set LCD bus size (4 or 8 bits)
DEFINE LCD_LINES 4 ' Set number of lines on LCD
DEFINE LCD_COMMANDUS 2000 ' Set command delay time in us
DEFINE LCD_DATAUS 50 ' Set data delay time in us
|
dodal sem svoj Lcd_Config();
Ne vem če sploh pravilno delam, ker nisem tako vešč v izdelovanju vezij in programiranju le-teh. Branez, ali bi mi lahko pokazal tvoj osnutek programa? Potem bi mi bilo bolj jasno, kako zadeva deluje.
|
|
Nazaj na vrh |
|
 |
bungee Član


Pridružen-a: Pon 07 Mar 2005 18:49 Prispevkov: 1479 Aktiv.: 6.24 Kraj: Ljubljana
|
|
Nazaj na vrh |
|
 |
Branez Moderator


Pridružen-a: Pon 14 Apr 2003 7:21 Prispevkov: 7831 Aktiv.: 33.04 Kraj: Koprivnica HR
|
Objavljeno: Tor Maj 05, 2009 4:14 pm Naslov sporočila: |
|
|
hocko18x je napisal/a: |
Program je samo copy/paste iz strani, na začetku sem zbrisal te ukaze, ker sem po svoje iniciliaziral LCD..... |
Katere strani?
Bungee ti je zelo lepo opisal potek programa.
_________________ The true sign of intelligence is not knowledge but imagination.
Creativity is intelligence having fun!
Albert Einstein |
|
Nazaj na vrh |
|
 |
hocko18x Član

Pridružen-a: Pet 03 Apr 2009 23:49 Prispevkov: 46 Aktiv.: 0.23 Kraj: Pod Šmarno Goro :P
|
Objavljeno: Tor Maj 05, 2009 11:19 pm Naslov sporočila: |
|
|
Skopiral sem si program dol in pozabil stran. Bom poiskal.
Prosil bi vas za uslugo. Na RA4 imam vezan PIEZO zvočnik. Ker mi LCD ne deluje, bi rad sprobal, če mi deluje vsaj zvočnik. Veliko sem iskal na internetu, vendar nobena stvar ne deluje. Se pravi RA4 mora biti nastavljen na output. Našel sem nekaj ukazov v Basicu, vendar se ne spoznam na ta jezik. C/C++ pa poznam, tako da bi prosil, če bi nekdo spisal teh par ukazov. Pogledal sem v Help in našel ukaz Sound_Init(unsigned *snd_port, unsigned snd_pin);
SND_PORT je sound output port address
SND_PIN je sound output pin.
RA4 je na 3 nogici čipa.
|
|
Nazaj na vrh |
|
 |
bungee Član


Pridružen-a: Pon 07 Mar 2005 18:49 Prispevkov: 1479 Aktiv.: 6.24 Kraj: Ljubljana
|
Objavljeno: Sre Maj 06, 2009 12:01 am Naslov sporočila: |
|
|
hocko18x je napisal/a: |
.... C/C++ pa poznam.... |
TULE imaš povezavo na MikroC za PIC-e od istega podjetja kot je razvojna plošča. Torej ni ovire če drži tvoja zgornja trditev.
Ker mi kristalna krogla ne deluje v tem trenutku bom moral vprašat. Piezo ima že vgrajen oscilator ali ga nima. Torej če že ima vgrajen oscilator potem ni težko, pin RA4 samo še postaviš na logično 1 in je. Če pa nimaš oscilatorja, pa moraš pač ta pin preklapljati v pravi frekvenci da boš kaj slišal 1kHz je odlična frekvenca. Perioda za 1kHz pa je 1ms --> Pin on delay_us(500) Pin off delay_us(500) in ponavljaš ....
Če pa potrebuješ še navodila za MikroC, pa jih dobiš TULE
Ker pa verjetno nisi prebral datasheet-a od samega PIC-a pa ti dodajam še link do njega TULE
Sam pišem programe za PIC-e v CCS-ju, ker je po mojih testiranjih naredil najmanjšo kodo, pa še par luštnih "featurjev" ima, ki jih drugi nimajo. No v CCS-ju bi piskanje za tale PIC zgledalo takole:
Koda: |
#include <16F628A.h>
#FUSES NOWDT, INTRC_IO, PUT, NOPROTECT, NOBROWNOUT, NOMCLR, NOLVP, NOCPD
#use delay(clock=4000000)
void main()
{
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_vref(FALSE);
while(1)
{
Output_toggle(pin_a4);
delay_us(500);
}
} |
Sicer pa verjetno veš, da ti tu tvoje seminarske naloge nihče ne bo naredil. Lahko ti pomagamo z nasveti, ko se ti bo zataknilo, vendar pa boš moral sam ugotoviti kaj in kako. To namreč je namen seminarskih nalog.
|
|
Nazaj na vrh |
|
 |
hocko18x Član

Pridružen-a: Pet 03 Apr 2009 23:49 Prispevkov: 46 Aktiv.: 0.23 Kraj: Pod Šmarno Goro :P
|
Objavljeno: Sre Maj 06, 2009 10:18 am Naslov sporočila: |
|
|
Piezo že ima vgrajen oscilator, tako da moram njegovo stanje postaviti na 1. Za to bi uporabil ukaz sound_init();, vendar ne vem na katerem pinu je sound output port address in pa sound output pin, ker tega v datasheetu ni.
|
|
Nazaj na vrh |
|
 |
bungee Član


Pridružen-a: Pon 07 Mar 2005 18:49 Prispevkov: 1479 Aktiv.: 6.24 Kraj: Ljubljana
|
Objavljeno: Sre Maj 06, 2009 10:49 am Naslov sporočila: |
|
|
Če ima piezzo že vgrajen oscilator, potem samo še postaviš izhod, na katerega je priključen na 1. Ne potrebuješ narediti sound_init.
Zgoraj si pisal, da se nahaja piezzo na RA4 torej postavi RA4 na 1. Kar naj bi bilo v MikroC:
Bo šlo?
|
|
Nazaj na vrh |
|
 |
bferlic Član

Pridružen-a: Tor 09 Dec 2003 17:28 Prispevkov: 99 Aktiv.: 0.42 Kraj: Brezula, Rače
|
Objavljeno: Sre Maj 06, 2009 2:09 pm Naslov sporočila: |
|
|
Čisto mimogrede: zakaj imaš piezo ravno na RA4? Na tem kontrolerju je RA4 izhod open drain, torej ga ne moreš postaviti na pozitivno napetost, samo na 0 ali pa je nepriključen.
LP Boštjan
|
|
Nazaj na vrh |
|
 |
bungee Član


Pridružen-a: Pon 07 Mar 2005 18:49 Prispevkov: 1479 Aktiv.: 6.24 Kraj: Ljubljana
|
Objavljeno: Sre Maj 06, 2009 2:12 pm Naslov sporočila: |
|
|
bferlic je napisal/a: |
Čisto mimogrede: zakaj imaš piezo ravno na RA4? Na tem kontrolerju je RA4 izhod open drain, torej ga ne moreš postaviti na pozitivno napetost, samo na 0 ali pa je nepriključen.
LP Boštjan |
No, če imaš "pull-up" potem ni težav
|
|
Nazaj na vrh |
|
 |
hocko18x Član

Pridružen-a: Pet 03 Apr 2009 23:49 Prispevkov: 46 Aktiv.: 0.23 Kraj: Pod Šmarno Goro :P
|
Objavljeno: Sre Maj 06, 2009 7:10 pm Naslov sporočila: |
|
|
Danes sem na vezju našel napako in sicer minus ni bil vezan ne na čip, ne na zvočnik in ne na LCD, tako da so bili vsi vezani + +. Malo sem prevezal in zadeva deluje.
Hvala bungee za flowchart, vendar ne poznam TIMER0 registra; kako se zažene, kako se konča, kako se prebere vrednost iz njega... in to v C jeziku. Nekaj sem iskal na netu vendar nisem našel nič konkretnega.
|
|
Nazaj na vrh |
|
 |
bungee Član


Pridružen-a: Pon 07 Mar 2005 18:49 Prispevkov: 1479 Aktiv.: 6.24 Kraj: Ljubljana
|
Objavljeno: Sre Maj 06, 2009 10:55 pm Naslov sporočila: |
|
|
Timer register je nekaj podobnega kot port register le s to razliko, da se v njem povečuje vrednost glede na nastavitve. In da se ga lahko bere ali pobriše.
Torej poizkusi brati TMR0. Nastavitve za timer boš pa videl iz datasheeta, ker je potrebno nastaviti resolucijo le tega, od kod jemlje clock in tako naprej. Ko je enkrat nastavljen, ga ni potrebno zaganjat ustavljat itd., le pobrišeš ga po vsakem pingu. Lahko celo nastaviš interrupt rutino, ki ti ob vsakem prelivu prišteje vrednost števcu, če bi želel "podaljšati" domet in občutljivost.
Če uporabljaš MikroC, potem ima le-ta code completion, torej napišeš 1-2 črki in pritisneš Ctrl+Space. Izpisal ti bo njemu poznane ukaze, spremenljivke itd, ki so ti na voljo. Sedaj le še prebereš iz datasheeta kako nastavit pravilno timer in si zmagal.
Pa da ti še malo pomagam
Citiram: |
OPTION_REG – OPTION REGISTER (ADDRESS: 81h, 181h)
bit 7 RBPU: PORTB Pull-up Enable bit
1 = PORTB pull-ups are disabled
0 = PORTB pull-ups are enabled by individual port latch values
bit 6 INTEDG: Interrupt Edge Select bit
1 = Interrupt on rising edge of RB0/INT pin
0 = Interrupt on falling edge of RB0/INT pin
bit 5 T0CS: TMR0 Clock Source Select bit
1 = Transition on RA4/T0CKI/CMP2 pin
0 = Internal instruction cycle clock (CLKOUT)
bit 4 T0SE: TMR0 Source Edge Select bit
1 = Increment on high-to-low transition on RA4/T0CKI/CMP2 pin
0 = Increment on low-to-high transition on RA4/T0CKI/CMP2 pin
bit 3 PSA: Prescaler Assignment bit
1 = Prescaler is assigned to the WDT
0 = Prescaler is assigned to the Timer0 module
bit 2-0 PS<2:0>: Prescaler Rate Select bits
|
Če pri 4Mhz nastaviš prescaler na 256 (111), potem boš imel resolucijo ravno 256us, kar je občutno preveč za tvoj projekt, pa vseeno delovalo bo. Zdaj pa le še matematiko ugotovi ....
Pa kot sem že parkrat do zdaj napisal BERI DATASHEET od PIC-a to je obvezno, tam vse piše
|
|
Nazaj na vrh |
|
 |
hocko18x Član

Pridružen-a: Pet 03 Apr 2009 23:49 Prispevkov: 46 Aktiv.: 0.23 Kraj: Pod Šmarno Goro :P
|
Objavljeno: Čet Maj 07, 2009 10:56 pm Naslov sporočila: |
|
|
Kako nastavim te ukaze, da se bodo vršili na TMR0, oz. ko sem malo gledal po forumu in po googlu sem opazil, da je TMR2 veliko boljši, ker naj bi imel natančnejši notranji clock. Ko sem napisal par ukazov, mi je prevajalnik javil napako, da ne ve na kateri register se te ukazi sklicujejo. Je mogoče kej z OPTION_REGISTER?
Aja pa zanima me, kaj je falling in rising edge? Je to mišljeno kot signal, ko dobimo logično 0 ali 1? Se pravi ko je rising je stanje 1 in falling je stane 0?
|
|
Nazaj na vrh |
|
 |
|
|
Ne, ne moreš dodajati novih tem v tem forumu Ne, ne moreš odgovarjati na teme v tem forumu Ne, ne moreš urejati svojih prispevkov v tem forumu Ne, ne moreš brisati svojih prispevkov v tem forumu Ne ne moreš glasovati v anketi v tem forumu Ne, ne moreš pripeti datotek v tem forumu Ne, ne moreš povleči datotek v tem forumu
|
Uptime: 496 dni
Powered by phpBB © 2001, 2005 phpBB Group
|