|
|
View previous topic :: View next topic |
Author |
Message |
rr2
Joined: 09 Mar 2009 Posts: 4
|
PIC18F67J50 read ADC channel |
Posted: Wed May 09, 2018 7:29 am |
|
|
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
|
|
Posted: Wed May 09, 2018 8:20 am |
|
|
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
|
|
Posted: Wed May 09, 2018 8:25 am |
|
|
Many thank´s.
I will report to CCS.
Best regards. |
|
|
|
|
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
|