codice PWM
- Login o registrati per inviare commenti
Salve, da poco sto programmando i microcontrollori, con un pic 18f4550 vorrei assegnare a 10 pulsanti una frequenza differente (la frequenza non è importante, è solo a scopo didattico), mi spiego schiaccio un pulsante ed esce un segnale PWM, schiaccio il secondo ed esce un altro segnale, ecc. Mi spiegate come fare scrivendomi un pezzo di codice in C (non è necessario inserire tutti e dieci i pulsanti, va benissimo come esempio tre). Come compilatore uso MPLABX.
Grazie
Per cortesia, puoi scrvermi il codice in C come hai fatto fino ad ora, per me diventa molto piu semplice ed intuitivo.
Grazie
Che dici è arrivata l'ora di fare il salto di qualità?
Prova a scrivere tu il codice in C, basandoti sui vari manuali Microchip è abbastanza semplice. Poi sarò lieto di analizzarlo ed eventualmente correggerlo :)
Puoi scriverlo anche in assembler se vuoi e vedere le differenze.
Per quale applicazione ti serve? e quale è la tua esperienza in elettronica / microcontrollori?
Ciao, la mia esperienza sui microcontrollori è sul materiale che ho trovato in rete, di seguito ti riporto il codice:
Grazie.
Ho bisogno di inserire dieci pulsanti e di assegnare dueci segnali pwm (non voglio che mi correggi il codice per tutti e dieci. Fai quello che puoi e senza impegno).
# include <p18f4550.h>
# include <pwm.h>
# include <timers.h>
#include <portb.h>
#pragma config FOSC = HS
#pragma config WDT = OFF
#pragma config LVP = OFF
#pragma config PBADEN = OFF
#pragma config CCP2MX = ON
//OSC = HS Impostato per lavorare ad alta frequenza
//WDT = OFF Disabilitato il Watchdog Timer
//LVT = OFF Disabilitato programmazione LVT
//PBADEN = OFF Disabilitato gli ingrassi analogici
//CCP2MX = ON il modulo CCP è posto su RC1
void main (void) {
int i; //Variabile usata per creare un conteggio fittizio di pausa
unsigned char period; //Periodo del segnale pwm
int duty_cycle = 0; //Duty Cycle
//Imposto PORTA tutti ingrrssi
LATA = 0x00;
TRISA = 0xFF;
//Imposto PORTB tutti ingrrssi
LATB = 0x00;
TRISB = 0xFF;
//Imposto PORTC tutti ingressi ad RC1 come uscita
LATC = 0x00;
TRISC = 0b11111101;
//Imposto PORTD tutte uscite
LATD = 0x00;
TRISD = 0x00;
//Imposto PORTE tutti ingrrssi
LATE = 0x00;
TRISE = 0xFF;
EnablePullups (); //Abilito resistori di pullups
OpenTimer2 (TIMER_INT_OFF & T2_PS_1_4 & T2_POST_1_8 ); //Apro il timer2 per il pwm
period = 252; //249Imposto una frequenza di 20KHz
while (1) { //Ciclo infinito
if (PORTBbits.RB4 == 0) { //Controllo la pressione di RB4
for (i=0; i<10000; i++) { //Pausa filtraggio spike
}
if (PORTBbits.RB4 == 0) { //Controllo la pressione di RB4
OpenPWM2(period) ; //Apro il modulo pwm
LATCbits.LATC1 = 0x01 ; //Accendo il Led 1
}
else {
LATCbits.LATC1 = 0x00 ;
ClosePWM2 () ; // Chiudo il modulo pwm
}
SetDCPWM2 (500); //Aggiorno il duty cycle
}
}
}
Da una prima occhiata mi sembra che si sia un problema sull'antirimbalzo del tasto su RB4.
Dovresti usare un unico ciclo IF per verificare PORTBbits.RB4 == 0
poi all'interno dello stesso puoi fare il FOR per testarne la durata della pressione (debounce) oppure semplicemente (se non è una applicazione sensibile) potresti inserire un ritardo (Delay) di 20mS e poi un altro IF PORTBbits.RB4 == 0.
Ma addirittura non mettere l'antirimbalzo se usi dei condensatori esterni (quest'ultima la userei solo per verificare poi se il tutto funziona)
Stai debuggando sul circuito oppure usi il simulatore?
P.S. la soluzione con interrupt sulla PortaB è comunque piu elegante, ma ripeto, dipende dall'applicazione (ed a chi la dovrai far vedere :)
- Login o registrati per inviare commenti


















8 ore 24 min fa
Io lo farei cosi:
Setup_iniziale:
valori di default ed assegnazione elementi
Interrupt_relativo_ai_tasti:
(puoi usare anche la matrice se non hai tutti gli interrupt)
Identificazione del tasto premuto con antirimbalzo
modifica parametri pwm relativamente al tasto premuto
Main_loop:
generazione pwm
loop_infinito
Il programma genera un pwm in un loop infinito, se viene premuto un tasto, si genera un interrupt (mentre il pwm continua) dove, in base al tasto premuto vengono modificati i parametri del pwm 'al volo'.All'uscita dall'interrupt ritorna nel loop infinito. Semmai resetta il pwm prima (anche se credo lo faccia da solo).
Una volta compreso (e validato) il flusso di programma, poi realizzarlo in assembler o c diventa solo una traduzione :)