|
|
View previous topic :: View next topic |
Author |
Message |
Tak
Joined: 22 Apr 2012 Posts: 6
|
ADC problem |
Posted: Fri Dec 07, 2012 2:37 am |
|
|
I wrote a code to get ADC every 4ms. I use 18f887 with 20MHz crystal. Everything works fine till i try to get some more samples while waiting for RF module. The buffer takes 2 or 3 more, problem is when ADC input's constant (every samples when TX Fifo hasn't locked is 185-186), 1 out of 3 samples is wrong (its value's 191, often the first one). I tried not use buffer but read and send to pc, it's still 190-191, read and discard first samples, there's still 1 "191" in one of three samples. I wonder what i did wrong?
Here's the code, suspected code marks with slash:
Code: |
#include "16f887.h"
#device ADC=8
#include "thu_vien_tx.h"
#FUSES HS,NOWDT
#use FAST_IO(A)
#use rs232(baud=115200,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)
unsigned int16 TX_pointer = address_TX_normal_FIFO+HEADER_LENGHT+2;
unsigned int8 ADCvalue = 0;
int1 Fifo_lock = 0;
//buffer, dai 96 byte, su dung kieu circlebuffer
//khong tao ham doc, ghi buffer roi vi gioi han 9 ngan xep cua 887
unsigned int8 buffer_read_pointer = 0;
unsigned int8 buffer_write_pointer = 0;
unsigned int8 buffer_size=0;
unsigned int8 freeze_count = 0;
unsigned int8 transmitted = 0;
#int_TIMER1
void TIMER1_isr(void)
{
set_timer1(63035);
if (TX_pointer >address_TX_normal_FIFO_end)
Fifo_lock = 1;
if(Fifo_lock==0)
{
ADCvalue = read_adc();
ghi_diachi_dai(TX_pointer, ADCvalue);
TX_pointer++;
printf("%u\n",ADCvalue);
}
////////////////////////////////////////////////////////////////////
/////////////////////////////////////
else if (buffer_size<96)
{
circle_buffer[buffer_write_pointer] = read_adc();
printf("%u\n",circle_buffer[buffer_write_pointer]);
buffer_size++;
if (buffer_write_pointer==95)
buffer_write_pointer = 0;
else
buffer_write_pointer++;
}
///////////////////////////////////
////////////////////////////////////////////////////////////////////
else
freeze_count++;
}
void main()
{
unsigned int8 temp1 = 0;
CS_Direction = 0;
RST_Direction = 0;
INT_Direction = 1;
WAKE_Direction = 0;
Delay_ms(5);
// SPI
setup_spi(SPI_MASTER | SPI_MODE_0 | SPI_CLK_DIV_4);
//Zigbee
mrf_start();
pin_wake();
cho_phep_LNA();
cau_hinh_adc();
setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);
enable_interrupts(INT_TIMER1);
unsigned int8 sequential_num=0;
TX_pointer = ghi_header(sequential_num);
TX_pointer += address_TX_normal_FIFO;
set_timer1(63035);
transmitted = 0;
int i =0;
for (i = 0;i<96;i++)
circle_buffer[i]=0;
enable_interrupts(GLOBAL);
while(1)
{
if (Doc_int() == 0)
{
temp1 = doc_diachi_ngan(INTSTAT);
Nhan_RX();
disable_interrupts(INT_TIMER1);
if (data_RX_FIFO[6]==1&&data_RX_FIFO[10]==0)
if (data_RX_FIFO[12] == 1)
if (TX_pointer >address_TX_normal_FIFO_middle)
{
Fifo_lock = 1;
while (TX_pointer <address_TX_normal_FIFO_end)
ghi_diachi_dai(TX_pointer++, 0);
truyen();
transmitted = 1;
}
set_timer1(63035);
enable_interrupts(INT_TIMER1);
///////////////////////////////////////////////////////////////////
delay_ms(10); ///////////////buffer work around here.
if (transmitted ==1)
{
transmitted = 0;
TX_pointer = ghi_header(++sequential_num);
TX_pointer += address_TX_normal_FIFO;
while ( buffer_size>0)
{
ghi_diachi_dai(TX_pointer,circle_buffer[buffer_read_pointer]);
TX_pointer++;
buffer_size--;
if (buffer_read_pointer==95)
buffer_read_pointer = 0;
else
buffer_read_pointer++;
}
Fifo_lock = 0;
}
flush_RX();
}
if (freeze_count==250)
{
disable_interrupts(INT_TIMER1);
freeze_count = 0;
TX_pointer = ghi_header(++sequential_num);
TX_pointer += address_TX_normal_FIFO;
transmitted = 0;
Fifo_lock = 0;
buffer_size = 0;
buffer_write_pointer = 0;
buffer_read_pointer = 0;
set_timer1(63035);
enable_interrupts(INT_TIMER1);
read_adc();
printf("dung\n");
}
}
}
void mrf_start()
{
software_reset();
Delay_us(300);
RF_reset();
set_WAKE_from_pin();
set_long_address(ADDRESS_long_kit_1);
set_short_address(ADDRESS_short_kit_1);
set_PAN_ID(PAN_ID);
flush_RX();
khoitao_nonbeacon();
Delay_us(300);
nonbeacon_PAN_coordinator_device();
chon_muc_nangluong(20);
set_frame_format_filter(1);
set_reception_mode(1);
//cho_phep_turbo_mode();
//pin_wake();
cho_phep_LNA();
}
|
Last edited by Tak on Fri Dec 07, 2012 3:48 am; edited 1 time in total |
|
|
Mike Walne
Joined: 19 Feb 2004 Posts: 1785 Location: Boston Spa UK
|
|
Posted: Fri Dec 07, 2012 2:51 am |
|
|
Reduce your code to the minimum which shows the problem.
It will then be a lot easier for either you, or us, to see what's going on.
Mike |
|
|
Tak
Joined: 22 Apr 2012 Posts: 6
|
|
Posted: Fri Dec 07, 2012 3:13 am |
|
|
problem's inside timer isr. When Fifo_lock = 1, the read_adc() got a little higher value (191 and normal it's 185). before that i disable and re-enable timer interrupt.
Code: |
////////////////////////////////////////////////////////////////////
/////////////////////////////////////
else if (buffer_size<96)
{
circle_buffer[buffer_write_pointer] = read_adc();
printf("%u\n",circle_buffer[buffer_write_pointer]);
buffer_size++;
if (buffer_write_pointer==95)
buffer_write_pointer = 0;
else
buffer_write_pointer++;
}
///////////////////////////////////
////////////////////////////////////////////////////////////////////
|
|
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9245 Location: Greensville,Ontario
|
|
Posted: Fri Dec 07, 2012 8:40 am |
|
|
couple of comments
1) always add 'errors' to the USE RS232(...) options when using the hardware UART for serial communications.It'll keep the UART from 'locking up' due to errors like overrun...
2) Putting printf() functions inside any ISR is NOT a good idea! ISRs must be short and fast.
Take a look at the ex_sisr.c example that CCS supplies.Several 'hints' in it tto help you along.
3) re:ADC. Be sure your power supply is rock stable! ANY minor 'ripple','glitch',etc. in VDD will result in an ADC 'misreading' as Vref is the Vdd.Having a separate Vref will eliminate the problem,but at a small cost in parts and layout.Also be sure to use bypass caps! Again, a 'glitch'(a current rush,say when displaying data on the LCD) can cause what appears as a bad ADC reading
hth
jay |
|
|
Tak
Joined: 22 Apr 2012 Posts: 6
|
|
Posted: Fri Dec 07, 2012 6:40 pm |
|
|
That's right. I used 5V source from FT232RL. Normally it's good but when mrf24j40MB module transmits, a large current sinks. ADC got after 10 or maybe 15ms will be unstable 'cause RF will restransmit if ack was not received. When I changed power supply to 500mA source with regulator, it worked.
printf's only for reliable test ....
Thank you very much, Temtronic |
|
|
|
|
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
|