Sari la conținut
ELFORUM - Forumul electronistilor

PIC16F690


Postări Recomandate

  • Răspunsuri 28
  • Creat
  • Ultimul Răspuns

Top autori în acest subiect

Top autori în acest subiect

CCPR este registrul in care incarci factorul de umplere. Intrebari - 1.Este un motor de CC sau un servomotor, adica tu vrei sa se invarta mai repede/mai incet dupa cum invarti din potentiometru sau sa URMAREASCA miscarea potentiometrului ? 2. Ce treaba are Timer1 ?Uita-te in datasheet , acolo este descris cum se configureaza.

Link spre comentariu

Pai in cazul asta raspunsul scurt este ca nu se poate. PWM genereaza un tren de impulsuri cu factor de umplere variabil care se transforma ( eventual, prin filtrare ) intr-o tensiune continua care invarte motorul mai repede sau mai incet - dar NU VA urmari miscarea potentiometrului. Adica , daca te opresti cu potentiometrul intr-o pozitie , motorul se invarte mai departe cu viteza respectiva, nu se opreste.

Link spre comentariu

Da, se poate face ceea ce vrei tu. Servomotorul asteapta niste impulsuri pe intrare intre 1 si 2ms si pauza intre ele de vreo 20ms(daca imi aduc aminte bine) . Tu trebuie sa generezi acest semnal, care este compus din 2 parti: impulsul fix de 1ms , apoi citesti valoarea potentiometrului si mai lungesti acel impuls functie de valoarea citita. De exemplu: potentiometru maxim stanga - impuls de 1 ms; potentiometru la mijloc - impuls de 1.5 ms; potentiometru maxim dreapta - impuls de 2 ms.Sper ca m-am facut inteles.

Link spre comentariu

Pai simplu:

Pui un potentiometru pe o intrare analogica. In functie de valoarea citita schimbi durata pulsului generat (partea "ON"), apoi generezi o pauza (partea "OFF") de maxim 18ms. Adica daca ai 0V ii vei zice sa trimita un puls de 1000us, daca este la 5V unul de 2000us. Asta ti s-a mai spus.

Nu va conta pentru servo ca frecventa este data de 19 si respectiv 20ms.

 

Daca ai rabdare un pic, iti pun un exemplu aici.

 

PS: Ceea ce vrei sa faci nu are nimic in comun cu modulul hardware PWM al lui PIC. De ce?!

1. Nu ai sa poti genera PWM la 50Hz (adica poti, dar la ce frecventa a PIC-ului?);

2. Nu ai sa poti controla factorul de umplere: 1/20 pana la 2/20, imposibil de realizat.

 

Sa fim intelesi: asta cauti? Servo este analogic?

Posted Image

Link spre comentariu

Imediat/* * File: main.c * Author: Cristian * * Created on November 23, 2013, 4:33 PM */#include // CONFIG#pragma config FOSC = INTRCIO // Oscillator Selection bits (INTOSCIO oscillator: I/O function on RA4/OSC2/CLKOUT pin, I/O function on RA5/OSC1/CLKIN)#pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled and can be enabled by SWDTEN bit of the WDTCON register)#pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled)#pragma config MCLRE = OFF // MCLR Pin Function Select bit (MCLR pin function is digital input, MCLR internally tied to VDD)#pragma config CP = OFF // Code Protection bit (Program memory code protection is disabled)#pragma config CPD = OFF // Data Code Protection bit (Data memory code protection is disabled)#pragma config BOREN = ON // Brown-out Reset Selection bits (BOR enabled)#pragma config IESO = ON // Internal External Switchover bit (Internal External Switchover mode is enabled)#pragma config FCMEN = ON // Fail-Safe Clock Monitor Enabled bit (Fail-Safe Clock Monitor is enabled)#define LED1 RC0#define LED2 RC1#define LED3 RC2#define ON 1#define OFF 0#define PRAG_50 284//Definire Praguri#define PRAG_110 625#define PRAG_130 739#define ADC_TO_mV 5#define Servo RC3volatile unsigned int ADCValue,lastADCValue;volatile unsigned int milliVolts;unsigned count=0;void pin_init();void tmr1_init();void tmr2_init();void ADC_init();void main(){ pin_init(); tmr1_init(); tmr2_init(); ADC_init();TMR1ON=1;TMR2ON=1; while(1) { ADCValue=(ADRESH<<8)+ADRESL; if(ADCValue!=lastADCValue) //verific daca valoarea de pe adc este diferita de urmatoarea valoare citita { milliVolts=ADCValue*ADC_TO_mV;//convertesc valoare citita de pe ADC in milivolti lastADCValue=ADCValue; if (ADCValue>PRAG_130) PORTC=0x07; else if (ADCValue>PRAG_110) PORTC=0x03; else if (ADCValue>PRAG_50) PORTC=0x01; else PORTC=0x00; }}} void pin_init()//Setari pini { ANSEL=0x01; ANSELH=0x00; TRISA=0x01; TRISC=0x00; PORTC=0x00; PORTA=0x00; }void tmr1_init()//Setare Timmer1 pentru 20ms {TMR1H=0xB1;TMR1L=0xDF;T1CON = 0x44;GIE = 1; PEIE = 1; TMR1IF = 0; TMR1IE = 1;}void tmr2_init()//Aici am configurat tmr2 cu PR2=250 valoare maxima(flag){ TMR2=0x00; PR2=187; T2CON=0b00000110; TMR2IF=0;//innterupt settings TMR2IE=1;}void ADC_init(){ANSEL=0x01;//set AN0 analog pin;ADCON0=0x81;//AN0 select channel;ADON=1;ADIF=0;ADIE=1;}void interrupt isr(void){ if((TMR1IE==1)&&(TMR1IF==1)) { TMR1L=0xB1; TMR1H=0xDF; ADCON0|=0x02; TMR1IF=0; } else if((ADIE==1)&&(ADIF==1)) { ADCValue=(ADRESH<<8)+ADRESL; ADIF=0; TMR2ON=1;if((TMR2IE==1)&&(TMR2IF==1)){ TMR2ON=0; TMR2IF=0;}}}

Link spre comentariu

Foarte simplu, dar tine PIC-ul ocupat cam 19-20ms:

while (TRUE)    PPM = 1000 + ADC_read(AN0) - citeste ADC si aduna-i 1000    for i = 1 to PPM                        - de la 1 la maxim 2023 (eroare 2us)        PIC_out = 1                         - iesirea PIC este "1"    next i                                       - ai terminat?    PIC_out = 0                             - iesirea PIC este "0"    Delay_ms(18)                          - tine iesirea PIC in "0" pentru 18mswend
- repeta la infinit

Sa facem un sketch: frecventa 4MHz, folosim TMR1 (16b) cu sau fara prescaler sau TMR2 (8b) cu postscaler (1:8):

 

1. Setari PIC

INTCON: bit 7 (GIE), bit 6 (PEIE) trebuie setati "1".

PIE1: bit 1 (TMR1IE) trebuie setat "1".

T1CON: bit 0 (TMR1ON) trebuie setat "0" (oprim TMR1), iar bitii 5 si 4 (prescaler) dupa cum vrei tu (sa zicem in exemplul meu ca fiind 1:1) adica setati "00".

 

2. Procedura intrerupere TMR1 - scrisa in basic, dar o traduci tu in C:

sub procedure Interrupt()   if PIR1.0 = 1 then                 ' "Overflow" detectat      "OFF" iesire PIC   end if   PIR1.0 = 0                         ' Reset overflow flagend sub
3. Bucla "WHILE"

Citire ADC si calculare valoare de pus in TMR1 ca sa numere exact 1000 sau 2000us (65536-1000=64536 sau 65536-2000=63536)

3.1 Simplu: valoare ADC (intre 0 si 1023) scazuta direct din 65536, in plus de alti 1000 scazuti indiferent de valoarea ADC (eroare 2.3us maximum).

3.2 Riguros: interpolare liniara (link http://en.wikipedia.org/wiki/Linear_interpolation)

 

TMR1 = 65536 - valoare ADC - 1000

T1CON: bit 0 (TMR1ON) trebuie setat "1" (pornim TMR1)

"ON" iesire PIC

 

Nu e nevoie sa "traduci" valoarea ADC in Volti, cred ca ai copiat de la un alt program.

 

In timpul asta PIC incrementeaza TMR1 de la valoare incarcata catre 65536 si executa alte operatii dupa nevoile programatorului.

Cand TMR1 a numarat pana la 65536, va avea "overflow = PIR1.0 = 1" deci procedura Interrupt() va fi automat apelata. Atunci iesirea PIC va trece in "OFF".

 

Procedura de intrerupere nu este in bucla WHILE, este in afara ei, in sectiunea de program unde se pun Procedurile. Daca ar fi in bucla WHILE ar ocupa timpul PIC-ului degeaba (vezi mai sus exemplul simplu cu PIC ocupat sa numere 20ms). Asta ca ai intrebat intr-un post precedent.

 

Tocmai ai generat un puls "1" intre 1000 si 2000us.

 

Ramane sa faci acelasi lucru pentru o temporizare de 20000us - pulsul generat (deci intre 19000 si 18000us), adica pauza "0" pana la urmatorul puls "1".

 

"END" bucla WHILE

 

4. Se repeta 3 la infinit.

 

atata timp cat ADC-ul nu citeste nimic e normal sa se opreasca si servomotorul deoarece nu mai apare intrerupere ca sa intre in rutina aceea de tratare.

Chiar daca nimic nu este conectat la ADC (deci va citi 0V), tot vei genera un puls de 1000us, de maniera ciclica, ceea ce are nevoie servo-ul ca sa-si pastreze cuplul. In caz ca pulsul nu mai este aplicat la intrarea lui, va ramane doar sa aplici o anumita forta la bratul lui, si se va misca.

 

La ce aplicatie vrei sa folosesti servo-ul?

Link spre comentariu

Creează un cont sau autentifică-te pentru a adăuga comentariu

Trebuie să fi un membru pentru a putea lăsa un comentariu.

Creează un cont

Înregistrează-te pentru un nou cont în comunitatea nostră. Este simplu!

Înregistrează un nou cont

Autentificare

Ai deja un cont? Autentifică-te aici.

Autentifică-te acum



×
×
  • Creează nouă...

Informații Importante

Am plasat cookie-uri pe dispozitivul tău pentru a îmbunătății navigarea pe acest site. Poți modifica setările cookie, altfel considerăm că ești de acord să continui.Termeni de Utilizare si Ghidări