CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

PIC18F67J50 read ADC channel

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
rr2



Joined: 09 Mar 2009
Posts: 4

View user's profile Send private message

PIC18F67J50 read ADC channel
PostPosted: Wed May 09, 2018 7:29 am     Reply with quote

At the moment I have a problem with a project on the analog inputs with the most up-to-date version of the compiler.
It is a project in which all the analog inputs of the micro are used and where they are selected individually in the software.
In the beginning it started with the CCS version 5.071, and there were no problems, the firmware is OK.
There was a pause in the project, and meanwhile the compiler was upgraded to version 5.075 and today to version 5.078.

In the last days, it was necessary to update the firmware, and the problems begin to appear, as the AD channels are selectable in the program, when reading channel 10 or 11 is active, the readings are all wrong on all AD ports.

Has anyone had the same problem?

With version 5.071 everything works ok, all channels read correctly and everything works like expected.
With version> = 5.075 when channel 10 or channel 11 is active, all AD channels get wrong readings (like blocked values even i change analog voltage with a potentiometer), even if channel 10 or 11 is deactivated again, the problem remains until a reset to μC.
Follow the code below only with the AD ports test, shown on LCD.

Best regards,
Thanks in advance.


main.h
Code:

#include <18F67J50.h>
#device PASS_STRINGS=IN_RAM
#device adc=8

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES WDT128                   //Watch Dog Timer uses 1:128 Postscale
#FUSES PLL5                     //Divide By 5(20MHz oscillator input)
#FUSES NOXINST                  //Extended set extension and Indexed Addressing mode disabled (Legacy mode)
#FUSES PROTECT                  //Code protected from reads
#FUSES HSPLL                    //High Speed Crystal/Resonator with PLL enabled

#use delay(clock=48MHz,crystal=20MHz)
#use rs232(baud=19200,parity=N,xmit=PIN_B6,bits=8,stream=DBG)


main.c
Code:

#include <main.h>

#define CODE_START   0x1000
#build(reset=CODE_START, interrupt=CODE_START+0x08)
#org 0, CODE_START-1 {}

#include <stdlib.h>

#define USB_CONFIG_HID_TX_SIZE   64
#define USB_CONFIG_HID_RX_SIZE   64

#include <pic18_usb.h>
#include "usb_desc_hid.h"   
#include <usb.c>
#include "hal.c"
#include "LCD4.c"
#include "47L16.c"
#include "e2prom.c"
#include "proc_usb.c"
#include "teclas.c"
#include "menu.c"
#include "menu_conf.c"
//#include "24256.c"

//int debug_c;

#ZERO_RAM

-------Timers routines----

void main() {
    set_tris_a(0b00111111);
    set_tris_b(0b00000111);
    set_tris_c(0b10000110);
    set_tris_d(0b00111111);
    set_tris_e(0b00000001);
    set_tris_f(0b11100100);
    set_tris_g(0b00011110);
    OUTPUT_A(0x00);
    OUTPUT_B(0x00);
    OUTPUT_C(0x00);
    OUTPUT_D(0x00);
    OUTPUT_E(0x00);
    OUTPUT_F(0x00);
    OUTPUT_G(0x00);

    HW_INIT();
   
    int adc_vals[8];

    //setup_adc_ports(sAN11 | sAN10 | sAN7 | sAN4 | sAN3 | sAN2 | sAN1 | sAN0);
    setup_adc_ports(ALL_ANALOG);
    setup_adc(ADC_CLOCK_INTERNAL | ADC_TAD_MUL_12);
    set_adc_channel(0);
    setup_timer_0(RTCC_INTERNAL | RTCC_DIV_128 | RTCC_8_bit); //2,7 ms overflow
    //setup_timer_1(T1_INTERNAL | T1_DIV_BY_1); //USED BY MODBUS
    setup_timer_2(T2_DIV_BY_16, 224, 2); //150 us overflow, 602 us interrupt //300 us overflow, 600 us interrupt setup_timer_2(T2_DIV_BY_16,224,2);
    setup_timer_3(T3_INTERNAL | T3_DIV_BY_8); //43.6
    setup_timer_4(T4_DIV_BY_16, 250, 15); //5mS

    disable_interrupts(INT_TIMER0);
    disable_interrupts(INT_TIMER3);
    enable_interrupts(INT_TIMER4);
    enable_interrupts(GLOBAL);

    init_vars(); //variables init lcd config,etc....

    while (1) {
        check_boot();
       
        set_adc_channel(0);
        delay_us(100);
        adc_vals[0] = read_adc();
       
        set_adc_channel(1);
        delay_us(100);
        adc_vals[1] = read_adc();
       
        set_adc_channel(2);
        delay_us(100);
        adc_vals[2] = read_adc();
       
        set_adc_channel(3);
        delay_us(100);
        adc_vals[3] = read_adc();
       
        set_adc_channel(4);
        delay_us(100);
        adc_vals[4] = read_adc();
       
        set_adc_channel(7);
        delay_us(100);
        adc_vals[5] = read_adc();
       
        set_adc_channel(10);       //----> IF Active -> ALL channels stop reading
        delay_us(100);
        adc_vals[6] = read_adc();
       
        set_adc_channel(11);      //----> IF Active -> ALL channels stop reading
        delay_us(100);
        adc_vals[7] = read_adc();
       
        clear_line(1);
        printf(lcd_putc,"1:%u 2:%u 3:%u",
                adc_vals[0],
                adc_vals[1],
                adc_vals[2]               
                );
        clear_line(2);
        printf(lcd_putc,"4:%u 5:%u 6:%u",
                adc_vals[3],
                adc_vals[4],
                adc_vals[5]               
                );
        clear_line(3);
        printf(lcd_putc,"7:%u 8:%u",
                adc_vals[6],
                adc_vals[7]               
                );
       
               

//        if (modbus_kbhit()) {
//            process_modbus();
//        }
//
//        process_loop();
//
//        usb_task();
//        if (usb_enumerated()) {
//            if (usb_kbhit(1)) {
//                usb_get_packet(1, in_usb, 64);
//                process_usb();
//            }
//        }
    }
}

Ttelmah



Joined: 11 Mar 2010
Posts: 19504

View user's profile Send private message

PostPosted: Wed May 09, 2018 8:20 am     Reply with quote

The old rule, trim things down to see what is happening.

Having cut the code down to a minimum to look at the set_adc_channel function, there is a mask error in the set_adc_channel function:

Code:

//old code
....................         set_adc_channel(10);       //----> IF Active -> ALL channels stop reading
0014E:  MOVLW  28
00150:  MOVWF  01
00152:  MOVF   FC2,W
00154:  ANDLW  C3
00156:  IORWF  01,W
00158:  MOVWF  FC2

//New code
....................         set_adc_channel(7);
00132:  MOVLW  1C
00134:  MOVWF  01
00136:  MOVF   FC2,W
00138:  ANDLW  E3 //problem - leaves bit 5 set
0013A:  IORWF  01,W
0013C:  MOVWF  FC2


Report this to CCS.
Because the mask is wrong the top bit of the actual ADC channel number gets left set, selecting the wrong channel...
A substitute:
Code:

#byte ADCON0=getenv("SFR:ADCON0")
#define SET_ADC_CHAN(x) adcon0 = ((adcon0 & 0xC3)+(x*4))|1


This should correctly generate the old code, till CCS can send a fix.
rr2



Joined: 09 Mar 2009
Posts: 4

View user's profile Send private message

PostPosted: Wed May 09, 2018 8:25 am     Reply with quote

Many thank´s.

I will report to CCS.

Best regards.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group