Skapa PWM signal med timers och interrupt
-
- Inlägg: 9
- Blev medlem: 14 april 2007, 13:46:02
- Ort: Växjö
Skapa PWM signal med timers och interrupt
Hej, Jag ska bygga mig en Robotbil och har lite problem då jag är rätt ny inom detta. Består just nu av PIC16F877A, tre IR-sensorer, ett servo och en ultraljudssensor och fyra motorer som styrs genom en dubbel H-brygga. Ska senare köras med en PIC18F4550 och även ha en AM-sändare så den går att styra från LabView.
Jag har fått igång allt som det ska förutom servot. Då jag inte har någon mer PWM signal kvar för båda går åt till motorena så behöver jag skapa en. Jag har testat lite med några delayfunktioner och det fungerar bra, men då kan inget annat köras under tiden.
Så det jag vill göra nu är att skapa en PWM signal med hjälp av Timer0 och interrupt. Men har inte använt mig av detta så mycket tidigare.
Är det någon här som har något exempel på något sådant eller har gjort det tidigare.
/Martin
Jag har fått igång allt som det ska förutom servot. Då jag inte har någon mer PWM signal kvar för båda går åt till motorena så behöver jag skapa en. Jag har testat lite med några delayfunktioner och det fungerar bra, men då kan inget annat köras under tiden.
Så det jag vill göra nu är att skapa en PWM signal med hjälp av Timer0 och interrupt. Men har inte använt mig av detta så mycket tidigare.
Är det någon här som har något exempel på något sådant eller har gjort det tidigare.
/Martin
Senast redigerad av martin5403 22 april 2007, 23:11:07, redigerad totalt 1 gång.
Är det ett standard RC-servo med 1.5 +/- 0.5 ms puls med 20 ms intervall ?
Det skapar du rellativt enkelt m.h.a en timer och lite räknare.
Exakt hur beror lite på, t.ex vilken upplösning du behöver, d.v.s
antal distinga lägen mellan 1.0 och 2.0 ms. Detta kommer bl.a att
styra om det är just timer0 (med 8 bitar) eller någon 16-bitars timer
som är lämpligast...
Varför har du redan valt just timer0 till servot ?
Det skapar du rellativt enkelt m.h.a en timer och lite räknare.
Exakt hur beror lite på, t.ex vilken upplösning du behöver, d.v.s
antal distinga lägen mellan 1.0 och 2.0 ms. Detta kommer bl.a att
styra om det är just timer0 (med 8 bitar) eller någon 16-bitars timer
som är lämpligast...
Varför har du redan valt just timer0 till servot ?
-
- Inlägg: 9
- Blev medlem: 14 april 2007, 13:46:02
- Ort: Växjö
Jo, det är ett standard servo med 14-20ms periodtid. Tror pulsen är mellan 0,5 och 2,3ms ungefär.
Varför jag tänkte använda mig av timer0 är för att timer1 använder jag till ultraljudet och timer2 används till PWM signalen. Är inte så insatt i det där med timers, men förmodar att de går att använda mer än en gång eller?
/Martin
Varför jag tänkte använda mig av timer0 är för att timer1 använder jag till ultraljudet och timer2 används till PWM signalen. Är inte så insatt i det där med timers, men förmodar att de går att använda mer än en gång eller?
/Martin
-
- Inlägg: 9
- Blev medlem: 14 april 2007, 13:46:02
- Ort: Växjö
-
- Inlägg: 9
- Blev medlem: 14 april 2007, 13:46:02
- Ort: Växjö
Problemet jag har är att jag inte lyckats få igång timer0 med interrupt.
Jag sitter och försöker få några lysdioders att blinka utan resultat. Om jag har förstått det rätt så skapas det ett interrupt varje gång timern slår över till 0. Jag har inte brytt mig om att räkna ut någon tid eller så ännu.
Tacksam för hjälp:-) En annan fråga skulle det fungera lika bra att använda RTCC tänkte då den var 16bitars.
/* timer.h
#include <16F877A.h>
#device adc=8
#use delay(clock=20000000)
#fuses NOWDT,HS, NOPUT, NOPROTECT, NODEBUG, BROWNOUT, LVP, NOCPD, NOWRT
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=9)
*/
#include "D:\Martin\test timer\timer.h"
#byte port_d = 8
int i=1000, j=10;
byte test=-1;
void init();
#int_timer0
void timer0interrupt(){ // #int_timer associates the following function with the
// interrupt service routine that should be called
if(i==0){
test=^test;
port_d=test; */ // Bitvis XOR(invers i detta fall)
i=1000;
}
else i--;
}
void main(){
init();
delay_ms(1000);
set_timer0(0);
while(1);
}
void init(){
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_psp(PSP_DISABLED);
setup_spi(FALSE);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_3);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
enable_interrupts(INT_TIMER0);
enable_interrupts(GLOBAL);
set_tris_d(0x00);
port_d=0x00;
}
Jag sitter och försöker få några lysdioders att blinka utan resultat. Om jag har förstått det rätt så skapas det ett interrupt varje gång timern slår över till 0. Jag har inte brytt mig om att räkna ut någon tid eller så ännu.
Tacksam för hjälp:-) En annan fråga skulle det fungera lika bra att använda RTCC tänkte då den var 16bitars.
/* timer.h
#include <16F877A.h>
#device adc=8
#use delay(clock=20000000)
#fuses NOWDT,HS, NOPUT, NOPROTECT, NODEBUG, BROWNOUT, LVP, NOCPD, NOWRT
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=9)
*/
#include "D:\Martin\test timer\timer.h"
#byte port_d = 8
int i=1000, j=10;
byte test=-1;
void init();
#int_timer0
void timer0interrupt(){ // #int_timer associates the following function with the
// interrupt service routine that should be called
if(i==0){
test=^test;
port_d=test; */ // Bitvis XOR(invers i detta fall)
i=1000;
}
else i--;
}
void main(){
init();
delay_ms(1000);
set_timer0(0);
while(1);
}
void init(){
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_psp(PSP_DISABLED);
setup_spi(FALSE);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_3);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
enable_interrupts(INT_TIMER0);
enable_interrupts(GLOBAL);
set_tris_d(0x00);
port_d=0x00;
}
Senast redigerad av martin5403 23 april 2007, 20:27:44, redigerad totalt 1 gång.
-
- Inlägg: 9
- Blev medlem: 14 april 2007, 13:46:02
- Ort: Växjö
Det är svårt för oss som inte kan din kompilator att felsöka när det är sån där "hög nivå-C". Det jag menar är att man inte ser vilka register som påverkas av alla "setupfunktioner".
Att få igång interrupt på timer0 görs iaf såhär enkelt:
INTCON.T0IE=1;
INTCON.GIE=1;
Kolla om PORTD funkar som utgång.
Att få igång interrupt på timer0 görs iaf såhär enkelt:
INTCON.T0IE=1;
INTCON.GIE=1;
Kolla om PORTD funkar som utgång.