Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

C code for PIC16F1508 with ADC

Status
Not open for further replies.
T

treez

Guest
Hi,
Please could you possibly check this XC8 C code for PIC16F1508?
All it is supposed to do is read the ADC input, and if greater than 10, then get on and switch on the led driver.
Its builds fine, but I fear the ADC registers have not all been set, and it wont work when on the hardware this week?

Code:
//pic16f1508  LED COLOR mixer

// CONFIG

// CONFIG1
#pragma config FOSC = INTOSC    // Oscillator Selection Bits (INTOSC oscillator: I/O function on CLKIN pin)
#pragma config WDTE = OFF       // Watchdog Timer Enable (WDT disabled)
#pragma config PWRTE = OFF      // Power-up Timer Enable (PWRT disabled)
#pragma config MCLRE = OFF      // MCLR Pin Function Select (MCLR/VPP pin function is digital input)
#pragma config CP = OFF         // Flash Program Memory Code Protection (Program memory code protection is disabled)
#pragma config BOREN = OFF      // Brown-out Reset Enable (Brown-out Reset disabled)
#pragma config CLKOUTEN = OFF   // Clock Out Enable (CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin)
#pragma config IESO = OFF       // Internal/External Switchover Mode (Internal/External Switchover Mode is disabled)
#pragma config FCMEN = OFF      // Fail-Safe Clock Monitor Enable (Fail-Safe Clock Monitor is disabled)

// CONFIG2
#pragma config WRT = OFF        // Flash Memory Self-Write Protection (Write protection off)
#pragma config STVREN = OFF     // Stack Overflow/Underflow Reset Enable (Stack Overflow or Underflow will not cause a Reset)
#pragma config BORV = LO        // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), low trip point selected.)
#pragma config LPBOR = OFF      // Low-Power Brown Out Reset (Low-Power BOR is disabled)
#pragma config LVP = OFF        // Low-Voltage Programming Enable (High-voltage on MCLR/VPP must be used for programming)


// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.

#include <xc.h>
#include <stdint.h>

#define  _XTAL_FREQ 4000000

    uint16_t   count;
    uint16_t   count1;
    uint16_t   count2;
    uint16_t   vbusmeas;

void main(void) {
    //SETUP PORTS

    TRISA = 0x38;   //ips are temp, commsbus
    TRISB = 0x00;
    TRISC = 0x04;
    
    //RA2 = PWM into RC for dimming
    //RC1 = PWM DIMMING OR TURN OFF
    
   /* PORT FUNCTIONS
    RA0 = DAT
    RA1 = CLK
    RA2 = DIM1_UC...dim the HV9910B with PWM into RC....................
    RA3 = MCLR
    RA4 = TEMP input    (MAKE OP LOW FOR NOW)
    RA5 = COMMSBUS  (MAKE IP) ***
    RA6 = NO PIN
    RA7 = NO PIN
            
    RB0 = NO PIN
    RB1 = NO PIN
    RB2 = NO PIN
    RB3 = NO PIN
    RB4 = NC OP LOW
    RB5 = NC OP LOW
    RB6 = NC OP LOW
    RB7 = NC OP LOW
            
    RC0 = CHILICOMMS OP LOW   (MAKE OP LOW FOR NOW) ..NNEDS WEAK PULLUP
    RC1 = TURN OFF HV9910B (OP)
    RC2 = VBUSMEAS
    RC3 = NC OP LOW
    RC4 = COMMSBUSDRIVE OP LOW
    RC5 = COLORMIX OP LOW..................................................
    RC6 = SC_OUT OP LOW   (MAKE OP LOW FOR NOW)
    RC7 = CURRENT MONITOR (MAKE OP LOW FOR NOW)     */
            
            
    //INITIATE PORTS
        LATAbits.LATA0 = 0; 
        LATAbits.LATA1 = 0; //
        LATAbits.LATA2 = 0; //
        //LATAbits.LATA3 = 0;   MCLR
        //LATAbits.LATA4 = 0;     //temp sensor input
        //LATAbits.LATA5 = 1;     
        //LATAbits.LATA6 = 0;     //NO INTERNAL PIN
        //LATAbits.LATA7 = 0;     //NO INTERNAL PIN
                  
        //LATBbits.LATB0 = 0;   //NO INTERNAL PIN  
        //LATBbits.LATB1 = 0;   //NO INTERNAL PIN
        //LATBbits.LATB2 = 0;   //NO INTERNAL PIN      
        //LATBbits.LATB3 = 0;   //NO INTERNAL PIN   
        LATBbits.LATB4 = 0;
        LATBbits.LATB5 = 0;           
        LATBbits.LATB6 = 0;
        LATBbits.LATB7 = 0;
                
        LATCbits.LATC0 = 0;
        LATCbits.LATC1 = 1;     //TURN OFF LED DRIVER    
        //LATCbits.LATC2 = 0;     
        LATCbits.LATC3 = 0;      
        LATCbits.LATC4 = 0;
        LATCbits.LATC5 = 1;              
        LATCbits.LATC6 = 0;
        LATCbits.LATC7 = 0;
        
        //SETUP FUNCTION REGISTERS
        ANSELA = 0x00;
        ANSELB - 0x00;
        ANSELC = 0x04;   //VBUSMEAS
        
        ADCON0 = 0x18;  //choose AN6
        ADCON1 = 0x40;  // fosc/4, leftjust, refvdd
        ADRESH = 0x00;
    
        CM1CON0 = 0x00;
        CM1CON1 = 0x00;
        CM2CON0 = 0x00;
        CM2CON1 = 0x00;
        
        INTCON = 0x00;
        
        OPTION_REG = 0x07;  //wpu BY latch
        WPUA = 0x10;    //temperature input
        WPUB = 0x00;
        //WPUC = 0x81;    //CURRNT MO, Chilicomms //NO WPUC
    
        PWM1CON = 0x00;
        
        ADON = 1;    //ENABLE ADC
    
        
        LATAbits.LATA2 = 0; //zero light
        LATCbits.LATC1 = 1; //led driver off
        
        
        
        while(1) {
        GO = 1;    //START CONVERSION
        while(GO) {;}
        vbusmeas = ADRESH; 
        if (vbusmeas > 10) {break;}
        }
        
        LATAbits.LATA2 = 1; //max light
        LATCbits.LATC1 = 0; //led driver on
        
 
        count = 0;
        while(1){
        LATCbits.LATC5 = 1;
        __delay_us(100);
        LATCbits.LATC5 = 0;
        __delay_us(100);
        }
        
        
 
    return;
}

- - - Updated - - -

Also, we have the enhanced version of the above where it reads the ADC, and then if >10, then it puts out a 50% PWM dimming signal at T=1ms on PWM1 and PWM3....we were unsure about the setting up of the PWM modules as it seemes to start off with setting the relevant TRIS bit, which seemed odd as this makes the PWM output an input. (page 253 of PIC16F1508 datasheet)

Please could you inspect the PWM bit of thios code?...it doesnt build as it dislikes the "T2CKPS" nemonic for some reason

PIC16F1508 datasheet
https://ww1.microchip.com/downloads/en/DeviceDoc/40001609E.pdf

Code:
//pic16f1508  LED COLOR mixer

// CONFIG

// CONFIG1
#pragma config FOSC = INTOSC    // Oscillator Selection Bits (INTOSC oscillator: I/O function on CLKIN pin)
#pragma config WDTE = OFF       // Watchdog Timer Enable (WDT disabled)
#pragma config PWRTE = OFF      // Power-up Timer Enable (PWRT disabled)
#pragma config MCLRE = OFF      // MCLR Pin Function Select (MCLR/VPP pin function is digital input)
#pragma config CP = OFF         // Flash Program Memory Code Protection (Program memory code protection is disabled)
#pragma config BOREN = OFF      // Brown-out Reset Enable (Brown-out Reset disabled)
#pragma config CLKOUTEN = OFF   // Clock Out Enable (CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin)
#pragma config IESO = OFF       // Internal/External Switchover Mode (Internal/External Switchover Mode is disabled)
#pragma config FCMEN = OFF      // Fail-Safe Clock Monitor Enable (Fail-Safe Clock Monitor is disabled)

// CONFIG2
#pragma config WRT = OFF        // Flash Memory Self-Write Protection (Write protection off)
#pragma config STVREN = OFF     // Stack Overflow/Underflow Reset Enable (Stack Overflow or Underflow will not cause a Reset)
#pragma config BORV = LO        // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), low trip point selected.)
#pragma config LPBOR = OFF      // Low-Power Brown Out Reset (Low-Power BOR is disabled)
#pragma config LVP = OFF        // Low-Voltage Programming Enable (High-voltage on MCLR/VPP must be used for programming)


// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.

#include <xc.h>
#include <stdint.h>

#define  _XTAL_FREQ 4000000

    uint16_t   count;
    uint16_t   count1;
    uint16_t   count2;
    uint16_t   vbusmeas;

void main(void) {
    //SETUP PORTS

    TRISA = 0x38;   //ips are temp, commsbus
    TRISB = 0x00;
    TRISC = 0x04;
    
    //RA2 = PWM into RC for dimming
    //RC1 = PWM DIMMING OR TURN OFF
    
   /* PORT FUNCTIONS
    RA0 = DAT
    RA1 = CLK
    RA2 = DIM1_UC...dim the HV9910B with PWM into RC....................
    RA3 = MCLR
    RA4 = TEMP input    (MAKE OP LOW FOR NOW)
    RA5 = COMMSBUS  (MAKE IP) ***
    RA6 = NO PIN
    RA7 = NO PIN
            
    RB0 = NO PIN
    RB1 = NO PIN
    RB2 = NO PIN
    RB3 = NO PIN
    RB4 = NC OP LOW
    RB5 = NC OP LOW
    RB6 = NC OP LOW
    RB7 = NC OP LOW
            
    RC0 = CHILICOMMS OP LOW   (MAKE OP LOW FOR NOW) ..NNEDS WEAK PULLUP
    RC1 = TURN OFF HV9910B (OP)
    RC2 = VBUSMEAS
    RC3 = NC OP LOW
    RC4 = COMMSBUSDRIVE OP LOW
    RC5 = COLORMIX OP LOW..................................................
    RC6 = SC_OUT OP LOW   (MAKE OP LOW FOR NOW)
    RC7 = CURRENT MONITOR (MAKE OP LOW FOR NOW)     */
            
            
    //INITIATE PORTS
        LATAbits.LATA0 = 0; 
        LATAbits.LATA1 = 0; //
        LATAbits.LATA2 = 0; //
        //LATAbits.LATA3 = 0;   MCLR
        //LATAbits.LATA4 = 0;     //temp sensor input
        //LATAbits.LATA5 = 1;     
        //LATAbits.LATA6 = 0;     //NO INTERNAL PIN
        //LATAbits.LATA7 = 0;     //NO INTERNAL PIN
                  
        //LATBbits.LATB0 = 0;   //NO INTERNAL PIN  
        //LATBbits.LATB1 = 0;   //NO INTERNAL PIN
        //LATBbits.LATB2 = 0;   //NO INTERNAL PIN      
        //LATBbits.LATB3 = 0;   //NO INTERNAL PIN   
        LATBbits.LATB4 = 0;
        LATBbits.LATB5 = 0;           
        LATBbits.LATB6 = 0;
        LATBbits.LATB7 = 0;
                
        LATCbits.LATC0 = 0;
        LATCbits.LATC1 = 1;     //TURN OFF LED DRIVER    
        //LATCbits.LATC2 = 0;     
        LATCbits.LATC3 = 0;      
        LATCbits.LATC4 = 0;
        LATCbits.LATC5 = 1;              
        LATCbits.LATC6 = 0;
        LATCbits.LATC7 = 0;
        
        //SETUP FUNCTION REGISTERS
        ANSELA = 0x00;
        ANSELB - 0x00;
        ANSELC = 0x04;   //VBUSMEAS
        
        ADCON0 = 0x18;  //choose AN6
        ADCON1 = 0x40;  // fosc/4, leftjust, refvdd
        ADRESH = 0x00;
    
        CM1CON0 = 0x00;
        CM1CON1 = 0x00;
        CM2CON0 = 0x00;
        CM2CON1 = 0x00;
        
        INTCON = 0x00;
        
        OPTION_REG = 0x07;  //wpu BY latch
        WPUA = 0x10;    //temperature input
        WPUB = 0x00;
        //WPUC = 0x81;    //CURRNT MO, Chilicomms //NO WPUC
    
        T2CON = 0x00;
       
        ADON = 1;    //ENABLE ADC
        
        PWM1CON = 0x00;
        PWM3CON = 0x00;
    
        
        LATAbits.LATA2 = 0; //zero light
        LATCbits.LATC1 = 1; //led driver off
        
        
        
        while(1) {
        GO = 1;    //START CONVERSION
        while(GO) {;}
        vbusmeas = ADRESH; 
        if (vbusmeas > 10) {break;}
        }
        
        //SET UP PWM1 (RC5) FOR 50% DUTY CYCLE AT T= 1ms
        //Page 253 of PIC16F1508 DATASHEET
        TRISC5 = 1;
        PWM1CON = 0x00;
        PR2 = 0xFF;
        PWM1DCH = 0x00;
        PWM1DCL = 0x00;
        TMR2IF = 0;
        T2CKPS = 0x00;
        TMR2ON = 1;
        PWM1EN = 1;
        while (!TMR2IF){;}
        TRISC5 = 0;
        PWM1OE = 1;
        PWM1EN = 1;
        
        
        //SET UP PWM3 (RA2) FOR 50% DUTY CYCLE AT T= 1ms
        //Page 253 of PIC16F1508 DATASHEET
        TRISA2 = 1;
        PWM3CON = 0x00;
        PR2 = 0xFF;
        PWM3DCH = 0x00;
        PWM3DCL = 0x00;
        TMR2IF = 0;
        T2CKPS = 0x00;
        TMR2ON = 1;
        PWM3EN = 1;
        while (!TMR2IF){;}
        TRISC5 = 0;
        PWM3OE = 1;
        PWM3EN = 1;
        
        
        while(1){;}
 
    return;
}
 

Do you really want to check the ADC output is > 10? By left justifying the ADC result and using ADRESH you are ignoring the two least significant bits. If the value to check is 10, right justify it and use ADRESL.

Brian.
 
  • Like
Reactions: treez

    T

    Points: 2
    Helpful Answer Positive Rating
Thanks yes, i agree, though i want to keep the same Left justification throughout as its ok and i will do other tests on the adc value later with a higher checking point.
One thing that got me about the datasheet is how involved it is to do a PWM output.....it requires interrupts to be set, use of the TMR2 etc etc
 

For PWM you need one timer (TMR2) to provide the start time for each pulse but you do not need any interrupts. Basically it works by clocking a counter and comparing the count value with the value that you choose for the PWM ratio. When the two are the same, it flips the PWM output bit and resets the counter again for the next shot. You can use it as a source of interrupts but they are not essential to PWM operation.

I'm not sure why it balks at T2CKPS, on my machine it is defined in the header file PIC16F1508.h as a two-bit wide field in 'T2CONbits_t' so it should accept it. What version of compiler are you using? I have XC8 version 2.10 here.

Brian.
 

I would update to v2.10, it may have corrections or better support for that device. As far as I know, just updating/replacing the compiler with the new one will work, I think they are backwards compatible even at command line level.

I think the reason for the TRIS anomaly is that in some situations, the PWM may be driving circuits that need a particular condition at start up. For example, motor speed control or a bridge driver circuit. By making the PWMx pin an input it becomes incapable of driving a logic level out. Only after configuring the PWM registers would it then be safe to enable the output. Consider what might happen if the PWM output sits high for a long time in bridge driver for example. The problem could be worse if two PWM outputs were used in the same circuit and both were stuck high. So it is basically a protection feature so you are sure the PWM signals are correct before unleashing them on the outside world.

Brian.
 
  • Like
Reactions: treez

    T

    Points: 2
    Helpful Answer Positive Rating
Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top