3х канальній измеритель напряжения на АТмега8

Вопросы настройки, программирования, прошивки микроконтроллеров и микросхем программируемой логики
Закрыто
Первый раз сказал Мяу!
Сообщения: 22
Зарегистрирован: Пн май 17, 2010 09:59:59
Откуда: Kiev

Сообщение RaDevan »

Доброго времени суток уважаемые форумчане, есть вопрос касательно устройства которое я собираю.
Идея такова:
есть три датчика тока (Алегро) знанома что выход датчика аналоговый и выдает вольтаж от 0...5В, необходимо производить замеры напруги на каждом датчике, и выводить информацию на экран, при чем выбор датчика дожен осуществлятся нажатием кнопки(канал+ или канал-), ну вот такая дилема возникла немогу разобратся как реализовать этот самый выбор канала, (в автоматическом режиме работало) но надо ж в ручном, буду рад любой помощи :shock: .

Вот программный код CodeVisionAVR
#include <mega8.h>
#include <stdio.h>
#include <delay.h>
#asm
.equ __lcd_port=0x18 ;PORTB
#endasm
#include <lcd.h>
//-----------------------------------------------------------------------------------------------
#define ADC_VREF_TYPE 0x00
char lcd_buffer[31];
unsigned int resultat;
unsigned char ch_plus=1;
unsigned char ch_minu=1;
unsigned char adc_input;
unsigned int read_adc(unsigned char adc_input)
{
resultat=(ADCW*5)-(ADCW/10);
ADMUX=adc_input | (ADC_VREF_TYPE & 0xff);
delay_us(10);
ADCSRA|=0x40;
while ((ADCSRA & 0x10)==0);
ADCSRA|=0x10;
return ADCW;
}
interrupt [EXT_INT0]void ext_int0_isr(void) // Кнопка переключения каналов+
{
ch_plus=0;
ADCSRA|=0x40;
adc_input+=0;
}
interrupt [EXT_INT1]void ext_int1_isr(void) // Кнопка переключения каналов-
{
ch_minu=0;
ADCSRA|=0x40;
adc_input-=0;
}

void main(void)
{
PORTD=0xFF;
DDRD=0x00;
MCUCR=0x0A;
ADMUX=ADC_VREF_TYPE & 0xff;
ADCSRA=0x83;

#asm("sei")
lcd_init(16);

while (1)
{
sprintf(lcd_buffer,"I=%4umA",resultat);
lcd_clear();
lcd_puts(lcd_buffer);
delay_ms(250);
};
}
Вложения
123.JPG
Схема
(153.23 КБ) 548 скачиваний
Реклама
Это не хвост, это антенна
Аватара пользователя
Сообщения: 1306
Зарегистрирован: Вс янв 18, 2009 20:51:02

Сообщение ooogo »

в прерываниях на кнопках производите увеличение/уменьшение номера канала АЦП и сразу конвертирование и вывод на экран, если не нужно постоянное слежение за напряжением, если нужно постоянное слежение, то в прерывании кнопок изменять номер канала, а преобразование АЦП вести постоянно и вывод в прерывании окончания преобразования.
Реклама
Первый раз сказал Мяу!
Сообщения: 22
Зарегистрирован: Пн май 17, 2010 09:59:59
Откуда: Kiev

Сообщение RaDevan »

Вывод информации на дисплей переписал, но вот совсем немогу разобратся как же все таки связать кнопку и переключение канала :( ,если есть возможность набросайте пару строчек кода, буду весьма благодарен
Это не хвост, это антенна
Аватара пользователя
Сообщения: 1306
Зарегистрирован: Вс янв 18, 2009 20:51:02

Сообщение ooogo »

сейчас не могу - на работе, на изусть управляющие регистры не помню.
примерно так :

переменную заведите новую, глобальную и локальную с одинаковым именем не стоит делать

unsigned char i=0;

в кнопках делаете проверку и декремент/инкремент этой переменной:

if(i>0) i--; //декремент

if(i<1) i++; //инкремент

вызов преобразования в нужном месте:

read_adc(i);
Реклама
Эиком - электронные компоненты и радиодетали
Это не хвост, это антенна
Аватара пользователя
Сообщения: 1306
Зарегистрирован: Вс янв 18, 2009 20:51:02

Сообщение ooogo »

я бы функцию поправил бы вот так, но могу ошибаться

Код: Выделить всё

void read_adc(unsigned char adc_input) 
{
ADMUX=adc_input | (ADC_VREF_TYPE & 0xff); 
delay_us(10); 
ADCSRA|=0x40; 
while ((ADCSRA & 0x10)==0); 
ADCSRA|=0x10;
resultat=(ADCW*5)-(ADCW/10); 
}
у Вас resultat глобальная переменная
Реклама
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18785
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

вот непонятна мне эта любовь делать работу с кнопками по прерываниям... ну а как вы будете дребезг давить?

где в вашем коде ограничение предела номера канала? что такое за хитрое действие adc_input+=0;?
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Реклама
Первый раз сказал Мяу!
Сообщения: 22
Зарегистрирован: Пн май 17, 2010 09:59:59
Откуда: Kiev

Сообщение RaDevan »

это хитрое действие , я ращитывал на присвоение с увеличением на 1, но увы не сработало, result глобальная переменная
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18785
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

RaDevan писал(а):это хитрое действие , я ращитывал на присвоение с увеличением на 1, но увы не сработало, result глобальная переменная
вообще-то без всяких хитростей делается ++ и все.

ваша программа крайне примитивна - чем меньше вы станете хитрить, тем скорее она у вас заработает.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Первый раз сказал Мяу!
Сообщения: 22
Зарегистрирован: Пн май 17, 2010 09:59:59
Откуда: Kiev

Сообщение RaDevan »

спасибо за дельный совет, обошелся вот так
if (!(button_pin.ch_plus)) num_ch++|ADMUX++;
if (!(button_pin.ch_minus)) num_ch--|ADMUX--;
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18785
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

RaDevan писал(а):спасибо за дельный совет, обошелся вот так
if (!(button_pin.ch_plus)) num_ch++|ADMUX++;
if (!(button_pin.ch_minus)) num_ch--|ADMUX--;
уважаемый, вы написали вообще невесть что. я вам набросаю костяк вашей программы, а вы помозгуйте над "мясом".

Код: Выделить всё

int main(void){
   char chanel = 0; // номер текущего канала измерения

   initialize_all(); // инициализируем всю задействованную периферию
   while(1){
      char key = get_key(); // опрос нажатых кнопок
      // обработка кнопок
      switch(key){
      key_plus: 
         if(++chanel == MAX_CHANEL) chanel = 0;
         break;
      key_minus:
         if(!chanel) 
            chanel--;
         else
            chanel = MAX_CHANEL-1;
         break;
      }
      // измерение
      int adc = get_adc(chanel);
      // индикация
      lcd_output(chanel, adc);
   }
}
я вам очень рекомендую подумать о том, что при нажатии кнопки обязательно возникнет дребезг ее контактов, который надо подавить - это надо учесть внутри функции get_key(). не советую делать работу с кнопками по прерываниям.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Первый раз сказал Мяу!
Сообщения: 22
Зарегистрирован: Пн май 17, 2010 09:59:59
Откуда: Kiev

Сообщение RaDevan »

спасибо огромное, щас этим и займусь
Первый раз сказал Мяу!
Сообщения: 22
Зарегистрирован: Пн май 17, 2010 09:59:59
Откуда: Kiev

Сообщение RaDevan »

я неразу не применял функции
get_key()
и
get_adc

и именно на них ругается коде вижен при компиляции проекта, дайте хоть какуюто ссылочку где про них можна почитать
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18785
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

RaDevan писал(а):я неразу не применял функции
get_key()
и
get_adc

и именно на них ругается коде вижен при компиляции проекта, дайте хоть какуюто ссылочку где про них можна почитать
вообще-то эти функции вы должны сделать самостоятельно :)))
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Первый раз сказал Мяу!
Сообщения: 22
Зарегистрирован: Пн май 17, 2010 09:59:59
Откуда: Kiev

Сообщение RaDevan »

угу понял, а как выглядит синтаксис для создания этой функции ???
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18785
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

RaDevan писал(а):угу понял, а как выглядит синтаксис для создания этой функции ???
вообще-то синтаксис для всех функций одинаковый :))) вы Си мало-мало изучили? если нет - срочно за букварь!
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Первый раз сказал Мяу!
Сообщения: 22
Зарегистрирован: Пн май 17, 2010 09:59:59
Откуда: Kiev

Сообщение RaDevan »

Вот это Вы правы, и так сижу книжками обложившись, так сказть учусь методом проб и ошибок, а также сопоставления и анализа :beer:
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18785
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

подсказка:
get_key() опрашивает кнопки на предмет нажатия (с подавлением дребезга) и возвращает код нажатой кнопки. коды могут быть любыми - я рекомендую описать их дефайнами. например, кнопка ПЛЮС это код 1, кнопка минус - код 2. если не нажата ни одна - возвратить 0.

get_adc(char ch) возвращает результат измерения напряжения на канале АЦП с номером ch. в зависимости от общей логики работы можно либо вернуть код АЦП сразу, либо преобразовав его к реальным "вольтам" или "амперам" - отсюда и тип результата может быть разным.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Первый раз сказал Мяу!
Сообщения: 22
Зарегистрирован: Пн май 17, 2010 09:59:59
Откуда: Kiev

Сообщение RaDevan »

если я правильно понял то необходимо зделать так ::
кнопки подключены к порту Д на 4й и 5й выводы
#define ch_plus 4
#define ch_minus 5
и непосредственно сама функция
unsigned char get_key(void)
{
unsigned char temp;
temp = ~PIND & ((1<<ch_plus) | (1<<ch_minus));
delay_ms(15);
if(temp != (~PIND & ((1<<ch_plus) | (1<<ch_minus))))
return 0;
else
return temp;
}
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18785
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

в принципе, логику вы уловили верно, но реализация ошибочна. смотрите: вы назначили макросы кодам кнопок - а что вернете из функции? а вернете вы совсем другие числа! лучше назначить кодам сразу значение (1<<4) или там что вам надо :) улавливаете мысль? ;)

P.S. оформляйте код отступами - вам не кажется, что с отступами понятнее и красивее?
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Первый раз сказал Мяу!
Сообщения: 22
Зарегистрирован: Пн май 17, 2010 09:59:59
Откуда: Kiev

Сообщение RaDevan »

так мысль немного не уловил, это необходимо записать таким образом :
...
temp = ~PIND & ((1<<ch_plus) |(2<<ch_plus)|(3<<ch_plus)|(4<<ch_plus) |....);
...
на щет отступов учту на будущее
Закрыто

Вернуться в «Микроконтроллеры и ПЛИС»