OlegALL (17.02.2014 23:44 - 19.02.2014 08:53, просмотров: 24096)
Проблема: измеряю напряжение с АЦП - контроллер Mega8535. Использую 2 канала (пока). По 1-му каналу считывается ок, по 2-му - ощущение, что 1-й канал влияет на 2-й, потому что при изменении напряжения на 1-м канале напряжение на 2-м такое же минус вольт. Отдельно по каналам меряет корректно. Скорее всего у меня ошибка с переключением каналов. Делаю вроде всё по даташиту - меняю регистр ADMUX до старта преобразования (бит ADSC). Помогите? Что делаю не так?
Исправил код
#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);
//ADCSRA &= ~(1<<ADEN);
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;
}
}
int main (void){
init();
while (1){
// Зондирование Dir_1, измерение Ain_0
if (request[1] == 0x01)
{
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);
//send_flag = 1;
request[1] = 0x00;
}
if (request[1] == 0x02)
{
PORTD = 1<<PD7;
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);
//send_flag = 1;
request[1] = 0x00;
}
if (request[1] == 0x03)
{
flag_Dir__Ain = Dir_1__Ain2;
set__in0_in1_in2_in3(OUTPUT_HIGH);
form_impulse(DIR_1);
set__in0_in1_in2_in3(INPUT);
_delay_us(16);
get_ADC_value(AIN_2);
_delay_ms(10);
//send_flag = 1;
request[1] = 0x00;
}
if (request[1] == 0x04)
{
flag_Dir__Ain = Dir_1__Ain3;
set__in0_in1_in2_in3(OUTPUT_HIGH);
form_impulse(DIR_1);
set__in0_in1_in2_in3(INPUT);
_delay_us(16);
get_ADC_value(AIN_3);
_delay_ms(10);
//send_flag = 1;
request[1] = 0x00;
}
if ((send_flag == 1) && (request[1] == 0x00)){
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;
//ADCSRA &= ~(1<<ADEN);
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);
ADCSRA |= 1<<ADSC;
_delay_us(10);
//ADCSRA |= 1<<ADEN | 1<<ADIE | 1<<ADSC | 1<<ADPS0 | 1<<ADPS1 | 1<<ADPS2;
//ADCSRA |= 1<<ADEN;
//_delay_us(500);
//_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)
{
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;
}
else
if (flag_Dir__Ain == Dir_1__Ain3)
{
answer[13] = v_in.byte.first_high;
answer[14] = v_in.byte.second;
answer[15] = v_in.byte.third;
answer[16] = 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);
}