Нескольно простых вопросов о программировании AVR на Си.
- Oxford
- Опытный кот
- Сообщения: 819
- Зарегистрирован: Вт окт 23, 2012 13:17:25
- Откуда: Прокопьевск
- Контактная информация:
Re: Нескольно простых вопросов о программировании AVR на Си.
[uquote="philosoraptor",url="/forum/viewtopic.php?p=3325277#p3325277"][uquote="Markusha",url="/forum/viewtopic.php?p=3321240#p3321240"]А вы не думали что оно не от хорошей жизни происходит?
Когда функции malloc и free отожрут лишних пару килобайт весьма ценного флеша?[/uquote]
Ну, тут уж вам придется сделать свой нелегкий выбор и решить, что для вас важнее: либо переменные, вечно сидящие во флеше из-за какой-то одной вторичной функции, или же динамическая работа с памятью, где объем используется в разы эффективнее и позволяет сделать на паре кБ то, что многие привыкли делать на 32-64 кБ.[/uquote]
Не порите чушь, ей больно.
Когда функции malloc и free отожрут лишних пару килобайт весьма ценного флеша?[/uquote]
Ну, тут уж вам придется сделать свой нелегкий выбор и решить, что для вас важнее: либо переменные, вечно сидящие во флеше из-за какой-то одной вторичной функции, или же динамическая работа с памятью, где объем используется в разы эффективнее и позволяет сделать на паре кБ то, что многие привыкли делать на 32-64 кБ.[/uquote]
Не порите чушь, ей больно.
Инженер R@D
Telegram чат: https://t.me/radiowolf или в поиске приложения @radiowolf. Личка:@cncoxford
Telegram чат: https://t.me/radiowolf или в поиске приложения @radiowolf. Личка:@cncoxford
- philosoraptor
- Прорезались зубы
- Сообщения: 225
- Зарегистрирован: Сб янв 14, 2012 22:53:50
Re: Нескольно простых вопросов о программировании AVR на Си.
[uquote="ARV",url="/forum/viewtopic.php?p=3325347#p3325347"]простор ARM голову вскружил[/uquote]
Есть немного.
Есть немного.
Есть много вещей, друг мой Горацио... Собственно, старшие AVRки с 64 и больше кБ на борту уже позволяют ваять многоуровневые проекты, где и динамическая память, и классы заметно упростят задачу.пока что мне не попадались проекты на AVR, где использование динамического распределения памяти давало бы какой-то заметный выигрыш.
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18544
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: Нескольно простых вопросов о программировании AVR на Си.
это о каких AVRках вы говорите? и о каких конкретно проектах?philosoraptor писал(а):Собственно, старшие AVRки с 64 и больше кБ на борту уже позволяют ваять многоуровневые проекты, где и динамическая память, и классы заметно упростят задачу
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- prinv
- Вымогатель припоя
- Сообщения: 677
- Зарегистрирован: Чт янв 20, 2011 09:07:08
- Откуда: Пермь
- Контактная информация:
Re: Нескольно простых вопросов о программировании AVR на Си.
Atmega64 и Atmega128, например
Никакая контра не уйдёт от нас
-
esperranza
- Нашел транзистор. Понюхал.
- Сообщения: 175
- Зарегистрирован: Пн фев 23, 2009 21:53:43
Re: Нескольно простых вопросов о программировании AVR на Си.
Не програмист! Нужно "поморгать" светодиодом на всех портах меги16. Как мог так написал код в CVAVR, прошил и такая ерунда: в полную яркость моргают только 0 биты, остальные 7 бит еле-еле видно свечение. Что не так?
#include <delay.h>
void main(void)
{
PORTA=0x00;
DDRA=0x01;
PORTB=0x00;
DDRB=0x01;
PORTC=0x00;
DDRC=0x01;
PORTD=0x00;
DDRD=0x01;
while (1)
{
PORTA.0=1;
PORTA.1=1;
PORTA.2=1;
PORTA.3=1;
PORTA.4=1;
PORTA.5=1;
PORTA.6=1;
PORTA.7=1;
PORTB.0=1;
PORTB.1=1;
PORTB.2=1;
PORTB.3=1;
PORTB.4=1;
PORTB.5=1;
PORTB.6=1;
PORTB.7=1;
PORTC.0=1;
PORTC.1=1;
PORTC.2=1;
PORTC.3=1;
PORTC.4=1;
PORTC.5=1;
PORTC.6=1;
PORTC.7=1;
PORTD.0=1;
PORTD.1=1;
PORTD.2=1;
PORTD.3=1;
PORTD.4=1;
PORTD.5=1;
PORTD.6=1;
PORTD.7=1; //включаем 0 ножку порта В
delay_ms(100); // ждем 100 мс
PORTA.0=0;
PORTA.1=0;
PORTA.2=0;
PORTA.3=0;
PORTA.4=0;
PORTA.5=0;
PORTA.6=0;
PORTA.7=0;
PORTB.0=0;
PORTB.1=0;
PORTB.2=0;
PORTB.3=0;
PORTB.4=0;
PORTB.5=0;
PORTB.6=0;
PORTB.7=0;
PORTC.0=0;
PORTC.1=0;
PORTC.2=0;
PORTC.3=0;
PORTC.4=0;
PORTC.5=0;
PORTC.6=0;
PORTC.7=0;
PORTD.0=0;
PORTD.1=0;
PORTD.2=0;
PORTD.3=0;
PORTD.4=0;
PORTD.5=0;
PORTD.6=0;
PORTD.7=0; //выключаем 0 ножку
delay_ms(100); //ждем 100 мс
};
};
Спойлер
#include <mega16.h>#include <delay.h>
void main(void)
{
PORTA=0x00;
DDRA=0x01;
PORTB=0x00;
DDRB=0x01;
PORTC=0x00;
DDRC=0x01;
PORTD=0x00;
DDRD=0x01;
while (1)
{
PORTA.0=1;
PORTA.1=1;
PORTA.2=1;
PORTA.3=1;
PORTA.4=1;
PORTA.5=1;
PORTA.6=1;
PORTA.7=1;
PORTB.0=1;
PORTB.1=1;
PORTB.2=1;
PORTB.3=1;
PORTB.4=1;
PORTB.5=1;
PORTB.6=1;
PORTB.7=1;
PORTC.0=1;
PORTC.1=1;
PORTC.2=1;
PORTC.3=1;
PORTC.4=1;
PORTC.5=1;
PORTC.6=1;
PORTC.7=1;
PORTD.0=1;
PORTD.1=1;
PORTD.2=1;
PORTD.3=1;
PORTD.4=1;
PORTD.5=1;
PORTD.6=1;
PORTD.7=1; //включаем 0 ножку порта В
delay_ms(100); // ждем 100 мс
PORTA.0=0;
PORTA.1=0;
PORTA.2=0;
PORTA.3=0;
PORTA.4=0;
PORTA.5=0;
PORTA.6=0;
PORTA.7=0;
PORTB.0=0;
PORTB.1=0;
PORTB.2=0;
PORTB.3=0;
PORTB.4=0;
PORTB.5=0;
PORTB.6=0;
PORTB.7=0;
PORTC.0=0;
PORTC.1=0;
PORTC.2=0;
PORTC.3=0;
PORTC.4=0;
PORTC.5=0;
PORTC.6=0;
PORTC.7=0;
PORTD.0=0;
PORTD.1=0;
PORTD.2=0;
PORTD.3=0;
PORTD.4=0;
PORTD.5=0;
PORTD.6=0;
PORTD.7=0; //выключаем 0 ножку
delay_ms(100); //ждем 100 мс
};
};
Re: Нескольно простых вопросов о программировании AVR на Си.
[uquote="esperranza",url="/forum/viewtopic.php?p=3358184#p3358184"]в полную яркость моргают только 0 биты, остальные 7 бит еле-еле видно свечение. Что не так?[/uquote]
Вот не так
Вот не так
Почитайте про регистры DDRxКод: Выделить всё
... DDRA=0x01; ... DDRB=0x01; ... DDRC=0x01; ... DDRD=0x01; ...
Re: Нескольно простых вопросов о программировании AVR на Си.
[uquote="esperranza",url="/forum/viewtopic.php?p=3358184#p3358184"]Не програмист! Нужно "поморгать" светодиодом на всех портах меги16. Как мог так написал код в CVAVR, прошил и такая ерунда: в полную яркость моргают только 0 биты, остальные 7 бит еле-еле видно свечение. Что не так?[/uquote]
остальные настроены на вход. Надо так:
DDRx = 0xff;
остальные настроены на вход. Надо так:
DDRx = 0xff;
Re: Нескольно простых вопросов о программировании AVR на Си.
Здравствуйте. Подскажите пожалуйста, как в программе сбросить микроконтроллер по нажатию например определенных кнопок. Т.е. интересует именно сброс не по сторожевому таймеру, он в моем случае отключен, а , например, нажал кнопку (любую, а не ту, которая вывод reset на "0" садит), и мк начинает выполнение команд со строки reset. Подскажите, как это реализовать в CodeVisionAvr. Спасибо.
Re: Нескольно простых вопросов о программировании AVR на Си.
[uquote="scv",url="/forum/viewtopic.php?p=3369612#p3369612"]Подскажите, как это реализовать в CodeVisionAvr.[/uquote]
"сбросить микроконтроллер" и "мк начинает выполнение команд со строки reset" - это разные вещи. Как минимум сброс предполагант установку регистров в начальное состояние. Так что, если хотите сбросить, то лучше запретить прерывания, включить сторожевой таймер, и уйти в спячку: через некоторое время микроконтроллер именно СБРОСИТСЯ.
Ну а если надо просто начать выполняться с вектора reset, то какие проблемы? Ассемблерные вставки в CVAVR вроде есть, адрес вектора reset известен, команда JMP в AVR имеется.
"сбросить микроконтроллер" и "мк начинает выполнение команд со строки reset" - это разные вещи. Как минимум сброс предполагант установку регистров в начальное состояние. Так что, если хотите сбросить, то лучше запретить прерывания, включить сторожевой таймер, и уйти в спячку: через некоторое время микроконтроллер именно СБРОСИТСЯ.
Ну а если надо просто начать выполняться с вектора reset, то какие проблемы? Ассемблерные вставки в CVAVR вроде есть, адрес вектора reset известен, команда JMP в AVR имеется.
-
Demiurg
- Это не хвост, это антенна
- Сообщения: 1480
- Зарегистрирован: Ср июн 25, 2008 15:19:44
- Контактная информация:
Re: Нескольно простых вопросов о программировании AVR на Си.
[uquote="scv",url="/forum/viewtopic.php?p=3369612#p3369612"]как в программе сбросить микроконтроллер по нажатию например определенных кнопок[/uquote]
Конечная цель такого решения? Что вы этим хотите добиться?
Как раз по сторожевому таймеру самое простое решение. При определенном событии уходим в глухой цикл. Сторожевой таймер сбросит МК. Но это полный сброс МК. Компиляторы Си в начале программы делают очистку ОЗУ. Этого не видно в коде, но видно в дизассемблере. Есть специальные ключи, которые позволяют начинать программу обходя блок инициализации ОЗУ. Если вам нужно, чтобы при вашем сбросе содержимое ОЗУ осталось как есть, нужно продумать алгоритм и применение специальных ключей. Скажем, в начале программы есть специальная переменная. Если эта переменная не инициализирована, считаем, что МК только что включен или был аппаратный сброс. Инициализируем эту переменную и переменные программы. Выполнение дальнейшего кода. Если переменная инициализирована, выполняем соответствующий код.
Конечная цель такого решения? Что вы этим хотите добиться?
Как раз по сторожевому таймеру самое простое решение. При определенном событии уходим в глухой цикл. Сторожевой таймер сбросит МК. Но это полный сброс МК. Компиляторы Си в начале программы делают очистку ОЗУ. Этого не видно в коде, но видно в дизассемблере. Есть специальные ключи, которые позволяют начинать программу обходя блок инициализации ОЗУ. Если вам нужно, чтобы при вашем сбросе содержимое ОЗУ осталось как есть, нужно продумать алгоритм и применение специальных ключей. Скажем, в начале программы есть специальная переменная. Если эта переменная не инициализирована, считаем, что МК только что включен или был аппаратный сброс. Инициализируем эту переменную и переменные программы. Выполнение дальнейшего кода. Если переменная инициализирована, выполняем соответствующий код.
- philosoraptor
- Прорезались зубы
- Сообщения: 225
- Зарегистрирован: Сб янв 14, 2012 22:53:50
Re: Нескольно простых вопросов о программировании AVR на Си.
[uquote="scv",url="/forum/viewtopic.php?p=3369612#p3369612"]Подскажите пожалуйста, как в программе сбросить микроконтроллер[/uquote]
if(keyReset) ((void(*)(void))0)();
if(keyReset) ((void(*)(void))0)();
-
Demiurg
- Это не хвост, это антенна
- Сообщения: 1480
- Зарегистрирован: Ср июн 25, 2008 15:19:44
- Контактная информация:
Re: Нескольно простых вопросов о программировании AVR на Си.
[uquote="philosoraptor",url="/forum/viewtopic.php?p=3370130#p3370130"]...[/uquote]
Тогда ужа так:
Есть "но" при таком решении. Сброс произошел программный, а не аппаратный. И нам неизвестно, какая периферия включена, как настроена и в каком сейчас состоянии. И запросто может быть ситуация, при глобальном разрешении прерываний начнут срабатывать прерывания.
Поэтому, этот способ неприемлем.
Тогда ужа так:
Код: Выделить всё
if(keyReset)
{
__watchdog_reset (); // wdt
__disable_interrupt (); // cli
((void(*)(void))0)();
}Поэтому, этот способ неприемлем.
-
esperranza
- Нашел транзистор. Понюхал.
- Сообщения: 175
- Зарегистрирован: Пн фев 23, 2009 21:53:43
Re: Нескольно простых вопросов о программировании AVR на Си.
Исправил код, в Протэусе мега 16 мигает всеми портами. Проверял работоспособность 2-х б/у мег16, в обеих не работают портыРС2-РС5. Заказал новую, прошил-история таже, не работают РС2-РС5. Может в настройках CV перед созданием проэкта нужно какие манипуляции сделать?
#include <delay.h>
void main(void)
{
PORTA=0x00;
DDRA=0xff;
PORTB=0x00;
DDRB=0xff;
PORTC=0x00;
DDRC=0xff;
PORTD=0x00;
DDRD=0xff;
while (1)
{
PORTA.0=1;
PORTA.1=1;
PORTA.2=1;
PORTA.3=1;
PORTA.4=1;
PORTA.5=1;
PORTA.6=1;
PORTA.7=1;
PORTB.0=1;
PORTB.1=1;
PORTB.2=1;
PORTB.3=1;
PORTB.4=1;
PORTB.5=1;
PORTB.6=1;
PORTB.7=1;
PORTC.0=1;
PORTC.1=1;
PORTC.2=1;
PORTC.3=1;
PORTC.4=1;
PORTC.5=1;
PORTC.6=1;
PORTC.7=1;
PORTD.0=1;
PORTD.1=1;
PORTD.2=1;
PORTD.3=1;
PORTD.4=1;
PORTD.5=1;
PORTD.6=1;
PORTD.7=1; //включаем 0 ножку порта В
delay_ms(100); // ждем 100 мс
PORTA.0=0;
PORTA.1=0;
PORTA.2=0;
PORTA.3=0;
PORTA.4=0;
PORTA.5=0;
PORTA.6=0;
PORTA.7=0;
PORTB.0=0;
PORTB.1=0;
PORTB.2=0;
PORTB.3=0;
PORTB.4=0;
PORTB.5=0;
PORTB.6=0;
PORTB.7=0;
PORTC.0=0;
PORTC.1=0;
PORTC.2=0;
PORTC.3=0;
PORTC.4=0;
PORTC.5=0;
PORTC.6=0;
PORTC.7=0;
PORTD.0=0;
PORTD.1=0;
PORTD.2=0;
PORTD.3=0;
PORTD.4=0;
PORTD.5=0;
PORTD.6=0;
PORTD.7=0; //выключаем 0 ножку
delay_ms(100); //ждем 100 мс
};
};
Спойлер
#include <mega16.h>#include <delay.h>
void main(void)
{
PORTA=0x00;
DDRA=0xff;
PORTB=0x00;
DDRB=0xff;
PORTC=0x00;
DDRC=0xff;
PORTD=0x00;
DDRD=0xff;
while (1)
{
PORTA.0=1;
PORTA.1=1;
PORTA.2=1;
PORTA.3=1;
PORTA.4=1;
PORTA.5=1;
PORTA.6=1;
PORTA.7=1;
PORTB.0=1;
PORTB.1=1;
PORTB.2=1;
PORTB.3=1;
PORTB.4=1;
PORTB.5=1;
PORTB.6=1;
PORTB.7=1;
PORTC.0=1;
PORTC.1=1;
PORTC.2=1;
PORTC.3=1;
PORTC.4=1;
PORTC.5=1;
PORTC.6=1;
PORTC.7=1;
PORTD.0=1;
PORTD.1=1;
PORTD.2=1;
PORTD.3=1;
PORTD.4=1;
PORTD.5=1;
PORTD.6=1;
PORTD.7=1; //включаем 0 ножку порта В
delay_ms(100); // ждем 100 мс
PORTA.0=0;
PORTA.1=0;
PORTA.2=0;
PORTA.3=0;
PORTA.4=0;
PORTA.5=0;
PORTA.6=0;
PORTA.7=0;
PORTB.0=0;
PORTB.1=0;
PORTB.2=0;
PORTB.3=0;
PORTB.4=0;
PORTB.5=0;
PORTB.6=0;
PORTB.7=0;
PORTC.0=0;
PORTC.1=0;
PORTC.2=0;
PORTC.3=0;
PORTC.4=0;
PORTC.5=0;
PORTC.6=0;
PORTC.7=0;
PORTD.0=0;
PORTD.1=0;
PORTD.2=0;
PORTD.3=0;
PORTD.4=0;
PORTD.5=0;
PORTD.6=0;
PORTD.7=0; //выключаем 0 ножку
delay_ms(100); //ждем 100 мс
};
};
- Ярослав555
- Поставщик валерьянки для Кота
- Сообщения: 2081
- Зарегистрирован: Пт май 31, 2013 17:14:38
- Откуда: Украина, Винница
Re: Нескольно простых вопросов о программировании AVR на Си.
[uquote="WiseLord",url="/forum/viewtopic.php?p=3371402#p3371402"]JTAG отключить надо
P.S. Имеется в виду FUSE-бит JTAGEN, конечно.[/uquote]
Может быть. Но как по мне странно: обычно наоборот - приходится включать житаг, если хочешь в отладчик.
P.S. Имеется в виду FUSE-бит JTAGEN, конечно.[/uquote]
Может быть. Но как по мне странно: обычно наоборот - приходится включать житаг, если хочешь в отладчик.
-
esperranza
- Нашел транзистор. Понюхал.
- Сообщения: 175
- Зарегистрирован: Пн фев 23, 2009 21:53:43
- Ярослав555
- Поставщик валерьянки для Кота
- Сообщения: 2081
- Зарегистрирован: Пт май 31, 2013 17:14:38
- Откуда: Украина, Винница
Re: Нескольно простых вопросов о программировании AVR на Си.
А теперь задачка от меня. Имеем в программе ряд дефайнов-констант.
Препроцессор позволяет сделать конструкцию вида
Что собственно генерит ошибку компиляции если параметры забиты не корректно и условие выполняется.
Вопрос - есть ли грамотный способ бросать ошибку на уровне препроцессора?
Чисто из перфекционизма интересуюсь.
Препроцессор позволяет сделать конструкцию вида
Код: Выделить всё
#define FIELD_LENGTH 21
#define RAM_ADDRESS_LENGTH 2
#define FULL_FIELD_LENGTH (FIELD_LENGTH + RAM_ADDRESS_LENGTH)
#define MAX_FRAM_ADDRESS 32767U
#define FIELDS_NUM 1700U
#if (FIELDS_NUM * FIELD_LENGTH) > MAX_FRAM_ADDRESS
Number of fields are bigger than all fram space!!!!!!!
#endif
Вопрос - есть ли грамотный способ бросать ошибку на уровне препроцессора?
Чисто из перфекционизма интересуюсь.
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18544
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: Нескольно простых вопросов о программировании AVR на Си.
Ярослав555 писал(а):Вопрос - есть ли грамотный способ бросать ошибку на уровне препроцессора?
Код: Выделить всё
#error Some error textесли рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- Ярослав555
- Поставщик валерьянки для Кота
- Сообщения: 2081
- Зарегистрирован: Пт май 31, 2013 17:14:38
- Откуда: Украина, Винница
Re: Нескольно простых вопросов о программировании AVR на Си.
[uquote="ARV",url="/forum/viewtopic.php?p=3371704#p3371704"][/uquote]
Спасибо, плюсик с меня
Код: Выделить всё
#error Some error textСпасибо, плюсик с меня
Re: Нескольно простых вопросов о программировании AVR на Си.
Здравствуйте. Откровенно говоря, хотел сам разобраться, но зашел в тупик. Увы, не хватает знаний. Может поможете, или пнете в нужное направление !?
Суть программки - В основном цикле таймер остановлен. При нажатии на кнопку (лог.0), срабатывает внешнее прерывании INT0 и в нем запускается плавно ШИМ от нуля до определенной величины. При отпускании кнопки - уходим опять в вечный цикл. Вроде все работает, но скважность ШИМ постоянно увеличивается и потом уменьшается. И так беcконечно, пока не отпустить кнопку. Как можно исправить этот момент? Подскажите пожалуйста.
Суть программки - В основном цикле таймер остановлен. При нажатии на кнопку (лог.0), срабатывает внешнее прерывании INT0 и в нем запускается плавно ШИМ от нуля до определенной величины. При отпускании кнопки - уходим опять в вечный цикл. Вроде все работает, но скважность ШИМ постоянно увеличивается и потом уменьшается. И так беcконечно, пока не отпустить кнопку. Как можно исправить этот момент? Подскажите пожалуйста.
Код: Выделить всё
#define F_CPU 1200000UL
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
unsigned int i=0;
void init_pwm()
{
TCCR0A |=(1<<WGM00); // Режим Phase correct PWM, в этом режиме счет идет до 255, а потом обратно до 0
TCCR0A |=(1<<COM0A1) | (0<<COM0A0); // 0 при 1-м равенстве регистров TCNT0 и OCROA и 1 при 2-м равенстве. (инвертированный ШИМ-сигнал)
TCCR0B |= (1<<CS01); // делитель 8
OCR0A =0;// регистр сравнения
}
//--------------------------------------------------------------------------
void start_pwm()
{
while(i<95)
{
i=i+1;
OCR0A=i;
_delay_ms(25);
}
}
//--------------------------------------------------------------------------
void stop_pwm()
{
TCCR0B= 0x00;
TCCR0A= 0x00;
}
//------------------------------------------------------------------------------
ISR (INT0_vect) /* Объявление функции прерывания INT0 (порт PB1) */
{
init_pwm();
start_pwm();
asm("sei"); // глобальное разрешение прерываний//
}
//------------------------------------------------------------------------------
int main(void)
{
DDRB|=(0<<PB1)|(1<<PB0)|(0<<PB4)|(1<<PB2);
PORTB=0b00010010;
MCUCR |= (0<<ISC01)|(0<<ISC00); // Низкий уровень на INT0 генерирует запрос прерывание//
GIMSK |= (1<<INT0); //Разрешение работы прерывания INT0 на выводе PB1//
GIFR= 0x00; // Флаг прерываний//
TIMSK0|=(1<<OCIE0B);
init_pwm();
asm("sei"); //глобальное разрешение прерываний//
while(1)
{
stop_pwm();
}
}