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

Re: Проблемы со сторожевым таймером. Что я делаю неправильно

Ср сен 11, 2013 14:37:56

Так а с чего вы взяли, что сторож не работает? Может, он работает — просто вы не замечаете?
Сложно разобраться в проге по 3-м кускам кода.

Re: Проблемы со сторожевым таймером. Что я делаю неправильно

Ср сен 11, 2013 14:43:27

Ну с того что когда ресетит МК, то видно как LED моргает. Есть же строчка

LED = 1; delay_ms(25); LED = 0; // когда контроллер спит, строж. таймер работает как надо, тому подтверждение работа этого светодиода (кратковременное моргание раз в 4 секунды)

А в основном цикле просто горит LED постоянно, что указывает на то, что МК не ресетится.
В осн. цикле стоит задержка несколько секунд перед включением светодиода (в первом посте не указал)

Re: Проблемы со сторожевым таймером. Что я делаю неправильно

Ср сен 11, 2013 14:46:09

Полный код такой:

Спойлер
Код:
/*****************************************************************
Chip type               : ATmega48PA
AVR Core Clock frequency: 8.000000 MHz

Делитель напряжения     : 13.1V / 0.833V = 15,726
                        Uref = 1.100V
*****************************************************************/
#include <mega48pa.h>
#include <delay.h>

#define LED PORTD.5
#define BD140 PORTC.4
#define LineCtr PIND.4 // Контроль за некомутируемой частью
#define BOOSTER_ON PORTB.1 = 0, PORTB.0 = 1
#define BOOSTER_OFF PORTB.1 = 1, PORTB.0 = 0

#define ADC_VREF_TYPE 0xE0 // Internal Uref

unsigned int batU = 0; // Переменная для хранения напряжения АКБ
char ctr = 0;

void WDT_off(void)
{
        #asm("cli")
        #asm("wdr")
        /* Clear WDRF in MCUSR */
        MCUSR &= ~(1<<WDRF);
        /* Write logical one to WDCE and WDE */
        /* Keep old prescaler setting to prevent unintentional time-out */
        WDTCSR |= (1<<WDCE) | (1<<WDE);
        /* Turn off WDT */
        WDTCSR = 0x00;
        #asm("sei")
}

void WDT_init()
{
        // Watchdog Timer initialization
        // Watchdog Timer Prescaler: OSC/512k
        // Watchdog Timer interrupt: Off
        #pragma optsize-
        #asm("wdr")
        WDTCSR=0x38;
        WDTCSR=0x28;
        #ifdef _OPTIMIZE_SIZE_
        #pragma optsize+
        #endif
}

// Read the 8 most significant bits
// of the AD conversion result
unsigned char read_adc(unsigned char adc_input)
{
ADMUX=adc_input | (ADC_VREF_TYPE & 0xff);
// Delay needed for the stabilization of the ADC input voltage
delay_us(10);
// Start the AD conversion
ADCSRA|=0x40;
// Wait for the AD conversion to complete
while ((ADCSRA & 0x10)==0);
ADCSRA|=0x10;
return ADCH;
}

void main(void)
{
// Crystal Oscillator division factor: 3
#pragma optsize-
CLKPR=0x80;
CLKPR=0x03;
#ifdef _OPTIMIZE_SIZE_
#pragma optsize+
#endif

PORTB=0x00; DDRB=0b00000011;
PORTC=0x00; DDRC=0x10;
PORTD=0b00001000; DDRD=0b00100000;

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
// Mode: Normal top=0xFF
// OC0A output: Disconnected
// OC0B output: Disconnected
TCCR0A=0x00;
TCCR0B=0x00;
TCNT0=0x00;
OCR0A=0x00;
OCR0B=0x00;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer1 Stopped
// Mode: Normal top=0xFFFF
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;

// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer2 Stopped
// Mode: Normal top=0xFF
// OC2A output: Disconnected
// OC2B output: Disconnected
ASSR=0x00;
TCCR2A=0x00;
TCCR2B=0x00;
TCNT2=0x00;
OCR2A=0x00;
OCR2B=0x00;

// External Interrupt(s) initialization
// INT0: Off
// INT1: On
// INT1 Mode: Low level
// Interrupt on any change on pins PCINT0-7: Off
// Interrupt on any change on pins PCINT8-14: Off
// Interrupt on any change on pins PCINT16-23: Off
EICRA=0x00;
EIMSK=0x02;
EIFR=0x02;
PCICR=0x00;

TIMSK0=0x00; TIMSK1=0x00; TIMSK2=0x00;

// USART initialization
// USART disabled
UCSR0B=0x00;

// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
ADCSRB=0x00;
DIDR1=0x00;

// ADC initialization
// ADC Clock frequency: 15,625 kHz
// ADC Voltage Reference: Int., cap. on AREF
// ADC Auto Trigger Source: ADC Stopped
// Only the 8 most significant bits of
// the AD conversion result are used
// Digital input buffers on ADC0: On, ADC1: On, ADC2: On, ADC3: On
// ADC4: On, ADC5: On
DIDR0=0x00;
ADMUX=ADC_VREF_TYPE & 0xff;
ADCSRA=0x86;

// SPI initialization
// SPI disabled
SPCR=0x00;

// TWI initialization
// TWI disabled
TWCR=0x00;

LED = 1; delay_ms(25); LED = 0;

// Watchdog Timer initialization
// Watchdog Timer Prescaler: OSC/512k
// Watchdog Timer interrupt: Off
#pragma optsize-
#asm("wdr")
WDTCSR=0x38;
WDTCSR=0x28;
#ifdef _OPTIMIZE_SIZE_
#pragma optsize+
#endif

// Global enable interrupts
#asm("sei")

SMCR = 0b00000101; // Power-down Mode Страница 43 мануала ATmega48
#asm("sleep"); //Вводит контроллер в режим энергосбережения
// Просыпаемся от прерыванием INT1 и сразу на обработчик

while (1)
      {
        delay_ms(2000); // Ждем чтобы разрядился конденсатор
       
        // Если сеть 220VAC есть, то засыпаем
        if (LineCtr == 0)
        {
                BOOSTER_OFF; LED = 0;
                main();
        }
       
        // Если пропала сеть 220VAC
        if (LineCtr == 1)
        {
                // Первое значение batU берется из обработчика (сюда по-другому и не попасть)
                if (batU >= 148 && LineCtr == 1 && PIND.3 == 1)
                {
                        ctr = 20; batU = 0;
                        while(ctr) // цикл из 20 измерений
                        {ctr--; batU = batU + read_adc(2);}
                        batU = batU / 20; // вычисляем среднее
                       
                        BOOSTER_ON;
                        delay_ms(500);
                }
                else main();
        }
      }
}

// External Interrupt 1 service routine
// В прерывании строжевой таймер не работает (?)
interrupt [EXT_INT1] void ext_int1_isr(void)
{
        BOOSTER_OFF;
       
        // Запускаем функцию контроля за зарядом АКБ
        //*******************************************************************
        ctr = 20; batU = 0;
        while(ctr) // цикл из 20 измерений
        {ctr--; batU = batU + read_adc(2);}
        batU = batU / 20; // вычисляем среднее

        /* Вычисление делителя на контроль напряжение АКБ
        Коэф. деления = 13.1V / 0.833V = 15,726
        Опорное напряжение (измеренное) = 1.100V
        Таким образом разрешение АЦП = 1.100 / 256 = 4,297 mV
        Для получения нижней границы заряда в 10V нужно
        10V / 15.726 = 636 mV на АЦП, или ее значения 636 mV / 4.297 = 148
        Для получения 13.4V нужно значение АЦП = 198*/
       
        // Если напряжение на АКБ меньше 13.4V, то заряжаем
        if(batU <= 207) {BD140 = 1; LED = 0;} // Включаем заряд АКБ
        else {BD140 = 0; LED = 0;} // Выключаем заряд АКБ
        delay_ms(500);
        //*******************************************************************
}

Re: Проблемы со сторожевым таймером. Что я делаю неправильно

Ср сен 11, 2013 14:49:06

С чего взяли, что не ресетится? Между LED= 0 в настройках и LED= 1 в теле проходит доля секунды. Вот и кажется, что не моргает.

Re: Проблемы со сторожевым таймером. Что я делаю неправильно

Ср сен 11, 2013 14:50:27

Я уже написал об этом.

while (1)
{
delay_ms(8000);
LED = 1;
}

Просто изначально в первом посте забыл вписать.

Re: Проблемы со сторожевым таймером. Что я делаю неправильно

Ср сен 11, 2013 14:51:01

стало интересно-почему так,погуглил-почитал,после повер-доун проц долго просыпается,по идее пваш проц должен проснуться от сторожевого таймера но этого не происходит,значит както отключается,как?
нашел похожую проблему http://530.ru/wwwboards/mcontrol/2233/messages/673767.shtml

Re: Проблемы со сторожевым таймером. Что я делаю неправильно

Ср сен 11, 2013 14:51:39

Кажется, я начал доезжать на своём бронепоезде.
Без внешнего прерывания МК засыпает, и через 4 секунды его ресетит сторож?
После ресета светодиод вспыхивает на 25 мс и гаснет.
Без внешнего прерывания так продолжается бесконечно долго. Правильно?
НО!
Если во время сна дёрнуть прерыванием, то после его обработки МК зависает в основном цикле с зажжёным светодидом, и МК не ресетится?
Ассемблерный файл смотрели? Может, компилятор где-то что-то отключил? Фьюз сторожа выставлен?

Re: Проблемы со сторожевым таймером. Что я делаю неправильно

Ср сен 11, 2013 14:53:15

Да, все правильно )))
Фьюз WDTON выставлен.

Re: Проблемы со сторожевым таймером. Что я делаю неправильно

Ср сен 11, 2013 15:01:24

VNN84 писал(а):Фьюз WDTON выставлен.

В смысле, запрограммирован? Т.е. работает по нижней строчке таблицы?
Изображение

Re: Проблемы со сторожевым таймером. Что я делаю неправильно

Ср сен 11, 2013 15:02:04

Да, верно.

Но и без него тоже пробовал - та же хрень.

Re: Проблемы со сторожевым таймером. Что я делаю неправильно

Ср сен 11, 2013 15:07:05

Я уже с этой проблемой неделю бьюсь, уже перепробовал все ))). Вот и решил узнать в форуме, может я в упор не вижу ошибку.

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

Re: Проблемы со сторожевым таймером. Что я делаю неправильно

Ср сен 11, 2013 15:13:29

Посмотрите ассемблерный файл.
Не ресетит ли сторож delay_ms или ещё кто.

Re: Проблемы со сторожевым таймером. Что я делаю неправильно

Ср сен 11, 2013 15:14:50

СПС. Попробую.
Но ассемблер уже хорошенько подзабыл )))

Спойлер
Код:
;CodeVisionAVR C Compiler V2.05.0 Professional
;(C) Copyright 1998-2010 Pavel Haiduc, HP InfoTech s.r.l.
;http://www.hpinfotech.com

;Chip type                : ATmega48PA
;Program type             : Application
;Clock frequency          : 1,000000 MHz
;Memory model             : Small
;Optimize for             : Size
;(s)printf features       : int, width
;(s)scanf features        : int, width
;External RAM size        : 0
;Data Stack size          : 128 byte(s)
;Heap size                : 0 byte(s)
;Promote 'char' to 'int'  : Yes
;'char' is unsigned       : Yes
;8 bit enums              : Yes
;global 'const' stored in FLASH: No
;Enhanced core instructions    : On
;Smart register allocation     : On
;Automatic register allocation : On

   #pragma AVRPART ADMIN PART_NAME ATmega48PA
   #pragma AVRPART MEMORY PROG_FLASH 4096
   #pragma AVRPART MEMORY EEPROM 256
   #pragma AVRPART MEMORY INT_SRAM SIZE 767
   #pragma AVRPART MEMORY INT_SRAM START_ADDR 0x100

   .LISTMAC
   .EQU EERE=0x0
   .EQU EEWE=0x1
   .EQU EEMWE=0x2
   .EQU UDRE=0x5
   .EQU RXC=0x7
   .EQU EECR=0x1F
   .EQU EEDR=0x20
   .EQU EEARL=0x21
   .EQU EEARH=0x22
   .EQU SPSR=0x2D
   .EQU SPDR=0x2E
   .EQU SMCR=0x33
   .EQU MCUSR=0x34
   .EQU MCUCR=0x35
   .EQU WDTCSR=0x60
   .EQU UCSR0A=0xC0
   .EQU UDR0=0xC6
   .EQU SPL=0x3D
   .EQU SPH=0x3E
   .EQU SREG=0x3F
   .EQU GPIOR0=0x1E

   .DEF R0X0=R0
   .DEF R0X1=R1
   .DEF R0X2=R2
   .DEF R0X3=R3
   .DEF R0X4=R4
   .DEF R0X5=R5
   .DEF R0X6=R6
   .DEF R0X7=R7
   .DEF R0X8=R8
   .DEF R0X9=R9
   .DEF R0XA=R10
   .DEF R0XB=R11
   .DEF R0XC=R12
   .DEF R0XD=R13
   .DEF R0XE=R14
   .DEF R0XF=R15
   .DEF R0X10=R16
   .DEF R0X11=R17
   .DEF R0X12=R18
   .DEF R0X13=R19
   .DEF R0X14=R20
   .DEF R0X15=R21
   .DEF R0X16=R22
   .DEF R0X17=R23
   .DEF R0X18=R24
   .DEF R0X19=R25
   .DEF R0X1A=R26
   .DEF R0X1B=R27
   .DEF R0X1C=R28
   .DEF R0X1D=R29
   .DEF R0X1E=R30
   .DEF R0X1F=R31

   .EQU __SRAM_START=0x0100
   .EQU __SRAM_END=0x02FF
   .EQU __DSTACK_SIZE=0x0080
   .EQU __HEAP_SIZE=0x0000
   .EQU __CLEAR_SRAM_SIZE=__SRAM_END-__SRAM_START+1

   .MACRO __CPD1N
   CPI  R30,LOW(@0)
   LDI  R26,HIGH(@0)
   CPC  R31,R26
   LDI  R26,BYTE3(@0)
   CPC  R22,R26
   LDI  R26,BYTE4(@0)
   CPC  R23,R26
   .ENDM

   .MACRO __CPD2N
   CPI  R26,LOW(@0)
   LDI  R30,HIGH(@0)
   CPC  R27,R30
   LDI  R30,BYTE3(@0)
   CPC  R24,R30
   LDI  R30,BYTE4(@0)
   CPC  R25,R30
   .ENDM

   .MACRO __CPWRR
   CP   R@0,R@2
   CPC  R@1,R@3
   .ENDM

   .MACRO __CPWRN
   CPI  R@0,LOW(@2)
   LDI  R30,HIGH(@2)
   CPC  R@1,R30
   .ENDM

   .MACRO __ADDB1MN
   SUBI R30,LOW(-@0-(@1))
   .ENDM

   .MACRO __ADDB2MN
   SUBI R26,LOW(-@0-(@1))
   .ENDM

   .MACRO __ADDW1MN
   SUBI R30,LOW(-@0-(@1))
   SBCI R31,HIGH(-@0-(@1))
   .ENDM

   .MACRO __ADDW2MN
   SUBI R26,LOW(-@0-(@1))
   SBCI R27,HIGH(-@0-(@1))
   .ENDM

   .MACRO __ADDW1FN
   SUBI R30,LOW(-2*@0-(@1))
   SBCI R31,HIGH(-2*@0-(@1))
   .ENDM

   .MACRO __ADDD1FN
   SUBI R30,LOW(-2*@0-(@1))
   SBCI R31,HIGH(-2*@0-(@1))
   SBCI R22,BYTE3(-2*@0-(@1))
   .ENDM

   .MACRO __ADDD1N
   SUBI R30,LOW(-@0)
   SBCI R31,HIGH(-@0)
   SBCI R22,BYTE3(-@0)
   SBCI R23,BYTE4(-@0)
   .ENDM

   .MACRO __ADDD2N
   SUBI R26,LOW(-@0)
   SBCI R27,HIGH(-@0)
   SBCI R24,BYTE3(-@0)
   SBCI R25,BYTE4(-@0)
   .ENDM

   .MACRO __SUBD1N
   SUBI R30,LOW(@0)
   SBCI R31,HIGH(@0)
   SBCI R22,BYTE3(@0)
   SBCI R23,BYTE4(@0)
   .ENDM

   .MACRO __SUBD2N
   SUBI R26,LOW(@0)
   SBCI R27,HIGH(@0)
   SBCI R24,BYTE3(@0)
   SBCI R25,BYTE4(@0)
   .ENDM

   .MACRO __ANDBMNN
   LDS  R30,@0+(@1)
   ANDI R30,LOW(@2)
   STS  @0+(@1),R30
   .ENDM

   .MACRO __ANDWMNN
   LDS  R30,@0+(@1)
   ANDI R30,LOW(@2)
   STS  @0+(@1),R30
   LDS  R30,@0+(@1)+1
   ANDI R30,HIGH(@2)
   STS  @0+(@1)+1,R30
   .ENDM

   .MACRO __ANDD1N
   ANDI R30,LOW(@0)
   ANDI R31,HIGH(@0)
   ANDI R22,BYTE3(@0)
   ANDI R23,BYTE4(@0)
   .ENDM

   .MACRO __ANDD2N
   ANDI R26,LOW(@0)
   ANDI R27,HIGH(@0)
   ANDI R24,BYTE3(@0)
   ANDI R25,BYTE4(@0)
   .ENDM

   .MACRO __ORBMNN
   LDS  R30,@0+(@1)
   ORI  R30,LOW(@2)
   STS  @0+(@1),R30
   .ENDM

   .MACRO __ORWMNN
   LDS  R30,@0+(@1)
   ORI  R30,LOW(@2)
   STS  @0+(@1),R30
   LDS  R30,@0+(@1)+1
   ORI  R30,HIGH(@2)
   STS  @0+(@1)+1,R30
   .ENDM

   .MACRO __ORD1N
   ORI  R30,LOW(@0)
   ORI  R31,HIGH(@0)
   ORI  R22,BYTE3(@0)
   ORI  R23,BYTE4(@0)
   .ENDM

   .MACRO __ORD2N
   ORI  R26,LOW(@0)
   ORI  R27,HIGH(@0)
   ORI  R24,BYTE3(@0)
   ORI  R25,BYTE4(@0)
   .ENDM

   .MACRO __DELAY_USB
   LDI  R24,LOW(@0)
__DELAY_USB_LOOP:
   DEC  R24
   BRNE __DELAY_USB_LOOP
   .ENDM

   .MACRO __DELAY_USW
   LDI  R24,LOW(@0)
   LDI  R25,HIGH(@0)
__DELAY_USW_LOOP:
   SBIW R24,1
   BRNE __DELAY_USW_LOOP
   .ENDM

   .MACRO __GETD1S
   LDD  R30,Y+@0
   LDD  R31,Y+@0+1
   LDD  R22,Y+@0+2
   LDD  R23,Y+@0+3
   .ENDM

   .MACRO __GETD2S
   LDD  R26,Y+@0
   LDD  R27,Y+@0+1
   LDD  R24,Y+@0+2
   LDD  R25,Y+@0+3
   .ENDM

   .MACRO __PUTD1S
   STD  Y+@0,R30
   STD  Y+@0+1,R31
   STD  Y+@0+2,R22
   STD  Y+@0+3,R23
   .ENDM

   .MACRO __PUTD2S
   STD  Y+@0,R26
   STD  Y+@0+1,R27
   STD  Y+@0+2,R24
   STD  Y+@0+3,R25
   .ENDM

   .MACRO __PUTDZ2
   STD  Z+@0,R26
   STD  Z+@0+1,R27
   STD  Z+@0+2,R24
   STD  Z+@0+3,R25
   .ENDM

   .MACRO __CLRD1S
   STD  Y+@0,R30
   STD  Y+@0+1,R30
   STD  Y+@0+2,R30
   STD  Y+@0+3,R30
   .ENDM

   .MACRO __POINTB1MN
   LDI  R30,LOW(@0+(@1))
   .ENDM

   .MACRO __POINTW1MN
   LDI  R30,LOW(@0+(@1))
   LDI  R31,HIGH(@0+(@1))
   .ENDM

   .MACRO __POINTD1M
   LDI  R30,LOW(@0)
   LDI  R31,HIGH(@0)
   LDI  R22,BYTE3(@0)
   LDI  R23,BYTE4(@0)
   .ENDM

   .MACRO __POINTW1FN
   LDI  R30,LOW(2*@0+(@1))
   LDI  R31,HIGH(2*@0+(@1))
   .ENDM

   .MACRO __POINTD1FN
   LDI  R30,LOW(2*@0+(@1))
   LDI  R31,HIGH(2*@0+(@1))
   LDI  R22,BYTE3(2*@0+(@1))
   LDI  R23,BYTE4(2*@0+(@1))
   .ENDM

   .MACRO __POINTB2MN
   LDI  R26,LOW(@0+(@1))
   .ENDM

   .MACRO __POINTW2MN
   LDI  R26,LOW(@0+(@1))
   LDI  R27,HIGH(@0+(@1))
   .ENDM

   .MACRO __POINTBRM
   LDI  R@0,LOW(@1)
   .ENDM

   .MACRO __POINTWRM
   LDI  R@0,LOW(@2)
   LDI  R@1,HIGH(@2)
   .ENDM

   .MACRO __POINTBRMN
   LDI  R@0,LOW(@1+(@2))
   .ENDM

   .MACRO __POINTWRMN
   LDI  R@0,LOW(@2+(@3))
   LDI  R@1,HIGH(@2+(@3))
   .ENDM

   .MACRO __POINTWRFN
   LDI  R@0,LOW(@2*2+(@3))
   LDI  R@1,HIGH(@2*2+(@3))
   .ENDM

   .MACRO __GETD1N
   LDI  R30,LOW(@0)
   LDI  R31,HIGH(@0)
   LDI  R22,BYTE3(@0)
   LDI  R23,BYTE4(@0)
   .ENDM

   .MACRO __GETD2N
   LDI  R26,LOW(@0)
   LDI  R27,HIGH(@0)
   LDI  R24,BYTE3(@0)
   LDI  R25,BYTE4(@0)
   .ENDM

   .MACRO __GETB1MN
   LDS  R30,@0+(@1)
   .ENDM

   .MACRO __GETB1HMN
   LDS  R31,@0+(@1)
   .ENDM

   .MACRO __GETW1MN
   LDS  R30,@0+(@1)
   LDS  R31,@0+(@1)+1
   .ENDM

   .MACRO __GETD1MN
   LDS  R30,@0+(@1)
   LDS  R31,@0+(@1)+1
   LDS  R22,@0+(@1)+2
   LDS  R23,@0+(@1)+3
   .ENDM

   .MACRO __GETBRMN
   LDS  R@0,@1+(@2)
   .ENDM

   .MACRO __GETWRMN
   LDS  R@0,@2+(@3)
   LDS  R@1,@2+(@3)+1
   .ENDM

   .MACRO __GETWRZ
   LDD  R@0,Z+@2
   LDD  R@1,Z+@2+1
   .ENDM

   .MACRO __GETD2Z
   LDD  R26,Z+@0
   LDD  R27,Z+@0+1
   LDD  R24,Z+@0+2
   LDD  R25,Z+@0+3
   .ENDM

   .MACRO __GETB2MN
   LDS  R26,@0+(@1)
   .ENDM

   .MACRO __GETW2MN
   LDS  R26,@0+(@1)
   LDS  R27,@0+(@1)+1
   .ENDM

   .MACRO __GETD2MN
   LDS  R26,@0+(@1)
   LDS  R27,@0+(@1)+1
   LDS  R24,@0+(@1)+2
   LDS  R25,@0+(@1)+3
   .ENDM

   .MACRO __PUTB1MN
   STS  @0+(@1),R30
   .ENDM

   .MACRO __PUTW1MN
   STS  @0+(@1),R30
   STS  @0+(@1)+1,R31
   .ENDM

   .MACRO __PUTD1MN
   STS  @0+(@1),R30
   STS  @0+(@1)+1,R31
   STS  @0+(@1)+2,R22
   STS  @0+(@1)+3,R23
   .ENDM

   .MACRO __PUTB1EN
   LDI  R26,LOW(@0+(@1))
   LDI  R27,HIGH(@0+(@1))
   RCALL __EEPROMWRB
   .ENDM

   .MACRO __PUTW1EN
   LDI  R26,LOW(@0+(@1))
   LDI  R27,HIGH(@0+(@1))
   RCALL __EEPROMWRW
   .ENDM

   .MACRO __PUTD1EN
   LDI  R26,LOW(@0+(@1))
   LDI  R27,HIGH(@0+(@1))
   RCALL __EEPROMWRD
   .ENDM

   .MACRO __PUTBR0MN
   STS  @0+(@1),R0
   .ENDM

   .MACRO __PUTBMRN
   STS  @0+(@1),R@2
   .ENDM

   .MACRO __PUTWMRN
   STS  @0+(@1),R@2
   STS  @0+(@1)+1,R@3
   .ENDM

   .MACRO __PUTBZR
   STD  Z+@1,R@0
   .ENDM

   .MACRO __PUTWZR
   STD  Z+@2,R@0
   STD  Z+@2+1,R@1
   .ENDM

   .MACRO __GETW1R
   MOV  R30,R@0
   MOV  R31,R@1
   .ENDM

   .MACRO __GETW2R
   MOV  R26,R@0
   MOV  R27,R@1
   .ENDM

   .MACRO __GETWRN
   LDI  R@0,LOW(@2)
   LDI  R@1,HIGH(@2)
   .ENDM

   .MACRO __PUTW1R
   MOV  R@0,R30
   MOV  R@1,R31
   .ENDM

   .MACRO __PUTW2R
   MOV  R@0,R26
   MOV  R@1,R27
   .ENDM

   .MACRO __ADDWRN
   SUBI R@0,LOW(-@2)
   SBCI R@1,HIGH(-@2)
   .ENDM

   .MACRO __ADDWRR
   ADD  R@0,R@2
   ADC  R@1,R@3
   .ENDM

   .MACRO __SUBWRN
   SUBI R@0,LOW(@2)
   SBCI R@1,HIGH(@2)
   .ENDM

   .MACRO __SUBWRR
   SUB  R@0,R@2
   SBC  R@1,R@3
   .ENDM

   .MACRO __ANDWRN
   ANDI R@0,LOW(@2)
   ANDI R@1,HIGH(@2)
   .ENDM

   .MACRO __ANDWRR
   AND  R@0,R@2
   AND  R@1,R@3
   .ENDM

   .MACRO __ORWRN
   ORI  R@0,LOW(@2)
   ORI  R@1,HIGH(@2)
   .ENDM

   .MACRO __ORWRR
   OR   R@0,R@2
   OR   R@1,R@3
   .ENDM

   .MACRO __EORWRR
   EOR  R@0,R@2
   EOR  R@1,R@3
   .ENDM

   .MACRO __GETWRS
   LDD  R@0,Y+@2
   LDD  R@1,Y+@2+1
   .ENDM

   .MACRO __PUTBSR
   STD  Y+@1,R@0
   .ENDM

   .MACRO __PUTWSR
   STD  Y+@2,R@0
   STD  Y+@2+1,R@1
   .ENDM

   .MACRO __MOVEWRR
   MOV  R@0,R@2
   MOV  R@1,R@3
   .ENDM

   .MACRO __INWR
   IN   R@0,@2
   IN   R@1,@2+1
   .ENDM

   .MACRO __OUTWR
   OUT  @2+1,R@1
   OUT  @2,R@0
   .ENDM

   .MACRO __CALL1MN
   LDS  R30,@0+(@1)
   LDS  R31,@0+(@1)+1
   ICALL
   .ENDM

   .MACRO __CALL1FN
   LDI  R30,LOW(2*@0+(@1))
   LDI  R31,HIGH(2*@0+(@1))
   RCALL __GETW1PF
   ICALL
   .ENDM

   .MACRO __CALL2EN
   LDI  R26,LOW(@0+(@1))
   LDI  R27,HIGH(@0+(@1))
   RCALL __EEPROMRDW
   ICALL
   .ENDM

   .MACRO __GETW1STACK
   IN   R26,SPL
   IN   R27,SPH
   ADIW R26,@0+1
   LD   R30,X+
   LD   R31,X
   .ENDM

   .MACRO __GETD1STACK
   IN   R26,SPL
   IN   R27,SPH
   ADIW R26,@0+1
   LD   R30,X+
   LD   R31,X+
   LD   R22,X
   .ENDM

   .MACRO __NBST
   BST  R@0,@1
   IN   R30,SREG
   LDI  R31,0x40
   EOR  R30,R31
   OUT  SREG,R30
   .ENDM


   .MACRO __PUTB1SN
   LDD  R26,Y+@0
   LDD  R27,Y+@0+1
   SUBI R26,LOW(-@1)
   SBCI R27,HIGH(-@1)
   ST   X,R30
   .ENDM

   .MACRO __PUTW1SN
   LDD  R26,Y+@0
   LDD  R27,Y+@0+1
   SUBI R26,LOW(-@1)
   SBCI R27,HIGH(-@1)
   ST   X+,R30
   ST   X,R31
   .ENDM

   .MACRO __PUTD1SN
   LDD  R26,Y+@0
   LDD  R27,Y+@0+1
   SUBI R26,LOW(-@1)
   SBCI R27,HIGH(-@1)
   RCALL __PUTDP1
   .ENDM

   .MACRO __PUTB1SNS
   LDD  R26,Y+@0
   LDD  R27,Y+@0+1
   ADIW R26,@1
   ST   X,R30
   .ENDM

   .MACRO __PUTW1SNS
   LDD  R26,Y+@0
   LDD  R27,Y+@0+1
   ADIW R26,@1
   ST   X+,R30
   ST   X,R31
   .ENDM

   .MACRO __PUTD1SNS
   LDD  R26,Y+@0
   LDD  R27,Y+@0+1
   ADIW R26,@1
   RCALL __PUTDP1
   .ENDM

   .MACRO __PUTB1PMN
   LDS  R26,@0
   LDS  R27,@0+1
   SUBI R26,LOW(-@1)
   SBCI R27,HIGH(-@1)
   ST   X,R30
   .ENDM

   .MACRO __PUTW1PMN
   LDS  R26,@0
   LDS  R27,@0+1
   SUBI R26,LOW(-@1)
   SBCI R27,HIGH(-@1)
   ST   X+,R30
   ST   X,R31
   .ENDM

   .MACRO __PUTD1PMN
   LDS  R26,@0
   LDS  R27,@0+1
   SUBI R26,LOW(-@1)
   SBCI R27,HIGH(-@1)
   RCALL __PUTDP1
   .ENDM

   .MACRO __PUTB1PMNS
   LDS  R26,@0
   LDS  R27,@0+1
   ADIW R26,@1
   ST   X,R30
   .ENDM

   .MACRO __PUTW1PMNS
   LDS  R26,@0
   LDS  R27,@0+1
   ADIW R26,@1
   ST   X+,R30
   ST   X,R31
   .ENDM

   .MACRO __PUTD1PMNS
   LDS  R26,@0
   LDS  R27,@0+1
   ADIW R26,@1
   RCALL __PUTDP1
   .ENDM

   .MACRO __PUTB1RN
   MOVW R26,R@0
   SUBI R26,LOW(-@1)
   SBCI R27,HIGH(-@1)
   ST   X,R30
   .ENDM

   .MACRO __PUTW1RN
   MOVW R26,R@0
   SUBI R26,LOW(-@1)
   SBCI R27,HIGH(-@1)
   ST   X+,R30
   ST   X,R31
   .ENDM

   .MACRO __PUTD1RN
   MOVW R26,R@0
   SUBI R26,LOW(-@1)
   SBCI R27,HIGH(-@1)
   RCALL __PUTDP1
   .ENDM

   .MACRO __PUTB1RNS
   MOVW R26,R@0
   ADIW R26,@1
   ST   X,R30
   .ENDM

   .MACRO __PUTW1RNS
   MOVW R26,R@0
   ADIW R26,@1
   ST   X+,R30
   ST   X,R31
   .ENDM

   .MACRO __PUTD1RNS
   MOVW R26,R@0
   ADIW R26,@1
   RCALL __PUTDP1
   .ENDM

   .MACRO __PUTB1RON
   MOV  R26,R@0
   MOV  R27,R@1
   SUBI R26,LOW(-@2)
   SBCI R27,HIGH(-@2)
   ST   X,R30
   .ENDM

   .MACRO __PUTW1RON
   MOV  R26,R@0
   MOV  R27,R@1
   SUBI R26,LOW(-@2)
   SBCI R27,HIGH(-@2)
   ST   X+,R30
   ST   X,R31
   .ENDM

   .MACRO __PUTD1RON
   MOV  R26,R@0
   MOV  R27,R@1
   SUBI R26,LOW(-@2)
   SBCI R27,HIGH(-@2)
   RCALL __PUTDP1
   .ENDM

   .MACRO __PUTB1RONS
   MOV  R26,R@0
   MOV  R27,R@1
   ADIW R26,@2
   ST   X,R30
   .ENDM

   .MACRO __PUTW1RONS
   MOV  R26,R@0
   MOV  R27,R@1
   ADIW R26,@2
   ST   X+,R30
   ST   X,R31
   .ENDM

   .MACRO __PUTD1RONS
   MOV  R26,R@0
   MOV  R27,R@1
   ADIW R26,@2
   RCALL __PUTDP1
   .ENDM


   .MACRO __GETB1SX
   MOVW R30,R28
   SUBI R30,LOW(-@0)
   SBCI R31,HIGH(-@0)
   LD   R30,Z
   .ENDM

   .MACRO __GETB1HSX
   MOVW R30,R28
   SUBI R30,LOW(-@0)
   SBCI R31,HIGH(-@0)
   LD   R31,Z
   .ENDM

   .MACRO __GETW1SX
   MOVW R30,R28
   SUBI R30,LOW(-@0)
   SBCI R31,HIGH(-@0)
   LD   R0,Z+
   LD   R31,Z
   MOV  R30,R0
   .ENDM

   .MACRO __GETD1SX
   MOVW R30,R28
   SUBI R30,LOW(-@0)
   SBCI R31,HIGH(-@0)
   LD   R0,Z+
   LD   R1,Z+
   LD   R22,Z+
   LD   R23,Z
   MOVW R30,R0
   .ENDM

   .MACRO __GETB2SX
   MOVW R26,R28
   SUBI R26,LOW(-@0)
   SBCI R27,HIGH(-@0)
   LD   R26,X
   .ENDM

   .MACRO __GETW2SX
   MOVW R26,R28
   SUBI R26,LOW(-@0)
   SBCI R27,HIGH(-@0)
   LD   R0,X+
   LD   R27,X
   MOV  R26,R0
   .ENDM

   .MACRO __GETD2SX
   MOVW R26,R28
   SUBI R26,LOW(-@0)
   SBCI R27,HIGH(-@0)
   LD   R0,X+
   LD   R1,X+
   LD   R24,X+
   LD   R25,X
   MOVW R26,R0
   .ENDM

   .MACRO __GETBRSX
   MOVW R30,R28
   SUBI R30,LOW(-@1)
   SBCI R31,HIGH(-@1)
   LD   R@0,Z
   .ENDM

   .MACRO __GETWRSX
   MOVW R30,R28
   SUBI R30,LOW(-@2)
   SBCI R31,HIGH(-@2)
   LD   R@0,Z+
   LD   R@1,Z
   .ENDM

   .MACRO __GETBRSX2
   MOVW R26,R28
   SUBI R26,LOW(-@1)
   SBCI R27,HIGH(-@1)
   LD   R@0,X
   .ENDM

   .MACRO __GETWRSX2
   MOVW R26,R28
   SUBI R26,LOW(-@2)
   SBCI R27,HIGH(-@2)
   LD   R@0,X+
   LD   R@1,X
   .ENDM

   .MACRO __LSLW8SX
   MOVW R30,R28
   SUBI R30,LOW(-@0)
   SBCI R31,HIGH(-@0)
   LD   R31,Z
   CLR  R30
   .ENDM

   .MACRO __PUTB1SX
   MOVW R26,R28
   SUBI R26,LOW(-@0)
   SBCI R27,HIGH(-@0)
   ST   X,R30
   .ENDM

   .MACRO __PUTW1SX
   MOVW R26,R28
   SUBI R26,LOW(-@0)
   SBCI R27,HIGH(-@0)
   ST   X+,R30
   ST   X,R31
   .ENDM

   .MACRO __PUTD1SX
   MOVW R26,R28
   SUBI R26,LOW(-@0)
   SBCI R27,HIGH(-@0)
   ST   X+,R30
   ST   X+,R31
   ST   X+,R22
   ST   X,R23
   .ENDM

   .MACRO __CLRW1SX
   MOVW R26,R28
   SUBI R26,LOW(-@0)
   SBCI R27,HIGH(-@0)
   ST   X+,R30
   ST   X,R30
   .ENDM

   .MACRO __CLRD1SX
   MOVW R26,R28
   SUBI R26,LOW(-@0)
   SBCI R27,HIGH(-@0)
   ST   X+,R30
   ST   X+,R30
   ST   X+,R30
   ST   X,R30
   .ENDM

   .MACRO __PUTB2SX
   MOVW R30,R28
   SUBI R30,LOW(-@0)
   SBCI R31,HIGH(-@0)
   ST   Z,R26
   .ENDM

   .MACRO __PUTW2SX
   MOVW R30,R28
   SUBI R30,LOW(-@0)
   SBCI R31,HIGH(-@0)
   ST   Z+,R26
   ST   Z,R27
   .ENDM

   .MACRO __PUTD2SX
   MOVW R30,R28
   SUBI R30,LOW(-@0)
   SBCI R31,HIGH(-@0)
   ST   Z+,R26
   ST   Z+,R27
   ST   Z+,R24
   ST   Z,R25
   .ENDM

   .MACRO __PUTBSRX
   MOVW R30,R28
   SUBI R30,LOW(-@1)
   SBCI R31,HIGH(-@1)
   ST   Z,R@0
   .ENDM

   .MACRO __PUTWSRX
   MOVW R30,R28
   SUBI R30,LOW(-@2)
   SBCI R31,HIGH(-@2)
   ST   Z+,R@0
   ST   Z,R@1
   .ENDM

   .MACRO __PUTB1SNX
   MOVW R26,R28
   SUBI R26,LOW(-@0)
   SBCI R27,HIGH(-@0)
   LD   R0,X+
   LD   R27,X
   MOV  R26,R0
   SUBI R26,LOW(-@1)
   SBCI R27,HIGH(-@1)
   ST   X,R30
   .ENDM

   .MACRO __PUTW1SNX
   MOVW R26,R28
   SUBI R26,LOW(-@0)
   SBCI R27,HIGH(-@0)
   LD   R0,X+
   LD   R27,X
   MOV  R26,R0
   SUBI R26,LOW(-@1)
   SBCI R27,HIGH(-@1)
   ST   X+,R30
   ST   X,R31
   .ENDM

   .MACRO __PUTD1SNX
   MOVW R26,R28
   SUBI R26,LOW(-@0)
   SBCI R27,HIGH(-@0)
   LD   R0,X+
   LD   R27,X
   MOV  R26,R0
   SUBI R26,LOW(-@1)
   SBCI R27,HIGH(-@1)
   ST   X+,R30
   ST   X+,R31
   ST   X+,R22
   ST   X,R23
   .ENDM

   .MACRO __MULBRR
   MULS R@0,R@1
   MOVW R30,R0
   .ENDM

   .MACRO __MULBRRU
   MUL  R@0,R@1
   MOVW R30,R0
   .ENDM

   .MACRO __MULBRR0
   MULS R@0,R@1
   .ENDM

   .MACRO __MULBRRU0
   MUL  R@0,R@1
   .ENDM

   .MACRO __MULBNWRU
   LDI  R26,@2
   MUL  R26,R@0
   MOVW R30,R0
   MUL  R26,R@1
   ADD  R31,R0
   .ENDM

;NAME DEFINITIONS FOR GLOBAL VARIABLES ALLOCATED TO REGISTERS
   .DEF _batU=R3
   .DEF _ctr=R6

;GPIOR0 INITIALIZATION VALUE
   .EQU __GPIOR0_INIT=0x00

   .CSEG
   .ORG 0x00

;START OF CODE MARKER
__START_OF_CODE:

;INTERRUPT VECTORS
   RJMP __RESET
   RJMP 0x00
   RJMP _ext_int1_isr
   RJMP 0x00
   RJMP 0x00
   RJMP 0x00
   RJMP 0x00
   RJMP 0x00
   RJMP 0x00
   RJMP 0x00
   RJMP 0x00
   RJMP 0x00
   RJMP 0x00
   RJMP 0x00
   RJMP 0x00
   RJMP 0x00
   RJMP 0x00
   RJMP 0x00
   RJMP 0x00
   RJMP 0x00
   RJMP 0x00
   RJMP 0x00
   RJMP 0x00
   RJMP 0x00
   RJMP 0x00
   RJMP 0x00

_0x33:
   .DB  0x0,0x0,0x0,0x0

__GLOBAL_INI_TBL:
   .DW  0x04
   .DW  0x03
   .DW  _0x33*2

_0xFFFFFFFF:
   .DW  0

__RESET:
   CLI
   CLR  R30
   OUT  EECR,R30
   OUT  MCUCR,R30

;DISABLE WATCHDOG
   LDI  R31,0x18
   WDR
   IN   R26,MCUSR
   CBR  R26,8
   OUT  MCUSR,R26
   STS  WDTCSR,R31
   STS  WDTCSR,R30

;CLEAR R2-R14
   LDI  R24,(14-2)+1
   LDI  R26,2
   CLR  R27
__CLEAR_REG:
   ST   X+,R30
   DEC  R24
   BRNE __CLEAR_REG

;CLEAR SRAM
   LDI  R24,LOW(__CLEAR_SRAM_SIZE)
   LDI  R25,HIGH(__CLEAR_SRAM_SIZE)
   LDI  R26,LOW(__SRAM_START)
   LDI  R27,HIGH(__SRAM_START)
__CLEAR_SRAM:
   ST   X+,R30
   SBIW R24,1
   BRNE __CLEAR_SRAM

;GLOBAL VARIABLES INITIALIZATION
   LDI  R30,LOW(__GLOBAL_INI_TBL*2)
   LDI  R31,HIGH(__GLOBAL_INI_TBL*2)
__GLOBAL_INI_NEXT:
   LPM  R24,Z+
   LPM  R25,Z+
   SBIW R24,0
   BREQ __GLOBAL_INI_END
   LPM  R26,Z+
   LPM  R27,Z+
   LPM  R0,Z+
   LPM  R1,Z+
   MOVW R22,R30
   MOVW R30,R0
__GLOBAL_INI_LOOP:
   LPM  R0,Z+
   ST   X+,R0
   SBIW R24,1
   BRNE __GLOBAL_INI_LOOP
   MOVW R30,R22
   RJMP __GLOBAL_INI_NEXT
__GLOBAL_INI_END:

;GPIOR0 INITIALIZATION
   LDI  R30,__GPIOR0_INIT
   OUT  GPIOR0,R30

;HARDWARE STACK POINTER INITIALIZATION
   LDI  R30,LOW(__SRAM_END-__HEAP_SIZE)
   OUT  SPL,R30
   LDI  R30,HIGH(__SRAM_END-__HEAP_SIZE)
   OUT  SPH,R30

;DATA STACK POINTER INITIALIZATION
   LDI  R28,LOW(__SRAM_START+__DSTACK_SIZE)
   LDI  R29,HIGH(__SRAM_START+__DSTACK_SIZE)

   RJMP _main

   .ESEG
   .ORG 0

   .DSEG
   .ORG 0x180

   .CSEG
;/*****************************************************************
;Chip type               : ATmega48PA
;AVR Core Clock frequency: 8.000000 MHz
;
;Делитель напряжения     : 13.1V / 0.833V = 15,726
;                        Uref = 1.100V
;*****************************************************************/
;#include <mega48pa.h>
   #ifndef __SLEEP_DEFINED__
   #define __SLEEP_DEFINED__
   .EQU __se_bit=0x01
   .EQU __sm_mask=0x0E
   .EQU __sm_adc_noise_red=0x02
   .EQU __sm_powerdown=0x04
   .EQU __sm_powersave=0x06
   .EQU __sm_standby=0x0C
   .EQU __sm_ext_standby=0x0E
   .SET power_ctrl_reg=smcr
   #endif
;#include <delay.h>
;
;#define LED PORTD.5
;#define BD140 PORTC.4
;#define LineCtr PIND.4 // Контроль за некомутируемой частью
;#define BOOSTER_ON PORTB.1 = 0, PORTB.0 = 1
;#define BOOSTER_OFF PORTB.1 = 1, PORTB.0 = 0
;
;#define ADC_VREF_TYPE 0xE0 // Internal Uref
;
;unsigned int batU = 0; // Переменная для хранения напряжения АКБ
;char ctr = 0;
;
;void WDT_off(void)
; 0000 0017 {

   .CSEG
; 0000 0018         #asm("cli")
; 0000 0019         #asm("wdr")
; 0000 001A         /* Clear WDRF in MCUSR */
; 0000 001B         MCUSR &= ~(1<<WDRF);
; 0000 001C         /* Write logical one to WDCE and WDE */
; 0000 001D         /* Keep old prescaler setting to prevent unintentional time-out */
; 0000 001E         WDTCSR |= (1<<WDCE) | (1<<WDE);
; 0000 001F         /* Turn off WDT */
; 0000 0020         WDTCSR = 0x00;
; 0000 0021         #asm("sei")
; 0000 0022 }
;
;void WDT_init()
; 0000 0025 {
; 0000 0026         // Watchdog Timer initialization
; 0000 0027         // Watchdog Timer Prescaler: OSC/512k
; 0000 0028         // Watchdog Timer interrupt: Off
; 0000 0029         #pragma optsize-
; 0000 002A         #asm("wdr")
; 0000 002B         WDTCSR=0x38;
; 0000 002C         WDTCSR=0x28;
; 0000 002D         #ifdef _OPTIMIZE_SIZE_
; 0000 002E         #pragma optsize+
; 0000 002F         #endif
; 0000 0030 }
;
;// Read the 8 most significant bits
;// of the AD conversion result
;unsigned char read_adc(unsigned char adc_input)
; 0000 0035 {
_read_adc:
; 0000 0036 ADMUX=adc_input | (ADC_VREF_TYPE & 0xff);
;   adc_input -> Y+0
   LD   R30,Y
   ORI  R30,LOW(0xE0)
   STS  124,R30
; 0000 0037 // Delay needed for the stabilization of the ADC input voltage
; 0000 0038 delay_us(10);
   __DELAY_USB 3
; 0000 0039 // Start the AD conversion
; 0000 003A ADCSRA|=0x40;
   LDS  R30,122
   ORI  R30,0x40
   STS  122,R30
; 0000 003B // Wait for the AD conversion to complete
; 0000 003C while ((ADCSRA & 0x10)==0);
_0x3:
   LDS  R30,122
   ANDI R30,LOW(0x10)
   BREQ _0x3
; 0000 003D ADCSRA|=0x10;
   LDS  R30,122
   ORI  R30,0x10
   STS  122,R30
; 0000 003E return ADCH;
   LDS  R30,121
   ADIW R28,1
   RET
; 0000 003F }
;
;void main(void)
; 0000 0042 {
_main:
; 0000 0043 // Crystal Oscillator division factor: 3
; 0000 0044 #pragma optsize-
; 0000 0045 CLKPR=0x80;
   LDI  R30,LOW(128)
   STS  97,R30
; 0000 0046 CLKPR=0x03;
   LDI  R30,LOW(3)
   STS  97,R30
; 0000 0047 #ifdef _OPTIMIZE_SIZE_
; 0000 0048 #pragma optsize+
; 0000 0049 #endif
; 0000 004A
; 0000 004B PORTB=0x00; DDRB=0b00000011;
   LDI  R30,LOW(0)
   OUT  0x5,R30
   LDI  R30,LOW(3)
   OUT  0x4,R30
; 0000 004C PORTC=0x00; DDRC=0x10;
   LDI  R30,LOW(0)
   OUT  0x8,R30
   LDI  R30,LOW(16)
   OUT  0x7,R30
; 0000 004D PORTD=0b00001000; DDRD=0b00100000;
   LDI  R30,LOW(8)
   OUT  0xB,R30
   LDI  R30,LOW(32)
   OUT  0xA,R30
; 0000 004E
; 0000 004F // Timer/Counter 0 initialization
; 0000 0050 // Clock source: System Clock
; 0000 0051 // Clock value: Timer 0 Stopped
; 0000 0052 // Mode: Normal top=0xFF
; 0000 0053 // OC0A output: Disconnected
; 0000 0054 // OC0B output: Disconnected
; 0000 0055 TCCR0A=0x00;
   LDI  R30,LOW(0)
   OUT  0x24,R30
; 0000 0056 TCCR0B=0x00;
   OUT  0x25,R30
; 0000 0057 TCNT0=0x00;
   OUT  0x26,R30
; 0000 0058 OCR0A=0x00;
   OUT  0x27,R30
; 0000 0059 OCR0B=0x00;
   OUT  0x28,R30
; 0000 005A
; 0000 005B // Timer/Counter 1 initialization
; 0000 005C // Clock source: System Clock
; 0000 005D // Clock value: Timer1 Stopped
; 0000 005E // Mode: Normal top=0xFFFF
; 0000 005F // OC1A output: Discon.
; 0000 0060 // OC1B output: Discon.
; 0000 0061 // Noise Canceler: Off
; 0000 0062 // Input Capture on Falling Edge
; 0000 0063 // Timer1 Overflow Interrupt: Off
; 0000 0064 // Input Capture Interrupt: Off
; 0000 0065 // Compare A Match Interrupt: Off
; 0000 0066 // Compare B Match Interrupt: Off
; 0000 0067 TCCR1A=0x00;
   STS  128,R30
; 0000 0068 TCCR1B=0x00;
   STS  129,R30
; 0000 0069 TCNT1H=0x00;
   STS  133,R30
; 0000 006A TCNT1L=0x00;
   STS  132,R30
; 0000 006B ICR1H=0x00;
   STS  135,R30
; 0000 006C ICR1L=0x00;
   STS  134,R30
; 0000 006D OCR1AH=0x00;
   STS  137,R30
; 0000 006E OCR1AL=0x00;
   STS  136,R30
; 0000 006F OCR1BH=0x00;
   STS  139,R30
; 0000 0070 OCR1BL=0x00;
   STS  138,R30
; 0000 0071
; 0000 0072 // Timer/Counter 2 initialization
; 0000 0073 // Clock source: System Clock
; 0000 0074 // Clock value: Timer2 Stopped
; 0000 0075 // Mode: Normal top=0xFF
; 0000 0076 // OC2A output: Disconnected
; 0000 0077 // OC2B output: Disconnected
; 0000 0078 ASSR=0x00;
   STS  182,R30
; 0000 0079 TCCR2A=0x00;
   STS  176,R30
; 0000 007A TCCR2B=0x00;
   STS  177,R30
; 0000 007B TCNT2=0x00;
   STS  178,R30
; 0000 007C OCR2A=0x00;
   STS  179,R30
; 0000 007D OCR2B=0x00;
   STS  180,R30
; 0000 007E
; 0000 007F // External Interrupt(s) initialization
; 0000 0080 // INT0: Off
; 0000 0081 // INT1: On
; 0000 0082 // INT1 Mode: Low level
; 0000 0083 // Interrupt on any change on pins PCINT0-7: Off
; 0000 0084 // Interrupt on any change on pins PCINT8-14: Off
; 0000 0085 // Interrupt on any change on pins PCINT16-23: Off
; 0000 0086 EICRA=0x00;
   STS  105,R30
; 0000 0087 EIMSK=0x02;
   LDI  R30,LOW(2)
   OUT  0x1D,R30
; 0000 0088 EIFR=0x02;
   OUT  0x1C,R30
; 0000 0089 PCICR=0x00;
   LDI  R30,LOW(0)
   STS  104,R30
; 0000 008A
; 0000 008B TIMSK0=0x00; TIMSK1=0x00; TIMSK2=0x00;
   STS  110,R30
   STS  111,R30
   STS  112,R30
; 0000 008C
; 0000 008D // USART initialization
; 0000 008E // USART disabled
; 0000 008F UCSR0B=0x00;
   STS  193,R30
; 0000 0090
; 0000 0091 // Analog Comparator initialization
; 0000 0092 // Analog Comparator: Off
; 0000 0093 // Analog Comparator Input Capture by Timer/Counter 1: Off
; 0000 0094 ACSR=0x80;
   LDI  R30,LOW(128)
   OUT  0x30,R30
; 0000 0095 ADCSRB=0x00;
   LDI  R30,LOW(0)
   STS  123,R30
; 0000 0096 DIDR1=0x00;
   STS  127,R30
; 0000 0097
; 0000 0098 // ADC initialization
; 0000 0099 // ADC Clock frequency: 15,625 kHz
; 0000 009A // ADC Voltage Reference: Int., cap. on AREF
; 0000 009B // ADC Auto Trigger Source: ADC Stopped
; 0000 009C // Only the 8 most significant bits of
; 0000 009D // the AD conversion result are used
; 0000 009E // Digital input buffers on ADC0: On, ADC1: On, ADC2: On, ADC3: On
; 0000 009F // ADC4: On, ADC5: On
; 0000 00A0 DIDR0=0x00;
   STS  126,R30
; 0000 00A1 ADMUX=ADC_VREF_TYPE & 0xff;
   LDI  R30,LOW(224)
   STS  124,R30
; 0000 00A2 ADCSRA=0x86;
   LDI  R30,LOW(134)
   STS  122,R30
; 0000 00A3
; 0000 00A4 // SPI initialization
; 0000 00A5 // SPI disabled
; 0000 00A6 SPCR=0x00;
   LDI  R30,LOW(0)
   OUT  0x2C,R30
; 0000 00A7
; 0000 00A8 // TWI initialization
; 0000 00A9 // TWI disabled
; 0000 00AA TWCR=0x00;
   STS  188,R30
; 0000 00AB
; 0000 00AC LED = 1; delay_ms(25); LED = 0;
   SBI  0xB,5
   LDI  R30,LOW(25)
   LDI  R31,HIGH(25)
   RCALL SUBOPT_0x0
   CBI  0xB,5
; 0000 00AD
; 0000 00AE // Watchdog Timer initialization
; 0000 00AF // Watchdog Timer Prescaler: OSC/512k
; 0000 00B0 // Watchdog Timer interrupt: Off
; 0000 00B1 #pragma optsize-
; 0000 00B2 #asm("wdr")
   wdr
; 0000 00B3 WDTCSR=0x38;
   LDI  R30,LOW(56)
   STS  96,R30
; 0000 00B4 WDTCSR=0x28;
   LDI  R30,LOW(40)
   STS  96,R30
; 0000 00B5 #ifdef _OPTIMIZE_SIZE_
; 0000 00B6 #pragma optsize+
; 0000 00B7 #endif
; 0000 00B8
; 0000 00B9 // Global enable interrupts
; 0000 00BA #asm("sei")
   sei
; 0000 00BB
; 0000 00BC SMCR = 0b00000101; // Power-down Mode Страница 43 мануала ATmega48
   LDI  R30,LOW(5)
   OUT  0x33,R30
; 0000 00BD #asm("sleep"); //Вводит контроллер в режим энергосбережения
   sleep
; 0000 00BE // Просыпаемся от прерыванием INT1 и сразу на обработчик
; 0000 00BF
; 0000 00C0 while (1)
_0xA:
; 0000 00C1       {
; 0000 00C2         delay_ms(2000); // Ждем чтобы разрядился конденсатор
   LDI  R30,LOW(2000)
   LDI  R31,HIGH(2000)
   RCALL SUBOPT_0x0
; 0000 00C3
; 0000 00C4         // Если сеть 220VAC есть, то засыпаем
; 0000 00C5         if (LineCtr == 0)
   SBIC 0x9,4
   RJMP _0xD
; 0000 00C6         {
; 0000 00C7                 BOOSTER_OFF; LED = 0;
   SBI  0x5,1
   CBI  0x5,0
   CBI  0xB,5
; 0000 00C8                 main();
   RCALL _main
; 0000 00C9         }
; 0000 00CA
; 0000 00CB         // Если пропала сеть 220VAC
; 0000 00CC         if (LineCtr == 1)
_0xD:
   SBIS 0x9,4
   RJMP _0x14
; 0000 00CD         {
; 0000 00CE                 // Первое значение batU берется из обработчика (сюда по-другому и не попасть)
; 0000 00CF                 if (batU >= 148 && LineCtr == 1 && PIND.3 == 1)
   LDI  R30,LOW(148)
   LDI  R31,HIGH(148)
   CP   R3,R30
   CPC  R4,R31
   BRLO _0x16
   SBIS 0x9,4
   RJMP _0x16
   SBIC 0x9,3
   RJMP _0x17
_0x16:
   RJMP _0x15
_0x17:
; 0000 00D0                 {
; 0000 00D1                         ctr = 20; batU = 0;
   RCALL SUBOPT_0x1
; 0000 00D2                         while(ctr) // цикл из 20 измерений
_0x18:
   TST  R6
   BREQ _0x1A
; 0000 00D3                         {ctr--; batU = batU + read_adc(2);}
   RCALL SUBOPT_0x2
   RJMP _0x18
_0x1A:
; 0000 00D4                         batU = batU / 20; // вычисляем среднее
   RCALL SUBOPT_0x3
; 0000 00D5
; 0000 00D6                         BOOSTER_ON;
   CBI  0x5,1
   SBI  0x5,0
; 0000 00D7                         delay_ms(500);
   LDI  R30,LOW(500)
   LDI  R31,HIGH(500)
   RCALL SUBOPT_0x0
; 0000 00D8                 }
; 0000 00D9                 else main();
   RJMP _0x1F
_0x15:
   RCALL _main
; 0000 00DA         }
_0x1F:
; 0000 00DB       }
_0x14:
   RJMP _0xA
; 0000 00DC }
_0x20:
   RJMP _0x20
;
;// External Interrupt 1 service routine
;// В прерывании строжевой таймер не работает (?)
;interrupt [EXT_INT1] void ext_int1_isr(void)
; 0000 00E1 {
_ext_int1_isr:
   ST   -Y,R0
   ST   -Y,R1
   ST   -Y,R15
   ST   -Y,R22
   ST   -Y,R23
   ST   -Y,R24
   ST   -Y,R25
   ST   -Y,R26
   ST   -Y,R27
   ST   -Y,R30
   ST   -Y,R31
   IN   R30,SREG
   ST   -Y,R30
; 0000 00E2         BOOSTER_OFF;
   SBI  0x5,1
   CBI  0x5,0
; 0000 00E3
; 0000 00E4         // Запускаем функцию контроля за зарядом АКБ
; 0000 00E5         //*******************************************************************
; 0000 00E6         ctr = 20; batU = 0;
   RCALL SUBOPT_0x1
; 0000 00E7         while(ctr) // цикл из 20 измерений
_0x25:
   TST  R6
   BREQ _0x27
; 0000 00E8         {ctr--; batU = batU + read_adc(2);}
   RCALL SUBOPT_0x2
   RJMP _0x25
_0x27:
; 0000 00E9         batU = batU / 20; // вычисляем среднее
   RCALL SUBOPT_0x3
; 0000 00EA
; 0000 00EB         /* Вычисление делителя на контроль напряжение АКБ
; 0000 00EC         Коэф. деления = 13.1V / 0.833V = 15,726
; 0000 00ED         Опорное напряжение (измеренное) = 1.100V
; 0000 00EE         Таким образом разрешение АЦП = 1.100 / 256 = 4,297 mV
; 0000 00EF         Для получения нижней границы заряда в 10V нужно
; 0000 00F0         10V / 15.726 = 636 mV на АЦП, или ее значения 636 mV / 4.297 = 148
; 0000 00F1         Для получения 13.4V нужно значение АЦП = 198*/
; 0000 00F2
; 0000 00F3         // Если напряжение на АКБ меньше 13.4V, то заряжаем
; 0000 00F4         if(batU <= 207) {BD140 = 1; LED = 0;} // Включаем заряд АКБ
   LDI  R30,LOW(207)
   LDI  R31,HIGH(207)
   CP   R30,R3
   CPC  R31,R4
   BRLO _0x28
   SBI  0x8,4
   RJMP _0x32
; 0000 00F5         else {BD140 = 0; LED = 0;} // Выключаем заряд АКБ
_0x28:
   CBI  0x8,4
_0x32:
   CBI  0xB,5
; 0000 00F6         delay_ms(500);
   LDI  R30,LOW(500)
   LDI  R31,HIGH(500)
   RCALL SUBOPT_0x0
; 0000 00F7         //*******************************************************************
; 0000 00F8 }
   LD   R30,Y+
   OUT  SREG,R30
   LD   R31,Y+
   LD   R30,Y+
   LD   R27,Y+
   LD   R26,Y+
   LD   R25,Y+
   LD   R24,Y+
   LD   R23,Y+
   LD   R22,Y+
   LD   R15,Y+
   LD   R1,Y+
   LD   R0,Y+
   RETI

   .CSEG
;OPTIMIZER ADDED SUBROUTINE, CALLED 4 TIMES, CODE SIZE REDUCTION:4 WORDS
SUBOPT_0x0:
   ST   -Y,R31
   ST   -Y,R30
   RJMP _delay_ms

;OPTIMIZER ADDED SUBROUTINE, CALLED 2 TIMES, CODE SIZE REDUCTION:1 WORDS
SUBOPT_0x1:
   LDI  R30,LOW(20)
   MOV  R6,R30
   CLR  R3
   CLR  R4
   RET

;OPTIMIZER ADDED SUBROUTINE, CALLED 2 TIMES, CODE SIZE REDUCTION:6 WORDS
SUBOPT_0x2:
   DEC  R6
   LDI  R30,LOW(2)
   ST   -Y,R30
   RCALL _read_adc
   LDI  R31,0
   __ADDWRR 3,4,30,31
   RET

;OPTIMIZER ADDED SUBROUTINE, CALLED 2 TIMES, CODE SIZE REDUCTION:4 WORDS
SUBOPT_0x3:
   __GETW2R 3,4
   LDI  R30,LOW(20)
   LDI  R31,HIGH(20)
   RCALL __DIVW21U
   __PUTW1R 3,4
   RET


   .CSEG
_delay_ms:
   ld   r30,y+
   ld   r31,y+
   adiw r30,0
   breq __delay_ms1
__delay_ms0:
   __DELAY_USW 0xFA
   wdr
   sbiw r30,1
   brne __delay_ms0
__delay_ms1:
   ret

__DIVW21U:
   CLR  R0
   CLR  R1
   LDI  R25,16
__DIVW21U1:
   LSL  R26
   ROL  R27
   ROL  R0
   ROL  R1
   SUB  R0,R30
   SBC  R1,R31
   BRCC __DIVW21U2
   ADD  R0,R30
   ADC  R1,R31
   RJMP __DIVW21U3
__DIVW21U2:
   SBR  R26,1
__DIVW21U3:
   DEC  R25
   BRNE __DIVW21U1
   MOVW R30,R26
   MOVW R26,R0
   RET

;END OF CODE MARKER
__END_OF_CODE:
Последний раз редактировалось VNN84 Ср сен 11, 2013 15:16:37, всего редактировалось 1 раз.

Re: Проблемы со сторожевым таймером. Что я делаю неправильно

Ср сен 11, 2013 15:16:26

Ищите "WDR".

Re: Проблемы со сторожевым таймером. Что я делаю неправильно

Ср сен 11, 2013 15:49:44

Уже было.
В CodeVisionAVR функции delay_ms ресетят WD однозначно (содержат команду WDR в цикле).
Переходите на WinAVR ;) или делайте задержку иным образом.

Re: Проблемы со сторожевым таймером. Что я делаю неправильно

Ср сен 11, 2013 15:50:29

Во как...
А от куда информация?

Завтра попробую сделать другую задержку ))). Попробую, наверное, таймером 16-битным.

Re: Проблемы со сторожевым таймером. Что я делаю неправильно

Ср сен 11, 2013 16:03:37

Блин, убрал в основном цикле delay_ms и все заработало!
СПС друзья! Буду думать как переделать задержки.

Re: Проблемы со сторожевым таймером. Что я делаю неправильно

Ср сен 11, 2013 17:13:10

Компилятор в delay_ms() ставит команду wdr. Посмотрите ассемблерный код, убедитесь сами. Может это поможет в понимании того, что происходит.

Re: Проблемы со сторожевым таймером. Что я делаю неправильно

Чт сен 12, 2013 08:49:00

pyzhman писал(а):Компилятор в delay_ms() ставит команду wdr

Хотя я искал, но нигде не нашёл упоминания об этом. Может, я слепой? :dont_know:
А похожая проблема вроде уже всплывала у кого-то, потому я и предложил.

Re: Проблемы со сторожевым таймером. Что я делаю неправильно

Чт сен 12, 2013 15:48:42

С текущего проекта содрал:
Код:
                 _delay_ms:
000340 91e9         ld   r30,y+
000341 91f9         ld   r31,y+
000342 9630         adiw r30,0
000343 f039         breq __delay_ms1
                 __delay_ms0:
                +
000344 ea80     +LDI R24 , LOW ( 0xFA0 )
000345 e09f     +LDI R25 , HIGH ( 0xFA0 )
                +__DELAY_USW_LOOP :
000346 9701     +SBIW R24 , 1
000347 f7f1     +BRNE __DELAY_USW_LOOP
                    __DELAY_USW 0xFA0
000348 95a8         wdr
000349 9731         sbiw r30,1
00034a f7c9         brne __delay_ms0
                 __delay_ms1:
00034b 9508         ret
Ответить