Обсуждаем контроллеры компании Atmel.
Ответить

Re: LED Driver на Attiny13A

Пн сен 13, 2021 20:28:26

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

Re: LED Driver на Attiny13A

Вт сен 14, 2021 05:39:52

Bondosha писал(а):когда разберусь с проблемой
О да.
Изучили таймер, прочитали АЦП, а вот доступ к портам I/O по чему-то пропустили.
Может вам, для начала, почитать тут?
Bondosha писал(а):в чем проблема
А проблема
в отсутствии схемы устройства и внятного ТЗ.

slav0nу работы на 30 минут была бы схема устройства и внятное ТЗ.

Re: LED Driver на Attiny13A

Вт сен 14, 2021 06:46:32

а Bondosha думает, что должно быть так:

Re: LED Driver на Attiny13A

Вт сен 14, 2021 10:05:13

slav0n, допустим, но мне бы лучше не по сокращению кода, а именно по проблеме помощь

изучи конечные автоматы.

Re: LED Driver на Attiny13A

Вт сен 14, 2021 17:21:52

Dimon456, вот схема и тех задание

Алгоритм работы:
1) Нажали кнопку, она замкнулась - 1 на порт PB0 (нога 5)
2) Полунажатие кнопки (кнопка KAN15-A, контакты на долю секунды размыкаются) - 1 на порт PB0 (нога 5) и 1 на порт PB1 (нога 6), повторное полунажатие приводит к пункту 1.
3) Контроль уровня батареи:
а) уровень напряжения 3.1-3.6 В (R5=30 кОм, R6=10 кОм - резистивный делитель) - зажигается синяя лампочка (0 на PB3, нога 2) в дополнение к пунктам 1 и 2
б) уровень напряжения 2.3-3.0 В - зажигается красная лампочка (0 на PB2, нога 7) + PB0(по пункту 1) или PB0 и PB1 (по пункту 2) горит 365 мс, затем кратковременно потухает на 3 мс и зажигается вновь.
в) уровень напряжения 1.8-2.2 В - наступает по уровню напряжения или спустя 30 минут от пункта б), что наступит первым. Красная лампочка не горит (1 на PB2, нога 7) + PB0(по пункту 1) или PB0 и PB1 (по пункту 2) не горит 365 мс, затем горит 15 мс и потухает опять.

Добавлено after 47 seconds:
slav0n, ну и переписала я, как вы хотели и ровно 0 изменений.

Код:
#ifndef MAIN_H_
#define MAIN_H_

// Определение частоты для компилятора.
#define F_CPU 9600000UL  // Attiny13 9.6MHz / PWM 36.8 KHz / CKDIV8 = 1

#include <util/delay.h>
#include <avr/io.h>
#include <avr/sleep.h>
#include <avr/interrupt.h>
#include <stdbool.h> // bool in C99

#define nop __asm__ __volatile__ ("nop");
typedef uint8_t u8;
typedef uint16_t u16;

int main(void);
static void setup(void);
static void wakeup(void);;
static u8 bat_getvoltage(void);

#endif /* MAIN_H_ */

#include <util/delay.h>
#include <avr/io.h>
#include <avr/sleep.h>
#include <avr/interrupt.h>
#include <stdbool.h> // bool in C99
int count = 0;
volatile uint8_t timer1 = 0;
volatile uint8_t timer2 = 0;
volatile uint8_t timerADC = 0;
volatile uint8_t countMode = 0;            //????? ?????????? ??????
volatile uint8_t reqChangeMode = 0;        //????, ???????????? ????? ????????? ???????? ?????
u8 adc_raw = 0;
u8 adc_raw2 = 0;
volatile uint8_t timerADC2 = 0;
volatile uint16_t voltage_buffer = 0;
volatile uint16_t voltage_counter = 0;

ISR(TIM0_COMPA_vect)
{
   knopka_check();
   bat_check();
}

void bat_check(void)
{
   u8 adc_raw = bat_getvoltage();
   if ((adc_raw <= 207)&&(adc_raw > 183))
   {
PORTB = (countMode) ? 0b0111 : 0b0101;
   } else if ((adc_raw <= 183)&&(adc_raw > 130))
   {
         if(++timer1 == 100)
         {
            PORTB = 0b1000;
            timer1 = 0;
         }
   else PORTB = (countMode) ? 0b1011 : 0b1001;
   }
   else if (adc_raw <= 130)
   {
         if (++timer2 >= 100)
         {
            PORTB = (countMode) ? 0b1111 : 0b1101;
            timer2 = 0;
         }
   else PORTB = 0b1100;   
   }
   if (adc_raw > 210)
   {
   PORTB = (countMode) ? 0b1111 : 0b1101;
   }
   if (adc_raw < 30)
   {
      DDRB = 0b00000011;
      PORTB = 0b00000000;
   }
}

void knopka_check(void) {
   u8 adc_knopki = bat_getvoltage();
   if (adc_knopki < 90)
   {
      if (count < 250)
      count++;
      } else {
      if (count > 0)
      count--;
      if ((count >= 4)&&(count < 50))
      {
         countMode = (countMode + 1) & 0x1;
         reqChangeMode = 1;
         count = 0;
      }
   }
   if (reqChangeMode) {       
      reqChangeMode = 0;         
      switch (countMode) {       
         case 0:
         {
            PORTB = 0b00001101;
         }
         break;
         case 1:
         {
            PORTB = 0b00001111;
         }
         break;
      }
   }
}


int main(void)   {
   setup();
   sei ();
   while(1)    {
   }
}

void setup(void){
   ADMUX =
   (1 << ADLAR) | (1 << REFS0) | (1 << MUX1)  | (0 << MUX0);
   ADCSRA |= (1 << ADEN)|(1 << ADPS2)|(1 << ADPS1);
   ACSR=(1<<ACD) | (0<<ACBG) | (0<<ACO) | (1<<ACI) | (0<<ACIE) | (0<<ACIS1) | (0<<ACIS0);
   TCCR0B = (0 << CS02) | (1 << CS01) | (1 << CS00 );
   TCCR0A = (0 << WGM02) | (1 << WGM01) | (0 << WGM00);
   OCR0A = 69;
   TCNT0 = 0;
   TIMSK0|=(1<<OCIE0A)|(0<<TOIE0);
   DDRB = 0b00001111;
   PORTB = 0b00001101;
   wakeup();
}

void wakeup(void) {
   ADCSRA |= (1 << ADSC);
}

u8 bat_getvoltage(void) {
   _delay_us(50);
   ADCSRA |= (1 << ADSC);
   while (ADCSRA & (1 << ADSC));
   return ADCH;
}
Вложения
схема.jpg
(106.72 KiB) Скачиваний: 687

Re: LED Driver на Attiny13A

Вт сен 14, 2021 18:31:48

Bondosha писал(а):Полунажатие кнопки (кнопка KAN15-A, контакты на долю секунды размыкаются)
Если на долю секунды разомкнуть кнопку, то ...
На сколь С4 установлен? Нужно удержать питание МК на эту долю секунды.

Re: LED Driver на Attiny13A

Вт сен 14, 2021 18:34:32

Dimon456, там ловится этот момент по ацп и вроде как он работает отлично сейчас, а вот с режимами: между б и в ловит помеху какую-то или перепады резкие от акб и получается очень быстрый стробоскоп.
С4 на 100 мкФ

Re: LED Driver на Attiny13A

Вт сен 14, 2021 19:34:38

Держите, пробуйте

Re: LED Driver на Attiny13A

Вт сен 14, 2021 19:44:02

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

и я бы тоже разделил индикацию и управление, чтобы все время не дергать countMode
Код:
#define RedLight_ON()   DDRB |= (1<<PB2)
#define RedLight_OFF()   DDRB &=~(1<<PB2)

#define BlueLight_ON()   DDRB |= (1<<PB3)
#define BlueLight_OFF()   DDRB &=~(1<<PB3)

#define out1_set()   DDRB |= (1<<PB0)+(1<<PB1); PORTB = (1<<PB0)
#define out1_clr()   PORTB &=~(1<<PB0)

#define out2_set()   PORTB |= (1<<PB1)
#define out2_clr()   PORTB &=~(1<<PB1)

Re: LED Driver на Attiny13A

Вт сен 14, 2021 19:54:14

slav0n, а пример этого гистерезиса можно, пожалуйста?

Dimon456, макет остался на работе, завтра утром ваш вариант проверю

Re: LED Driver на Attiny13A

Вт сен 14, 2021 20:17:40

slav0n писал(а):нет гистерезиса
не в гистерезисе дело.
Вот ее стробоскоп

Вот исправленный код

Re: LED Driver на Attiny13A

Ср сен 15, 2021 07:56:42

Bondosha писал(а):а пример этого гистерезиса можно, пожалуйста?

будь ласка:
Код:
void bat_check(void)
{
  u8 adc_raw = bat_getvoltage();
  if(adc_raw > 210) {//MAX - 211
    ...    
  
} else
  if
(adc_raw > 183) {//210 - 184
    ...
  } else
  if
(adc_raw < 170) //HYSTERESIS 183 - 170
  if(adc_raw > 150) {//169 - 151
    ...
  } else
  if
(adc_raw > 30) {//150 - 31
    ...
  } else { // adc_raw <= 30
    ...
  }

Re: LED Driver на Attiny13A

Ср сен 15, 2021 10:46:51

slav0n, тогда на том участке между 150 и 170 вообще ничего не происходит, а это тоже не подходит под задание

Re: LED Driver на Attiny13A

Ср сен 15, 2021 14:24:54

в том и смысл гистерезиса.
на его участке сохраняется предыдущее состояние системы

Добавлено after 31 minute 13 seconds:
Bondosha писал(а):между 150 и 170 вообще ничего не происходит
там же написано:
Код:
//HYSTERESIS 183 - 170


Добавлено after 3 hours 4 minutes 5 seconds:
мигание лампочками.
если не нужен гистерезис - просто закоментить его строку
Код:
void bat_check(void)
{
    static u8 dutycycle;
    u8 adc_raw = bat_getvoltage();
    
    if 
(adc_raw > 210) { //MAX - 211
        BlueLight_ON();
        dutycycle = 0;
    } else
    if 
(adc_raw > 183) { //210 - 184
        BlueLight_OFF();
        dutycycle = 5;
    } else
    if 
(adc_raw < 170) //HYSTERESIS 183 - 170
    if (adc_raw > 150) { //169 - 151
        BlueLight_OFF();
        dutycycle = 95;
    } else
    if 
(adc_raw > 30) { //150 - 31
        BlueLight_OFF();
        dutycycle = 0;
    } else { // adc_raw <= 30
        BlueLight_OFF();
        dutycycle = 0;
    }
    
    static u8 timer
;
    if(++timer >= 100) timer = 0;
    
    if
(dutycycle && timer > dutycycle) RedLight_ON();
    else RedLight_OFF();
}

Re: LED Driver на Attiny13A

Ср сен 15, 2021 17:17:54

slav0n, видимо, он все же нужен, ибо без него по прежнему мигало, но завтра еще ваш последний вариант посмотрю

Re: LED Driver на Attiny13A

Ср сен 15, 2021 21:36:51

гистерезис (зона нечувствительности) нужен обязательно.

Re: LED Driver на Attiny13A

Ср сен 15, 2021 21:58:28

в алгоритм надо еще добавить начальную инициализацию состояния
если при включении напряжение попадет в зоны нечувствительности

Re: LED Driver на Attiny13A

Ср сен 15, 2021 22:06:01

Starichok51 и slav0n, вы что несете оба?
Вы схему смотрели?
Диод VD3 и кондер С4, нагрузка VD1 VD2 и МК.
Время разряда конденсатора С4(100мкФ) до напряжения 1,5В заряженного до 3В током всего 10 миллиА составляет 20 милли секунд.
Там на 1000мкФ надо ставить и то мало будет.

Re: LED Driver на Attiny13A

Ср сен 15, 2021 22:25:42

речь пока про лампочки,
до кнопки дело еще не дошло

Re: LED Driver на Attiny13A

Ср сен 15, 2021 22:28:37

попробовал посмотреть схему. я со своим цветоаномальным зрением ничего в этой цветовой палитре рассмотреть и понять не могу.
Ответить