cmicrocontrollerpicmicrochip

Analog data operations do not work in PIC12F675, there is not even a reaction on GPIO pins


This Analog data is read and the number 1-5 is shown on the 7 segment common anode display with 7447, but I can't set this number for analog value because I can't show analog values or output I wrote this code in MPLAB X IDE.

#include <xc.h>

#pragma config FOSC = INTRCIO   // Oscillator Selection bits (INTOSC oscillator: I/O function on GP4/OSC2/CLKOUT pin, I/O function on GP5/OSC1/CLKIN)
#pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = OFF      // Power-Up Timer Enable bit (PWRT disabled)
#pragma config MCLRE = ON       // GP3/MCLR pin function select (GP3/MCLR pin function is MCLR)
#pragma config BOREN = OFF      // Brown-out Detect Enable bit (BOD disabled)
#pragma config CP = OFF         // Code Protection bit (Program Memory code protection is disabled)
#pragma config CPD = OFF   

#define _XTAL_FREQ 4000000
#define HIGH 1
#define LOW 0

unsigned int adc_value=0;

void main(void) {
    TRISIObits.TRISIO0 = 1;
    TRISIObits.TRISIO1 = 0;
    TRISIObits.TRISIO2 = 0;
    TRISIObits.TRISIO4 = 0;
    TRISIObits.TRISIO5 = 0;
    
    ANSELbits.ADCS2 = 0;
    ANSELbits.ADCS1 = 0;
    ANSELbits.ADCS0 = 0;
    ANSELbits.ANS0 = 1;
    
    ADCON0bits.CHS0 = 0;
    ADCON0bits.CHS1 = 0;
    ADCON0bits.ADON = 1;
    ADCON0bits.GO = 1;
    ADCON0bits.ADFM = 1;

    while(1) {
        ADON = 1;
        GO_DONE = 1;
        while(GO_DONE);
        adc_value = (((unsigned int) ADRESH << 8) + ADRESL);
        ADON = 0;
        if (adc_value >= 0 && adc_value <= 200) {
            GP4 = 0;
            GP5 = 0;
            GP2 = 0;
            GP1 = 0;
        } else if (adc_value > 200 && adc_value <= 400) {
            GP4 = 0;
            GP5 = 0;
            GP2 = 0;
            GP1 = 1;
        } else if (adc_value > 400 && adc_value <= 600) {
            TRISIObits.TRISIO4 = 0;
            TRISIObits.TRISIO5 = 0;
            TRISIObits.TRISIO2 = 1;
            TRISIObits.TRISIO1 = 0;
        } else if (adc_value > 600 && adc_value <= 800) {
            TRISIObits.TRISIO4 = 0;
            TRISIObits.TRISIO5 = 0;
            TRISIObits.TRISIO2 = 1;
            TRISIObits.TRISIO1 = 1;
        } else if (adc_value > 800 && adc_value <= 1023) {
            TRISIObits.TRISIO4 = 0;
            TRISIObits.TRISIO5 = 1;
            TRISIObits.TRISIO2 = 0;
            TRISIObits.TRISIO1 = 0;
        } else {
            TRISIObits.TRISIO4 = 1;
            TRISIObits.TRISIO5 = 1;
            TRISIObits.TRISIO2 = 1;
            TRISIObits.TRISIO1 = 1;
        }
        __delay_ms(100);
    }
    return;
}

my aim in this project is to print the number between 0-5 on the 7 segment common anode display according to the analog data between 0-1023, but I could not solve this problem.

Schema


Solution

  • As a solution, according to the code given by @Kozmotronik, the problem was solved when 74hc595 was used instead of 7447.

    This is the solved code and scheme:

    
    #include <xc.h>
    
    #pragma config FOSC = INTRCIO   // Internal oscillator
    #pragma config WDTE = OFF       // Watchdog Timer disabled
    #pragma config PWRTE = OFF      // Power-up Timer disabled
    #pragma config MCLRE = ON      // GP3/MCLR pin function is digital I/O
    #pragma config BOREN = ON       // Brown-out Reset enabled
    #pragma config CP = OFF         // Code Protection disabled
    #pragma config CPD = OFF        // Data Memory Code Protection disabled
    
    #define _XTAL_FREQ 4000000
    
    #define ST_CP GP4
    #define DS GP2
    #define SH_CP GP1
    
    
    unsigned int adc_value = 0;
    float volt=0;
    uint8_t LED [10]={
      0xE7, //0    0xE7
      0x21, //1
      0xDB, //2   0xD3
      0x6B, //3   0xD6
      0x3D, // 4  0xB4
      0x7E, // 5  0x76
      0xEE, //6
      0x23, //7   0xE4
      0xEF, //8
      0x7F, //9   0xF6
    };
    
    void spi_shift_out(uint8_t data) {
        uint8_t i;
        for (i = 0; i < 8; i++) {
            if (data & (1 << (7 - i))) {
                DS = 1;
            } else {
                DS = 0;
            }
            
            SH_CP = 1;
            __delay_us(1);
            SH_CP = 0;
        }
        
        ST_CP = 1;
        __delay_us(1);
        ST_CP = 0; 
    }
    
    void display_digit(uint8_t digit) {
        spi_shift_out(LED[digit]);
    }
    
    void main(void) {
        GPIO = 0; // Clear output latches
        CMCON = 7; // Turn off analog comparators
        TRISIO = 1; // GP0 and GP3 (GP3 is an only input pin) are input and other pins are output
        ANSEL = 0x21; 
        ADCON0 = 0x81; 
        while (1) {
            ADCON0bits.GO = 1;
            while (ADCON0bits.GO);
            adc_value = (ADRESH <<8) + ADRESL;
            volt=(adc_value*5)/1023;
            if (volt >= 0 && adc_value < 0.99) {
                display_digit(0);
            } else if (volt >= 1.0 && volt < 1.99) {
                display_digit(1);
            } else if (volt >= 2.0 && volt < 2.99) {
                display_digit(2);
            } else if (volt >= 3.0 && volt < 3.99) {
                display_digit(3);
            } else if (volt >= 4.0 && volt <= 4.99) {
                display_digit(4);
            } else {
                display_digit(4);
            }
            __delay_ms(100);
        }
    
        return;
    }
    

    Shema