Обсуждаем контроллеры компании Atmel.
Ср мар 07, 2018 18:26:13
А вы не думали что оно не от хорошей жизни происходит?
Когда функции malloc и free отожрут лишних пару килобайт весьма ценного флеша?
Ну, тут уж вам придется сделать свой нелегкий выбор и решить, что для вас важнее: либо переменные, вечно сидящие во флеше из-за какой-то одной вторичной функции, или же динамическая работа с памятью, где объем используется в разы эффективнее и позволяет сделать на паре кБ то, что многие привыкли делать на 32-64 кБ.
Не порите чушь, ей больно.
Пт апр 13, 2018 11:25:44
простор ARM голову вскружил
Есть немного.
пока что мне не попадались проекты на AVR, где использование динамического распределения памяти давало бы какой-то заметный выигрыш.
Есть много вещей, друг мой Горацио... Собственно, старшие AVRки с 64 и больше кБ на борту уже позволяют ваять многоуровневые проекты, где и динамическая память, и классы заметно упростят задачу.
Пт апр 13, 2018 11:40:55
philosoraptor писал(а):Собственно, старшие AVRки с 64 и больше кБ на борту уже позволяют ваять многоуровневые проекты, где и динамическая память, и классы заметно упростят задачу
это о каких AVRках вы говорите? и о каких конкретно проектах?
Пт апр 13, 2018 14:31:17
Atmega64 и Atmega128, например
Чт апр 19, 2018 21:52:09
Не програмист! Нужно "поморгать" светодиодом на всех портах меги16. Как мог так написал код в CVAVR, прошил и такая ерунда: в полную яркость моргают только 0 биты, остальные 7 бит еле-еле видно свечение. Что не так?
Спойлер
#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 мс
};
};
Чт апр 19, 2018 22:51:58
в полную яркость моргают только 0 биты, остальные 7 бит еле-еле видно свечение. Что не так?
Вот не так
- Код:
...
DDRA=0x01;
...
DDRB=0x01;
...
DDRC=0x01;
...
DDRD=0x01;
...
Почитайте про регистры DDRx
Пт апр 20, 2018 08:09:46
Не програмист! Нужно "поморгать" светодиодом на всех портах меги16. Как мог так написал код в CVAVR, прошил и такая ерунда: в полную яркость моргают только 0 биты, остальные 7 бит еле-еле видно свечение. Что не так?
остальные настроены на вход. Надо так:
DDRx = 0xff;
Сб май 05, 2018 13:42:38
Здравствуйте. Подскажите пожалуйста, как в программе сбросить микроконтроллер по нажатию например определенных кнопок. Т.е. интересует именно сброс не по сторожевому таймеру, он в моем случае отключен, а , например, нажал кнопку (любую, а не ту, которая вывод reset на "0" садит), и мк начинает выполнение команд со строки reset. Подскажите, как это реализовать в CodeVisionAvr. Спасибо.
Сб май 05, 2018 14:51:53
Подскажите, как это реализовать в CodeVisionAvr.
"сбросить микроконтроллер" и "мк начинает выполнение команд со строки reset" - это разные вещи. Как минимум сброс предполагант установку регистров в начальное состояние. Так что, если хотите сбросить, то лучше запретить прерывания, включить сторожевой таймер, и уйти в спячку: через некоторое время микроконтроллер именно СБРОСИТСЯ.
Ну а если надо просто начать выполняться с вектора reset, то какие проблемы? Ассемблерные вставки в CVAVR вроде есть, адрес вектора reset известен, команда JMP в AVR имеется.
Сб май 05, 2018 16:22:13
как в программе сбросить микроконтроллер по нажатию например определенных кнопок
Конечная цель такого решения? Что вы этим хотите добиться?
Как раз по сторожевому таймеру самое простое решение. При определенном событии уходим в глухой цикл. Сторожевой таймер сбросит МК. Но это полный сброс МК. Компиляторы Си в начале программы делают очистку ОЗУ. Этого не видно в коде, но видно в дизассемблере. Есть специальные ключи, которые позволяют начинать программу обходя блок инициализации ОЗУ. Если вам нужно, чтобы при вашем сбросе содержимое ОЗУ осталось как есть, нужно продумать алгоритм и применение специальных ключей. Скажем, в начале программы есть специальная переменная. Если эта переменная не инициализирована, считаем, что МК только что включен или был аппаратный сброс. Инициализируем эту переменную и переменные программы. Выполнение дальнейшего кода. Если переменная инициализирована, выполняем соответствующий код.
Сб май 05, 2018 23:15:29
Подскажите пожалуйста, как в программе сбросить микроконтроллер
if(keyReset) ((void(*)(void))0)();
Вс май 06, 2018 07:23:01
...
Тогда ужа так:
- Код:
if(keyReset)
{
__watchdog_reset (); // wdt
__disable_interrupt (); // cli
((void(*)(void))0)();
}
Есть "но" при таком решении. Сброс произошел программный, а не аппаратный. И нам неизвестно, какая периферия включена, как настроена и в каком сейчас состоянии. И запросто может быть ситуация, при глобальном разрешении прерываний начнут срабатывать прерывания.
Поэтому, этот способ неприемлем.
Пн май 07, 2018 19:52:48
Исправил код, в Протэусе мега 16 мигает всеми портами. Проверял работоспособность 2-х б/у мег16, в обеих не работают портыРС2-РС5. Заказал новую, прошил-история таже, не работают РС2-РС5. Может в настройках CV перед созданием проэкта нужно какие манипуляции сделать?
Спойлер
#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 мс
};
};
Пн май 07, 2018 19:58:28
JTAG отключить надо:
P.S. Имеется в виду FUSE-бит JTAGEN, конечно.
Пн май 07, 2018 20:23:07
JTAG отключить надо
P.S. Имеется в виду FUSE-бит JTAGEN, конечно.
Может быть. Но как по мне странно: обычно наоборот - приходится включать житаг, если хочешь в отладчик.
Пн май 07, 2018 21:39:47
JTAG отключить надо:
P.S. Имеется в виду FUSE-бит JTAGEN, конечно.
Спасибо!, таки помогло
Вт май 08, 2018 10:48:12
А теперь задачка от меня. Имеем в программе ряд дефайнов-констант.
Препроцессор позволяет сделать конструкцию вида
- Код:
#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
Что собственно генерит ошибку компиляции если параметры забиты не корректно и условие выполняется.
Вопрос - есть ли грамотный способ бросать ошибку на уровне препроцессора?
Чисто из перфекционизма интересуюсь.
Вт май 08, 2018 10:50:58
Ярослав555 писал(а):Вопрос - есть ли грамотный способ бросать ошибку на уровне препроцессора?
- Код:
#error Some error text
Вт май 08, 2018 10:53:49
- Код:
#error Some error text
Спасибо, плюсик с меня
Чт май 31, 2018 19:44:14
Здравствуйте. Откровенно говоря, хотел сам разобраться, но зашел в тупик. Увы, не хватает знаний. Может поможете, или пнете в нужное направление !?
Суть программки - В основном цикле таймер остановлен. При нажатии на кнопку (лог.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();
}
}
Powered by phpBB © phpBB Group.
phpBB Mobile / SEO by Artodia.