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

Проблема с OCR0A Attiny13


NDG

Рекомендуемые сообщения

Прошу помощи сообщества в решении такой проблемы.

Имеем Attiny13 задачей которой стоит формирование ШИМ сигнала, скважность задаём состояние входов PB4 PB3 PB2. 

Загвоздка в том, что не могу заставить тиньку сменить скважность, несмотря на то, что на прерывание по состоянию входов реагирует, значения в OCR0A заносит. Маленькое замечание в железе не делал, только в Proteus.

Код:

#define F_CPU 9600000

#include <avr/io.h>
#include <avr/eeprom.h>
#include <avr/interrupt.h>

volatile bool SetMode_flag = false;
volatile char Select_Mode = 0;

//-------------------------------------------------

void PWM_init() 
{
    //Порты PB0 и PB1 устанавливаем на выход, остальные на вход
    DDRB = 0b00000011;
    //Входные порты PINB0 и PINB1 в HIGH, остальные в Pull-UP 
    PORTB = 0b00111111;
    //Разрешаем прерывания PCINT1 - по изменению вывода 
    GIMSK |= (1<<PCIE);
    //Накладываем маску на выводы
    PCMSK |= (1<<PINB4) |(1<<PINB3) |(1<<PINB2);
    //Запрещаем все прерывания пo совпадению и переполнению
    TIMSK0 = 0x00;
    //Устанавливаем режим работы таймера в режиме ШИМ с фазовой коррекцией
    TCCR0A |= (1<<COM0A1) |(1<<COM0B1) |(0<<WGM01) |(1<<WGM00);
    TCCR0B |= (1<WGM02);
    //Предделитель частоты уставливаем clk\1024 или приблизительно 18Гц
    //         Fclk_I/O
    //Fpcpwm = --------  (N предделитель 1, 8, 64, 256, 1024)
    //          N *510 
    TCCR0B |= (1<<CS02) |(0<<CS01) |(1<<CS00);
    //Обнуляем счётный регистр
    TCNT0 = 0x00;    
}

//-------------------------------------------------

ISR (PCINT0_vect)
{
    SetMode_flag = true;  // Устанавливаем флаг события
    Select_Mode = (PINB >> 2); //Сохраняем значение со сдвигом младших разрядов
}

//-------------------------------------------------

int main(void)
{
    PWM_init();
    sei();
    while (1)
    {
        
        if (SetMode_flag) 
        {
            switch ( Select_Mode )
            {    case 0:
                    OCR0A = 0; break;        // ШИМ выключен
                case 1:
                    OCR0A = 40; break;        //Скважность 15%
                case 2:
                    OCR0A = 80; break;        //Скважность 30%
                case 3:
                    OCR0A = 120; break;        //Скважность 45%
                case 4:
                    OCR0A = 150; break;        //Скважность 60%
                case 5:
                    OCR0A = 180; break;        //Скважность 75%
                case 6:
                    OCR0A = 210; break;        //Скважность 90%
                case 7:
                    OCR0A = 255; break;        //Включен постоянно
                default:
                     break;
            }
            SetMode_flag = false; //Сбрасывем флаг
        }
    }
}

main.cpp

PWM neew.pdsprj

Ссылка на комментарий
Поделиться на другие сайты

Реклама: ООО ТД Промэлектроника, ИНН: 6659197470, Тел: 8 (800) 1000-321

15 минут назад, NDG сказал:

 //Порты PB0 и PB1 устанавливаем на выход, остальные на вход
    DDRB = 0b00000011;

Дык почему на вход то??? Если:

 

15 минут назад, NDG сказал:

задачей которой стоит формирование ШИМ сигнала, скважность задаём состояние входов PB4 PB3 PB2. 

они должны быть на выход:

DDRB = 0b00011111;

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

Можно сделать все! Но чем больше можно, тем больше нельзя!

Ссылка на комментарий
Поделиться на другие сайты

20% скидка на весь каталог электронных компонентов в ТМ Электроникс!

Акция "Лето ближе - цены ниже", успей сделать выгодные покупки!

Плюс весь апрель действует скидка 10% по промокоду APREL24 + 15% кэшбэк и бесплатная доставка!

Перейти на страницу акции

Реклама: ООО ТМ ЭЛЕКТРОНИКС, ИНН: 7806548420, info@tmelectronics.ru, +7(812)4094849

Спасибо откликнувшимся.

Выводы PB0 и PB1 это единственные ноги на которые аппаратно завязан выход ШИМ.

 На РВ0 так же завязан INT0, поэтому использовать это прерывание не возможно. Поэтому решил использовать PCIE, который реагирует на изменение состояния порта - поэтому PB4 PB3 PB2 переведены на вход в состояние Pull-Up, что бы слушать шину.

Как только на любой из трех ног измениться состояние с LOW на HIGH, включается обработчик прерывания, в котором считывается, через  PINB, состояние выводов.

Далее выборка и... проблема - значение OCR0A поменялось, а скважность нет. Причём если запихнуть это без SWITCH в обработчик - работает, добавит здесь же условия IF() - работает. Но это же обработчик прерывания - негоже здесь время занимать.

Есть мысль, что всё завязано на двойной буферизации.

Да в Proteus файле я закоротил кнопки - это для эксперимента, забыл убрать.

Изменено пользователем NDG
Ошибки в тексте
Ссылка на комментарий
Поделиться на другие сайты

Выбираем схему BMS для корректной работы литий-железофосфатных (LiFePO4) аккумуляторов

 Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ, также как и для других, очень важен контроль процесса заряда и разряда, а специализированных микросхем для этого вида аккумуляторов не так много. Инженеры КОМПЭЛ подготовили список имеющихся микросхем и возможных решений от разных производителей. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

Неделя мозгового штурма и задача решена.

Не знаю как это правильно объяснить, но проблема кроется в обработчике прерываний и используемом режиме ШИМ. 

Выяснилось, что обработчику прерывания требуется несколько дополнительных тактов, в течение которых теряются значения  счётчиков . Поэтому грубую работу в лоб пришлось разделить на части  создание пресета скважности - обработка прерывания - расчёт значения пресета  в соответствии с состоянием РВ2 РВ3 РВ4 - установка OCRA0 значением из пресета.

Вот как то так.

Ссылка на комментарий
Поделиться на другие сайты

В 22.12.2017 в 17:28, NDG сказал:

Как только на любой из трех ног измениться состояние с LOW на HIGH, включается обработчик прерывания, в котором считывается, через  PINB, состояние выводов.

А я что то не вижу где фронт задан, на который прерывание срабатывает??? где задано что  "измениться состояние с LOW на HIGH, включается обработчик прерывания"???

Вроде регистром EICRA задается, а он не инициализируется значит = 0!

Value Description
00 The low level of INT0 generates an interrupt request.
01 Any logical change on INT0 generates an interrupt request.
10 The falling edge of INT0 generates an interrupt request.
11 The rising edge of INT0 generates an interrupt request

Можно сделать все! Но чем больше можно, тем больше нельзя!

Ссылка на комментарий
Поделиться на другие сайты

По фронту можно отловить только INT0 на РВ0, а у меня используется PCIE. Это прерывание не настраивается, а только сигнализирует об изменении уровня.

На это прерывание завязаны все оставшиеся порты РВ1-РВ5. Именно поэтому накладывается маска PCMSK.

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

Ну, а если с одного, то через маску проверяем, что изменилось - LOW -> HIGH или наоборот, и далее что делать.

GIMSK.JPG.fa65eb5eb3e963252dea510dfac50774.JPG

Изменено пользователем NDG
Стилистика
Ссылка на комментарий
Поделиться на другие сайты

Вот кусочек кода из другой моей разработки - реально работающей на объекте:

ISR (PCINT0_vect) //Обработчик прерывания PCIE
{
    flag_PCINT = true; //Устанавливаем флаг прерывания ДЛЯ ПРОГРАММЫ 
}

int main(void)

    Init_mail();
    while (1)
    {
        if (flag_PCINT == true)
        {
            if (start_flag == false)
            {
                Button_Block;
                Rele; Wait;
                //Если состояние PORTB1 LOW, то реле не сработало
                if (!Port_HIGH) led_error (2); 
                else Contact; Wait;
                //Если состояние PORTB1 HIGH, то контактор не сработал
                if (Port_HIGH) led_error (2); 
                else { start_flag = true; flag_PCINT = false; } //Сбрабываем флаги
            }
            else if (start_flag == true)
                {
                    Rele; Wait; LED_Off;
                    start_flag = false; flag_PCINT = false;
                }
        }    

Ссылка на комментарий
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Ответить в этой теме...

×   Вставлено с форматированием.   Восстановить форматирование

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

Загрузка...
  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
  • Сообщения

    • Всем доброго дня! Есть ДВД проигрыватель Toshiba, изначально с питанием 110В. По глупости был включен в розетку с 220В, взорвался конденсатор на входе. Был заменён на аналогичный по ёмкости, но с большим напряжением. Какое-то время проигрыватель работал. Потом перестал включаться. Нужен совет, по переделке БП данного ДВД, если такое вообще возможно с минимальным вмешательством. Паять умею. Схему БП прилагаю. Заранее спасибо за советы.
    • Именно так!  Таким способом дядюшки Ляо добиваются максимальной яркости при минимальном времени работы, убивая сразу двух зайцев: а) минимизируя количество потребных светодиодов и б) заставляют потребителя снова и снова покупать свою продукцию. 
    • Вот так должен выглядеть старый, оригинальный, неваренный оригинал, покупался в ЧиД. Есть и более новые такие Тошибы, тоже оригинал, но совсем совсем чуть-чуть отличается корпус и маркировка, у них на сколько помню, эти впадинки по краям чуть менее глубокие, но они тоже оригинальные. У меня такой, только 2SA1943 новодельный в ОМ 2.5 стоит вместе с таким как на фото старым 2SC5200, работают отлично. 
    • Какой  бред  сивой  кобылы!  Все радиолюбители  знают и есть  таблицы  по  которым  мы  видим  процент  КНИ и  отношение  амплитуды  гармоники к амплитуде  основного  сигнала!  Если  уровень  наибольшей гармоники   находиться на -20dB  относительно  пика  основного  сигнала, это 10%  КНИ. Вот  и вся  калибровка! Если  Спектроанализатор  мой  показывает   КНИ и  именно  такое  соотношение амплитуд ,я  точно  верю  ему. И твои  древние  спектроанализаторы  основаны  на этом  же принципе, индикатор  стрелочный  измеряет  амплитуду  основного тона 1 кГц,потом  режекторный   фильтр  вырезает  основной  тон,а  резонансный  контур  настраиваем на 2ю гармонику 2 кГц  и измеряем амплитуду 2й  гармоники и так  все гармоники  измеряем и по таблице  видим  каковы  КНИ  данного  сигнала! Компьютер  это  делает всё  программно! Смотрим скрин.
    • Так может зарядка "гуано" не? Сомневалка у вас отрастет с опытом в профильной работе, пока вам сомневаться нечем. Для особо необразованных пользователей и проверяющий органов выдающих сертификацию для устройств. Вы сегодня про где? см. п.1 ПЛАВДА? у меня допустим до сих пор в пользовании mi watch 3 заряжаемый от чего попало... Внутри. Но вам же по любому виднее... Ок. Это правильно. А проблема в чем?
    • Для увеличения sram у контроллера atmega128a, использую внешнюю sram. Код настройки контроллера на внешнюю sram: in r16, MCUCR              ; ori r16, 0xC0                 ; out MCUCR, r16            ; ldi r16, 0x04                  ; sts XMCRA, r16             ; ldi r16, 0x80                  ; sts XMCRA, r16             ; Возникает вопрос, адрес возврата из подпрограммы будет хранится по адресам 0x10FE и 0x10FF, то есть в конце оперативной памяти самого контроллера или по адресам 0xFFFE и 0xFFFF, то есть в конце внешней оперативной памяти???
  • Похожий контент

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