Generar señal cuadrada (PWM) con microcontrolador PIC18F25K50

Buenas tardes comunidad, esta es mi primera publicación, estoy empezando en el mundo de los microcontroladores.
Quiero generar un PWM, con el microcontrolador PIC18F25K50, el cual varíe su frecuencia y su ciclo de trabajo (duty), por medio del modulo timer0, estoy intentando usar un pulsador en el T0CKL, que me cambie el estado del timer, la idea es que por medio del pulso se varíe la frecuencia y el duty. Pero tengo problemas con el código, ya que no tengo mucha experiencia en el lenguaje c, el programa que estoy usando en el MPLAB XC8, cualquier ayuda o consejo lo agradecería mucho.
 
Buenas tardes comunidad, esta es mi primera publicación, estoy empezando en el mundo de los microcontroladores.
Quiero generar un PWM, con el microcontrolador PIC18F25K50, el cual varíe su frecuencia y su ciclo de trabajo (duty), por medio del modulo timer0, estoy intentando usar un pulsador en el T0CKL, que me cambie el estado del timer, la idea es que por medio del pulso se varíe la frecuencia y el duty. Pero tengo problemas con el código, ya que no tengo mucha experiencia en el lenguaje c, el programa que estoy usando en el MPLAB XC8, cualquier ayuda o consejo lo agradecería mucho.
Publica lo que tiene realizado y aclara dentro del código que escribiste donde tienes problemas porque me imagino que escribiste un código ¿ NO ?
 
Hola, buenas tardes.
En el archivo user.c tengo las siguientes configuraciones.
C:
    INTCONbits.INT0IF = 0; //Pone la bandera del timer0,
    INTCON2bits.INTEDG0 = 0; //selecciono el flanco
    INTCONbits.INT0IE = 1; //Habilita la interrupcion del timer0


    //Registros para configurar el timer0
    T0CONbits.TMR0ON = 0; //Habilita el timer0
    T0CONbits.T08BIT = 0; //Contador de 16 bits, la interrupcion salta al reiniciar
    T0CONbits.T0CS = 0; // Cuenta los pulsos del reloj interno
    T0CONbits.T0SE = 0; // Cuenta los flancos de subida o de bajada
    T0CONbits.PSA = 0; // Se le asigna un valor al prescaler
    T0CONbits.T0PS = 0b101; // Prescaler 1:64

    T0CON = 0X00; //Escrito en hexo

    //Configuracion de interrupciones
    INTCONbits.T0IF = 0;
    INTCONbits.T0IE = 1;
    TMR0 = 0; //Empieza en 0
    T0CONbits.TMR0ON = 1; // Lo prendo
En el archivo main.c tengo.
C:
int on = 0;
int off = 0;

/******************************************************************************/
/* Main Program */
void timer0(int on, int off);
void cambio_ciclo();
void cambio_frecuencia();

void main(void) {
    /*Configure the oscillator for the device */
    ConfigureOscillator();

    /* Initialize I/O and Peripherals for application */

    InitApp();

    /* TODO <INSERT USER APPLICATION CODE HERE> */

    while (1) {
        timer0(on, off);
    }
}

void timer0(int on, int off) {
    on++; // Incrementa el contador

    if (on = 100) { // Si pasaron 100ms
        LATAbits.LATA4 = LATAbits.LATA4 + 1; // Se hace el cambio de estado
        on = 0; // Reinicia el contador
    }
    TMR0 = 131; //Carga para el debordamiento en 1ms
}

void cambio_ciclo() {

}

void cambio_frecuencia(){
        OSCCONbits.IRCF = 0b111
    }
}
Lo que planeo hacer es que el pulsador genere las interrupciones y se ejecute cambio_ciclo y cambio_frecuencia.
 
Lo que planeo hacer es que el pulsador genere las interrupciones y se ejecute cambio_ciclo y cambio_frecuencia.
¿Cuál pulsador? ¿Cuáles interrupciones?
En tu programa no se ve declarado ningún pin para un pulsador y tampoco ningún servicio de interrupción.
Puedes usar alguna interrupción externa, tal vez innecesariamente a menos que sea de prioridad.

Esto está mal:
if (on = 100) { // Si pasaron 100ms
Tendría de que ser comparación y no asignación.
Podría ser así: if (++on == 100) o if (++on > 99) o if (++on >= 100)

Esto no me gusta:
LATAbits.LATA4 = LATAbits.LATA4 + 1; // Se hace el cambio de estado
Es más "elegante" así:
LATAbits.LATA4 ^= 1;

El uso de las variables globales "on" y "off" no es necesario porque no les estás asignando valores.
Como son para uso exclusivo de la subrutina "timer0" podrían ser locales o estáticas.
Supongo que a esa subrutina es la que llamas "interrupción", pero no lo es porque no está declarada como tal.
Aparte, las interrupciones no se llaman, se ejecutan, ya sea por eventos externos o internos como el desborde de un timer.
 
Mi consejo es empezar con pic mas sencillos.
En esto tiene mucha razón, es mas practico sin fallos y elegante.
Esto no me gusta:
LATAbits.LATA4 = LATAbits.LATA4 + 1; // Se hace el cambio de estado
Es más "elegante" así:
LATAbits.LATA4 = 1;

Y esto seria lo correcto
if (++on > 99)
Para asegurar que no pase de largo la variable.

Solo una errata. El salto a la parte de interrupciones es un comando base que se añade en cada proceso. Normalmente nunca cuentan con ello por que el compilador x lo hace automáticamente eso incrementa un proceso complotado dentro del código... Es difícil de esplicar por aquí (por lo menos para mi) seria mejor demostrar como lo usa un compilador en persona programando... Recordar que las series 18 tiene interrupciones primarias y secundarias. Tampoco puedo aconsejar nada en ese integrado por que nunca trabaje nada en concreto con el, lo mas en el foro de microchip una ocurrencia de usar la memoria de cache edernet para ampliar su RAM y tan sólo fue un pequeño añadido

Un saludo
Sigo opinando que para empezar en el mundo de los pic mejor modelos mas sencillos para configurar con menos cosas

Y una pregunta??
Esto
//Registros para configurar el timer0
T0CONbits.TMR0ON = 0; //Habilita el timer0
T0CONbits.T08BIT = 0; //Contador de 16 bits, la interrupcion salta al reiniciar
T0CONbits.T0CS = 0; // Cuenta los pulsos del reloj interno
T0CONbits.T0SE = 0; // Cuenta los flancos de subida o de bajada
T0CONbits.PSA = 0; // Se le asigna un valor al prescaler
T0CONbits.T0PS = 0b101; // Prescaler 1:64

No seria lo mismo que esto
T0CONbits = 0b00000101

Y en 2 procesos nada mas cuando lo compilas???
Y no 12 procesos. Al ir borrando bit a bit. Piensa que tardaría 6 veces menos en hacer lo mismo

No molesto mas sorry

Un saludo
 
Última edición:
Atrás
Arriba