реклама на сайте
подробности

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> Не переключаются каналы АЦП, AtMega8535
OlegALL
сообщение Feb 17 2014, 19:45
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 70
Регистрация: 30-11-10
Пользователь №: 61 275



Привет.
Проблема: измеряю напряжение с АЦП - контроллер Mega8535. Использую 2 канала (пока). По 1-му каналу считывается ок, по 2-му - ощущение, что 1-й канал влияет на 2-й, потому что при изменении напряжения на 1-м канале напряжение на 2-м такое же минус вольт. Отдельно по каналам меряет корректно. Скорее всего у меня ошибка с переключением каналов. Делаю вроде всё по даташиту - меняю регистр ADMUX до старта преобразования (бит ADSC). Помогите? Что делаю не так? Пока кода нет, пришлю завтра.
Go to the top of the page
 
+Quote Post
coolbassnik
сообщение Feb 17 2014, 20:31
Сообщение #2


Участник
*

Группа: Участник
Сообщений: 62
Регистрация: 22-10-10
Из: Украина
Пользователь №: 60 348



Думаю тут кроме кода еще и схему нужно видеть
Go to the top of the page
 
+Quote Post
OlegALL
сообщение Feb 18 2014, 04:17
Сообщение #3


Участник
*

Группа: Участник
Сообщений: 70
Регистрация: 30-11-10
Пользователь №: 61 275



Код ниже. Извините, не знаю как форматировать здесь
CODE
#include "main.h"

volatile unsigned int send_flag = 0;

void init(){

// Порт A
DDRA &= ~(1<<DDA0 | 1<<DDA1 | 1<<DDA2 | 1<<DDA3);
PORTA &= ~(1<<PA0 | 1<<PA1 | 1<<PA2 | 1<<PA3);
// Порт B
DDRB |= (1<<DDB0) | (1<<DDB1);
// Порт D
DDRD &= ~(1<<DDD0);
DDRD |= (1<<DDD1) | (1<<DDD2) | (1<<DDD7); // ????? 7 - ????????

//ADCSRA |= 1<<ADEN | 1<<ADIE | 1<<ADSC | 1<<ADPS0 | 1<<ADPS1 | 1<<ADPS2;
// ?????????? ?????? ? ????????? ??????????????, ????????? ??????? (????????) ???


// UART
UBRRH = 0;
UBRRL = 15; // 57600
UCSRB |= (1<<RXEN) | (1<<RXCIE) | (1<<TXEN); // ????????? ?????????? ?? ?????? ? ????????

// ADC
ADCSRA |= 1<<ADEN | 1<<ADIE | 1<<ADPS0 | 1<<ADPS1 | 1<<ADPS2;
ADMUX |= REFS0;


request[0] = 0; // ???????: 0x3A 0x01 0x00 0x3B
request[1] = 0;
request[2] = 0;
request[3] = 0;

// Dir_1 // Dir_1 // Dir_1 // Dir_1 // Dir_2 // Dir_2 // Dir_2
// Ain_0 // Ain_1 // Ain_2 // Ain_3 // Ain_0 // Ain_1 // Ain_2
//answer = {REQUEST_START, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};

answer[0] = REQUEST_START;
// Dir_1 Ain_0
answer[1] = 0;
answer[2] = 0;
answer[3] = 0;
answer[4] = 0;
// Dir_1 Ain_1
answer[5] = 0;
answer[6] = 0;
answer[7] = 0;
answer[8] = 0;
// Dir_1 Ain_2
answer[9] = 0;
answer[10] = 0;
answer[11] = 0;
answer[12] = 0;
// Dir_1 Ain_3
answer[13] = 0;
answer[14] = 0;
answer[15] = 0;
answer[16] = 0;
// Dir_2 Ain_0
answer[17] = 0;
answer[18] = 0;
answer[19] = 0;
answer[20] = 0;
// Dir_2 Ain_1
answer[21] = 0;
answer[22] = 0;
answer[23] = 0;
answer[24] = 0;
// Dir_2 Ain_2
answer[25] = 0;
answer[26] = 0;
answer[27] = 0;
answer[28] = 0;


//flags.send_answer = 0;

rx_stage = 0;
flag_Dir__Ain = 0;
//flags.ADC_converts = 0;

// Разрешили все прерывания:
SREG |= 0b10000000; // ???
}

ISR(USART_RX_vect){
/*
unsigned char a = UDR;
if (rx_stage == 2)
{
PORTD = 1<<PD7;
}
rx_stage++;
*/

switch (rx_stage){
case WAITING_START:
if (UDR == REQUEST_START){
request[rx_stage] = UDR;
rx_stage++;

}
break;

case WAITING_COMMAND:
request[rx_stage] = UDR;
rx_stage++;

break;

case WAITING_LRC_HIGH:
request_lrc.byte.high = UDR;
rx_stage++;

break;

case WAITING_LRC_LOW:
request_lrc.byte.low = UDR;
rx_stage = 0;

//flags.send_answer = 1;
send_flag = 1;

break;

//default:
// rx_stage = 0;
//break;

}

}

ISR(ADC_vect)
{
cli();
flags.ADC_converts = 0;

unsigned char byte_ADCL = ADCL;
unsigned char byte_ADCH = ADCH;
unsigned int uint_adch = (byte_ADCH << 8) | byte_ADCL;
v_in.as_float = ((float)(VREF * uint_adch))/1024;


/*
unsigned char byte_ADCL = 0;
unsigned char byte_ADCH = 0;
unsigned int uint_adch = 0;
*/


if (flag_Dir__Ain == Dir_1__Ain0)
{

/*

ADMUX &= ~(1<<MUX0 | 1<<MUX1 | 1<<MUX2 | 1<<MUX3 | 1<<MUX4);
byte_ADCL = ADCL;
byte_ADCH = ADCH;
uint_adch = (byte_ADCH << 8) | byte_ADCL;
v_in.as_float = ((float)(VREF * uint_adch))/1024;
*/


answer[1] = v_in.byte.first_high;
answer[2] = v_in.byte.second;
answer[3] = v_in.byte.third;
answer[4] = v_in.byte.fourth_low;
}
else
if (flag_Dir__Ain == Dir_1__Ain1)
{
PORTD = 1<<PD7;
/*
ADMUX |= 1<<MUX0;
ADMUX &= ~(1<<MUX1 | 1<<MUX2 | 1<<MUX3 | 1<<MUX4);

byte_ADCL = ADCL;
byte_ADCH = ADCH;
uint_adch = (byte_ADCH << 8) | byte_ADCL;
v_in.as_float = ((float)(VREF * uint_adch))/1024;
*/
answer[5] = v_in.byte.first_high;
answer[6] = v_in.byte.second;
answer[7] = v_in.byte.third;
answer[8] = v_in.byte.fourth_low;
}
else
if (flag_Dir__Ain == Dir_1__Ain2)
{
answer[9] = v_in.byte.first_high;
answer[10] = v_in.byte.second;
answer[11] = v_in.byte.third;
answer[12] = v_in.byte.fourth_low;
}
//ADCSRA &= ~(1<<ADEN); // !!!!!!!!!!!!!!
sei();
}

int main (void){

init();

while (1){
// Зондирование Dir_1, измерение Ain_0
flag_Dir__Ain = Dir_1__Ain0;
set__in0_in1_in2_in3(OUTPUT_HIGH);
form_impulse(DIR_1);
set__in0_in1_in2_in3(INPUT);
_delay_us(16);
get_ADC_value(AIN_0);
_delay_ms(10);


flag_Dir__Ain = Dir_1__Ain1;
set__in0_in1_in2_in3(OUTPUT_HIGH);
form_impulse(DIR_1);
set__in0_in1_in2_in3(INPUT);
_delay_us(16);
get_ADC_value(AIN_1);
_delay_ms(10);

if (send_flag == 1){

PORTD |= 1<<PD2; // En = 1
_delay_ms(1);
send_answer();
_delay_ms(1);
PORTD &= ~(1<<PD2); // En = 0
flags.send_answer = 0;
send_flag = 0;
}

}
}



void set__in0_in1_in2_in3(unsigned char level)
{
if (level == INPUT)
{
DDRC &= ~(1<<DDC0 | 1<<DDC1 | 1<<DDC2 | 1<<DDC3);
PORTC &= ~(1<<PC0 | 1<<PC1 | 1<<PC2 | 1<<PC3);
}
else
if (level == OUTPUT_HIGH)
{
DDRC |= (1<<DDC0) | (1<<DDC1) | (1<<DDC2) | (1<<DDC3);
PORTC &= ~(1<<PC0) | (1<<PC1) | (1<<PC2) | (1<<PC3);
}
}

void get_ADC_value(unsigned char line)
{

//flags.ADC_converts = 1;
if (line == AIN_0)
{
ADMUX &= ~(1<<MUX0 | 1<<MUX1 | 1<<MUX2 | 1<<MUX3 | 1<<MUX4);
}
else
if (line == AIN_1)
{
ADMUX |= 1<<MUX0;
ADMUX &= ~(1<<MUX1 | 1<<MUX2 | 1<<MUX3 | 1<<MUX4);
//ADMUX &= 0b11100001;
}
else
if (line == AIN_2)
{
ADMUX |= 1<<MUX1;
ADMUX &= ~(1<<MUX0 | 1<<MUX2 | 1<<MUX3 | 1<<MUX4);
}
else
if (line == AIN_3)
{
ADMUX |= 1<<MUX1 | 1<<MUX0;
ADMUX &= ~(1<<MUX2 | 1<<MUX3 | 1<<MUX4);
}

//ADCSRA |= 1<<ADEN | 1<<ADIE | 1<<ADSC | 1<<ADPS0 | 1<<ADPS1 | 1<<ADPS2;
ADCSRA |= 1<<ADSC;

}



void send_byte(unsigned char data){
while(!(UCSRA & (1<<UDRE)));
UDR = data;
while(!(UCSRA & (1<<UDRE)));
}

void send_answer() {
for (unsigned char j = 0; j < 31; j++){
while(!(UCSRA & (1<<UDRE)));
UDR = answer[j];
while(!(UCSRA & (1<<UDRE)));
}
}


void form_impulse(unsigned char line){
if (line == DIR_1)
{
PORTB |= (1<<PB0);
_delay_us(10);
PORTB &= ~(1<<PB0);
}
else
if (line == DIR_2)
{
PORTB |= (1<<PB1);
_delay_us(10);
PORTB &= ~(1<<PB1);
}
}



void debug(){
PORTC |= 1<<PC4;
for (unsigned long k = 0; k < 100000; k++){
asm("nop");
}
PORTC &= ~(1<<PC4);
}


Сообщение отредактировал IgorKossak - Feb 18 2014, 08:58
Причина редактирования: [codebox] для длинного кода, [code] - для короткого!!!
Go to the top of the page
 
+Quote Post
smalcom
сообщение Feb 18 2014, 06:16
Сообщение #4


Профессионал
*****

Группа: Свой
Сообщений: 1 292
Регистрация: 26-06-07
Пользователь №: 28 718



Код
ISR(ADC_vect)
{
cli();

в запрещении прерываний нет необходимости.

для ожидания конца цикла измерения используется delay... что не гут вообще и это потенциально "гоночный" код.
также не видно всё ли, что в прерываниях с модификатором volatile.

теперь можно и схему глянуть.
Go to the top of the page
 
+Quote Post
OlegALL
сообщение Feb 18 2014, 07:19
Сообщение #5


Участник
*

Группа: Участник
Сообщений: 70
Регистрация: 30-11-10
Пользователь №: 61 275



Переделал код попроще, без прерываний. Со схемой проблемы, могу только сказать, что точно на входе Канала 1 осциллографом наблюдается 0, а выводится такое же напряжение, как у 1 канала, только меньше на вольт. По коду всё нормально?

CODE
#include "main.h"

volatile unsigned int send_flag = 0;

void init(){

// Порт A
DDRA &= ~(1<<DDA0 | 1<<DDA1 | 1<<DDA2 | 1<<DDA3);
PORTA &= ~(1<<PA0 | 1<<PA1 | 1<<PA2 | 1<<PA3);
// Порт B
DDRB |= (1<<DDB0) | (1<<DDB1);
// Порт D
DDRD &= ~(1<<DDD0);
DDRD |= (1<<DDD1) | (1<<DDD2) | (1<<DDD7); // ????? 7 - ????????

//ADCSRA |= 1<<ADEN | 1<<ADIE | 1<<ADSC | 1<<ADPS0 | 1<<ADPS1 | 1<<ADPS2;
// ?????????? ?????? ? ????????? ??????????????, ????????? ??????? (????????) ???


// UART
UBRRH = 0;
UBRRL = 15; // 57600
UCSRB |= (1<<RXEN) | (1<<RXCIE) | (1<<TXEN); // ????????? ?????????? ?? ?????? ? ????????

// ADC
ADCSRA |= 1<<ADEN | /*1<<ADIE |*/ 1<<ADPS0 | 1<<ADPS1 | 1<<ADPS2;
ADMUX |= (1<<REFS0);


request[0] = 0; // ???????: 0x3A 0x01 0x00 0x3B
request[1] = 0;
request[2] = 0;
request[3] = 0;

// Dir_1 // Dir_1 // Dir_1 // Dir_1 // Dir_2 // Dir_2 // Dir_2
// Ain_0 // Ain_1 // Ain_2 // Ain_3 // Ain_0 // Ain_1 // Ain_2
//answer = {REQUEST_START, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};

answer[0] = REQUEST_START;
// Dir_1 Ain_0
answer[1] = 0;
answer[2] = 0;
answer[3] = 0;
answer[4] = 0;
// Dir_1 Ain_1
answer[5] = 0;
answer[6] = 0;
answer[7] = 0;
answer[8] = 0;
// Dir_1 Ain_2
answer[9] = 0;
answer[10] = 0;
answer[11] = 0;
answer[12] = 0;
// Dir_1 Ain_3
answer[13] = 0;
answer[14] = 0;
answer[15] = 0;
answer[16] = 0;
// Dir_2 Ain_0
answer[17] = 0;
answer[18] = 0;
answer[19] = 0;
answer[20] = 0;
// Dir_2 Ain_1
answer[21] = 0;
answer[22] = 0;
answer[23] = 0;
answer[24] = 0;
// Dir_2 Ain_2
answer[25] = 0;
answer[26] = 0;
answer[27] = 0;
answer[28] = 0;


//flags.send_answer = 0;

rx_stage = 0;
flag_Dir__Ain = 0;
//flags.ADC_converts = 0;

// Разрешили все прерывания:
SREG |= 0b10000000; // ???

_delay_us(500);
}

ISR(USART_RX_vect){
/*
unsigned char a = UDR;
if (rx_stage == 2)
{
PORTD = 1<<PD7;
}
rx_stage++;
*/

switch (rx_stage){
case WAITING_START:
if (UDR == REQUEST_START){
request[rx_stage] = UDR;
rx_stage++;

}
break;

case WAITING_COMMAND:
request[rx_stage] = UDR;
rx_stage++;

break;

case WAITING_LRC_HIGH:
request_lrc.byte.high = UDR;
rx_stage++;

break;

case WAITING_LRC_LOW:
request_lrc.byte.low = UDR;
rx_stage = 0;

//flags.send_answer = 1;
send_flag = 1;

break;

//default:
// rx_stage = 0;
//break;

}

}

ISR(ADC_vect)
{


}

int main (void){

init();

while (1){
// Зондирование Dir_1, измерение Ain_0

flag_Dir__Ain = Dir_1__Ain0;
set__in0_in1_in2_in3(OUTPUT_HIGH);
form_impulse(DIR_1);
set__in0_in1_in2_in3(INPUT);
_delay_us(16);
get_ADC_value(AIN_0);
//DDRA |= (1<<DDA0 | 1<<DDA1 | 1<<DDA2 | 1<<DDA3);
//PORTA &= ~(1<<PA0 | 1<<PA1 | 1<<PA2 | 1<<PA3);
_delay_ms(10);

flag_Dir__Ain = Dir_1__Ain1;
set__in0_in1_in2_in3(OUTPUT_HIGH);
form_impulse(DIR_1);
set__in0_in1_in2_in3(INPUT);
_delay_us(16);

get_ADC_value(AIN_1);

//DDRA |= (1<<DDA0 | 1<<DDA1 | 1<<DDA2 | 1<<DDA3);
//PORTA &= ~(1<<PA0 | 1<<PA1 | 1<<PA2 | 1<<PA3);
_delay_ms(10);




if (send_flag == 1){

PORTD |= 1<<PD2; // En = 1
_delay_ms(1);
send_answer();
_delay_ms(1);
PORTD &= ~(1<<PD2); // En = 0
flags.send_answer = 0;
send_flag = 0;
}

}
}



void set__in0_in1_in2_in3(unsigned char level)
{
if (level == INPUT)
{
DDRC &= ~(1<<DDC0 | 1<<DDC1 | 1<<DDC2 | 1<<DDC3);
PORTC &= ~(1<<PC0 | 1<<PC1 | 1<<PC2 | 1<<PC3);
}
else
if (level == OUTPUT_HIGH)
{
DDRC |= (1<<DDC0) | (1<<DDC1) | (1<<DDC2) | (1<<DDC3);
PORTC &= ~(1<<PC0) | (1<<PC1) | (1<<PC2) | (1<<PC3);
}
}

void get_ADC_value(unsigned char line)
{
//ADCSRA |= 1<<ADEN;
//flags.ADC_converts = 1;
if (line == AIN_0)
{
ADMUX &= ~(1<<MUX0 | 1<<MUX1 | 1<<MUX2 | 1<<MUX3 | 1<<MUX4);
}
else
if (line == AIN_1)
{
ADMUX |= 1<<MUX0;
ADMUX &= ~(1<<MUX1 | 1<<MUX2 | 1<<MUX3 | 1<<MUX4);
//ADMUX &= 0b11100001;
}
else
if (line == AIN_2)
{
ADMUX |= 1<<MUX1;
ADMUX &= ~(1<<MUX0 | 1<<MUX2 | 1<<MUX3 | 1<<MUX4);
}
else
if (line == AIN_3)
{
ADMUX |= 1<<MUX1 | 1<<MUX0;
ADMUX &= ~(1<<MUX2 | 1<<MUX3 | 1<<MUX4);
}


_delay_us(10);
//ADCSRA |= 1<<ADEN | 1<<ADIE | 1<<ADSC | 1<<ADPS0 | 1<<ADPS1 | 1<<ADPS2;
ADCSRA |= 1<<ADSC;
//_delay_ms(10);
while (!(ADCSRA & (1<<ADIF)));


unsigned char byte_ADCL = ADCL;
unsigned char byte_ADCH = ADCH;
unsigned int uint_adch = (byte_ADCH << 8) | byte_ADCL;
v_in.as_float = ((float)(VREF * uint_adch))/1024;
if (flag_Dir__Ain == Dir_1__Ain0)
{
answer[1] = v_in.byte.first_high;
answer[2] = v_in.byte.second;
answer[3] = v_in.byte.third;
answer[4] = v_in.byte.fourth_low;
}
else
if (flag_Dir__Ain == Dir_1__Ain1)
{
PORTD = 1<<PD7;
answer[5] = v_in.byte.first_high;
answer[6] = v_in.byte.second;
answer[7] = v_in.byte.third;
answer[8] = v_in.byte.fourth_low;
}
else
if (flag_Dir__Ain == Dir_1__Ain2)
{
answer[9] = v_in.byte.first_high;
answer[10] = v_in.byte.second;
answer[11] = v_in.byte.third;
answer[12] = v_in.byte.fourth_low;
}
//ADCL = 0;
//ADCH = 0;
//ADCSRA &= ~(1<<ADEN);
}



void send_byte(unsigned char data){
while(!(UCSRA & (1<<UDRE)));
UDR = data;
while(!(UCSRA & (1<<UDRE)));
}

void send_answer() {
for (unsigned char j = 0; j < 31; j++){
while(!(UCSRA & (1<<UDRE)));
UDR = answer[j];
while(!(UCSRA & (1<<UDRE)));
}
}


void form_impulse(unsigned char line){
if (line == DIR_1)
{
PORTB |= (1<<PB0);
_delay_us(10);
PORTB &= ~(1<<PB0);
}
else
if (line == DIR_2)
{
PORTB |= (1<<PB1);
_delay_us(10);
PORTB &= ~(1<<PB1);
}
}



void debug(){
PORTC |= 1<<PC4;
for (unsigned long k = 0; k < 100000; k++){
asm("nop");
}
PORTC &= ~(1<<PC4);
}


Сообщение отредактировал IgorKossak - Feb 18 2014, 08:59
Причина редактирования: [codebox] для длинного кода, [code] - для короткого!!!
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Feb 18 2014, 10:20
Сообщение #6


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(OlegALL @ Feb 18 2014, 09:19) *
могу только сказать, что точно на входе Канала 1 осциллографом наблюдается 0, а выводится такое же напряжение, как у 1 канала, только меньше на вольт

Осциллограф не показатель. Вы на нем можете и не заметить выбросы в момент заряда емкости УВХ, если не будете специально искать. Откуда берется сигнал на вход канала 1? Если совсем в лоб: какое выходное сопротивление у источника сигнала канала 1? Какая емкость висит на входе AREF?
Цитата(OlegALL @ Feb 18 2014, 09:19) *
По коду всё нормально?

Вот зачем вы делаете так?
Код
ADCSRA |= 1<<ADEN | /*1<<ADIE |*/ 1<<ADPS0 | 1<<ADPS1 | 1<<ADPS2;

Что вам мешает написать тут просто '='? Вы сэкономите команду, такт и будете точно уверены, что в остальных битах окажется ноль. А не то, что оставила там предыдущая часть программы.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
OlegALL
сообщение Feb 18 2014, 16:13
Сообщение #7


Участник
*

Группа: Участник
Сообщений: 70
Регистрация: 30-11-10
Пользователь №: 61 275



Цитата(Сергей Борщ @ Feb 18 2014, 13:20) *
Осциллограф не показатель. Вы на нем можете и не заметить выбросы в момент заряда емкости УВХ, если не будете специально искать. Откуда берется сигнал на вход канала 1? Если совсем в лоб: какое выходное сопротивление у источника сигнала канала 1? Какая емкость висит на входе AREF?

Вот зачем вы делаете так?
Код
ADCSRA |= 1<<ADEN | /*1<<ADIE |*/ 1<<ADPS0 | 1<<ADPS1 | 1<<ADPS2;

Что вам мешает написать тут просто '='? Вы сэкономите команду, такт и будете точно уверены, что в остальных битах окажется ноль. А не то, что оставила там предыдущая часть программы.


На вопросы по схемотехнике ответов не знаю, плохо разбираюсь, завтра спрошу. Пока схема:

http://yadi.sk/d/SKpjyairJ8nVf

Очень жду помощи, если за завтра не сделаю, будет мне очень плохо. Сейчас политинформация: опрашиваю каналы АЦП раз в секунду, ситуация получше но тоже есть вроде влияние каналов. Завтра напишу точнее

Сообщение отредактировал IgorKossak - Feb 21 2014, 08:31
Причина редактирования: удаление схемы по просьбе пользователя
Go to the top of the page
 
+Quote Post
smalcom
сообщение Feb 18 2014, 21:39
Сообщение #8


Профессионал
*****

Группа: Свой
Сообщений: 1 292
Регистрация: 26-06-07
Пользователь №: 28 718



Забавно, поисковики не знают, что это за ОУ - 432УД8.
Первое предположение: отвален один из полюсов питания ОУ.
И вопрос на всякий случай - вы же в курсе, что "оно" постоянку не пропускает?
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Feb 19 2014, 07:04
Сообщение #9


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(OlegALL @ Feb 18 2014, 18:13) *
Пока схема:
Ой.

Ну вот смотрите сами:
Допустим у вас на Ain0 будет 1 вольт. Конденсатор УВХ зарядится до этого самого 1 вольта.
Потом вы переключаете на Ain1, на выходе DA4 у вас ноль вольт. И каким образом конденсатор УВХ должен разрядиться, током утечки диода D7?

Повесьте с катодов D6, D7 на землю резисторы 1...10К. Не зря же в даташите пишут - максимальное выходное сопротивление источника сигнала для АЦП - не более 10К. У вас же для вытекающего тока сопротивление почти бесконечно, отсюда все проблемы.

P.S. А чтобы не смотреть на подобные вещи как на чудеса, найдите в гугле и прочитайте от начала и до конца книгу Уолта Кестера "Аналого-Цифровое преобразование". Найдете там очень много интересного и полезного. Читается легко буквально за пару вечеров.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
OlegALL
сообщение Feb 19 2014, 09:13
Сообщение #10


Участник
*

Группа: Участник
Сообщений: 70
Регистрация: 30-11-10
Пользователь №: 61 275



Спасибо. Хотите сказать, между Ain0...Ain4 и землёй сопротивление > 10кОм?

Намерял 9 МОм

Сообщение отредактировал OlegALL - Feb 19 2014, 09:40
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Feb 19 2014, 10:57
Сообщение #11


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(OlegALL @ Feb 19 2014, 11:13) *
Спасибо. Хотите сказать, между Ain0...Ain4 и землёй сопротивление > 10кОм?
Вы все же книжку почитайте. Вы измерили входное сопротивление АЦП. Оно большое, да. А даташит требует от вас обеспечить сопротивление источника сигнала не более 10К в режиме без внутреннего усилителя и несколько сот кОм с использованием внутреннего усилителя. Потому что большее сопротивление не сможет обеспечить перезарядку накопительного конденсатора УВХ до напряжения источника сигнала с погрешностью не более единицы младшего значащего разряда (LSB) за время выборки. У вас же сопротивление практически бесконечно и конденсатору физически некуда разряжаться. Посмотрите картинку 105 в даташите.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
OlegALL
сообщение Feb 19 2014, 11:04
Сообщение #12


Участник
*

Группа: Участник
Сообщений: 70
Регистрация: 30-11-10
Пользователь №: 61 275



Что-то схемотехник поделал с платой и ситуация стала лучше. Например: меряю адекватные 3 вольта на 0-м канале. На 1-м: 2В (должно быть 0), на 2-м и 3-м каналах - 0В. То есть влияние есть только на соседний канал в сторону увеличения. На других каналах всё ок. И посмотрите код - алгоритмически всё правильно?
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Feb 19 2014, 11:30
Сообщение #13


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(OlegALL @ Feb 19 2014, 13:04) *
Что-то схемотехник поделал с платой и ситуация стала лучше.
Попросите его припаять по одному резистору 10К с катодов D6 и D7 на землю. Проблема уйдет. И посоветуйте ему ту книжку тоже.
Цитата(OlegALL @ Feb 19 2014, 13:04) *
И посмотрите код - алгоритмически всё правильно?
На первый взгляд ляпов в части измерения не видно.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
OlegALL
сообщение Feb 20 2014, 06:04
Сообщение #14


Участник
*

Группа: Участник
Сообщений: 70
Регистрация: 30-11-10
Пользователь №: 61 275



Спасибо! Между какими 2-мя точками на схеме мне померять сопротивление, которое не больше 10кОм? Он меня слушать не хочет, говорит прав
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Feb 20 2014, 08:30
Сообщение #15


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(OlegALL @ Feb 20 2014, 08:04) *
Спасибо! Между какими 2-мя точками на схеме мне померять сопротивление, которое не больше 10кОм?
Между катодом D7 и землей. Потом между катодом D6 и землей. Причем плюсовой щуп мультиметра должен быть на катоде (вы будете измерять сопротивление для вытекающего тока).

Цитата(OlegALL @ Feb 20 2014, 08:04) *
Он меня слушать не хочет, говорит прав
Тяжелый случай. Дайте ему учебник теории цепей, пусть почитает, что такое "выходное сопротивление". А просто припаять резистор и проверить на практике он тоже отказывается? В этом случае наука бессильна...


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post

2 страниц V   1 2 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 18th July 2025 - 11:54
Рейтинг@Mail.ru


Страница сгенерированна за 0.01613 секунд с 7
ELECTRONIX ©2004-2016