Подключение двух каналов АЦП

Модератор: boogyman

Re: Подключение двух каналов АЦП

Сообщение:#21  Сообщение Sergey F » 21 дек 2014, 15:12

AntonChip писал(а):Эти строчки я бы убрал до while(1)
Код: Выделить всё
lcd_string(0x80, "    VOLTAGE     ");
lcd_string(0xC0, "      ,  V      ");


Убрал эти строчки до while(1) - все то же самое, нет даже надписи " VOLTAGE " и " , V ".
Далее убрал все, что связано с АЦП и надписи появились. Что это значит? АЦП влияет на LCD?
Контроллер использую ATMEGA8L-8PU.
Аватара пользователя
Sergey F
Любитель
 
Сообщения: 13
Зарегистрирован: 13 мар 2014, 14:33
ТегиAtmega8, вольтметр, АЦП

Re: Подключение двух каналов АЦП

Сообщение:#22  Сообщение AntonChip » 21 дек 2014, 17:17

Если так
Код: Выделить всё
if(adc_counter > 300) // вычисляем среднее значение АЦП
{
display = value/adc_counter;
lcd_com(0xC5);
lcd_num_to_str(display/1000, 1); // Выводим на экран целое значение
lcd_com(0xC7);
lcd_num_to_str(display/100, 1); // Выводим на экран значение после запятой
lcd_com(0xC8);
lcd_num_to_str(display/10, 1);
adc_counter = 0;
value = 0;
}
Аватара пользователя
AntonChip
Администратор
 
Сообщения: 190
Зарегистрирован: 24 дек 2011, 21:11
Откуда: Киров

Re: Подключение двух каналов АЦП

Сообщение:#23  Сообщение Sergey F » 21 дек 2014, 18:14

AntonChip писал(а):Если так
Код: Выделить всё
if(adc_counter > 300) // вычисляем среднее значение АЦП
{
display = value/adc_counter;
lcd_com(0xC5);
lcd_num_to_str(display/1000, 1); // Выводим на экран целое значение
lcd_com(0xC7);
lcd_num_to_str(display/100, 1); // Выводим на экран значение после запятой
lcd_com(0xC8);
lcd_num_to_str(display/10, 1);
adc_counter = 0;
value = 0;
}


Не помогает. Если все убрать с while даже нет надписей "VOLTAGE" и " , V ", которые должны появиться.
Если запретить прерывание ADCSRA = |(0 << ADIE); надписи появляются, но конечно напряжение не измеряет.
Так получается, что прерывание мешает индикации?
Аватара пользователя
Sergey F
Любитель
 
Сообщения: 13
Зарегистрирован: 13 мар 2014, 14:33

Re: Подключение двух каналов АЦП

Сообщение:#24  Сообщение yarik1111 » 28 апр 2015, 19:20

Вот у меня работает термометр и потом через 2 сек вольтметр, только вольтметр постоянно показывает 28,1. В чем причина?
Код: Выделить всё
#define F_CPU 8000000 // устанавливаем рабочую частоту контроллера
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>

//-------------------0-----1------2-------3------4------5-----6-------7-----8------9----
char SEGMENTE[] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F,
//------------------dp---minus-blank---t------о------E------r-----U---
                      0x80, 0x40, 0x00, 0x78, 0x63, 0x79, 0x50, 0x3E};


volatile unsigned char segcounter = 0;
volatile int display1 = 0, display2 = 0, display3 = 0, display4 = 0;//разряды

/*** Прерывание по переполнению T2, динамическая индикация ***/

ISR (TIMER2_OVF_vect)
{
PORTD = 0x00;
PORTB = ~(1 << segcounter);

switch (segcounter)
{
case 0:
PORTD = (SEGMENTE[display1]);
break;
case 1:
PORTD = ((SEGMENTE[display2])|0x80);
break;
case 2:
PORTD = (SEGMENTE[display3]);
break;
case 3:
PORTD = (SEGMENTE[display4]);
break;
}
if ((segcounter++) > 2) segcounter = 0;
}

volatile unsigned long value;
volatile unsigned int adc_counter;
unsigned char Temp_H = 0,Temp_L = 0,OK_Flag = 0,temp_flag;

/*** Инициализация DS18B20 ***/
unsigned char DS18B20_init(void)
{
PORTC &= ~(1 << PC1); // устанавливаем низкий уровень
DDRC |= (1 << PC1);
_delay_us(490);
DDRC &= ~(1 << PC1);
_delay_us(68);
OK_Flag = (PINC & (1 << PC1)); // ловим импульс присутствия датчика
// если OK_Flag = 0 датчик подключен, OK_Flag = 1 датчик не подключен
_delay_us(422);
return OK_Flag;
}

/*** Функция чтения байта из DS18B20 ***/
unsigned char read_18b20(void)
{
unsigned char i;
unsigned char dat = 0;
for(i = 0;i < 8;i++)
{
DDRC |= (1 << PC1);
_delay_us(2);
DDRC &= ~(1 << PC1);
_delay_us(4);
dat = dat >> 1;
if(PINC & (1 << PC1))
{
dat |= 0x80;
}
_delay_us(62);
}
return dat;
}

/*** функция записи байта в DS18B20 ***/
void write_18b20(unsigned char dat)
{
unsigned char i;
for(i = 0;i < 8;i++)
{
DDRC |= (1 << PC1);
_delay_us(2);
if(dat & 0x01)
{
DDRC &= ~(1 << PC1);
}
else
{
DDRC |= (1 << PC1);
}
dat = dat >> 1;
_delay_us(62);
DDRC &= ~(1 << PC1);
_delay_us(2);
}
}



// Прерывание по окончанию преобразования АЦП


ISR (ADC_vect)
{
 value = value + (ADC*11/4); // Суммируем старое и новое значения АЦП, преобразуем
 adc_counter++; // Увеличиваем счетчик измерений
}


/*** Главная функция ***/
int main(void)
{
   DDRD = 0xFF;
   DDRB = 0xFF;//DDRB |= (1 << PB0)|(1 << PB1)|(1 << PB2)|(1 << PB3);
   PORTD = 0x00;
   PORTB = 0x00;




TIMSK |= (1 << TOIE2); // разрешение прерывания по таймеру2
TCCR2 |= (0 << CS22) | (1 << CS21) | (0 << CS20); // предделитель на 8

// Настройка АЦП
ADCSRA |= (1 << ADEN) // Разрешение АЦП
|(1 << ADSC) // Запуск преобразования
|(1 << ADFR) // Непрерывный режим работы АЦП
|(1 << ADPS2)|(1 << ADPS1) // Предделитель на 64 (частота АЦП 125kHz)
|(1 << ADIE); // Разрешение прерывания от АЦП
ADMUX |= (0 << REFS1)|(0 << REFS0); // Внешний ИОН 2,56V, вход ADC0


_delay_ms(50);


unsigned int tempint = 0,tempint1,tempint2,tempint3; // переменные для целого значения температуры
unsigned int temppoint = 0,temppoint1; // переменные для дробного значения температуры
unsigned int voltintA = 0,voltintA1,voltintA2,voltintA3;//переменные для вольтметра
sei(); //глобально разрешаем прерывания

while(1)

{
    if(adc_counter >300) // Если количество измерений больше 300
    {
       voltintA = value/adc_counter; // Вычисляем среднее значение АЦП
       voltintA1 = voltintA % 10000 / 1000;
       voltintA2 = voltintA % 1000 / 100;
       voltintA3 = voltintA % 100 / 10;
       display1 = voltintA1;
       display2 = voltintA2;
       display3 = voltintA3;
       display4 = 17; // значок напряжения U
       _delay_ms(2000);
       adc_counter = 0; // Обнуляем счетчик измерений
       value = 0; // Обнуляем буфер АЦП

    }
   
   if(OK_Flag) // если датчик не ответил
   {
      // ставим Err во всех разрядах
      display1 = 15;
      display2 = 16;
      display3 = 16;
      display4 = 14;
      
   }

DS18B20_init(); // инициализация DS18B20
write_18b20(0xCC); // проверка кода датчика
write_18b20(0x44); // запуск температурного преобразования
_delay_ms(1000);
DS18B20_init(); // инициализация DS18B20
write_18b20(0xCC); // проверка кода датчика
write_18b20(0xBE); // считываем содержимое ОЗУ
Temp_L = read_18b20(); // читаем первые 2 байта блокнота
Temp_H = read_18b20();
temp_flag = 1; // флаг знака температуры равен 1(плюс)

if(Temp_H &(1 << 3)) // проверяем бит знака температуры на равенство единице
{
signed int tmp;
temp_flag = 0; // флаг знака равен 0(минус)
tmp = (Temp_H << 8) | Temp_L;
tmp = -tmp;
Temp_L = tmp;
Temp_H = tmp >> 8;

}
tempint = ((Temp_H << 4) & 0x70)|(Temp_L >> 4); // вычисляем целое значение температуры
tempint1 = tempint % 1000 / 100;
tempint2 = tempint % 100 / 10;
tempint3 = tempint % 10;
temppoint = Temp_L & 0x0F; // вычисляем дробное значение температуры
temppoint = temppoint * 625; // точность температуры
temppoint1 = temppoint / 1000;

if(temp_flag == 0) // если флаг знака температуры равен 0, в первом разряде ставим минус
tempint2 = 11;


if(tempint1 < 1) // если первая цифра значения температуры меньше 1, то гасим 1 разряд индикатора
tempint1 = 12;

if(tempint1 == 12 && tempint2 < 1) // если первая цифра погашена и вторая цифра значения температуры меньше 1, то гасим 2 разряд индикатора
tempint2 = 12;

if(tempint2 < 1 && temp_flag == 0) // если вторая цифра значения температуры меньше 1 и знак равен "минус", то гасим 2 разряд индикатора
tempint2 = 12;




// выводим значения на дисплей

display1 = tempint2;
display2 = tempint3;
display3 = temppoint1;
display4 = 14;//значок градуса о

 _delay_ms(2000);
}
}
Аватара пользователя
yarik1111
Новичок
 
Сообщения: 5
Зарегистрирован: 28 апр 2015, 19:17

Re: Подключение двух каналов АЦП

Сообщение:#25  Сообщение AntonChip » 28 апр 2015, 21:52

Вход вольтметра ADC0, нужно использовать резистивный делитель, проверил твою программу в протеусе работает
Аватара пользователя
AntonChip
Администратор
 
Сообщения: 190
Зарегистрирован: 24 дек 2011, 21:11
Откуда: Киров

Re: Подключение двух каналов АЦП

Сообщение:#26  Сообщение yarik1111 » 28 апр 2015, 23:00

У меня в протеусе по схеме что скачал с сайта, а все равно не хочет работать. Выложите пожалуйста hex файл
Аватара пользователя
yarik1111
Новичок
 
Сообщения: 5
Зарегистрирован: 28 апр 2015, 19:17

Re: Подключение двух каналов АЦП

Сообщение:#27  Сообщение AntonChip » 28 апр 2015, 23:28

Проект AVRStudio
Вложения
thermometer_voltmeter.rar
Проект AVRStudio
(59.85 КБ) Скачиваний: 1523
Аватара пользователя
AntonChip
Администратор
 
Сообщения: 190
Зарегистрирован: 24 дек 2011, 21:11
Откуда: Киров

Re: Подключение двух каналов АЦП

Сообщение:#28  Сообщение yarik1111 » 29 апр 2015, 06:27

Ваша прошивка работает. А у меня в Atmel Studio 6 не хочет
Аватара пользователя
yarik1111
Новичок
 
Сообщения: 5
Зарегистрирован: 28 апр 2015, 19:17

Re: Подключение двух каналов АЦП

Сообщение:#29  Сообщение AntonChip » 29 апр 2015, 18:39

Еще попробую в шестой студии
Аватара пользователя
AntonChip
Администратор
 
Сообщения: 190
Зарегистрирован: 24 дек 2011, 21:11
Откуда: Киров

Re: Подключение двух каналов АЦП

Сообщение:#30  Сообщение AntonChip » 29 апр 2015, 21:46

Проект в AVRStudio 6, термометр-вольтметр работает
Вложения
termometer_voltmeter.rar
Проект в AVRStudio 6
(64 КБ) Скачиваний: 1502
Аватара пользователя
AntonChip
Администратор
 
Сообщения: 190
Зарегистрирован: 24 дек 2011, 21:11
Откуда: Киров

Re: Подключение двух каналов АЦП

Сообщение:#31  Сообщение yarik1111 » 29 апр 2015, 22:43

Вот ошибки при открытии вашего проекта. Наверно переустановлю студию
[WARNING] The avrdbg process exited with code 0
[WARNING] The device [atmega8] is not supported in ASF Version [3.1.3] that is used in the project termometer_voltmeter
Аватара пользователя
yarik1111
Новичок
 
Сообщения: 5
Зарегистрирован: 28 апр 2015, 19:17

Re: Подключение двух каналов АЦП

Сообщение:#32  Сообщение yarik1111 » 11 май 2015, 20:12

а как сделать точку подвижную в температуре, когда минусовая температура?
Аватара пользователя
yarik1111
Новичок
 
Сообщения: 5
Зарегистрирован: 28 апр 2015, 19:17

Re: Подключение двух каналов АЦП

Сообщение:#33  Сообщение Addja » 23 ноя 2015, 16:15

Здравствуйте.
Помогите начинающему.
Пытаюсь (виртуально, в Студии и Протеусе) повторить 2-х канальный вольтметр, с небольшими изменениями.
Где-то "нахомутал", что-то показывает, но не то, что должно. И цифры все время меняются.
Вложения
Volt_2ch.rar
(47.69 КБ) Скачиваний: 965
Аватара пользователя
Addja
Новичок
 
Сообщения: 2
Зарегистрирован: 18 ноя 2015, 17:23

Re: Подключение двух каналов АЦП

Сообщение:#34  Сообщение AntonChip » 25 ноя 2015, 22:14

Выбрал в Протеусе другой тип Atmega8 в dip корпусе, показания не скачут. На верхнем индикаторы перепутаны местами общие аноды 1 и 3
Аватара пользователя
AntonChip
Администратор
 
Сообщения: 190
Зарегистрирован: 24 дек 2011, 21:11
Откуда: Киров

Re: Подключение двух каналов АЦП

Сообщение:#35  Сообщение Addja » 26 ноя 2015, 09:22

Да, я это тоже уже вычислил, спасибо.
Не знаю может правильнее создать новую тему, ведь измерение это только часть проекта.
Озадачился стабилизатором напряжения.
Выкладываю уже следующие шаги. Может я что-то усложняю, может что-то подскажите, покритикуете.
Правда еще не дописаны функции защиты (Стоп, Старт, Авария).
Пока не врубился: как в Протеусе имитировать (в Студии, пошагово вроде все правильно, правда что-то я перемудрил с вычислением показаний АЦП)
Спасибо, буду рад любым советам. Учиться никогда не поздно :D .
Вложения
Stab_1_1.rar
(39.95 КБ) Скачиваний: 975
Аватара пользователя
Addja
Новичок
 
Сообщения: 2
Зарегистрирован: 18 ноя 2015, 17:23

Re: Подключение двух каналов АЦП

Сообщение:#36  Сообщение Alex86 » 16 фев 2016, 23:20

Здравствуйте. Подскажите, пожалуйста, как из приведенного в статье кода для индикатора с общим катодом сделать обычный амперметр (0-20В, 0-15А) с таким же форматом вывода: 00,0?
Заранее спасибо.
Аватара пользователя
Alex86
Новичок
 
Сообщения: 1
Зарегистрирован: 16 фев 2016, 23:14

Пред.

Вернуться в Микроконтроллеры AVR

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1

Rambler's Top100