Per un progetto che vedrete prossimamente, avevo bisogno di generare un segnale PWM dalla seriale del pc... il problema principale è che mi serviva di continuare a generare lo stesso segnale anche dopo aver staccato il cavo di collegamento al pc. Bene, basta un pic, un max232 e una manciata di componenti a contorno.
questo è il circuito che ho realizzato:
I componenti sono pochi e la lista precisa è la seguente:
C1 1uF
C2 1uF
C3 1uF
C4 1uF
C5 22pF
C6 22pF
C7 22uF
C8 0,47uF
C9 100nF
IC1 PIC16F628A
IC2 MAX232
IC2 MAX232
IC3 LM2940T
Q1 4.000Hz
Q1 4.000Hz
Q5 IRF540
R4 100ohm
I più attenti noteranno che sul circuito che ho realizzato manca il MOSFET... si lo so, all'ultimo momento ho pensato che tanto non mi serviva di controllare l'accensione e lo spegnimento degli impulsi PWM, quindi non l'ho più messo.
Per chi non lo sapesse, il 2940 è un regolatore di tensione fisso a 5v LDO (Low Drop Out) che regge fino a 1Ampere circa. Lo uso spesso perché mi permette di alimentare i circuiti "come viene", senza dovermi preoccupare di fornire 5v stabili (di solito uso pacchi batterie da modellismo).
Per la realizzazione ho usato un semplice millefori, non mi andava di fare lo stampato e comunque non è che il circuito sia poi così difficile da assemblare
e questo è il codice MikroC necessario per far funzionare il tutto:
char buffer[4];
int posizione;
int cursore_buffer;
char car_letto;
void interrupt(){
if(Uart1_data_ready()){
car_letto=Uart1_Read();
if(car_letto!=0x0D && car_letto!=0x0A){
buffer[cursore_buffer]=car_letto;
cursore_buffer++;
}
if(cursore_buffer==3){
buffer[3]='\0';
cursore_buffer=0;
posizione=atoi(buffer);
}
}
}
void main(){
TRISA=0;
TRISB=0x00001000;
CMCON=0x07;
INTCON.GIE=1;
PIE1.RCIE=1;
INTCON.PEIE=1;
UART1_Init(9600);
PWM1_Start();
PWM1_Init(50000);
cursore_buffer=0;
posizione=0;
PWM1_Set_Duty(posizione);
while(1){
Delay_ms(20);
PWM1_Set_Duty(posizione);
}
int posizione;
int cursore_buffer;
char car_letto;
void interrupt(){
if(Uart1_data_ready()){
car_letto=Uart1_Read();
if(car_letto!=0x0D && car_letto!=0x0A){
buffer[cursore_buffer]=car_letto;
cursore_buffer++;
}
if(cursore_buffer==3){
buffer[3]='\0';
cursore_buffer=0;
posizione=atoi(buffer);
}
}
}
void main(){
TRISA=0;
TRISB=0x00001000;
CMCON=0x07;
INTCON.GIE=1;
PIE1.RCIE=1;
INTCON.PEIE=1;
UART1_Init(9600);
PWM1_Start();
PWM1_Init(50000);
cursore_buffer=0;
posizione=0;
PWM1_Set_Duty(posizione);
while(1){
Delay_ms(20);
PWM1_Set_Duty(posizione);
}
}
Vorrei solo far notare che l'interrupt dalla seriale è generato ogni volta che arrivano dei dati, ma è un canale orientato al byte, e quindi ogni volta che si chiama la read si legge un byte. Per questo è necessario concatenare l'input e solo dopo convertirlo in numero. NO, non esiste una read bloccante o se esiste (e io non l'ho vista) non la potevo usare dentro la procedura di interrupt, che già è troppo lunga così).
Ovviamente la sintassi per generare i PWM è la stessa seguita dall'struzione MikroC. Il PIC si aspetterà sulla seriale un numero di 3 cifre, quindi se volete passare "8" alla PWM1_Set_Duty dovrete in realtà scrivere "008".
In conclusione si tratta di un circuito semplice e fine a se stesso, in realtà stiamo controllando un segnale dalla porta del pc semplificando la programmazione di quest'ultimo, visto che non si dovranno generare i treni di impulsi. Ma non vorrei rivelare troppo sul progetto che sto portando avanti, maggiori dettagli nei prossimi articoli!
E questo è il risultato finale:
Duty cycle del 50% circa |
Nessun commento:
Posta un commento