Jump to content
PLC Forum


Sign in to follow this  
m4tt3o

Pwm Pic 16f877a C++

Recommended Posts

m4tt3o

Ciao a tutti, dobbiamo generare un segnale pwm con il pic 16f877a per pilotare una ventola in dc, in c++ con il programma pic c compiler.

Non riusciamo proprio a generare questo segnale, vi prego datemi una mano con il programma. Calcolate che di programmazione sto a zero e se non faccio questo programma x tdp che sto in 5 si mette male!

pwm freq. 10.000 duty 80

L'oscillatore è a 20mhz

Ho copiato questa istruzione dal professore:

Timer> timer 2 enable

other > ccp1 > pwm freq. 10.000 duty 80

timer 1 (t2_div_by_4,70,1)

set_pwm1_duty((int16)140)

setup timer 2

setup_ccp1

while_true{

delay_ms 2000

set_pwm1_duty((int16)99)

delay_ms 2000

set_pwm1_duty((int16)198)

delay_ms 2000

set_pwm1_duty((int16)297)

delay_ms 2000

set_pwm1_duty((int16)393)

E ho copiato il programma, ma non funziona! Perchè?

Datemi una mano grazie!

#include <main.h>

#include "na_lcd4x20_D2Free.c"

#define LED PIN_D3

#define BUZZER PIN_D2

float volt,val,T;

void Beep(void) {

output_high(BUZZER);

delay_ms(100);

output_low(BUZZER);

}

// --- End Beep Buzzer

// --- Prova led e beep di sistema

void led_buzz(void){

int j;

for(j=0; j<=4; j++) {

delay_ms(400);

output_high(LED);

Beep();

delay_ms(400);

output_low(LED);

}

}

// --- End Prova led e beep di sistema

// --- Presentazione progetto in avvio

void presentation(void){

lcd_putc("\f"); //Pulisco il display

lcd_gotoxy(2,1);

lcd_putc("PIC16F877A 20 MHz");

beep(); //Avviso start

delay_ms(500);

lcd_putc("\f");

lcd_gotoxy(1,1);

lcd_putc("R. C. D. M.");

delay_ms(500);

lcd_gotoxy(1,3);

lcd_putc("1 canale input ADC");

delay_ms(500);

lcd_gotoxy(3,4);

lcd_putc("canale AN0");

led_buzz(); //Avviso start

delay_ms(500);

}

void Testata(void){

lcd_putc("\f");

lcd_gotoxy(1,1);

lcd_putc("Val: Volt:");

lcd_gotoxy(3,2);

lcd_putc("T:");

}

void main()

{

float volt,val,T;

setup_adc_ports(NO_ANALOGS);

setup_adc(ADC_CLOCK_DIV_2);

setup_psp(PSP_DISABLED);

setup_spi(SPI_SS_DISABLED);

setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);

setup_timer_1(T1_DISABLED);

setup_timer_2(T2_DIV_BY_4,124,1);

setup_ccp1(CCP_PWM);

set_pwm1_duty(512);

setup_comparator(NC_NC_NC_NC);

output_low(PIN_D2);

output_low(PIN_D3);

lcd_init();

delay_ms(100);

Presentation();

delay_ms(1000);

Testata();

delay_ms(50);

delay_ms(2000);

set_pwm1_duty((int16)99);

delay_ms(2000);

set_pwm1_duty((int16)198);

delay_ms(2000);

set_pwm1_duty((int16)297);

delay_ms(2000);

set_pwm1_duty((int16)393);

delay_ms(2000);

set_pwm1_duty((int16)99);

delay_ms(2000);

set_pwm1_duty((int16)198);

delay_ms(2000);

set_pwm1_duty((int16)297);

delay_ms(2000);

set_pwm1_duty((int16)393);

//ripete il ciclo infinite volte

while(true){

set_adc_channel(0); //seleziona il canale 0 dell'ADC(AN0)

delay_us(50);

val=read_adc();//leggo valori registrati

volt=(float)val*0.0048828;//ampiezza segnale di ingresso = valore ADC x risoluzione

T = (volt*100)/5;

lcd_gotoxy(5,1);

printf(lcd_putc,"%.2f ",val);

lcd_gotoxy(17,1);

printf(lcd_putc,"%.2f",Volt);

lcd_gotoxy(5,2);

printf(lcd_putc,"%2.2f",T);

if(volt>4){

output_high(buzzer);

delay_ms(200);

output_low(buzzer);

}

}

}

Share this post


Link to post
Share on other sites

Livio Orsini

Dovresti speccificare, per prima cosa, che compilatore usi; scrivere "con il programma pic c compiler" non significa nulla.

Poi dovresti specificare meglio cosa non funziona.

Da quello che posso vedere c'è tanta roba che nulla ha a che vedere con la generazione di PWM che, tra l'altro è semplicissima.

Da ultimo, ma non ultimo, che conoscenze hai dei microcontrollori PIC?

Share this post


Link to post
Share on other sites
m4tt3o

Livio Orsini+14/02/2012, 17:57--> (Livio Orsini @ 14/02/2012, 17:57)

Grazie della risposta. Per compilare utilizziamo pick kit 3, tutto il programma non funziona!

Il professore ha generato il segnale pwm con questa semplicissima istruzione quando ci ha spiegato il pwm, l'ho copiata ma niente!

timer 1 (t2_div_by_4,70,1)

set_pwm1_duty((int16)140)

setup timer 2

setup_ccp1

while_true{

delay_ms 2000

set_pwm1_duty((int16)99)

delay_ms 2000

set_pwm1_duty((int16)198)

delay_ms 2000

set_pwm1_duty((int16)297)

delay_ms 2000

set_pwm1_duty((int16)393)

Ho provato a mettere questo codice dopo aver abilitato il timer, pwm, duty cycle etc etc ma non funziona!

Il problema è tutto il programma!

In via teorica quando il professore ha spiegato l'argomento so cosa è un pwm, so co sos'è il duty cycle, il problema è il codice!

So cosa è un microcontrollore, il suo funzionamento, ho persino fatto una board su circuito stampato dove ci metto il pick, c'è un display e tutte le varie porte e lo spinotto per programmarlo, quest'ultimo è il problema.

In 3° abbiamo fatto programmazione in c in sistemi e facevamo programmi semplici, ma ci ha spiegato tutte le basi, poi il prof è andato in pensione e in 4° è arrivato un altro professore di sistemi e programmazione in c non l'abbiamo più fatta!

Quest'anno in 5° a sistemi ancora non abbiamo fatto programmazione, stiamo facendo i trasduttori a pari passo con il programma di elettronica. Ora come materia agli esami è uscito sistemi, e cominceremo a farla 2 ore a settimana.

Invece con tdp abbiamo sbagliato, perché il prof ha dato per scontato che sapevamo fare certe cose e solo ora si è reso conto che su certe cose stiamo a zero!

Calcola che faccio il 5° indirizzo elettronica e telecomunicazioni, e il transistor è stato spiegato quest'anno quando è programma di 3° (Io già lo sapevo il funzionamento).

Il professore di tdp se gli chiediamo aiuto lui viene ce lo spiega ma quando ci fa le domande non sappiamo rispondere, perché non abbiamo le giuste competenze e si incazza (Abbiamo sbagliato anche noi a non dirglielo subito).

Ora che sto in 5° devo fare 21 anni (Sono stato bocciato 2 volte) non ho ne il tempo ne la voglia di imparare il linguaggio c da capo, voglio solo prendere questo benedetto diploma e stop.

Il progetto che dobbiamo fare in tdp è suddiviso in 3 fasi, la prima fase bisognava creare un modulo che leggeva la temperatura ambientale, il 2° step quello attuale generare un segnale in pwm e fare girare una ventola, 3° e ultimo step fare girare la ventola in base alla temperatura che varia da 20 a 50 gradi se non erro, sotto i 20 gradi ventola ferma e sopra i 50 gradi ventola ferma.

Io nella pratica sono il più bravo di tutto l'istituto, ma nella pratica se mi parli di software è arabo!

Siamo stati penalizzati con il 1° step, nonostante avevo fatto la parte hardware funzionante il 1° giorno in 30 min, ma mancava la parte software che leggeva la temperatura, leggeva in maniera sbagliata, c'èrano problemi di codice (perché copiato) e ci ha messo come voto di laboratorio 5, ora dobbiamo consegnare entro fine mese il 2° step, per il 3° step non c'è problema sono riuscito ad avere il codice perfettamente funzionante, anche simulandolo funziona perfettamente, ma se non facciamo il 2° step e non glielo facciamo vedere e gli portiamo il 3° non è stupido capisce che è stato copiato.

Non sto messo male solo io, ma tutta la classe, quasi 20 persone suddivise in 6 gruppi, soltanto 1 "i lecchini" sono riusciti a fare il programma funzionante con molti più aiuti e non lo passano.

Edited by m4tt3o

Share this post


Link to post
Share on other sites
Livio Orsini

Se hai un attimo di pazienza ti metto in linea un mio programmino fatto proprio per testare il PWM del 16F877, devo solo rintracciare dove l'hoi memorizzato.

E' scritto i "C" e compilato con il compilatore CCS.

Probabilmente il PIC kit 3 usa la versione demo del "C" compiler della High Tech, che è un poco differente dal CCS, però dovresti capirlo.

Da un'esame superficiale della funzione che hai scritto mi sembra manchi il riferimento al pin di uscita del PWM, ma non conoscendo quel compilatore può essere che non sia così.

Poi un consiglio.

Vai al manuale del Pic 16F877x e leggi bene il capitolo dedicato al PWM. Anche se è in inglese, con un po' di sforzo lo puoi studiare. Solo studiando i manuali del costruttore si capisce come funziona tutto l'ambaradan.

Un'altra brutta abitudine scolastica, forse dovuta a pigrizia dei docenti, è l'abbandono dell'assembler.

Se l'insegnante, invece di scrive 2 righe di "C", avesse spiegato il tutto usando l'asm non ci sarebbero dubbi sul funzionamento. Certo spiegare usando l'asm è più oneroso, poi presuppone anche la conoscenza approfondita del linguaggio e, soprattutto, della macchina.

Share this post


Link to post
Share on other sites
m4tt3o

Grazie mille dell'aiuto. Aspetto non c'è problema.

Il pin di uscita si sceglie dal wizard del programma, lo mette in automati, si sceglie quale pin abilitare, la frequenza e il duty cycle e crea quel pezzo di codice automaticamente.

Share this post


Link to post
Share on other sites
Livio Orsini

Non riesco a reperire il programmino, probabilmente era nel PC che mi hanno zanzaato l'estate scorsa. mad.gifsad.gif

Questa è una brutta cosa dal punto di vista didattico, si fan le cose senza sapere cosa si sta facendo.

Di seguito ti riporto come funziona il generatore di PWM nel 16F877 e cosa si deve fare per generarlo, ligio alla filosofia che è meglio inseganre ad un affamato a pescare, piuttosto che regalargli un pesce. smile.gif

Allora il pic16f877 dispone di due geenratori PWM legati ai due registri CCP (CCP1 e CCP2). L'uscita PWM è legata, ovviamente al CCP selezionato) RC2 per CCP1 e RC1 per CCP1. Questo lo puoi vedere facilemnte nel data sheet alla pagina dove è descritto il pinout del micro.

Bisogna eseguire 4 passi successivi per usare il modulo CCP.

1 - Definire e scrivere nel registro PR2 del pic, il periodo del PWM

2 - Definire il modulo CCPx come PWM

3 - Abilitare il timer TMR2 ed il suo prescaler opportunamente scelto in funzione del periodo

4 - Definire il duty cycle del segnale generato.

Queste 4 operazioni possono essere scritte più o meno semplicemente in funzione del linguaggio usato. Ma anche se scritte in Assembler, non sono molto faticose. Io solitamente uso il "C" della CCS e basta una riga per operazione, grazie anche alle built in function del compilatore.

Come esempio ipotizziamo di usare CCP2 con uscita su RC1.

Dovremo stabilire per prima cosa il periodo del nostro segnale.

periodo PWM =[(PR2)+1]*4*Tosc*(TMR2 prescale value)
dove: - TMR2 prescale value è il valore di prescaler associato al Timer2 del 16f877 - PR2 è un registro (associato a Tmr2) da impostare con opportuno valore per ottenere il periodo voluto - Tosc è l’inverso della frequenza del quarzo esterno che fornisce il clock al PIC TMR2 prescale value può valere 1, 4, 16 e PR2 è un registro a 8 bit pertanto il valore deve essere compreso tra 0 e 255. Usando CCS come compilatore scriverei:
          setup timer_2(T2_DIV_BY_1,99,1);
          setup CCP2( CCP_PWM);
          setpwm2_duty (200); 

In questo caso si geenrerebbe un PWM al 50% perchè il valore inserito in duty va diviso per 4.

Dato che non usi CCS ma un altro compilatore devi vedere le funzioni equivalenti studiando il manuale del compilatore. Copiare un programma, sperando che funzioni, è qaundto di più sbaglaito si possa fare dal punto di vista didattico.

Altro consiglio.

Non usare cicli di delay, occupano la CPU e non fanno nulla. Meglio che tu associ un interrupt al timer1 e usi questo interrupt per fare le tue operazioni.

Immagina di voler cambiare il duty partendo dal 10% sino al 90% con passi del 5% ogni 20 ms.

Programmi Tmr1 per avere un interrupt ogni 20 ms.; ad ogni scadenza di interrupt andrai a modificare il valore di pwm_duty. Nel frattempo il micro è libero dafare quello che più necessita, mentre se avessi emsso un ciclo di delay di 20ms non avresti potuto fare altro che quello.

Share this post


Link to post
Share on other sites
m4tt3o

Grazie mille dell'aiuto, penso di aver capito.

Oggi quando vado a casa provo e ti faccio sapere, grazie.

Share this post


Link to post
Share on other sites
m4tt3o

Niente ci ho provato, sono senza speranze. Ho capito la teoria, ma non riesco a metterla in pratica.

Ti faccio vedere tutto quello che ho fatto:

Come prima cosa, il wizard del programma si presenta cosi, comincio a impostarlo

Metto il pic che utilizzo, hight speed osc maggiore di 4mhz perchè ho l'oscillatore a 20mhz e abilito power up timer.

user posted image

By m4tt3o1 at 2012-02-16

Automaticamente cliccando su code, mi genera automaticamente questo:

user posted image

By m4tt3o1 at 2012-02-16

Vado avanti per abilitare il pwm.

user posted image

By m4tt3o1 at 2012-02-16

E esce questo in automatico:

user posted image

By m4tt3o1 at 2012-02-16

Abilito il timer 2.

http://img190.imageshack.us/img190/949/immagine3zw.jpg

E genera questo codice.

http://img832.imageshack.us/img832/5681/immagine4k.jpg

E mi trovo ora a dover scrivere il programma, le cose che vedi le ha messe il programma in automatico.

http://img191.imageshack.us/img191/8990/immagine7au.jpg

Ho letto attentamente quello che mi hai scritto, ho seguito attentamente la guida, ma niente, è giusto quello che ho fatto? Ho abilitato le opzioni correttamente?

Edited by m4tt3o

Share this post


Link to post
Share on other sites
Livio Orsini

Non so che dirti, io non uso i wizard automatici, ma scrivo direttamente quello che mi serve.

Comunque visto che non riesco a recuperare il vecchio programmino di prova ne rifaccio uno ex novo, tanto prima o poi potrà servirmi, e te lo rigiro; devi solo aver pazienza ancora un poco.

Nel frattempo non demordere, studiati il data sheet del pic, credi a me non ti fa male e ti servirà comunque.

Edited by Livio Orsini

Share this post


Link to post
Share on other sites
m4tt3o

Grazie, si certo lo sto studiando, penso di esserci quasi riuscito.

Share this post


Link to post
Share on other sites
kappa47

Non conosco il C che stai usando: per i PIC16 uso sempre l'assembler (ho sempre bisogno di sfruttarli fino all'osso...)

Ti mando un esempio scritto in asm (spero tu riesca a prendere uno spunto di utilizzo)

Tieni presente che:

1) quarzo da 16 MHz.

2) i bit meno significativi del PWM non sono gestiti (CCPxX:CCPxY del registro CCP1CON sempre a zero)

3) ho utilizzato la porta C bit 2 come output PWM (CCP1)

4) timer 2 usato come periodo del PWM e richiamato da interrupt

5) timer 1 usato duty-cycle

6) con il valore di prescaler hai un periodo di 2,5 milliSec.

7) se vuoi un valore fisso di duty-cycle PWM ti basta non abilitare l'interrrupt delle periferiche (PUNTO 1 del listing)

title 'prova PWM'

subtitl 'esempio per PLC_FORUM'

list P=16f877, C=132, N=0

RADIX DEC

PROCESSOR PIC16F877

ERRORLEVEL -302, -306

; __CONFIG _CP_OFF & _DEBUG_OFF & _WRT_ENABLE_OFF & _CPD_OFF & _LVP_OFF & _BODEN_ON & _PWRTE_ON & _WDT_ON & _XT_OSC

;quando uso ICD2

__CONFIG _CP_OFF & _DEBUG_OFF & _WRT_ENABLE_ON & _CPD_OFF & _LVP_OFF & _BODEN_ON & _PWRTE_ON & _WDT_OFF & _XT_OSC

#include <p16f877.inc>

ram_0 macro

bcf STATUS,RP0

bcf STATUS,RP1

endm

;Definizione Porta C

;

#define OUT_PWM PORTC,2 ;output: PWM (CCP1)

#define PWM_PERIODO 0xff ;valore per TMR2 (periodo)

#define PWM_DUTY_UP 0xfe ;limite superiore duty-cycle PWM

#define PWM_DUTY_DW 0x01 ;limite inferiore duty-cycle PWM

;Equate flag di sistema (fl_sys)

;

#define PWM_UP_DW fl_sys,3 ;se 1, PWM rampa up

;***** MEMORIA IN COMUNE A TUTTI I BANCHI *****

CBLOCK 0x71 ;per abitudine lascio sempre il primo byte libero (non c'e' un perche' specifico)

fl_sys ;flag varie funzioni

delay_pwm ;cnt. ritardo aggiornamento PWM

act_pwm ;valore attuale duty-cycle PWM

;

w_save ;save W (interrupt)

st_save ;save STATUS (interrupt)

pc_save ;save PCLATH

fsr_save ;save FSR

ENDC

org 0x00 ;Reset Vector

start

bcf PCLATH,3 ;mi assicuro pagina 0

bcf PCLATH,4

nop ;non serve (per arrivare a int. vector)

goto main

org 0x04 ;Interrupt Vector

i_serv

movwf w_save ;save w wathever is the bank

swapf STATUS,w ;swap status in w

;clrf STATUS ;bank 0 (clear IRP, RP1, RP0)

ram_0

movwf st_save ;save status in bank 0

movfw FSR

movwf fsr_save ;save FSR

movfw PCLATH

movwf pc_save ;save PCLATH

clrf PCLATH ;seleziono pagina o (precauzione se uso altre pagine)

;

;who_int

btfsc PIR1,TMR2IF ;PWM interrupt ?

goto pwm_int

; goto err_int ;non ci sono altri interrupt abilitati

;

;****************************************************************************************

;* Interrupt sconosciuto !!! *

;****************************************************************************************

;

err_int

bcf INTCON,GIE ;disable all interrupt

err_i1

goto err_i1 ;per debug: aspetto eventuale watch-dog

;

;****************************************************************************************

;* PWM Interrupt *

;****************************************************************************************

;

pwm_int

decfsz delay_pwm,f

goto pwm_end

pwm_int1

movlw 0xff

movwf delay_pwm

btfss PWM_UP_DW ;se 1, rampa up

goto pwm_dw

pwm_up

incf act_pwm,f

movlw PWM_DUTY_UP

subwf act_pwm,w

btfss STATUS,C

goto pwm_com

pwm_up1

bcf PWM_UP_DW

movlw PWM_DUTY_UP

movwf act_pwm

goto pwm_com

;

pwm_dw

decf act_pwm,f

movlw PWM_DUTY_DW+1

subwf act_pwm,w

btfsc STATUS,C

goto pwm_com

pwm_dw1

bsf PWM_UP_DW

movlw PWM_DUTY_DW

movwf act_pwm

;goto pwm_com

pwm_com

banksel CCPR1L

movfw act_pwm

movwf CCPR1L ;duty-cycle

;goto pwm_end

;

pwm_end

banksel PIR1

bcf PIR1,TMR2IF

;goto end_int

;

end_int

;ripristino registri

ram_0

movfw pc_save ;restore PCLATH

movwf PCLATH

movfw fsr_save

movwf FSR

swapf st_save,w ;restore STATUS

movwf STATUS

swapf w_save,f ;swap "w_save" con se stesso

swapf w_save,w ;restore W

retfie

;************************************************************************

;* Inizio del main *

;************************************************************************

main

; disable

ram_0

;la configurazione della porta C dipende dal mio hardware (importante RC2 in output)

banksel PORTC

clrf PORTC ;clear data latch C (0=out / 1=in)

movlw b'11001111' ;Tx=1 & Rx=1

movwf PORTC

banksel TRISC

movlw b'10000000' ;tutta in out tranne Rx (bit 7)

movwf TRISC

;

;azzero variabili

movlw 0x01

movwf delay_pwm

movlw PWM_PERIODO / 2

movwf act_pwm

;

;prova PWM (output su RC2)

pr_pwm

banksel PR2

movlw PWM_PERIODO

movwf PR2 ;periodo

banksel CCPR1L

movlw PWM_PERIODO / 2

movwf CCPR1L ;duty-cycle di partenza...

clrf CCPR1H ;

; banksel CCP1CON ;non serve: stesso banco

movlw 0x0c ;

movwf CCP1CON ;...fino a qui

; ;banksel TRM2 ;non serve: stesso banco

;movlw 0x20

;movwf TMR2 ;prescaler

banksel T2CON ;non serve: stesso banco

;movlw b'00000100' ;prescaler 1:1 / postscale 1:1

movlw b'00000101' ;prescaler 1:4 / postscale 1:1

;movlw b'00000110' ;prescaler 1:16 / postscale 1:1

movwf T2CON

banksel PIE1

bsf PIE1,TMR2IE ;enable interrupt TMR2

banksel INTCON

; bsf INTCON,PEIE ;en. peripheral interrupt (PUNTO 1)

bsf INTCON,GIE ;enable interrupt

pr_pwm1

nop

goto pr_pwm1

;

end

Share this post


Link to post
Share on other sites
Livio Orsini

Ti riporto le parti relative al PWM di un programam che funziona.


#include <16F877A.H>
#DEVICE ADC=10
#fuses HS,NOPROTECT,PUT,BROWNOUT,NOWDT,DEBUG
#use Delay(oscillator=20M)
#use fast_io(b)
#use fast_io(c)
//

#define CLK 20000000         // Frequenza dell'oscillatore
#zero_ram

//
#byte PORT_A = 5      // Assign at port_a the phisical PORTA address
#byte PORT_B = 6      // Assign at port_b the phisical PORTB address
#byte PORT_C = 7      // Assign at port_c the phisical PORTC address
#byte PORT_D = 8
#byte INTCON = 0x0B
--------
/*-----------------16-05-2009 16.05--------------------------------------------*
 *                                                                             *
 *                                 MAIN                                        *
 *                                                                             *
 *----------------------------------------------------------------------------*/

void main ()
{
   int i, row =0;
   setup_adc(ADC_CLOCK_INTERNAL);
   setup_adc_ports(ALL_ANALOG);
   set_adc_channel(0);
   disable_interrupts(global);
   port_b_pullups(FALSE);            //Inizializzazioni Porte
   setup_timer_1(T1_INTERNAL);
   set_timer1(0x3caf);   //Caricato 65.535 - 50.000 = 15.535(0x3CAF)
                          //==> 50.000 * 4 * 50nsec = 10msec
   // set_tris_a (0b11111001);    //tutti input tranne A1 e A2
   set_tris_b(0xC0);                   //I primi 6 bit sono uscite!!
   set_tris_c(0x00);
   set_tris_d(0x00);
   set_tris_e(0x00);
   setup_ccp1(CCP_PWM);   // Configure CCP1 as a PWM
   setup_timer_2(T2_DIV_BY_4, 255, 1);
 /*-----------------26-05-2009 18.59-------------------------------------------*
  *                         inizializza diplay                                 *
  * ---------------------------------------------------------------------------*/
   delay_ms(20);
   lcd_init(); //Inizializza il display
   enable_interrupts(GLOBAL);
   enable_interrupts(int_timer1);

while (i=!0)
 {
    row = 0;
    temperatura = itemp_buffer[0]*19;;
    wr_temp(row);
//
    row = 0x10;
    temperatura = itemp_buffer[1]*19;
    wr_temp(row);
    set_pwm1_duty(itemp_buffer[0]);

 }
}
#int_timer1
 void Timer10ms()
/* Timer presettato a 10ms; conteggio = 10 tics ==> 100ms */
    {
        set_timer1(0x3caf);   // Caricato 15535 ==>
                  // 50.000 * 4 * 50nsec = 10msec
                  // 65535 - 50000 = 15535(0x3caf)
         ++tic_cnt;
         if (tic_cnt > 19)
            {
               tic_cnt = 0;
            por_d++;
               if (flg_ADC0 == 0)
                 {
                     flg_ADC0 = 1;
                     itemp_buffer[0] =  read_adc();
                     set_adc_channel(1);
                 }
                else
                 {
                     flg_ADC0 = 0;
                     itemp_buffer[1] =  read_adc();
                     set_adc_channel(0);
                 }

            }
   }

Nella pratica si legge un canale ADC ed il risultato si usa per asseganre il valore di duty Cycle all'uscita RC2. Il PWM è settato su 10 bits sfruttantone la possibilità che offre il rtegisto.

Mancano le funzioni per pilotare il display e quelle di conversione, però visualizzazione a parte questo programma può funzionare così come è scritto. Se rimuovi i richiami alle funzioni di visualizzazione e lo compili con CCS lo puoi veder funzionare subito.

Edited by Livio Orsini

Share this post


Link to post
Share on other sites
m4tt3o

Grazie mille veramente, si ho visto funziona smile.gif

Comunque ci siamo riusciti, bastava un po' di impegno.

Share this post


Link to post
Share on other sites
Livio Orsini

Forse questa è il migliore insegnamento che hai tratto dall'avventura.

Fatti risentire e tienici aggiornati sui tuoi progressi nel campo.

Share this post


Link to post
Share on other sites
m4tt3o

Certo, dobbiamo mettere a punto il progetto e farlo controllare al professore. Simulandolo funziona ora vediamo se anche in pratica fa il suo dovere.

Share this post


Link to post
Share on other sites
m4tt3o

Ciao Livio, ho scoperto alla fine di aver buttato nottate davanti al pc per niente, i programmi che facevo e non li simulava funzionavano, ma era proteus che avevo sul mio pc e simulava soltanto quello che gli pareva a lui, i stessi programmi su proteus a scuola funzionavano, ho sprecato almeno una 15 ina di ore a creare sempre programmi identici per fare generare questo pwm che non generava, era la simulazione che non andava, e chi ci aveva pensato!

E generare il pwm è veramente semplice sono 5 righe di codice!

Share this post


Link to post
Share on other sites
Livio Orsini

I simulatori sono comodi, a patto che funzionino perfettamente. Purtroppo la maggior parte ha dei grandi limiti e parecchi errori.

Share this post


Link to post
Share on other sites
Shinelco

Salve, stavo leggendo la discussione é mi interessava parecchio.In pratica in ccs devo generare un codice che mi generi un segnale pwm (che poi vedró sull oscilloscopio) e successivamente tramite il potenziometro sul pic16F887 variare il duty cicle Dell onda. Ho a disposizione tutto il kit del microprocessore, é anche il motore che dovró regolare con il programma in ccs. Il problema e che ho scritto un programma che mi genera il pwm ma non riesco a scrivere quello che mi regola il duty cycle......qualcuno puó darmi una mano.....grazie mille in

Share this post


Link to post
Share on other sites
Livio Orsini

E' facilissimo.

Leggi il potenziometro tramite un A/D (porta Ax) configurato per lettura a 10 bit quello che leggi lo butti direttamente come parametro al PWM.

Se proprio non ti riesce ti metto in linea il codice.

Edited by Livio Orsini

Share this post


Link to post
Share on other sites
nicoct

salve sono nuovissimo del forum,

mi sto appassionando ultimamente del pic,

prima facendo un o di esempi su led e contatori;

adesso fra qualche giorno rispolvero il c e rimetto in gioco con esempi analoghi;

questo del pwm mi sembra un ottimo progetto;

mi puoi postare il file in c in modo da provarlo..grazie

Share this post


Link to post
Share on other sites
Livio Orsini

Il guaio è che sono in vacanza sino ad inizio agosto, quindi niente files disponibili.

Share this post


Link to post
Share on other sites
nicoct

ok...aspetterò e nel frattempo mi metterò un pò a fare qualche altro progetto..ciaoooo e grazie

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this  

×
×
  • Create New...