switch (I2c_uC_status){ // .... код case 0x80: //** адресованы, был принят байт данных и послан ACK ------ Mr_I2C_SL_On_A ; // Макрос. Настраивает TWCR : Будет принят байт + ACK Mr_SetBit_0(PORTC, Led2) ; // Макрос. Записывает 0 в бит "Led2" в регистре "PORTC" = Зажигает светодиод break; //...... код } Mr_SetBit_1(TWCR, TWINT) ; // <- 1 : Сброс флага прерывания (записать 1) } ----------
Испытываю в железе. Отправляю посылку по I2C. МК принимает. Светодиод зажигается. Всё ОК. Обрабатывать принятый байт буду в MAIN. Поэтому вместо включения светодиода в прерывании ставлю флаг, который проверяется в главном цикле и при выставленном флаге включается светодиод.
Код:
Файл Main.c ---------- int main(void) { Sb_Start() ; // Инициализация. Там же запускается Sb_I2c_Init() while (1) { if (0 != (I2c_uC_Flags1 & (1<<I2c_Fe_Mess_Byte_New))) { // ФЛАГ = принят байт ? Mr_SetBit_0(I2c_uC_Flags1, I2c_Fe_Mess_Byte_New) ; // Макрос. Сброс флага Mr_SetBit_0(PORTC, Led2) ; // Макрос. Записывает 0 в бит "Led2" в регистре "PORTC" = Зажигает светодиод } } } ----------
Файл I2Cs.c ---------- void Sb_I2c_Init(void){ ... Тут инициализация TWI в режиме SLAVE }
switch (I2c_uC_status){ // .... код case 0x80: //** адресованы, был принят байт данных и послан ACK ------ Mr_I2C_SL_On_A ; // Макрос. Настраивает TWCR : Будет принят байт + ACK Mr_SetBit_1(I2c_uC_Flags1, I2c_Fe_Mess_Byte_New) ; Макрос. УСТАНОВКА ФЛАГА. Записывает 1 в бит "I2c_Fe_Mess_Byte_New" в регистре "I2c_uC_Flags1" break; //...... код } Mr_SetBit_1(TWCR, TWINT) ; // <- 1 : Сброс флага прерывания (записать 1) } ----------
Компилируется без ошибок и предупреждений. Собственно проблема в том, что так НЕ работает, светодиод не включается. Почему !? Простейшая задача Поставить флаг в прерывании. А в главном цикле зажечь светодиод, если флаг установлен.
_________________ Одни хотели бы понимать то, во что верят, другие - поверить в то, что пнимают.
Ещё заметил, что удивило в варианте 2: Отлаживаю по шагам. Доходит до строки в MAIN, где макрос сброса бита в регистре I2c_uC_Flags1. Отладчик просто перепрыгивает её - игнорирует. Как будто там ничего нет !! Я там для чего это этот код писал ? Сволочь такая, хоть бы предупреждение какое-нибудь выдал! Это нормально ?
P.S. Почитал про volatile
Цитата:
Переменная должна быть декларирована как volatile всякий раз, когда возможно её неожиданное изменение.
Как так "неожиданно" !?!?
_________________ Одни хотели бы понимать то, во что верят, другие - поверить в то, что пнимают.
Неожиданно - это когда переменная может поменяться извне, а не только в линейном коде программы. Компилятор в общем случае смотрит, где может меняться переменная. И если видит, что изменений нет в линейном коде, то он вправе вообще эту переменную выбросить. Что в вашем случае и произошло. А когда вы ему сказали, что это волатильная переменная, тогда компилятор отбросил в сторону свои влажные мечты про оптимизацию и сделал как хотели вы.
А баском - ну сложно про него что либо сказать. Возможно, там или нет оптимизации такого уровня, как в си, или оптимизации вообще нет. ИМХО - это вообще тупиковая ветвь в эмбедде.
Использование модульных источников питания открытого типа широко распространено в современных устройствах. Присущие им компактность, гибкость в интеграции и высокая эффективность делают их отличным решением для систем промышленной автоматизации, телекоммуникационного оборудования, медицинской техники, устройств «умного дома» и прочих приложений. Рассмотрим подробнее характеристики и особенности трех самых популярных вариантов AC/DC-преобразователей MW открытого типа, подходящих для применения в промышленных устройствах - серий EPS, EPP и RPS представленных на Meanwell.market.
Второй блок кода. (Вариант 2, в котором проблема) Строка Код: Mr_SetBit_1(I2c_uC_Flags1, I2c_Fe_Mess_Byte_New) ; Макрос. УСТАНОВКА ФЛАГА. Записывает 1 в бит "I2c_Fe_Mess_Byte_New" в регистре "I2c_uC_Flags1"
Есть код или нет, надо смотреть в дизассемблере, как там прыгает высокоуровневый отладчик, еще ни о чём не говорит. При включенной оптимизации отладчик может показывать удивительные вещи, поскольку теряется прямое соответствие между строкой Си и машинными командами. Хотите гулять строго по строкам Си - отключайте оптимизацию.
Добавлено after 2 minutes 41 second: Особенно весело это выглядит при отладке в Протеусе, который помечает точечкой строки исходника, для которых есть отладочная информация: смотришь, и волосы дыбом! На фигурной скобке точка есть, а в теле цикла, которое эта скобка ограничивает, ни одной точки нет!!!
Добавлено after 1 minute 26 seconds: Пардон, на счет точек это я с прямым углом перепутал... Протеус адреса вместо точек показывает, точки это из другого...
_________________ если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе при взгляде на многих сверху ничего не меняется...
И если видит, что изменений нет в линейном коде, то он вправе вообще эту переменную выбросить.
Вообщето я считаю, это не уровнем ответственности компилятора. Раз написал, значит так нужно! И компилятор не вправе изменять мой код ! Ну или предупреждать, что переменная НЕ используется\меняется.
Вообщето я считаю, это не уровнем ответственности компилятора. Раз написал, значит так нужно! И компилятор не вправе изменять мой код ! Ну или предупреждать, что переменная НЕ используется\меняется.
Это ваше право. Включите в настройках компилятора соответствующие ворнинги. И почитайте про уровни оптимизации, что и до какого уровня может делать компилятор с вашим кодом.
Вообщето я считаю, это не уровнем ответственности компилятора. Раз написал, значит так нужно! И компилятор не вправе изменять мой код ! Ну или предупреждать, что переменная НЕ используется\меняется.
Это последствия оптимизации кода, можете выключить, но код займет больше места(может даже не поместится в проц.) или будет медленнее исполнятся(иногда не будет успевать делать то, что вы задумали).
Приветствую всех. Лет 12 к электронике не прикасался. Но вот пришлось снова заняться ATMega8. БОльшую часть вопросов решил выкуриванием тем здесь на форуме и в Яндексе, но возникла одна проблема, которую я сам побороть не могу. Чтение Евстифеева пока тоже завесу не приоткрыло.
Собственно есть простой код с инициализацией таймера и потом вызов прерывания по совпадению. В прерывании переключение одного бита в регистре TCCR1B. Но переключения почему-то не происходит. Ни при отладке в ATMELStudio(в разных версиях эффект одинаковый) ни в Proteus. Думал, что забыл какой-то бит настроить и прерывания просто не работают, но поставил обнуление маркерной переменной "i" в прерывании, и при совпадении TCNT1 и OSR1A она благополучно обнуляется, т.е. прерывания исполняются. Но команда записи в регистр нужный бит в регистре не меняет. Но точно такая же команда в основном теле кода отлично нужный бит переключает. Может я упустил, и есть какой запрет на запись в этот регистр в прерывании? В литературе ничего такого не нашёл. Как думаете, в чем может быть загвоздка?
Код, который вызывает вопрос: #include <avr/io.h> volatile unsigned int i;
ISR (TIMER1_COMPA_vect) { // Обработчик прерывания по совпадению TCNT1 и одного из регистров сравнения TCCR1B^=0b00010000; // переключаем бит в регистре в противоположное состояние при каждом прерывании (и тут оно не работает сумуляции i ^= 0; //--- А это отлично исполняется, видно через AddWatch }
int main(void) { ICR1 = 100; OCR1A = 200; asm("sei"); timer1_ini(); // Вызов функции инициализации таймера
while(1) {
i++; // TCCR1B^=0b00010000; // А здесь абсолютно тот же код исполняется отлично. } }
Но команда записи в регистр нужный бит в регистре не меняет. Но точно такая же команда в основном теле кода отлично нужный бит переключает. Может я упустил, и есть какой запрет на запись в этот регистр в прерывании? В литературе ничего такого не нашёл. Как думаете, в чем может быть загвоздка?
Нет никакого запрета. Конструкция типа как ниже работает
Код:
.org 6 T1_COMPA: LDI R17,1<<WGM13 IN R0,TCCR1B EOR R0,R17 OUT TCCR1B,R0 RETI
Нужно поменять значения в ICR1 и OCR1A местами, тогда заработает.
У вас тактирование таймера не внешнее? (1<<ICES1) - вроде не нужен.
Нет, тактирование от внутреннего генератора, без прескалера. Да, действительно бит не имеет смысла, видимо ошибся.
akl писал(а):
Нужно поменять значения в ICR1 и OCR1A местами, тогда заработает.
Не помогло. ( Бит в регистре как стоял в нуле, так и стоит. Асмовский кусочек понял как работает, но может я не правильно его в код применил, т.к. эффекта тоже нет.
Выглядит так, как будто происходит оптимизация при компиляции. Но в настройках стоит -O0 (ATMELStudio 7.0.1931, если что. Более менее безглючное из того, что по нынешним временам удалось скачать). Открыл дизассемблер, по идее, после обработки прерывания должна идти команда "reti" и по ней можно найти этот кусочек кода. Но в дизассемблере ни одной такой команды не встречается. При этом эта чёртова i вполне себе сбрасывается при совпадении. И я пока не могу понять где (не силен в ассемблере).
Инициализировал еще один порт и добавил в обработчик прерываний еще одну команду, чтобы писать TCCR1B в порт D. Хрена лысого, не пишет. Порт так и остаётся в нулях. И в Proteus и в ATMELStudio. Но эта чёртова i продолжает сбрасываться как положено.
Спойлер
OKF писал(а):
код вставляй через тег Code, как люди.
1. Если вы обратили внимание, то это мой первый пост на форуме за последние минимум 12 лет. Если бы я на момент публикации сообщения знал как это работает, я бы именно так и сделал.
OKF писал(а):
Зачем мне лезть в ДШ!
2. Вам незачем. Зачем Вам вообще кому-то помогать?! Это же требует столько усилий!
OKF писал(а):
И, если хочешь показать все биты, так все и показывай, даже которых нет:
3. Я так делаю, чтобы быть уверенным, что всё, что можно изменить находится под контролем. Вам не стоит быть таким самоуверенным.
OKF писал(а):
Это просто совет. Что бы люди не плевались.)
Можно было бы принять Ваши претензии, но Вы написали много, и ничего по теме вопроса.
Да что ж ты такой обидчивый то! ПУсть даже 100 лет ты не посещал форум, но ты же прежде чем постить, посмотри как делают люди, уж соверши пару телодвижений. А вот когда делается тяп-ляп, и так сойдёт, а вы там разбирайтесь, тогда и нет никакого желания помогать. Именно это я и хотел донести. Жаль что не доходит с первого раза.( Удачи!
СпойлерВопрос не обиды, а простого уважения к собеседнику. Вы мне отвечаете не на тот вопрос, который я задаю. Это не мало мешает сосредоточиться на решении проблемы. Ваши пожелания не имеют никакой ценности в этой ветке, и могли быть вполне озвучены в личных сообщениях. И поверьте мне, я на Вас сейчас не наезжаю. Просто присмотритесь к себе. Представьте, что мы поменялись местами. Такие сообщения очень утомляют при поисках полезной информации на форуме. Я Вам говорю как человек, который уже неделю "курит" этот форум сообщение за сообщением.
В общем полез я в настройки ATMELStudio и начал отключать всё подряд, что касается оптимизации. В дизассемблере появился кусок кода обработчика прерывания. Но при отладке по наступлении совпадения регистров, отладчик почему-то не делает переход на обработчик прерывания. Причём интересно, появилась возможность поставить в это место breakpoint. Но при запуске симуляции программа в это место так и не попадает. И еще прикол. Если я делаю пошаговую симуляцию по коду СИ, то при совпадении переменная "i" сбрасывается на ноль как задумано в коде обработчика прерывания, а если я веду симуляцию в окне дизассемблера, то при достижении совпадения переменная "i" не сбрасывается и продолжает расти.
По сему делаю вывод, что глючит отладка в режиме симуляции.
Прошу подсказать какая версия ATMELStudio более менее стабильная? И если возможно, то где скачать. Нынче санкции, фирменный сайт просто не открывается. Пишет доступ запрещен. ((
Я где-то в сети видел, что у ATMELStudio есть проблемы с симуляцией прерываний, но там была пометка, что это только для прерываний поступающих извне. Как-то для меня все не понятно. Прошло больше 12 лет, а ПО стало только корявее. А старое ПО или не найти, или оно не ставится на современный Windows. ( Видимо Микрочип потихоньку сливает AVR серию в утиль.
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 5
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения