Jump to content
ummagumma

3-х разрядный вольтметр/амперметр на ATmega_8

Recommended Posts

Posted (edited)

Здравствуйте православные! Прошу помочь с кодом для усреднения результатов оцифровки двух аналоговых на входах admux_3/admux_4. Без этого в младших разрядах экс_верть и хаос... код на Си...

Скрытый текст

ind_1.thumb.jpg.b9092e922c294b51824fe4b43494b2c3.jpgind_2.thumb.jpg.bb0180da0e0cd358b7b2e0d4835403d0.jpg

 

main.c

Edited by ummagumma

слабоумие и отвага

внимание! все трюки выполнены профессионалом! не пытайтесь повторить это дома!

Share this post


Link to post
Share on other sites

Что у вас опорное? Разводка питания правильна? 

Share this post


Link to post
Share on other sites

Вебинар «Решения Microchip и сервисы Microsoft для интернета вещей. Подключение устройств IoT к облачным сервисам Azure» (15.07.2021)

Приглашаем всех желающих 15 июля 2021 г. принять участие в бесплатном вебинаре, посвященном решениям Microchip и сервисам Microsoft для интернета вещей. На вебинаре будут рассмотрены наиболее перспективные решения Microchip, являющиеся своеобразными «кирпичиками» – готовыми узлами, из которых можно быстро собрать конечное устройство интернета вещей на базе микроконтроллеров и микропроцессоров производства Microchip. Особое внимание на вебинаре будет уделено облачным сервисам Microsoft для IoT.
Подробнее

1 час назад, Yuriy.pv сказал:

Что у вас опорное?

Vref = +4...AVcc, разводка как в схеме... а вот как этот код встроить в оригинальный цикл?

av_meter_ver_1.EMF


слабоумие и отвага

внимание! все трюки выполнены профессионалом! не пытайтесь повторить это дома!

Share this post


Link to post
Share on other sites

Вебинар «Работа с графическими возможностями новой линейки STM32H7» (07.07.2021)

Приглашаем 07/07/2021 всех желающих принять участие в вебинаре, посвященном работе с графической библиотекой TouchGFX и новой линейке высокопроизводительных микроконтроллеров STM32H7A/B производства STMicroelectronics. На вебинаре будут разобраны ключевые преимущества линейки STM32H7A/B, а также показан пример создания проекта с помощью среды TouchGFX Designer и методы взаимодействия этой программы с экосистемой STM32Cube.

Подробнее

6 часов назад, ummagumma сказал:

av_meter_ver_1.EMF 843 kB · 3 скачивания

Не у каждого программы есть для вашего файла. Если вы берете просто от ноги питания то это плохой вариант.

Бери фунцию getMA и вставляй.

 

Share this post


Link to post
Share on other sites

LDH-25/65 – новые серии повышающих DC/DC LED-драйверов от Mean Well

Компания Mean Well расширила семейство популярных повышающих DC/DC LED-драйверов LDH двумя новыми сериями меньшей и большей мощности – LDH-25 и LDH-65, соответственно. Новые серии, обладая высоким КПД, применимы для изготовления экономичных светодиодных светильников с питанием от автономных источников тока, в том числе – на транспорте. Конструктивно драйверы выпускаются в двух различных вариантах.
Подробнее

8 часов назад, ummagumma сказал:

код на Си...

функцию unsigned long ADC_Convert (unsigned char Kanal_ADC) разбейте на две отдельных функции для каждого канала АЦП и добавьте скользящие средние типа

{
 static unsigned int symm;
 static unsigned int areyADC[8];
 static unsigned char count;
 
 count++;
 count &= 0x07;
 symm -= areyADC[count];
 
 //  читаем АЦП
 
 areyADC[count]=ADC;
 symm += ADC;
 
 return symm/8;

}

 

Share this post


Link to post
Share on other sites

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


слабоумие и отвага

внимание! все трюки выполнены профессионалом! не пытайтесь повторить это дома!

Share this post


Link to post
Share on other sites

в общем и целом я такое сам не смогу починить. нужен нормальный программист. если кому интересно, скидывайте свои коммерческие предложения в личку. я сам в Москве обитаю. нужно написать программу для 10-битной оцифровки двух анналоговых сигналов с усреднением для атмега8а и max7219.

Скрытый текст

1991711041_.png.a2b99f354160ecc6ac89c093590fe332.png

 


слабоумие и отвага

внимание! все трюки выполнены профессионалом! не пытайтесь повторить это дома!

Share this post


Link to post
Share on other sites

починилось... благородный сир Карбофос с радиокотов исправил код вот так

Скрытый текст

#define F_CPU 16000000UL                                     //тактовая частота мк (unsigned long)
#include <avr/io.h>                                          //подключение библиотеки "ввод/вывод" мк
#include <util/delay.h>                                      //подключение библиотеки "пауза" мк
#include <avr/interrupt.h>                                   //подключение библиотеки "прерывание" мк

#define CLK_0 PORTC &= ~(1<<PORTC0)                          //отправить 0 на вывод Clk микросхемы MAX7219
#define CLK_1 PORTC |=1<<PORTC0                              //отправить 1 на вывод Clk микросхемы MAX7219
#define CS_0 PORTC &= ~(1<<PORTC1)                           //отправить 0 на вывод Cs микросхемы MAX7219
#define CS_1 PORTC |=1<<PORTC1                               //отправить 1 на вывод Cs микросхемы MAX7219
#define DIN_0 PORTC &= ~(1<<PORTC2)                          //отправить 0 на вывод Din микросхемы MAX7219
#define DIN_1 PORTC |= 1<<PORTC2                             //отправить 1 на вывод Din микросхемы MAX7219
#define measure 128                 // по результатам 128 измерений вычислить среднее значение measure/128

unsigned int Digit[8]; //массив беззнаковых 4-x байтных переменных Digit из 8 переменных
unsigned char Data_In[8]; //массив беззнаковых обнобайтных символьных переменных Data_In из 8 переменных
unsigned int Display1_ADC; //беззнаковая 4-х байтная переменная Display1_ADC
unsigned int Display2_ADC; //беззнаковая 4-х байтная переменная Display2_ADC
unsigned char X; //беззнаковая однобайтная символьная переменная X (значение регистра ацп с результатом оцифровки напряжения)
unsigned char I; //беззнаковая однобайтная символьная переменная I (значение регистра ацп с результатом оцифровки тока)

//----------------------------------------
void port_ini(void) //объявим функцию инициализации порта PB1 (выход сигнала генератора -V=-5v0)
{
    PORTB=0x00; //portb сброс
    DDRB=0x02; //portb1 на вывод (OC1A)
}
//----------------------------------------
void init_PWM_timer(void) //функция таймера
{
    ASSR=0x00; //сбрасываем полностью регистр assr
    TCCR1A |=0b10000001; //Fast PWM oc1a, Clear OC1A on Compare Match, clkT2S/1 (no prescalling)
    TCCR1B |=0b00001001;
    TCNT1H=0x00; // Timer Value = 0 сброс счётного регистра таймера 1
    TCNT1L=0x00;
    OCR1AH=0x00; //Output Compare Register = dec85 - в нашем случае это заполнение шим DC~68%
    OCR1AL=0x55;
    TIMSK|=0x00; //сброс регистра timsk
}
//----------------------------------------

//********************* Передача данных в Max7219 *****************
void Write_MAX7219(unsigned char Adres_Reg,unsigned char Data_In_Write)
{
  unsigned char Adres_Reg_Copy;
 
  Data_In[Adres_Reg] = Data_In_Write;
  Adres_Reg_Copy = Adres_Reg;                //создадим копию значения переменной Adres_Reg
                
  CS_0;                                     //отправим «0» на вывод CS микросхемы MAX7219, чтобы начать процесс передачи адреса и данных    
  asm("nop");                               //пауза в 1 такт
    
  for(I=0;I<8;I++)                          //цикл от 0 до 7 с шагом 1, для побитной отправки байта адреса в микросхему MAX7219    
  {
    if((Adres_Reg & 0x80)==0x80)            //если 7 бит переменной Adres_reg=1
    {
      DIN_1;                                //отправим 1 на вывод Din микросхемы MAX7219
    }
    else                                    //если 7 бит переменной Adres_reg=0
    {
      DIN_0;                                //отправим 0 на вывод Din микросхемы MAX7219
    }
    
    //создадим тактовый импульс на выводе CLK микросхемы MAX7219
    asm("nop");                             //пауза в 1 такт                        
    CLK_1;                                  //отправим 1 на вывод Clk микросхемы MAX7219
    asm("nop");                             //пауза в 1 такт
    CLK_0;                                  //отправим 0 на вывод Clk микросхемы MAX7219
    Adres_Reg <<= 1;                        //сдвинем значение переменной Adres_reg на 1 бит влево
  }                                         //выйдем из цикла когда i станет равной 7, т.е. когда отправка байта адреса в микросхему MAX7219 будет окончена
    
  for(I=0;I<8;I++)                          //цикл от 0 до 7 с шагом 1, для побитной отправки байта данных в микросхему MAX7219
  {                                               
    if((Data_In[Adres_Reg_Copy] & 0x80)==0x80) //если 7 бит переменной Data_in=1
    {
      DIN_1;                                //отправим 1 на вывод Din микросхемы MAX7219
    }
    else                                    //если 7 бит переменной Data_in=0
    {
      DIN_0;                                //отправим 0 на вывод Din микросхемы MAX7219
    }
    
    //создадим тактовый импульс на выводе CLK микросхемы MAX7219
    asm("nop");                             //пауза в 1 такт
    CLK_1;                                  //отправим 1 на вывод Clk микросхемы MAX7219
    asm("nop");                             //пауза в 1 такт
    CLK_0;                                  //отправим 0 на вывод Clk микросхемы MAX7219
    Data_In[Adres_Reg_Copy] <<= 1;          //сдвинем значение переменной Data_in на 1 бит влево
  }
                                            //выйдем из цикла когда i станет равной 7, т.е. когда отправка байта данных в микросхему MAX7219 будет окончена
  CS_1;                                     //отправим «1» на вывод CS микросхемы MAX7219, чтобы завершить процесс передачи адреса и данных
}                                             


//********************* Инициализация MAX7219 *****************                       
void Init_MAX7219()                      
{                                             
  Write_MAX7219(0x09,127);                  //включаем режим BCD code B, для 7 разрядов
  Write_MAX7219(0x0A,10);                   //яркость свечения сегментов 10 (от 0 до 15)
  Write_MAX7219(0x0B,7);                    //число используемых разрядов (7 разрядов)
  Write_MAX7219(0x0C,1);                    //отключаем режим энергосбережения (Shutdown)
}


//******** Функция вывода значений на 7 сегм.индикатор №1 ******                       
void Out_Display_1(unsigned int Display_Ust)                      
{
 Digit[7]=Display_Ust/100;                                   //сотни
 Digit[6]=Display_Ust%100/10;                                //десятки
 Digit[6]=Digit[6]|128;                                      //вкл децимальную точку в разряде Digit_6
 Digit[5]=Display_Ust%10;                                    //единицы
 
 
 for(X=5;X<8;X++)
 {
   Data_In[X] = Digit[X];
   Write_MAX7219(X,Data_In[X]);
 }
}


//******** Функция вывода значений на 7 сегм.индикатор №2 ******                       
void Out_Display_2(unsigned int Display_Ust)                      
{
 Digit[4]=15;                                                //Отключим не используемую цифру старшего разряда индикатора №2
 Digit[3]=Display_Ust/100;                                   //сотни
 Digit[2]=Display_Ust%100/10;                                //десятки
 Digit[2]=Digit[2]|128;                                      //вкл децимальную точку в разряде Digit_2
 Digit[1]=Display_Ust%10;                                    //единицы
 
 for(X=1;X<5;X++)
 {
   Data_In[X] = Digit[X];
   Write_MAX7219(X,Data_In[X]);
 }
}


//*************************** Функция измерения напряжения на входах АЦП ***************************


unsigned long ADC_Convert (unsigned char Chan_ADC)
{
  uint32_t sum = 0;
  //ADMUX = ADMUX&224|Chan_ADC;//выберем канал АЦП (обнулим биты MUX4-MUX0 в регистре ADMUX, не изменяя при этом биты 5,6,7, после этого заменим значение битов MUX4-MUX0 на номер(код) канала)
  ADMUX = ADMUX & 224; //выберем канал АЦП (сначала обнулим биты MUX4-MUX0 в регистре ADMUX, не изменяя при этом биты 5,6,7)
  ADMUX = ADMUX | Chan_ADC; //выберем канал АЦП (затем заменим значение битов MUX4-MUX0 на номер(код) канала)
  for(uint8_t i = 0; i < measure; ++i)
  {
    ADCSRA |= (1<<ADSC); //Начинаем аналого-цифровое преобразование (для этого запишем 1 в бит ADSC регистра ADCSRA)
    while((ADCSRA & (1<<ADSC))); //Ждём когда закончиться аналого-цифровое преобразование (преобразование закончится, когда бит ADSC регистра ADCSRA станет равным 0)
    sum += ADCW;
  }
  sum += measure >> 1;
  sum /= measure;
  return (unsigned long) sum; //Выйдем из функции и вернём (запишем) полученное значение (из регистров результата ADCL и ADCH) в переменную типа unsigned int
}

//************************** Основная функция с бесконечным циклом *******************************
int main(void)
{
  DDRC = 7; //биты PC0-PC2 порта PC на вывод  
 
  Init_MAX7219();                            //Инициализация MAX7219
 
  //---------------Инициализация АЦП-----------------
  ADCSRA |= (1<<ADEN)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0); //Разрешение использования АЦП, Делитель 16M/128 = 125 кГц
  ADMUX &= ~((1<<REFS0)|(1<<REFS1)); //внешний источник опорного напряжения Aref
 
  //-------------------------------------------
  port_ini(); //инициализация порта PB1
  init_PWM_timer(); //вызов функции таймер 1
  OCR1AH = 0x00; //запись в регистр число dec85
  OCR1AL = 0x55;
  //-------------------------------------------
  while(1)
  {              
    Display1_ADC = ADC_Convert(4);                  //Считаем значение с 4 канала АЦП
    Out_Display_1(Display1_ADC);                    //Отправим считанное значение в функцию вывода на индикатор №1
    _delay_ms(200);
 
    Display2_ADC = ADC_Convert(3);                  //Считаем значение с 3 канала АЦП
    Out_Display_2(Display2_ADC);                    //Отправим считанное значение в функцию вывода на индикатор №2
    _delay_ms(200);
  }
}

спасибо всем откликнувшимся!

main.c


слабоумие и отвага

внимание! все трюки выполнены профессионалом! не пытайтесь повторить это дома!

Share this post


Link to post
Share on other sites
Posted (edited)

код вполне себе достойно хороший. цифры стоят как вкопанные. младший не мельтешит, не выбешивает. смена показаний без задержки. пульсации питающего и опорного побоку и не влияют. при обнуленых входах на индикатрах нульсэны. погрешность по току при калибровке на верхнем пределе 100adc при подаче в шинку 30а не боле +/-1а, тож самое с напряженьем. при калибровке по верху +100vdc в серединке погрешность менее 0.5vdc. нормально работает от +13vdc to +35vdc. кушает от +24vdc порядка 90ма... яркость и контрастность вполне достойная. индикаторы китайские 0.56inch с великасовковым шлаком алс334 даже сравнивать неэтично. микры с алиэкспрессера max 7219 вроде пашуть, все не проверял, а атмеги 8а ау пришли с калибровкой не 1е9307 а вообче ***** знает что бл... не рабочие... замену на Митино брал в микробутиках... те запустились сразу... что  на грёбаном эспрессе, что в митино, приблизительно по ценникам одно и тоже ок 110р...ckopt запрограммировал фьюз, размах 16MHz около 4v... запуск кварца чёткий...

Скрытый текст

Vin_27v_31adc.thumb.jpg.a8684292cdc27b1dda7f5afbf338d942.jpgVin_27vdc_30adc.thumb.jpg.2ab8d9c5b5e08d68030efc6b39a29484.jpg848017138__61.thumb.jpg.11783f6cff38d38b94788d8d73a9f30b.jpghall.thumb.jpg.cde5a454243122dea4a39baaed7ba8fd.jpgbottom.thumb.jpg.0e968695e0d52b598085105bec9d26ee.jpgtop.thumb.jpg.9dab4864216cc38839d0dc3d54f00f32.jpg

 

 

 

 

Edited by ummagumma

слабоумие и отвага

внимание! все трюки выполнены профессионалом! не пытайтесь повторить это дома!

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

×
×
  • Create New...