Ladda ner presentationen
Presentation laddar. Vänta.
1
William Sandqvist william@kth.se DA-omvandling, oftast PWM
2
William Sandqvist william@kth.se PWM med Timer0 75% 25% void main( void) { Duty = 0; /* start with zero DutyCycle */ TRISB = 0b11111110 ; /* PORTB.0 is output */ /* PORTB.1 is input */ OPTION = 0b11000111; /* Timer0 1/256 */ while (1) /* forever */ { char i; if (TMR0 < Duty) PWM_out = 1; else PWM_out = 0; Duty = GetDuty(); /* Be back in one TIMER0-tick ! */ MoreToDo(); } } Tillbaks inom ett Timer0-tick!
3
William Sandqvist william@kth.se PWM med Timer0 75% 25% /* Function */ char GetDuty( void) { char Duty; if( Contact == ON ) Duty = 191; /* 191/255 = 75% Dutycycle */ /* _______ __ */ /* _| |__| */ /* */ else Duty = 64; /* 64/255 = 25% Dutycycle */ /* __ __ */ /* _| |_______| */ /* */ return Duty; }
4
William Sandqvist william@kth.se PWM med Timer0 /* Function */ void MoreToDo( void) { } Gör lite nytta här, men … Missa inte nästa Timer0-tick!
5
William Sandqvist william@kth.se Valfri färg med RGB Led Difus plast behövs för att färgerna ska ”blandas”. Så här skulle man kunna göra …
6
William Sandqvist william@kth.se Valfri färg med RGB Led while (1) /* forever */ { if(PORTB.0==0) intensity =75; else intensity =255; R_Duty = 0; G_Duty = 0; B_Duty = 0; if( PORTB.3 ) R_Duty = intensity ; if( PORTB.2 ) G_Duty = intensity ; if( PORTB.1 ) B_Duty = intensity ; /* PWM-generation */ if (TMR0 < R_Duty) RA0 = ON; /* Red PWM */ else RA0 = OFF; if (TMR0 < G_Duty) RA1 = ON; /* Green PWM */ else RA1 = OFF; if (TMR0 < B_Duty) RB5 = ON; /* Blue PWM */ else RB5 = OFF; }
7
William Sandqvist william@kth.se Styr färg med slumptal … Många algoritmer för slumptal utnyttjar multiplikation och division, något som inte är midrange PIC-processorernas starkaste sida. Nedanstående algoritm bygger i stället på tekniken med "återkopplade shiftregister", som ger hyfsade slumptal utan allt för mycket kod... /* Random number function */ char rand( void ) { /* 0x0000 won't run... */ bit EXOR_out; static char rand_hi, rand_lo; if( !rand_hi && !rand_lo ) rand_lo = 0x01; EXOR_out = rand_lo.0; EXOR_out ^= rand_lo.2; EXOR_out ^= rand_lo.3; EXOR_out ^= rand_lo.5; Carry = EXOR_out; /* rotate right */ rand_hi = rr( rand_hi); rand_lo = rr( rand_lo); return rand_lo; }
8
Så här ser de första 700 8-bits slumptalen ut … William Sandqvist william@kth.se char rand( void ); 100 190 223 239 247 251 253 254 255 127 191 223 111 183 219 109 …
9
William Sandqvist william@kth.se CCP - PWM Det finns ett uppenbart behov av en självständig enhet för generering av PWM. CCP-enheten kan programmeras till detta!
10
William Sandqvist william@kth.se För PWM används TIMER2
11
William Sandqvist william@kth.se TIMER2
12
William Sandqvist william@kth.se Samplingsklocka Har man en reglerloop är det viktigt med en konstant samplings- frekvens. Blir Du lovad löneförhöjning med 500 kr/varv så vill Du nog gärna veta om det är: 500:-/tim 500:-/vecka 500:-/månad TIMER2 postscaler overflow kan an- vändas som samp- lingsklocka.
13
William Sandqvist william@kth.se TIMER2 servoupdate TIMER2 postscaler overflow kan an- vändas som samp- lingsklocka. Man kan få interrupt efter tex. var 4:e, var 8:e, var 16:e PWM-puls och då passa på att uppdatera PWM-signalen. ( Se programmet PIC-talker ).
14
William Sandqvist william@kth.se PWM frekvens T2CON postscale 1/1 … 1/16 ON/OFF prescale 1/1, 1/4, 1/16 PR2 förkortar räknecykeln Frekvensinställning görs således med ”prescale” och ”PR2”.
15
William Sandqvist william@kth.se PWM-mode PWM-mode = 11xx CCP1X, CCP1Y Två extra bitar
16
William Sandqvist william@kth.se PWM-frekvens och DutyCycle PWM-frekvens DutyCycle
17
William Sandqvist william@kth.se PWM till 1000! PWM-frekvens 1000 Hz DutyCycle 50% för att testsignal … 1000 Hz DutyCycle 50%
18
William Sandqvist william@kth.se pwm1k62x.c void main( void) { TRISB.3 = 0; /* CCP1 is output at RB3 ( pin 9 ) */ /* Setup TIMER 2 */ /* 0.xxxx.x.xx - x.0000.x.xx 1:1 postscaler x.xxxx.1.xx TMR2 on x.xxxx.x.01 1:4 prescaler */ T2CON = 0b0.0000.1.01; PR2 = 249; /* PWM frequency 1000 Hz */ /* Setup CCP1 PWM-mode */ /* 00.x.x.xxxx -- xx.0.0.xxxx CCP1X=0 CCP1Y=0 xx.x.x.1111 PWM-mode (11--) */ CCP1CON = 0b00.0.0.1111; /* 50% 10 bit Duty 0b01111101.0.0 = 500 */ CCPR1L = 125; /* 0b01111101 */ while(1) nop(); } Lyssna med hörluren, och mät frekvensen och DutyCyclen med Scopemeter123 PWM-enheten är helt självgående …
19
William Sandqvist william@kth.se
20
Varvtalsratt till LEGO-motor
21
William Sandqvist william@kth.se PWM till motor Enklast. PR2=255, ingen förkortning. Enklast. 8 bitars PWM, rör ej CCP1X=0 och CCP1Y=0. CCPR1L = Duty; /* 000...255 0%...100% */ PWM-frekvensen blir då vad den blir … ( Om PWM-frekvensen < 20000 Hz kan den ”höras” när motorn kör )
22
William Sandqvist william@kth.se Varvtalsratten Interruptrutinen /* read encoder new value */ trans.0 = quad_A; trans.1 = quad_B; /* compare with old value */ if( (trans == 0b00.01) && (count != 255) ) count ++; if( (trans == 0b01.00) && (count != 0) ) count --; /* replace old value with new value */ trans.2 = trans.0; trans.3 = trans.1; OBS! Max och mingränserna!
23
William Sandqvist william@kth.se DutyCycle while(1) { speed = count; CCPR1L = speed; /* new PWM-value */ } count uppdateras av interruptrutinen!
24
William Sandqvist william@kth.se Utmaningen – Fram/Back
25
William Sandqvist william@kth.se 1 bit Riktning i ”tal med tecken” int count; Kör moturs för negativa tal, de har teckenbiten = 1 Kör medurs för positiva tal, de har teckenbiten = 0 /* rotate cw or ccw */ PORTA.1 = count.7;
26
William Sandqvist william@kth.se ”tal med tecken” och invertering av Dutycycle Vid moturs rotationsriktning måste DutyCycle inverteras. Detta innebär att motorn går snabbt vid låg DutyCycle och att motorn går långsamt vid hög DutyCycle. Men detta stämmer ju helt med hur negativa tal representeras! Ökande negativa tal 11111111, 11111110, 11111101, 11111100 … 10000000 ger ökande moturs hastighet. Vi behöver därför inte göra någon extra invertering!
27
William Sandqvist william@kth.se 8 bitars hastighet ? Om pulsgivarens räknar hastigheten i en int så använder vi 7 bitar per riktning. PWM-enheten använder en char och behöver 8 bitar för full fart. Lösning: Multiplicera med 2. speed = count* 2; CCPR1L = speed; /* new PWM-value */ OBSERVERA! Nu behövs nya gränser för räknevärdet: if( (trans == 0b00.01) && (count != 127) ) count ++; if( (trans == 0b01.00) && (count != -128) ) count --;
28
William Sandqvist william@kth.se
29
Uni- eller Bipolär PWM PWM-signaler En bipolär PWM-signal kan köra motorn i två riktningar, men också hålla en motor stillastående med ett Hållmoment! Unipolär PWM signal kör en motor i en riktning.
30
William Sandqvist william@kth.se PIC16F690 har enhanced PWM! Byta rotationsriktning kan man då göra genom att styra över PWM-signalen till en annan utgång i stället för att invertera DutyCycle!
31
William Sandqvist william@kth.se Två drivsignaler (ex. halvbrygga) Undviker kortslutning! Två drivsignaler till helbrygga
32
William Sandqvist william@kth.se 4 drivsignaler Helbrygga
33
William Sandqvist william@kth.se Helbrygga Forward mode: PWM på P1D Reverse mode: PWM på P1B
Liknande presentationer
© 2024 SlidePlayer.se Inc.
All rights reserved.