WinAvr в вопросах и ответах
- urry
- Сверлит текстолит когтями
- Сообщения: 1262
- Зарегистрирован: Пн дек 08, 2008 10:58:48
- Откуда: Винница
- Контактная информация:
Re: WinAvr в вопросах и ответах
Нужно не перебирать, а зайти в винавр и в папке avr\include\avr - найти заголовочный файл Вашего камня.
Оттуда переписать правильное название прерывания.
Оттуда переписать правильное название прерывания.
- Реклама
Re: WinAvr в вопросах и ответах
urry писал(а):Нужно не перебирать, а зайти в винавр и в папке avr\include\avr - найти заголовочный файл Вашего камня.
Оттуда переписать правильное название прерывания.
Спасибо urry, я нашел что искал:
/* USART, Tx Complete */
#define USART_TXC_vect _VECTOR(13)
#define SIG_UART_TRANS _VECTOR(13)
PS: Кстати правильный пример прерывания по таймеру ты написал на этом форуме, а я его переписал. Спасибо тебе.

Кот должен прожить жизнь без сожаления.
- Goldsmith
- Опытный кот
- Сообщения: 736
- Зарегистрирован: Пн янв 10, 2011 03:06:36
- Откуда: Ростов-на-Дону
- Контактная информация:
Re: WinAvr в вопросах и ответах
DruidCat писал(а):Кстати, по поводу прерываний и WINAVR.
...
инициализация функции прерывания по таймеру старой версии WINAVR.
INTERRUPT (SIG_OVERFLOW1)
Сейчас эти функции пишутся по другому.
ISR(TIMER1_OVF_vect)
Поищите в директории, где установлен WinAVR, файл с руководством (у меня сейчас под рукой версия с именем avr-libc-user-manual-1.6.5.pdf, у Вас, возможно, цифры версии будут другими). В нем в разделе <avr/interrupt.h>: Interrupts есть таблица с описанием всех векторов прерываний и их доступности по моделям МК (в моем экземпляре она начинается на стр. 217). Перед таблицей приведен ряд ценных указаний по обработке прерываний в WinAVR в общем.
Несколько замечаний.DruidCat писал(а):По предыдущему примеру таймеров, могу написать для USART прерывание.
...
#include <avr/interrupt.h>//Для доступа к функции sei()
ISR(USART_TXC_vect){
........
}
int main(void){
UCSRB = (0<<RXCIE)|(1<<TXCIE)|(1<<RXEN)|(1<<TXEN);//Активизируем прерывание по завершении передачи, приемник и передатчик
Во-первых, Вы разрешили прерывание по готовности приемника, но не определили функцию для его обработки. Это приведет к неприятным последствиям, если кто-то не просто ограничится наблюдением выводимых на терминал сообщений, но и попробует потыкать клавиши в ответ. Каждый принятый байт будет приводить к переходу на вектор сброса, т.е. перезапуску программы. Не следует разрешать лишние прерывания, которые в данный момент не задействованы.
Далее, я бы не рекомендовал разрешать прерывания по готовности передатчика в самом начале программы. Получается такая ситуация: сначала передатчик готов, но данные для передачи еще не подготовлены; вызывается обработчик прерывания, а делать ему пока еще нечего. Потом программа подготовит данные, но прерывания уже не будет (т.к. оно было обработано вхолостую), и придется опрашивать флаг готовности. Лучше разрешать прерывания в тот момент, когда есть данные для передачи, и запрещать, когда их нет.
И последнее. Прерывания нужны для того, чтобы исключить непродуктивное зацикливание процессора на ожидании готовности устройства и заставить процессор заняться чем-то более полезным. Наиболее эффективно сочетать работу по прерыванием с буферизацией данных. Для этого в памяти выделяется буферная очередь с дисциплиной доступа FIFO (First In First Out, т.е. "первым пришел - первым ушел"). Главная программа заносит текст сообщения в буфер и инициирует передачу (разрешает прерывания от передатчика). Далее программа занимается своим делом, а обработчик прерываний извлекает байты из очереди по одному и отправляет в линию. После передачи последнего байта из очереди прерывание от передатчика следует снова запретить до лучших времен.
Если дружите с английским, рекомендую пару хороших книг:
1. Jean J. Labrosse. Embedded Systems Building Blocks, Second Edition. Complete and Ready-to-Use Modules in C. Книга изначально ориентирована на процессоры Intel, но хороший код C (а у Лабросса другого не бывает) слабо связан с оборудованием.
2. Bruce Powel Douglass. Real-Time Design Patterns: Robust Scalable Architecture for Real-Time Systems. Масса шаблонов работы в реальном времени от Всемогущего Брюса.
Любой дурак может писать код. Настоящий профессионал - это тот, кто способен постоянно создавать продукт высокого качества, укладываясь при этом в бюджет.
J. Ganssle
J. Ganssle
Re: WinAvr в вопросах и ответах
Вот тут я нашел таблицу прерываний <avr/interrupt.h>: Interrupts в WINAVR
WinAVR-20100110\doc\avr-libc\avr-libc-user-manual\group__avr__interrupts.html
А по поводу прерываний, буду учиться и читать. Спасибо за помощь. Как будут успехи, я отпишу переделанный листинг с itoa и прерываниями со всеми вашими замечаниями. Вдруг, кому понадобится из новичков.
WinAVR-20100110\doc\avr-libc\avr-libc-user-manual\group__avr__interrupts.html
А по поводу прерываний, буду учиться и читать. Спасибо за помощь. Как будут успехи, я отпишу переделанный листинг с itoa и прерываниями со всеми вашими замечаниями. Вдруг, кому понадобится из новичков.
Кот должен прожить жизнь без сожаления.
- vitalik_1984
- Поставщик валерьянки для Кота
- Сообщения: 2482
- Зарегистрирован: Пт авг 27, 2010 05:57:06
- Откуда: Тюмень
- Контактная информация:
Re: WinAvr в вопросах и ответах
Каждый принятый байт будет приводить к переходу на вектор сброса, т.е. перезапуску программы. Не следует разрешать лишние прерывания, которые в данный момент не задействованы.
Вот тут хочу поправить, не на вектор сброса, а на вектор прерывания, как правило в конце всех векторов стоит заглушка в виде reti таким образом возвращая в выполняемый код даже если обработка прерывания пропущена.
Но это опять же пустая трата времени на переход к прерыванию и обратно.К тому же компилятор может еще и запихать в обработку прерывания сохранение регистров, то тогда еще и на это время тратится бесполезно.
Хм кстати я не пробовал нужно посмотреть как себя ведет программа, если пропущена обработка.
В поисках истины человек развивается.
- Реклама
- avreal
- Опытный кот
- Сообщения: 842
- Зарегистрирован: Чт дек 31, 2009 19:27:45
- Откуда: Бровари, Україна
- Контактная информация:
Re: WinAvr в вопросах и ответах
«Вот тут хочу поправить»™, именно у WinAVR в стартапе на всех неиспользуемых векторах стоит переход на weak-метку __bad_interrupt, по которой находится переход на тоже weak-метку __vector_default , которая приравнена метке __vectors, которая является адресом начала таблицы векторов. Т.е. в конечном итоге будет переход на вектор сброса (но не сброс! периферия остаётся непроинициализированной).
Можно объявить ISR(__vector_default) и в ней перехватывать не имеющие обработчика, но разрешённые прерывания.
А reti для прерываний без обработчика — это заметание проблемы под коврик.
Особо весело с прерываниями, не сбрасываемыми самим фактом входа в обработчик (например, внешнее прерывание по уровню или даже UDRE). При этом программа будет после каждой команды бегать на reti, замедлясь в 7..9 раз в зависимости от того, reti прямо в векторе или до него ещё по jmp добираться.
Можно объявить ISR(__vector_default) и в ней перехватывать не имеющие обработчика, но разрешённые прерывания.
А reti для прерываний без обработчика — это заметание проблемы под коврик.
Особо весело с прерываниями, не сбрасываемыми самим фактом входа в обработчик (например, внешнее прерывание по уровню или даже UDRE). При этом программа будет после каждой команды бегать на reti, замедлясь в 7..9 раз в зависимости от того, reti прямо в векторе или до него ещё по jmp добираться.
Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.
- Goldsmith
- Опытный кот
- Сообщения: 736
- Зарегистрирован: Пн янв 10, 2011 03:06:36
- Откуда: Ростов-на-Дону
- Контактная информация:
Re: WinAvr в вопросах и ответах
Ну, давайте поучим разработчиков, которые написали документацию. Они, конечно же, хуже знают, как работает их же продукт, и будут рады поправке:vitalik_1984 писал(а):Каждый принятый байт будет приводить к переходу на вектор сброса, т.е. перезапуску программы. Не следует разрешать лишние прерывания, которые в данный момент не задействованы.
Вот тут хочу поправить, не на вектор сброса, а на вектор прерывания, как правило в конце всех векторов стоит заглушка в виде reti таким образом возвращая в выполняемый код даже если обработка прерывания пропущена.
Catch-all interrupt vector If an unexpected interrupt occurs (interrupt is enabled and no handler is installed, which usually indicates a bug), then the default action is to reset the device by jumping to the reset vector. You can override this by supplying a function named BADISR_vect which should be defined with ISR() as such. (The name BADISR_vect is actually an alias for __vector_default. The latter must be used inside assembly code in case <avr/interrupt.h> is not included.)
Любой дурак может писать код. Настоящий профессионал - это тот, кто способен постоянно создавать продукт высокого качества, укладываясь при этом в бюджет.
J. Ganssle
J. Ganssle
- Goldsmith
- Опытный кот
- Сообщения: 736
- Зарегистрирован: Пн янв 10, 2011 03:06:36
- Откуда: Ростов-на-Дону
- Контактная информация:
Re: WinAvr в вопросах и ответах
Совершенно верно, золотые слова.avreal писал(а):Можно объявить ISR(__vector_default) и в ней перехватывать не имеющие обработчика, но разрешённые прерывания.
А reti для прерываний без обработчика — это заметание проблемы под коврик.
И самое разумное, что можно сделать в ISR(__vector_default), - это аварийный останов программы с соответствующей диагностикой. Ибо поверхностное заштукатуривание провороненных прерываний пустыми reti - весьма отчетливый индикатор дефектного кода.
Любой дурак может писать код. Настоящий профессионал - это тот, кто способен постоянно создавать продукт высокого качества, укладываясь при этом в бюджет.
J. Ganssle
J. Ganssle
- vitalik_1984
- Поставщик валерьянки для Кота
- Сообщения: 2482
- Зарегистрирован: Пт авг 27, 2010 05:57:06
- Откуда: Тюмень
- Контактная информация:
Re: WinAvr в вопросах и ответах
Вот тут я дал маху, будем исправляться.
Просто я в листинге видел после векторов такую фичу вот и подумал.
Только не додумал, что проектировщики winavr были более прозорливые и отправили всех невнимательных в нужное место.Так сразу становится видно ошибку.
Goldsmith, avreal плюсую вам.
только я не понял, если на сброс кидает, значит инициализация снова происходит или как при нажатии на кнопку сброса?Но опять же для разделения причины сброса нужно код писать.
Вообще получается в любом случае, если используются прерывания реально необходимо прорабатывать вектор корявых прерываний.
Наверно можно даже через тот же Юсарт слать для определения проблемы.Или светодиод зажечь в качестве индикатора.
А можно ли еще какие нибудь данные отправить?Получается вроде только глобальные переменные можно.
Только не додумал, что проектировщики winavr были более прозорливые и отправили всех невнимательных в нужное место.Так сразу становится видно ошибку.
Goldsmith, avreal плюсую вам.
только я не понял, если на сброс кидает, значит инициализация снова происходит или как при нажатии на кнопку сброса?Но опять же для разделения причины сброса нужно код писать.
Вообще получается в любом случае, если используются прерывания реально необходимо прорабатывать вектор корявых прерываний.
Наверно можно даже через тот же Юсарт слать для определения проблемы.Или светодиод зажечь в качестве индикатора.
А можно ли еще какие нибудь данные отправить?Получается вроде только глобальные переменные можно.
В поисках истины человек развивается.
- Goldsmith
- Опытный кот
- Сообщения: 736
- Зарегистрирован: Пн янв 10, 2011 03:06:36
- Откуда: Ростов-на-Дону
- Контактная информация:
Re: WinAvr в вопросах и ответах
Недооценивать сообразительность разработчиков продуктов уровня WinAVR - очень большая ошибка.vitalik_1984 писал(а):Только не додумал, что проектировщики winavr были более прозорливые и отправили всех невнимательных в нужное место.
При нажатии на кнопку сброса сначала происходит аппаратный сброс, а уже затем переход на вектор сброса. Что именно происходит в момент аппаратного сброса, лучше смотреть в описании конкретного устройства. Например, для Mega16 указано:vitalik_1984 писал(а):только я не понял, если на сброс кидает, значит инициализация снова происходит или как при нажатии на кнопку сброса?
Resetting the AVR During Reset, all I/O Registers are set to their initial values, and the program starts execution from the Reset Vector.
...
The I/O ports of the AVR are immediately reset to their initial state when a reset source goes active. This does not require any clock source to be running.
В случае программного перехода на вектор сброса аппаратная инициализация регистров ввода/вывода не произойдет, они сохранят прежние значения. Программная инициализация в обоих случаях (аппаратный сброс и переход по вектору сброса) будет происходить одинаково:
.init0 - если __init() определена пользователем;
.init1 - не используется;
.init2 - инициализация стека, обнуление r1;
.init3 - не используется;
.init4 - используется лишь в старших моделях (ROM > 64K);
.init5 - не используется;
.init6 - используется для конструкторов C++:
.init7, .init8 - не используются;
.init9 - переход на main().
Можно отделить аппаратный сброс от программного (из-за перехода по неожиданному прерыванию), например, путем анализа содержимого MCUCSR (для Mega16). Но лучше все же перехватывать все лишние прерывания и аварийно останавливать программу по ним (если это не свистелка/перделка/мигалка светодиодами и подобный шедевр человеческого гения). Устройства, в которых возникают такие прерывания, живут своей жизнью независимо от автора, и лучше выявлять это при первой возможности, возвращая на доработку. Так что такое отделение возможно, но вряд ли будет реально полезным на практике.vitalik_1984 писал(а):Но опять же для разделения причины сброса нужно код писать.
Любой дурак может писать код. Настоящий профессионал - это тот, кто способен постоянно создавать продукт высокого качества, укладываясь при этом в бюджет.
J. Ganssle
J. Ganssle
- vitalik_1984
- Поставщик валерьянки для Кота
- Сообщения: 2482
- Зарегистрирован: Пт авг 27, 2010 05:57:06
- Откуда: Тюмень
- Контактная информация:
Re: WinAvr в вопросах и ответах
А я видел как делали кнопку на ресет, и нажимая на нее получается тоже происходит аппаратный сброс, только переменные все сохраняются.Потом анализируется повод ресета и выполняются нужные действия.Получается на mega16 так не получится сделать?
В поисках истины человек развивается.
- avreal
- Опытный кот
- Сообщения: 842
- Зарегистрирован: Чт дек 31, 2009 19:27:45
- Откуда: Бровари, Україна
- Контактная информация:
Re: WinAvr в вопросах и ответах
Вот зараза, ещё вчера вечером упал сервер, где я в гостях у нескольких толстых сайтов «хощусь». У меня на сайте есть примеры использования этих «не используется» (они специально вставлены для программы пользователя).Goldsmith писал(а):.init1 - не используется;
Можно, только переменные надо заводить в секции .noinit.vitalik_1984 писал(а):А я видел как делали кнопку на ресет, и нажимая на нее получается тоже происходит аппаратный сброс, только переменные все сохраняются.Потом анализируется повод ресета и выполняются нужные действия.Получается на mega16 так не получится сделать?
Пример выдёргивания MCUSR в неинициализируемую переменную в .noinit для последующего анализа причины сброса (перед ранним сбросом WDT в секции .init3, там нужно занулить MCUSR, поэтому нужно сохранить исходное значение для анализа) приведён в avr/wdt.h
http://www.nongnu.org/avr-libc/user-man ... chdog.html
Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.
- avreal
- Опытный кот
- Сообщения: 842
- Зарегистрирован: Чт дек 31, 2009 19:27:45
- Откуда: Бровари, Україна
- Контактная информация:
Re: WinAvr в вопросах и ответах
Прочихался.avreal писал(а):упал сервер
Немного о секциях в gcc вообще и avr-gcc (aka WinAVR aka Atmel toolchain) в частности.
Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.
Re: WinAvr в вопросах и ответах
Эх, жалко, что я в 1998году выбрал профессию инженера-электрика а не программиста, когда поступал в университет. Так бы я сейчас понимал о чем вы говорите.
К слову, сегодня ночью я дописал исходный код своего листинга, в котором используется стандартная функция itoa. И выводится число и символьный массив разной длины через универсальную функцию вывода по USART. Вы мне в прошлых постах помогли с прерываниями по USART и у меня заработала функция вывода, которую я переписывал из учебника Шпака. Данный листинг будет, наверное, полезен новичкам, типо меня. Он экономичнее в три раза функции printf. Чего я и добивался.
//********************************************************************************
//
// Автор : DruidCat
//
// МК : ATMega8L
//
// Компилятор : WinAVR
//
// Назначение : Выводим число и строку по USART через универсальную функцию
//
// Дата : 18.08.2012
//
//********************************************************************************
#include <avr/io.h>
#include <util/delay.h> //Для вызова функции _delay_ms()
#include <avr/interrupt.h> //Для доступа к функции sei()
#define F_CPU 8000000UL //Частота МК
#define USART_SPEED 9600 //Скорость USART желаемая
#define BAUD ((F_CPU/(USART_SPEED*16UL)) + 1) //Формула расчета БОД
#include <stdlib.h> //Вызов функции itoa, ltoa
unsigned char queueC, sendC; //Индексы текущего и переданного символа
unsigned char queue[50]; //Очередь
ISR(USART_TXC_vect){ //Подпрограмма обработки прерывания при завершении передачи очередного символа
if (queueC != sendC) UDR = queue[sendC++]; //Если был передан не последний символ, то передаем текущий и увеличиваем счетчик переданных на 1
}
void SEND_USART(char *s){ //Функция формирования очереди символов из строки
queueC = 0; //Текущий символ - первый
sendC = 1; //Первый символ считаем уже переданным
queue[queueC++] = 0x0D; //Добавляем в конец очереди символы
queue[queueC++] = 0x0A; //возврата каретки и переноса строки
while (*s) queue[queueC++] = *s++; //Просматриваем строку и помещаем в очередь символы
UDR = queue[0]; //Передаем первый символ, чтоб начать процесс
}
void INIT_USART(void){ //Функция настройка USART
UCSRB = (0<<RXCIE)|(1<<TXCIE)|(0<<RXEN)|(1<<TXEN); //Активизируем прерывание по окончание передачи и передатчик
UCSRC=(1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0); //размер слова 8 разрядов
UBRRH = (unsigned char)(BAUD >> 8 ); //Скорость передач
UBRRL = (unsigned char)BAUD; //Скорость передач
}
int main (void){
INIT_USART(); //Вызываем функцию для настройки USART
char HIGHT[] = "Высота 239"; //Массив символов HIGHT
long int NUMBERS = 1234567; //Число для преобразования NUMBERS
char *CHAR_NUMBERS; //Результат преобразования будет сюда записываться CHAR_NUMBERS
char BUFFER[20]; //Символьный буфер преобразуемого числа
CHAR_NUMBERS = ltoa(NUMBERS, BUFFER, 10); //Отсылаем в функцию ltoa число
sei(); //Разрешаем прерывание
while (1){ //Бесконечный цикл
SEND_USART(CHAR_NUMBERS); //Отсылаем массив CHAR_NUMBERS в функцию SEND_USART
_delay_ms(1000); //Пауза в 1сек
SEND_USART(HIGHT); //Отсылаем массив HIGHT в функцию SEND_USART
_delay_ms(1000); //Пауза в 1сек
}
}
PS: Спасибо всем кто мне помогал, приятно понимать, что такие грамотные ребята помогают новичкам, типо меня.
К слову, сегодня ночью я дописал исходный код своего листинга, в котором используется стандартная функция itoa. И выводится число и символьный массив разной длины через универсальную функцию вывода по USART. Вы мне в прошлых постах помогли с прерываниями по USART и у меня заработала функция вывода, которую я переписывал из учебника Шпака. Данный листинг будет, наверное, полезен новичкам, типо меня. Он экономичнее в три раза функции printf. Чего я и добивался.
//********************************************************************************
//
// Автор : DruidCat
//
// МК : ATMega8L
//
// Компилятор : WinAVR
//
// Назначение : Выводим число и строку по USART через универсальную функцию
//
// Дата : 18.08.2012
//
//********************************************************************************
#include <avr/io.h>
#include <util/delay.h> //Для вызова функции _delay_ms()
#include <avr/interrupt.h> //Для доступа к функции sei()
#define F_CPU 8000000UL //Частота МК
#define USART_SPEED 9600 //Скорость USART желаемая
#define BAUD ((F_CPU/(USART_SPEED*16UL)) + 1) //Формула расчета БОД
#include <stdlib.h> //Вызов функции itoa, ltoa
unsigned char queueC, sendC; //Индексы текущего и переданного символа
unsigned char queue[50]; //Очередь
ISR(USART_TXC_vect){ //Подпрограмма обработки прерывания при завершении передачи очередного символа
if (queueC != sendC) UDR = queue[sendC++]; //Если был передан не последний символ, то передаем текущий и увеличиваем счетчик переданных на 1
}
void SEND_USART(char *s){ //Функция формирования очереди символов из строки
queueC = 0; //Текущий символ - первый
sendC = 1; //Первый символ считаем уже переданным
queue[queueC++] = 0x0D; //Добавляем в конец очереди символы
queue[queueC++] = 0x0A; //возврата каретки и переноса строки
while (*s) queue[queueC++] = *s++; //Просматриваем строку и помещаем в очередь символы
UDR = queue[0]; //Передаем первый символ, чтоб начать процесс
}
void INIT_USART(void){ //Функция настройка USART
UCSRB = (0<<RXCIE)|(1<<TXCIE)|(0<<RXEN)|(1<<TXEN); //Активизируем прерывание по окончание передачи и передатчик
UCSRC=(1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0); //размер слова 8 разрядов
UBRRH = (unsigned char)(BAUD >> 8 ); //Скорость передач
UBRRL = (unsigned char)BAUD; //Скорость передач
}
int main (void){
INIT_USART(); //Вызываем функцию для настройки USART
char HIGHT[] = "Высота 239"; //Массив символов HIGHT
long int NUMBERS = 1234567; //Число для преобразования NUMBERS
char *CHAR_NUMBERS; //Результат преобразования будет сюда записываться CHAR_NUMBERS
char BUFFER[20]; //Символьный буфер преобразуемого числа
CHAR_NUMBERS = ltoa(NUMBERS, BUFFER, 10); //Отсылаем в функцию ltoa число
sei(); //Разрешаем прерывание
while (1){ //Бесконечный цикл
SEND_USART(CHAR_NUMBERS); //Отсылаем массив CHAR_NUMBERS в функцию SEND_USART
_delay_ms(1000); //Пауза в 1сек
SEND_USART(HIGHT); //Отсылаем массив HIGHT в функцию SEND_USART
_delay_ms(1000); //Пауза в 1сек
}
}
PS: Спасибо всем кто мне помогал, приятно понимать, что такие грамотные ребята помогают новичкам, типо меня.

Кот должен прожить жизнь без сожаления.
- Goldsmith
- Опытный кот
- Сообщения: 736
- Зарегистрирован: Пн янв 10, 2011 03:06:36
- Откуда: Ростов-на-Дону
- Контактная информация:
Re: WinAvr в вопросах и ответах
Каюсь, несколько упростил для уровня начинающих.avreal писал(а):У меня на сайте есть примеры использования этих «не используется» (они специально вставлены для программы пользователя).Goldsmith писал(а):.init1 - не используется;
На самом деле, конечно, все эти секции в документации объявлены как ".initN: Unused. User definable", а не просто "unused". Но для того, чтобы действительно возникла потребность в их использовании, нужны задачи потоньше. Например, собственный менеджер управления "кучей", который обязан быть готовым к работе перед входом в main(). На данном этапе не хотел запутывать.
Любой дурак может писать код. Настоящий профессионал - это тот, кто способен постоянно создавать продукт высокого качества, укладываясь при этом в бюджет.
J. Ganssle
J. Ganssle
- vitalik_1984
- Поставщик валерьянки для Кота
- Сообщения: 2482
- Зарегистрирован: Пт авг 27, 2010 05:57:06
- Откуда: Тюмень
- Контактная информация:
Re: WinAvr в вопросах и ответах
DruidCat , вам же уже писали, что при инициализации не нужно активировать передатчик и прерывания от него.Там столько много текста было, видать ускользнуло от внимания.
Мне кажется это лучше сделать когда поместили в буфер строку.
Потом в прерывании передачи проверяете есть ли в буфере символы, если нет- отключать нафиг лишние потребители.
Есть еще пара замечаний.
1.Как будет очищаться буфер передачи? Везде только добавляем к счетчику, где сброс?
2.Что будет, если в буфер поместить еще фрагмент до того, как буфер опустошится?
На место первого массива встанет второй?Причем может даже произойти замена символов первого прямо перед передачей, таким образом принятыми будут вначале символы часть от первой строки,и оставшаяся часть от второй.И возможно еще часть от первой, если вторая строка короче первой.Хотя нет, там конец строки добавится.
Мне кажется это лучше сделать когда поместили в буфер строку.
Потом в прерывании передачи проверяете есть ли в буфере символы, если нет- отключать нафиг лишние потребители.
Есть еще пара замечаний.
1.Как будет очищаться буфер передачи? Везде только добавляем к счетчику, где сброс?
2.Что будет, если в буфер поместить еще фрагмент до того, как буфер опустошится?
На место первого массива встанет второй?Причем может даже произойти замена символов первого прямо перед передачей, таким образом принятыми будут вначале символы часть от первой строки,и оставшаяся часть от второй.И возможно еще часть от первой, если вторая строка короче первой.Хотя нет, там конец строки добавится.
В поисках истины человек развивается.
- Goldsmith
- Опытный кот
- Сообщения: 736
- Зарегистрирован: Пн янв 10, 2011 03:06:36
- Откуда: Ростов-на-Дону
- Контактная информация:
Re: WinAvr в вопросах и ответах
Ничего страшного, если действительно захотите - быстро освоите. Лучшие программисты, создавшие информатику, тоже не имели таких дипломов (а Никлаус Вирт, кстати, имеет степень доктора в области электротехники). Зато еще знаете и электричество, а это для разработки на МК не менее важно, чем жонглировать переменными. Далеко не все программисты знают, с какого конца браться за паяльник. (Знаю не понаслышке, в нашем отделе из 15 человек таких всего двое).DruidCat писал(а):Эх, жалко, что я в 1998году выбрал профессию инженера-электрика а не программиста, когда поступал в университет. Так бы я сейчас понимал о чем вы говорите.
Еще пара советов. Во-первых, Ваш код в цитатах очень трудно воспринимается визуально, поскольку отступы удаляются форумским движком, и полностью теряется структура кода. Заключите код между тэгами [соde] и [/соde], и структура сохранится (над окном ввода текста есть кнопка Code для этого). Если структура изначально была "не очень", можно быстро привести ее в порядок, обработав утилитами вроде Indent или Artistic Style (обе они бесплатны, легко найдете их в Сети).
Во-вторых, Вы сразу же выработали очень полезную привычку не лениться писать комментарии как к отдельным фрагментам кода, так и к модулю целиком. Рекомендую сделать еще один шаг в этом направлении и применить утилиту Doxygen, который позволяет генерировать из комментариев довольно удобную документацию. Утилита простая (и, кстати, тоже бесплатная), освоить ее легко, и в ее составе есть удобная графическая оболочка; а чем раньше начнете писать правильные комментарии, тем меньше потом придется переписывать.
Любой дурак может писать код. Настоящий профессионал - это тот, кто способен постоянно создавать продукт высокого качества, укладываясь при этом в бюджет.
J. Ganssle
J. Ganssle
Re: WinAvr в вопросах и ответах
Здравствуйте, пишу под at90usb162 в code:blocks+WinAVR. Прошиваю flip'ом.
Светодиод мигает по таймеру. Столкнулся с проблемой, что частота процессора(вычислил по периоду миганий)
получается 1MHz(встроенный генератор видимо), хотя стоит кварц на 8. Аналогичный код, скомпилированный в CVAVR, работает в 8 раз быстрей, то есть как надо. В avr studio 6 тот же 1MHz. Подскажите пожалуйста в чем может быть проблема?
Привожу код
Светодиод мигает по таймеру. Столкнулся с проблемой, что частота процессора(вычислил по периоду миганий)
получается 1MHz(встроенный генератор видимо), хотя стоит кварц на 8. Аналогичный код, скомпилированный в CVAVR, работает в 8 раз быстрей, то есть как надо. В avr studio 6 тот же 1MHz. Подскажите пожалуйста в чем может быть проблема?
Привожу код
Код: Выделить всё
#define F_CPU 8000000UL
#include <avr/io.h>
#include <avr/interrupt.h>
volatile unsigned int ticks = 0;
ISR(TIMER0_OVF_vect)
{
TCNT0 = 0;
ticks++;
}
int main(void)
{
//io init
DDRB = 0xFF;
PORTB = 0x00;
//timer init
TCCR0A=0x00;
TCCR0B=0x05;
TCNT0=0x00;
TIMSK0=0x01;
sei();
while(1)
{
if(ticks >= 4)
{
PORTB = ~PORTB;
ticks = 0;
}
}
}Re: WinAvr в вопросах и ответах
vitalik_1984 писал(а):1.Как будет очищаться буфер передачи? Везде только добавляем к счетчику, где сброс?
А как очищать буфер? Нулей в его записать?
Goldsmith писал(а):Если структура изначально была "не очень", можно быстро привести ее в порядок, обработав утилитами вроде Indent или Artistic Style (обе они бесплатны, легко найдете их в Сети).
Осилил еле еле Indent для WinAVR, лежит он в WinAVR-20100110\utils\bin\
Настроил так в WinAVR: Tools -> Options ->Tools -> add и настроил как на рисунке.
Прикольная утилита, а я все думал, как сделать как в AVRStudio 5 формотирование исходного кода. Ответ Indent/
- Вложения
-
- Indent.jpg
- (80.17 КБ) 680 скачиваний
Кот должен прожить жизнь без сожаления.
Re: WinAvr в вопросах и ответах
maff писал(а): хотя стоит кварц на 8мГц
Я человек новый в AVR, но хочу задать тебе вопрос, а ты Fuses (Фьюзы) прошил в своем МК на внешний кварц 8 Мгц? Если ты это не сделал, то у тебя все будет работать в 8 раз медленнее. Так как по умолчанию в некоторых МК заводские настройки выставленны на 1 Мгц внутреннего резонатора.
Кот должен прожить жизнь без сожаления.


