Перейти к содержанию

strengerst

Members
  • Постов

    35
  • Зарегистрирован

  • Посещение

Сообщения, опубликованные strengerst

  1. Помогите пожалуйста правильно подключить компаратор, чтоб входил в прерывания: Вот код но у меня не получается создать прерывания, как я уже не пробовал подключать в протеусе, все равно прерывания не происходит. 

    .include "tn13def.inc" 	; Header files
    //.equ MCUclock=4000000		; 4MHz 
    
    
    .list; // Отоброжения листинга исполнения команды.
    .cseg; работаем с програмной памятью а не озу или eeprom
    .org 0; устанавливаем начальную позицию строки
    rjmp START; Reset Handler
    rjmp START; IRQ0 Handler
    rjmp START;; PCINT0Z Handler
    rjmp START; Timer0 Overflow Handler
    rjmp START; EEPROM Ready Handler
    rjmp Comparator; Analog Comparator Handler
    rjmp START; TIM0_COMPA CompareA Handler
    rjmp START; Timer0 CompareB Handler
    rjmp START; Watchdog Interrupt Handler
    rjmp START; ADC Conversion Handler
    
    //Оброботка прерывания от компаратора
    Comparator:
    cbi DDRB,4;
    cbi PORTB,4; - Подкючаем подтягивающий резистор для включения лампы
    reti; - Выход с под программы прерывания
    //оброботка прерывания порта INT0, по высокому сигналу.
    
    
    
    
    
    
    //Определяем начальные параметры микроконтролера.
    
    START:
     
     CLI; команда запрещает глобальные прерывания.
     //инициализация стэка.(установка максимально размера ОЗУ);
     ldi R17, RAMEND;
     out SPL, R17;
     
     //Отключаем аналогово-цифровой преобразователь
     CBI ADCSRA, ADEN;
    //Подключаем компаратор для сравнения сигналов
    //Разрешаем прерывания
    sbi ACSR, ACIE;
    //Подключаем внутрений ион 1,23 Вольт.  на AIN0 вывод.
    sbi ACSR, ACBG;
    
    LDI R22,1<<AIN1D|1<<AIN0D;//Если какой-либо из входов ADC3-0 используется как аналоговый,
    OUT DIDR0,R22;//то в соответствующий бит ADC3D-ADC0D нужно устанавливать логическую единицу.
    
    
    //Устанавливаем работу портов на вход и выход.
    //Устанавливаем выходы DDB1 и DDB0 работу на вход для компаратора
    //Если порт DDB установлен в 1 то данный порт является выходам,
    //а если в 0 то входам.
    ldi R16,1<<DDB4;
    out DDRB,R16;
    
    ldi R16, 1<<PB4;
    out PORTB, R16;
    //Разрешаем глобальные прерывания
    sei;
    //Переходим к основному циклу проверки
    rjmp START1;
    
    START1:
    nop;
    rjmp START1;
    .exit

     

    картинка.png

  2. 70мА как минимум. То есть после диодного моста приходит 158мА тока из них 18/240=75ма пойдет через резистор на стабилитрон. 158-75=83ма - пойдет через колектор-эмитер в схему питания. Стабилитрон на 5ват для нормальной его работы необходимо 65мА предельные 256ма по даташиту, подключал без транзистора но стабилитрон сильно греется хочу снизить нагрев стабилитрона.

  3. блин ну че за коменты хрен че поймешь. Нормально я подключил смотрите новую схему а там запарился говорил же http://piccy.info/vi...499de14156f9bf/

  4. подскажите можно ли подключить по такой схеме 5_240.jpg

    при этом ток в цепи 158мА. ток на стабилитрон 18/240=75мА, по идеи в цепи остается 158 - 73=83мА. при допустимых Collector Current – Continuous IC 150 mAdc

  5. ...Но лучше всего в обработчике прерываний отключать наверное так:

    Зачем?

    С момента первого фронта до отключения прерывания проходит 29 тактов. на частоте 1,2 это и будет 24 мкСек, А при таком отключении прерывания это будет почти моментально.

    Хочу попробовать так подключить получиться ? http://savepic.ru/9638274.png

  6. Большое всем спасибо за уделенное время и внимание, Буду переделывать схему под эту http://savepic.ru/9537168.png что из этого выйдет отпишусь.

    Как вы вычислили 24 мкСек ?

    Кинул ваш код в AVRStudio и посмотрел. С момента первого фронта до отключения прерывания проходит 29 тактов. на частоте 1,2 это и будет 24 мкСек

    Та вроде 24 мкСек хватает прежде чем сработает прерывания по спаду.Но лучше всего в обработчике прерываний отключать наверное так:

    /*Код прерывания по выводам PCINT*/
    PCINT0Z:
    ldi R16, (0<<PCIE); отключаем внешнее прерывания PCINT
    out GIMSK,R16;
    in R20, SREG;
    inc PINT;
    out SREG, R20;
    reti;
    

    Спасибо за замечание очень пригодились.

  7. Так в том то и проблема, что ограничивать ток по питанию не нужно (микроконтроллер сам возьмет столько, сколько ему нужно), а вот ограничивать ток по выходам (например по выходу контроллера, который управляет симистором) нужно. В результате у вас получается что при открывании симистора (предположим что вам необходим ток 20 мА) Происходит просадка напряжения до 3 вольт, в результате контроллер начинает глючить (причем проблема именно не в том что напряжение опускается до 3 вольт, контроллер и при 3 вольтах может работать, а в самом факте просадок, когда во время просадки при записи информации в регистры, она может быть повреждена или возникающий перепад может спровоцировать срабатывание внешнего прерывания).

    Хорошое замечание я и не думал о просадки напряжения при открытие. Надеюсь это поможет устранить глюки. Меня смущал тот факт что сама микра работала исправно в начале. а лишь через промежуток времени зависало попробую переделать схему.

    Так правильно будет? http://savepic.ru/9537168.png

    Вариант управления симистором http://www.microchip...pport/dimm.html

    Очень полезная статья спасибо как раз в тему.

  8. На какой частоте работает МK, если 1,2 то с момента первого фронта до отключения прерывания проходит 24 мкСек. И как насчёт импульсных помех. Да и по поводу предыдущих моих цитат вашего кода. Если кусок кода просто есть и не выполняет ничего то не лучше ли его выкинуть отредактировав. Чтоб читающие ваш код не спотыкались об уже оговорённое. Какое питание у вашего Мк (имею в виду стабилизатор линейный/импульсный) У меня были случаи зависания МК при линейном стабилизаторе( атмега8 и тини13 даже wdr не помагал), менял на импульсный и проблема исчезала.

    В настройках fuses стоит 9,6MHz и также fuses ставлю СLKDIV8 что в суме дает нам частоту 9,6/8=1,2 MHz Как вы вычислили 24 мкСек ? очень интересно. Питание от линейного стабилизатора точнее микросхемы 7805. Вот схема подключения http://savepic.ru/9527162.htm

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

    Здравствуйте, хотелось бы сразу отбросить аппаратные вопросы.

    1. У вас стоит конденсатор между выводами питания контроллера (непосредственно около них, а не где-нибудь за 20 см)? Если нет, то причина зависания может быть именно в этом.

    2. У вас контроллер управляет мощной нагрузкой, которая питается от того же источника питания что и контроллер? Если да, то тогда следует развязать питание при помощи диода и электролитического конденсатора, я имею ввиду возможные просадки напряжения при включении мощной нагрузки, которые могут приводить к зависанию контроллера.

    1. С7 на 0,1 мкф стоит возле микроконтроллера при запитывании от 7805.

    2. Контролер управляет симистором. через который проходит нагрузка которая питается от другова источника. Вот схема http://savepic.ru/9527162.htm

  9. Повторяюсь ещё раз

    //Выбираем режим срабатывания по нарастающему фронту

    ldi R16, (1<<ISC01)|(1<<ISC00);

    out MCUCR, R16;

    Это для прерывания по INT0. Вы же используете прерывание PCINT. PCINT не имеет возможности настройки по фронту/по спаду/по любому перепаду/или по низкому уровню. Эта настройка доступна только для INT0. PCINT может только - по любому перепаду на ноге. То есть когда вы хлопнули один раз вы два раза попали в прерывание (по фронту и по спаду), когда хлопаете 3 раза соответственно 6 раз в прерывание.Если вы хотите инкрементировать только по фронту, то попадая в прерывание проверяйте состояние входа а потом инкрементируйте.

    Это правильное замечание но на код оно не влияет так как после первого хлопка у нас срабатывает прерывания по высокому фронту и что бы мы не попадали в прерывания по низкому фронту в коде после первого прерывания отключаются прерывания по PCINT до окончания действия таймера а потом опять подключаем прерывания и ждем второй хлопок. Это исключает возможность двойного попадания в прерывания. Почему PCINT а не INT0 потому что нога отведеная под INT0 расположения микроконтроллера находиться не в удобном для моей схемы места.

    //если сроботало прерывание (поступил перый хлопок pint=1)
    ldi R16, 1;
    cpse R16, pint;
    rjmp PC+0x05; если pint не равно 1 то переходим на 5 позиции в низ.
    inc pint; прибавляем 1 что бы больше сюда не заходить.
    ldi R16, (0<<PCIE); отключаем внешнее прерывания PCINT
    out GIMSK,R16;
    rjmp TIME0RIN;/*Если второй хлопок поступил*/
    ldi R16, 4;
    cpse R16, pint;
    rjmp PC+0x08;
    ldi R16, (0<<PCIE); отключаем внешнее прерывания PCINT
    out GIMSK,R16;
    inc pint;
    ldi R16, 0;
    mov timea, R16;
    ldi R16, 0x00; скидываем таймер счетчик
    out TCNT0, R16;
    

    Обратите внимание на это место:

    .org 2
    /*Код прерывания по выводам PCINT*/
    in R20, SREG;
    inc PINT;
    out SREG, R20;
    reti;
    /*Код прерывания по совпадению с таймером значения А*/
    .org 6
    in R20, SREG;
    INC TIMEA;
    out SREG, R20;
    reti;
    

    Учту ваше замечание и попробую переделать. Вот так вроде бы должно быть

    .include "tn13def.inc";
    //Переименованные регистра
    .def PINT=R24; //R24 переименовуем в VECTORPCINT
    .def TIMEA=R25;
    .list;
    .cseg; работаем с програмной памятью а не озу или eeprom
    .org 0; устанавливаем начальную позицию строки
    rjmp N0; Reset Handler
    rjmp N0 ; IRQ0 Handler
    rjmp PCINT0Z ; PCINT0 Handler
    rjmp N0 ; Timer0 Overflow Handler
    rjmp N0; EEPROM Ready Handler
    rjmp N0; Analog Comparator Handler
    rjmp TIM0_COMPA ; Timer0 CompareA Handler
    rjmp N0; Timer0 CompareB Handler
    rjmp N0; Watchdog Interrupt Handler
    rjmp N0; ADC Conversion Handler
    
    
    /*Код прерывания по выводам PCINT*/
    PCINT0Z:
    in R20, SREG;
    inc PINT;
    out SREG, R20;
    reti;
    /*Код прерывания по совпадению с таймером значения А*/
    TIM0_COMPA:
    in R20, SREG;
    INC TIMEA;
    out SREG, R20;
    reti;
    
    
    /*Код установки таймера счетчика*/
    TIME0RIN:
    ldi R16, 0x00;// Сбрасываем все флаги таймера
    out TIFR0, R16;
    ldi R16, (1<<OCIE0A);Установка по совпадению с А;
    out TIMSK0, R16;
    ldi R16, 0xFF; Устанавливаем значение при совпадении с А
    out OCR0A, R16;
    ldi R16, (1<<CS02)|(0<<CS01)|(1<<CS00);
    out TCCR0B, R16;
    rjmp start;
    /*Основной код начало программы*/
    
    N0:
    cli; ЗАПРЕOFTV ГЛОБАЛЬНЫЕ ПРЕРЫВАНИЯ перед установкой параметров
    //инициализация стэка.(установка максимально размера ОЗУ);
    ldi R17, RAMEND;
    out SPL, R17;
    
    

  10. Ну вот же в коде написано

    ///Выбераем режим срабатывания по PCMSK
    ldi R16, (1<<PCIF);
    out GIFR, R16; ..Скидываем флаг прерывания если он установлен.
    ldi R16, (1<<PCIE);
    out GIMSK, R16;
    //Выбираем режим срабатывания по нарастающему фронту
    ldi R16, (1<<ISC01)|(1<<ISC00);
    out MCUCR, R16;
    //Выбираем ножку микроконтролера
    ldi R16, (1<<PCINT1);
    out PCMSK, R16;
    

    А вообще работа следующая, когда на ножку микроконтроллера приходит сигнал, которым является хлопок, передающийся через микрофон и усилитель, у нас срабатывает прерывание в котором происходит увлечение на один переменной PINT, в коде везде есть сравнение этой переменой с разными значениями суть которых определяет работу определенного участка кода, заданного значение, где совпадает с переменой PINT. а также значения таймера которые записываются в переменную timea что дает нам возможность производить задержку по времени и учитывать длительность хлопков. Так если хлопнуть три раза значение переменой PINT превысит допустимое и микроконтроллер уснет при это все параметры обнулим и при следующем хлопке счет начнется заново. А если один хлопок, то по истечению промежутка времени у нас в коде

    /*Уходим в режим sleep если второй хлопок не поступил по прошествию 5 секунд*/
    ldi R16, 120;
    cpse R16, timea;
    rjmp PC+0x07;
    ldi R16, 3;
    cpse R16, pint;
    rjmp PC+0x04;
    nop;
    nop;
    rjmp N1;
    

    который сравнивает количество прерываний по времени с переменой timea.

    Да все по сути работает я лично проверял. но вот только не долго определеный промежуток времени там 5 мин. А потом контролер зависает чета.

    Вы это сами "изобретали" или "сдернули" откуда-то?

    да сам писал видно же что любительский код.

  11. Написал простенький код для хлопкового переключателя, собрал схему все работает но не долго и каждый раз разное время то 5 то 7 минут а потом ступор на хлопки перестает реагировать. Подскажите в чем может быть причина, такое чувства что память переполняется и он просто зависает. Вот код:

    .include "tn13def.inc";
    //Переименованные регистра
    .def PINT=R24; //R24 переименовуем в VECTORPCINT
    .def TIMEA=R25;
    .list;
    .cseg; работаем с програмной памятью а не озу или eeprom
    .org 0; устанавливаем начальную позицию строки
    exit: rjmp N0;
    .org 2
    /*Код прерывания по выводам PCINT*/
    in R20, SREG;
    inc PINT;
    out SREG, R20;
    reti;
    /*Код прерывания по совпадению с таймером значения А*/
    .org 6
    in R20, SREG;
    INC TIMEA;
    out SREG, R20;
    reti;
    
    /*Код установки таймера счетчика*/
    TIME0RIN:
    ldi R16, 0x00;// Сбрасываем все флаги таймера
    out TIFR0, R16;
    ldi R16, (1<<OCIE0A);Установка по совпадению с А;
    out TIMSK0, R16;
    ldi R16, 0xFF; Устанавливаем значение при совпадении с А
    out OCR0A, R16;
    ldi R16, (1<<CS02)|(0<<CS01)|(1<<CS00);
    out TCCR0B, R16;
    rjmp start;
    /*Основной код начало программы*/
    N0:
    cli; ЗАПРЕOFTV ГЛОБАЛЬНЫЕ ПРЕРЫВАНИЯ перед установкой параметров
    //инициализация стэка.(установка максимально размера ОЗУ);
    ldi R17, RAMEND;
    out SPL, R17;
    //Установка предделителя частоты тактового сигнала Устанавляваем деление на 8 что бы не перегревать процесор.
    ldi R16, (1<<CLKPCE)|(0<<CLKPS1)|(0<<CLKPS0);
    out CLKPR, R16;
    ldi R16, (0<<CLKPCE);
    out CLKPR, R16;
    ////Запрет прерывания от компаратора перед его отключением ;
    //Команда сбрасывает значение в 0 регистра ACSR ячейки ACIE;
    CBI ACSR, ACIE;
    //Отключение компаратора
    ////Команда устанавливает значение в 1 регистра ACSR ячейки ASD;
    SBI ACSR, ACD;
    ///Выбераем режим срабатывания по PCMSK
    ldi R16, (1<<PCIF);
    out GIFR, R16; ..Скидываем флаг прерывания если он установлен.
    ldi R16, (1<<PCIE);
    out GIMSK, R16;
    //Выбираем режим срабатывания по нарастающему фронту
    ldi R16, (1<<ISC01)|(1<<ISC00);
    out MCUCR, R16;
    //Выбираем ножку микроконтролера
    ldi R16, (1<<PCINT1);
    out PCMSK, R16;
    //Обнулям занечния наших переменых
    CLR ZH;
    mov pint, ZH;
    mov timea, ZH;
    
    //Устанавливаем работу некоторых ножек порта как на выход.
    ldi R16, (1<<DDB4)|(0<<DDB1)|(1<<DDB0);
    out DDRB, R16;
    //Подключаем подтягивающия резистр к ножке микроконтролера
    ldi R16,(1<<PORTB1);
    out PORTB, R16;
    N1:
    //Оключаем работу таймера
    ldi R16, (0<<CS02)|(0<<CS01)|(0<<CS00);
    out TCCR0B, R16;
    sei;//Разрешаем глобальные прерывания
    //Скидываем в 0 значение переменых PINT, TIMEA;
    mov PINT, ZH;
    mov TIMEA, ZH;
    // MCUCR ячейки SE-Бит разрешения спящего режима;
    // Выбираем режим POWER DOWN, битами SM1 и SM0;
    ldi R16, (1<<SE)|(1<<SM1)|(0<<SM0);
    out MCUCR, R16;
    sleep;
    //Отключаем разрешение перехода в спящий режим
    ldi R16, (0<<SE);
    out MCUCR, R16;
    //При первом включении микроконтролера выставлям начальные параметры в метки N0;
    start:
    wdr; //сбрасываем сторожевой таймер
    ldi R16, 0;
    //сравнение двух переменных и если они равны то пропуск следующей команды
    cpse R16, pint;
    rjmp PC+0x02;
    rjmp start;
    //если сроботало прерывание (поступил перый хлопок pint=1)
    ldi R16, 1;
    cpse R16, pint;
    rjmp PC+0x05; если pint не равно 1 то переходим на 5 позиции в низ.
    inc pint; прибавляем 1 что бы больше сюда не заходить.
    ldi R16, (0<<PCIE); отключаем внешнее прерывания PCINT
    out GIMSK,R16;
    rjmp TIME0RIN;
    /*По прошествию 2 секунд после первого прерывания подключаем глобальное прерывание */
    ldi R16, 10;
    cpse R16, timea;
    rjmp PC+0x14;
    ldi R16, 2;
    cpse R16, PINT;
    rjmp PC+0x11;
    inc timea;
    ldi R16, (1<<PCIF); скидываем флаг прерывания
    out GIFR,R16;
    ldi R16, (1<<PCIE); потключаем внешнее прерывания PCINT
    out GIMSK,R16;
    ldi R16, 0x81; скидываем таймер счетчик
    out GTCCR, R16;
    ldi R16, 0x00; скидываем таймер счетчик
    out GTCCR, R16;
    ldi R16, 3;
    mov PINT, R16;
    ldi R16, 0;
    mov timea, R16;
    nop;
    nop;
    sei;
    /*Уходим в режим sleep если второй хлопок не поступил по прошествию 5 секунд*/
    ldi R16, 120;
    cpse R16, timea;
    rjmp PC+0x07;
    ldi R16, 3;
    cpse R16, pint;
    rjmp PC+0x04;
    nop;
    nop;
    rjmp N1;
    
    /*Если второй хлопок поступил*/
    ldi R16, 4;
    cpse R16, pint;
    rjmp PC+0x08;
    ldi R16, (0<<PCIE); отключаем внешнее прерывания PCINT
    out GIMSK,R16;
    inc pint;
    ldi R16, 0;
    mov timea, R16;
    ldi R16, 0x00; скидываем таймер счетчик
    out TCNT0, R16;
    /*Выжидаем одну секунду и подключаем внешнее прерывание*/
    ldi R16, 10;
    cpse R16, timea;
    rjmp PC+0x0D;
    ldi R16, 5;
    cpse pint, R16;
    rjmp PC+0x0A;
    ldi R16, (1<<PCIF); скидываем флаг прерывания
    out GIFR,R16;
    ldi R16, (1<<PCIE); потключаем внешнее прерывания PCINT
    out GIMSK,R16;
    inc pint;
    ldi R16, 0x00; скидываем таймер счетчик
    out TCNT0, R16;
    ldi R16, 0;
    mov timea, R16;
    /*Если поступил третий хлопок в течении 2сек нечего не включаем и идем спать */
    ldi R16, 60;
    cpse R16, timea;
    rjmp PC+0x05;
    ldi R16, 7;
    cpse R16, pint;
    rjmp PC+0x02;
    rjmp N1;
    /*Если третий хлопок не поступил в течении 2сек подключаем пин PORTB2 */
    ldi R16, 60;
    cpse R16, timea;
    rjmp PC+0x09;
    ldi R16, 6;
    cpse R16, pint;
    rjmp PC+0x06;
    ldi R16, (1<<PORTB4);
    in R17, PORTB;
    eor R16, R17;
    out PORTB,R16;
    rjmp N1;
    rjmp start;
    

  12. На микропроцесоре tyni13A подерживает 8 битный таймер /счетчик. Мне нужно отсчитать 5секунд после того как на PORTB.4 прийдет положительный импульс сигнала. После окончания времени 5 секунд присвоить PORTB.1 значение 1. Изначально PORTB.1 сконфигурирован как порт выхода с выходным параметром 0.

    Вот код как я пробовал сделать но почемуто не работает:

    #include <tiny13.h>
    void main(void)
    {  PORTB=0x00; DDRB=0x03; TCCR0A=0x00; TCCR0B=0b101; TCNT0=0x00; ACSR=0x80;
    while (1)
         {   if(PINB.4==1){  unsigned char z=19; unsigned char z1=256;
             while(TCNT0<z){while (TCNT0<z1){}}
    PORTB.1=1;}}} 

    //Максимальный кофициент пределителя выбран 1024 (TCCR0B=0b101; ) для тактовой частоты 1Мгц и получаеться 1000000/1024=976,56Гц; период такого сигнала будет равен 1/976,56=0,001024(сек). Для 5 сек нужно 5/0,001024=4882.

    Так как восьмиразрядный таймер имеет максимальный коэфициент пересчета 256, и после этого начинает все с 0 то 4882 явно большой для нашего таймера. по этому число 4882/256 =19 циклов. То есть цикл состоящий из 19 циклов в котором вложенных 256 циклов на каждый из 19 и дадут нам задержку в сумме 5 секунд. После окончания работы таймера PORTB.1 должен принять значение 1, но почемуто 5 секунд не выдерживають а сразу меняет значения при соответствии условя PINB.4==1. Как исправить ситуацию имено что бы таймер заработал

  13. Ну динамик вроде есть на 4ома, дела за схемой, с птанием что подруку попадет. На рынке еще поищу.

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

  14. Мне вообще не понятно, для чего нужно было "огород городить" с TDA2005, да ещё и мостом, чтобы в конечном итоге получить меньше 0.5W выходной мощности, да ещё и используя её не в режиме?! :blink:

    Хотел создать переносной УНЧ, с одним динамиком, ну что бы мощность хотя бы больше 11W была, вот и решил с TDA2005 попробовать. Может кто хорошую альтернативу в месте с правильной схемой сборки подскажет, буду только рад. Ну что бы и выходная мощность была хорошая, 11W или больше, и от батареек запитывать можно было, ну только на зарубежных схемах. А то наши сейчас тяжело найти.

×
×
  • Создать...