Книга. В этой книге очень подробно, доступно расписаны архитектура МК, система команд. Примеры программ. Джон Мортон - Микроконтроллеры AVR. Вводный курс
Для какого камня эта "простенькая" программа Судя по названиям регистров, похоже ATmega48...328 DS в помощь, никакие Мортоны и Трамперты не помогут.
дык написал же ардуино уно, атмега328 там. кроме как ссылку на книгу, больше подсказок не будет? асм загрузить в студию там дело двух минут. шагаешь до цикла ожидания, стваишь брикпойнт на прерывание 8, жмешь рун, и по адресу стека видишь вместо обратного адреса примерно в два раза меньший адрес.
дык написал же ардуино уно, атмега328 там. кроме как ссылку на книгу, больше подсказок не будет?
Не будет. И не потому что я такой нехороший дядька. Все просто и банально. Потому что вы заипете все форумы своими вопросами. Тогда как многие первые вопросы отпадут сами собой после чтения и самостоятельной практики.
Качественное и безопасное устройство, работающее от аккумулятора, должно учитывать его физические и химические свойства, профили заряда и разряда, их изменение во времени и под влиянием различных условий, таких как температура и ток нагрузки. Мы расскажем о литий-ионных аккумуляторных батареях EVE и нескольких решениях от различных китайских компаний, рекомендуемых для разработок приложений с использованием этих АКБ. Представленные в статье китайские аналоги помогут заменить продукцию западных брендов с оптимизацией цены без потери качества.
дык написал же ардуино уно, атмега328 там. кроме как ссылку на книгу, больше подсказок не будет? асм загрузить в студию там дело двух минут. шагаешь до цикла ожидания, стваишь брикпойнт на прерывание 8, жмешь рун, и по адресу стека видишь вместо обратного адреса примерно в два раза меньший адрес.
Спокойнее, я, например, без понятия что стоит в ардуйне. Так работает, потому что вектора стоят правильно. Удачи Спойлер
Компания EVE выпустила новый аккумулятор серии PLM, сочетающий в себе высокую безопасность, длительный срок службы, широкий температурный диапазон и высокую токоотдачу даже при отрицательной температуре.
Эти аккумуляторы поддерживают заряд при температуре от -40/-20°С (сниженным значением тока), безопасны (не воспламеняются и не взрываются) при механическом повреждении (протыкание и сдавливание), устойчивы к вибрации. Они могут применяться как для автотранспорта (трекеры, маячки, сигнализация), так и для промышленных устройств мониторинга, IoT-устройств.
дык написал же ардуино уно, атмега328 там. кроме как ссылку на книгу, больше подсказок не будет? асм загрузить в студию там дело двух минут. шагаешь до цикла ожидания, стваишь брикпойнт на прерывание 8, жмешь рун, и по адресу стека видишь вместо обратного адреса примерно в два раза меньший адрес.
Спокойнее, я, например, без понятия что стоит в ардуйне. Так работает, потому что вектора стоят правильно. Удачи
во гут, спасибки. Т0 не отключен был, а обработка прерывания неправильная рета небыло. короч как обычно собственный человеческий фактор
ISR (TIMER0_OVF_vect) { TCNT0=125; //значение для T0_0VF переполнения 1 раз в MS TIMER.MS++; //Подсчет MS if (TIMER.MS==65535) { TIMER.MS=0; } } /*Функция вернет TRUE через время TimeVar,Иначе возвращает CurrentFlag */ uint8_t OnAfterTimeMS(uint16_t TimeVar,uint8_t Number,uint8_t CurrentFlag) { uint8_t OutFlag=0; //Переменная отвечает за RETURN f(). TIMER.TimeCurrent=TIMER.MS; //Присваиваем текущие значение МС if (TIMER.Channel[Number].FlagTimersON==0) //Условия для захвата времени вызова функции и установки флага работы { TIMER.Channel[Number].TimeCountingON=TIMER.MS; TIMER.Channel[Number].FlagTimersON=1; } uint16_t TimerToStart = TIMER.TimeCurrent-TIMER.Channel[Number].TimeCountingON; if (TimerToStart == TimeVar) //Если время до старта == TimeVar, то OutFlag=1 и обнуляем Флаг работы. { OutFlag=1; TIMER.TimeCurrent=0; TIMER.Channel[Number].FlagTimersON=0; } else { OutFlag=CurrentFlag; } return OutFlag; }
uint8_t OFFAfterTimeMS(uint16_t TimeVar,uint8_t Number,uint8_t CurrentFlag) { uint8_t OutFlag=0; //Переменная отвечает за RETURN f(). TIMER.TimeCurrent=TIMER.MS; //Присваиваем текущие значение МС if (TIMER.Channel[Number].FlagTimersOFF==0) //Условия для захвата времени вызова функции и установки флага работы { TIMER.Channel[Number].TimeCountingOFF=TIMER.MS; TIMER.Channel[Number].FlagTimersOFF=1; } uint16_t TimerToSTOP = TIMER.TimeCurrent-TIMER.Channel[Number].TimeCountingOFF; if (TimerToSTOP == TimeVar) //Если время до старта == TimeVar, то OutFlag=1 и обнуляем Флаг работы. { OutFlag=0; TIMER.TimeCurrent=0; TIMER.Channel[Number].FlagTimersOFF=0; } else { OutFlag=CurrentFlag; } return OutFlag; }
ISR (TIMER0_OVF_vect) { // TCNT0=125; //значение для T0_0VF переполнения 1 раз в MS TCNT0=-125; //значение для T0_0VF переполнения 1 раз в MS
Формирование интервала досчётом до переполнения должно делаться так. Например, попробуйте формировать 0,64мс, занося число 80, получите лажу. Если будет занесено -80, будет похоже на правду. По мне, правильнее записывать такие вещи в символьном виде, типа
А по чему следует заносить отрицательное число ? я почему то думал что счетчик считает от 00 до 256 .
Добавлено after 52 minutes 24 seconds: Может кто подсказать почему не обнуляется переменная TIMER.Channel[Number].FlagTimersOFF и аналогично TIMER.Channel[Number].FlagTimersON
Код:
uint8_t OnAfterTimeMS(uint16_t TimeVar,uint8_t Number,uint8_t CurrentFlag) { uint8_t OutFlag=0; //Переменная отвечает за RETURN f(). TIMER.TimeCurrent=TIMER.MS; //Присваиваем текущие значение МС if (TIMER.Channel[Number].FlagTimersON==0) //Условия для захвата времени вызова функции и установки флага работы { TIMER.Channel[Number].TimeCountingON=TIMER.MS; TIMER.Channel[Number].FlagTimersON=1; } uint16_t TimerToStart = TIMER.TimeCurrent-TIMER.Channel[Number].TimeCountingON; if (TimerToStart == TimeVar) //Если время до старта == TimeVar, то OutFlag=1 и обнуляем Флаг работы. { OutFlag=1; TIMER.TimeCurrent=0; TIMER.Channel[Number].FlagTimersON=0; TimerToStart=0; } else { OutFlag=CurrentFlag; } return OutFlag; }
uint8_t OFFAfterTimeMS(uint16_t TimeVar,uint8_t Number,uint8_t CurrentFlag) { uint8_t OutFlag=0; //Переменная отвечает за RETURN f(). TIMER.TimeCurrent=TIMER.MS; //Присваиваем текущие значение МС if (TIMER.Channel[Number].FlagTimersOFF==0) //Условия для захвата времени вызова функции и установки флага работы { TIMER.Channel[Number].TimeCountingOFF=TIMER.MS; TIMER.Channel[Number].FlagTimersOFF=1; } uint16_t TimerToSTOP = TIMER.TimeCurrent-TIMER.Channel[Number].TimeCountingOFF; if (TimerToSTOP == TimeVar) //Если время до старта == TimeVar, то OutFlag=1 и обнуляем Флаг работы. { OutFlag=0; TIMER.TimeCurrent=0; TIMER.Channel[Number].FlagTimersOFF=0; TimerToSTOP=0; } else { OutFlag=CurrentFlag; } return OutFlag; }
Далее uint16_t MS максимально может контролировать до 65535мс = 65 секунд. Далее что бы это все у вас работало нужно постоянно опрашивать функцию OnAfterTimeMS или OFFAfterTimeMS что не есть зергуд. И опишите еще раз что вы путаетесь получить?
Ну если уж на все случаи жизни, то не uint16_t, а uint32_t, 4294967295миллисекунд = 4294967,295секунд = 71582,78825минут = 1193.046470833часов = 49.71026961804дней, и то может не хватить.
ISR (TIMER0_OVF_vect) { TCNT0=125; //значение для T0_0VF переполнения 1 раз в MS TIMER.MS++; //Подсчет MS if (TIMER.MS == 4294967295UL) { TIMER.MS=0; } } /*Функция вернет TRUE через время TimeVar,Иначе возвращает CurrentFlag */ uint8_t OnAfterTimeMS(uint32_t TimeVar,uint8_t Number,uint8_t CurrentFlag) { cli(); uint8_t OutFlag=0; //Переменная отвечает за RETURN f(). TIMER.TimeCurrent=TIMER.MS; //Присваиваем текущие значение МС if (TIMER.Channel[Number].FlagTimersON==0) //Условия для захвата времени вызова функции и установки флага работы { TIMER.Channel[Number].TimeCountingON=TIMER.MS; TIMER.Channel[Number].FlagTimersON=1; } uint32_t TimerToStart = TIMER.TimeCurrent-TIMER.Channel[Number].TimeCountingON; if (TimerToStart >= TimeVar) //Если время до старта == TimeVar, то OutFlag=1 и обнуляем Флаг работы. { OutFlag=1; TIMER.Channel[Number].FlagTimersON=0; TIMER.TimeCurrent=0; TIMER.Channel[Number].TimeCountingON=0; TimerToStart=0; } else { OutFlag=CurrentFlag; } sei(); return OutFlag; }
uint8_t OFFAfterTimeMS(uint32_t TimeVar,uint8_t Number,uint8_t CurrentFlag) { cli(); uint8_t OutFlag=CurrentFlag; //Переменная отвечает за RETURN f(). TIMER.TimeCurrent=TIMER.MS; //Присваиваем текущие значение МС if (TIMER.Channel[Number].FlagTimersOFF==0) //Условия для захвата времени вызова функции и установки флага работы { TIMER.Channel[Number].TimeCountingOFF=TIMER.MS; TIMER.Channel[Number].FlagTimersOFF=1; } uint32_t TimerToSTOP = TIMER.TimeCurrent-TIMER.Channel[Number].TimeCountingOFF; if (TimerToSTOP >= TimeVar) //Если время до старта == TimeVar, то OutFlag=1 и обнуляем Флаг работы. { OutFlag=0; TIMER.Channel[Number].FlagTimersOFF=0; TIMER.TimeCurrent=0; TIMER.Channel[Number].TimeCountingOFF=0; TimerToSTOP=0; } else { OutFlag=CurrentFlag; } sei(); return OutFlag; }
поле MS структуры имеет тип uint32_t, поэтому более логично
Код:
if (TIMER.MS == UINT32_MAX)
И вообще код
Код:
if (TIMER.MS == 4294967295UL) { TIMER.MS=0; }
лишний!!! Чем Вам так "неугодило" значение 4294967295UL, что Вы его исключаете??? Если увеличить на единицу - будет 0UL
2) Поле TimeCurrent не соответствует названию TimeCurrent (текущее время) - это поле MS. Да и логика TimeCurrent станная,
3) поле MS (не понимаю, зачем большими буквами) неплохо бы volatile объявить. мало ли как компилятор соптимизирует. Или нет?
4)
Код:
/*Функция вернет TRUE через время TimeVar,Иначе возвращает CurrentFlag */ uint8_t OnAfterTimeMS(uint32_t TimeVar,uint8_t Number,uint8_t CurrentFlag)
Не знаю, может и задумка хитрая. Но (по крайнем мере комметарий "супер-крутой"). Как по по возвращенному значению понять, время TimeVar истекло или это CurrentFlag?
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 8
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения