Ну зачем же записать нулей? можно просто queueC обнулить после передачи последнего символа.DruidCat писал(а): А как очищать буфер? Нулей в его записать?
WinAvr в вопросах и ответах
- vitalik_1984
- Поставщик валерьянки для Кота
- Сообщения: 2482
- Зарегистрирован: Пт авг 27, 2010 05:57:06
- Откуда: Тюмень
- Контактная информация:
Re: WinAvr в вопросах и ответах
В поисках истины человек развивается.
- Реклама
Re: WinAvr в вопросах и ответах
Я и сам на это первое же и подумал:) Но получается так, что во flip'е нет настроек фьюзов. Целый день гуглил по поводу flip и fuse bits, frequency, clock ну и в том же духе. Перелазил кучу буржуйских форумов и нифигаDruidCat писал(а):Я человек новый в AVR, но хочу задать тебе вопрос, а ты Fuses (Фьюзы) прошил в своем МК на внешний кварц 8 Мгц?
Шью скомпиленое в CVAVR получаю 8Mhz. А если скомпиленое WinAVR'ом то 1MHz.
- zero648
- Вымогатель припоя
- Сообщения: 650
- Зарегистрирован: Пн июн 18, 2012 12:01:04
- Откуда: Челябинская область, Копейск
Re: WinAvr в вопросах и ответах
Это в симуляторе так частота настраивается, т.е. подразумевается, что камень будет прошит (не компилятором) под заявленную частоту, а в железе частота только по фузам.maff писал(а):Шью скомпиленое в CVAVR получаю 8Mhz. А если скомпиленое WinAVR'ом то 1MHz.
- zero648
- Вымогатель припоя
- Сообщения: 650
- Зарегистрирован: Пн июн 18, 2012 12:01:04
- Откуда: Челябинская область, Копейск
Re: WinAvr в вопросах и ответах
maff , скорей всего у компиляторов разная оптимизация кода, да и в цикле не понятно где прерывание таймера включится. Попробуй использовать режим сна, так хотябы можно прерывания таймера котролировать, да и процик отоспица
, когда он спит, жрать не просит 
Re: WinAvr в вопросах и ответах
Прошиваю я через Atmel Flip(через аппаратный ЮСБ контроллера). Во Flip'e нет настройки фьюзов!!! - вот в чем беда.zero648 писал(а):Это в симуляторе так частота настраивается, т.е. подразумевается, что камень будет прошит (не компилятором) под заявленную частоту, а в железе частота только по фузам.
Цикл(смотрите код, приведенный выше) содержит только смену состояния светодиода спустя 4 переполнения таймер - оптимизировать нечего))zero648 писал(а):maff , скорей всего у компиляторов разная оптимизация кода, да и в цикле не понятно где прерывание таймера включится. Попробуй использовать режим сна, так хотябы можно прерывания таймера котролировать, да и процик отоспица, когда он спит, жрать не просит
Светодиод меняет состояние с периодом примерно 1с(по факту).
Предделитель таймера 1024. 4 переполниня. Таймер 8бит.
Частота соответсвенно камня (4 * 1024 * 256) / 1 = 1048576ГЦ(1МГц).
Скомпилено WinAVR'ом.
Если компилить в CVAVR, то мигание с периодо в 1с получаются при 32 переполнениях, то есть
частота будет (32 * 1024 * 256) / 1 = 8388608Гц(8МГц).
Так фьюзы хз как Флип прошивает, но разница в компиляторах на лицо) CVAVR чтото в hex дописывает видимо, но как добится этого от WinAVR я просто в отчаянии
- Реклама
Re: WinAvr в вопросах и ответах
АЛИЛУЯ! Наконец! Делюсь открытиями
Такая штука как CLKPR = 0x00; - установить предделитель частоты камня равным 1. Уже пробовал юзать, но не помогло. Оказалось надо делать вот так:
Причем они так подряд и пишутся в начале мэйна!
Даташит at90usb говорит что-то типа
вот и надо было его программно извенить на 1
Такая штука как CLKPR = 0x00; - установить предделитель частоты камня равным 1. Уже пробовал юзать, но не помогло. Оказалось надо делать вот так:
Код: Выделить всё
CLKPR=0x80; //Установка бита CLKPCE/ Разрешает изменение предделителя
CLKPR=0x00;Даташит at90usb говорит что-то типа
Я так понял в at90usb162 фьюзы с завода идут на внешний кварц, но предделитель чатоты установлен на 8The CLKPCE bit must be written to logic one to enable change of the CLKPS bits. The CLKPCE
bit is only updated when the other bits in CLKPR are simultaneously written to zero. CLKPCE is
cleared by hardware four cycles after it is written or when CLKPS bits are written. Rewriting the
CLKPCE bit within this time-out period does neither extend the time-out period, nor clear the
CLKPCE bit.
вот и надо было его программно извенить на 1
Re: WinAvr в вопросах и ответах
vitalik_1984 подскажи код написания в С обнуления queueC, я не знаю как.vitalik_1984 писал(а):Ну зачем же записать нулей? можно просто queueC обнулить после передачи последнего символа.DruidCat писал(а): А как очищать буфер? Нулей в его записать?
Кот должен прожить жизнь без сожаления.
- vitalik_1984
- Поставщик валерьянки для Кота
- Сообщения: 2482
- Зарегистрирован: Пт авг 27, 2010 05:57:06
- Откуда: Тюмень
- Контактная информация:
Re: WinAvr в вопросах и ответах
например так:
но это опять же нужно целиком все согласовывать, у вас ведь очередь всего 50 символов, а это нигде не контролируется
Код: Выделить всё
ISR(USART_TXC_vect){ //Подпрограмма обработки прерывания при завершении передачи очередного символа
if (queueC != sendC){ UDR = queue[sendC++];} //Если был передан не последний символ, то передаем текущий и увеличиваем счетчик переданных на 1
if (sendC>50) {sendC=0;}
}
В поисках истины человек развивается.
- Goldsmith
- Опытный кот
- Сообщения: 736
- Зарегистрирован: Пн янв 10, 2011 03:06:36
- Откуда: Ростов-на-Дону
- Контактная информация:
Re: WinAvr в вопросах и ответах
Ненадежное решение. Закладываетесь на то, что передача заведомо должна уложиться в определенное время.DruidCat писал(а):while (1){ //Бесконечный цикл
SEND_USART(CHAR_NUMBERS); //Отсылаем массив CHAR_NUMBERS в функцию SEND_USART
_delay_ms(1000); //Пауза в 1сек
SEND_USART(HIGHT); //Отсылаем массив HIGHT в функцию SEND_USART
_delay_ms(1000); //Пауза в 1сек
}
В программе присутствует "магическое число" 1000 мс (1 с). По счастливой случайности этой задержки достаточно для отправки и данного преобразованного числа, и данного текстового сообщения при данной скорости 9600 бит/с. Достаточно либо повысить скорость передачи, либо увеличить длину сообщения, чтобы программа перестала работать. Такой код нельзя считать качественным.
Возможно два выхода из этой ситуации:
1. (попроще): добавить функцию, которая возвращает признак "передача буфера окончена", и в цикле ожидать, пока она станет истинной;
2. (немного сложнее, но корректнее): реализовать кольцевой буфер и передавать литеры на вывод через него, блокируя фоновое приложение при заполнении буфера.
Какой бы вариант Вы ни выбрали, в любом случае это решение будет надежнее, чем полагаться, что передача заведомо уложится в заданный интервал времени.
P.S. В случае кольцевого буфера также отпадет вопрос о его очистке.
Любой дурак может писать код. Настоящий профессионал - это тот, кто способен постоянно создавать продукт высокого качества, укладываясь при этом в бюджет.
J. Ganssle
J. Ganssle
Re: WinAvr в вопросах и ответах
Спасибо большое.vitalik_1984 писал(а):например так:но это опять же нужно целиком все согласовывать, у вас ведь очередь всего 50 символов, а это нигде не контролируетсяКод: Выделить всё
ISR(USART_TXC_vect){ //Подпрограмма обработки прерывания при завершении передачи очередного символа if (queueC != sendC){ UDR = queue[sendC++];} //Если был передан не последний символ, то передаем текущий и увеличиваем счетчик переданных на 1 if (sendC>50) {sendC=0;} }
Кот должен прожить жизнь без сожаления.
Re: WinAvr в вопросах и ответах
Блин, я эти паузы ставил просто для наглядности, чтоб строчки на терминале не мельтешили. А оказывается, если бы я их не поставил, у меня ничерта не заработало. Я только что убирал эти паузы, вообще ничего на терминале не появляется. Эх.Goldsmith писал(а):Ненадежное решение. Закладываетесь на то, что передача заведомо должна уложиться в определенное время.DruidCat писал(а):while (1){ //Бесконечный цикл
SEND_USART(CHAR_NUMBERS); //Отсылаем массив CHAR_NUMBERS в функцию SEND_USART
_delay_ms(1000); //Пауза в 1сек
SEND_USART(HIGHT); //Отсылаем массив HIGHT в функцию SEND_USART
_delay_ms(1000); //Пауза в 1сек
}
В программе присутствует "магическое число" 1000 мс (1 с). По счастливой случайности этой задержки достаточно для отправки и данного преобразованного числа, и данного текстового сообщения при данной скорости 9600 бит/с. Достаточно либо повысить скорость передачи, либо увеличить длину сообщения, чтобы программа перестала работать. Такой код нельзя считать качественным.
PS: Спасибо всем за советы, постораюсь их все учесть. Думал написал уже финальный исходный код, а оказывается, он почти не работает. Теперь я понимаю, что чувствовали разработчики игры "Сталкер: Чистые небеса."
Кот должен прожить жизнь без сожаления.
Re: WinAvr в вопросах и ответах
Astyle я тоже победил.
Выкладываю инструкцию, как настроить Astyle в WINAVR:
1) Качаем утилиту Astyle от сюда http://sourceforge.jp/projects/sfnet_astyle/releases/
2) Закидываем файл Astyle.exe сюда WinAVR-20100110\utils\bin\
3) Настраиваем astyle в WINAVR Tools->Options->Tools->add и заполняем строчки как на картинке.
Надеюсь кому-то это поможет из новичков.
Выкладываю инструкцию, как настроить Astyle в WINAVR:
1) Качаем утилиту Astyle от сюда http://sourceforge.jp/projects/sfnet_astyle/releases/
2) Закидываем файл Astyle.exe сюда WinAVR-20100110\utils\bin\
3) Настраиваем astyle в WINAVR Tools->Options->Tools->add и заполняем строчки как на картинке.
Надеюсь кому-то это поможет из новичков.
- Вложения
-
- AStyle.jpg
- (76.19 КБ) 390 скачиваний
Кот должен прожить жизнь без сожаления.
Re: WinAvr в вопросах и ответах
Можно попросить совета по поводу симулятора VMLAB и WINAVR. Ситуация такая, по некоторым причинам не могу пользоваться PROTEUS на том компьютере, где занимаюсь с WINAVR. Решил воспользоваться VMLAB. Когда создаю makefile через Mfile в WINAVR ставлю галочку в строке Debug format -> MVLAB 3.10+ (сам пользуюсь MVLAB 3.15). Пишу исходный код в main.c, компилирую его и не компилируется заветного файла main.prj с которым работает VMLAB. Запускаю сам MVLAB, создаю проект через Project -> New project и заполняю поля в wizard. Создаю проект, делаю Build. И в окне mesage вижу о том что успешно все создалось. Жму на светофор. Все запускается. Но симулятор работает не так как надо. На одном из порталов *123*, там очень много написанно по MVLAB и для компилятора CVAVR, а для WINAVR почти ничего. Я запускал проект предложенный на портале *123*, и мне там понравилось как в VMLAB появилась в control panel вкладка TTY(терминал), а у меня не появляется в моем проекте и не могу её я создать, так как во вкладке VMLAB Componets нет ни одной активной строки.
Подскажите, хотя бы, как создать в симуляции терминал.
PS: Я весь день сижу в инете и ищу ответы по MVLAB и не нахожу, не хотелось ребята вас тревожить такими вопросами. Может я и плохо ищу, меня постоянно отвлекает моя беременная жена:(
PS: Я весь день сижу в инете и ищу ответы по MVLAB и не нахожу, не хотелось ребята вас тревожить такими вопросами. Может я и плохо ищу, меня постоянно отвлекает моя беременная жена:(
Кот должен прожить жизнь без сожаления.
- vitalik_1984
- Поставщик валерьянки для Кота
- Сообщения: 2482
- Зарегистрирован: Пт авг 27, 2010 05:57:06
- Откуда: Тюмень
- Контактная информация:
Re: WinAvr в вопросах и ответах
А че мордашка то такая грустная?Жена беременна !Может я и плохо ищу, меня постоянно отвлекает моя беременная жена:(
В поисках истины человек развивается.
Re: WinAvr в вопросах и ответах
Да радуюсь я всем сердцем, скоро у меня наследник родится.
PS: Вопрос по симулятору я снимаю. Сегодня ночью с переводчиком читал документацию на симулятор. Разобрался.
PS: Вопрос по симулятору я снимаю. Сегодня ночью с переводчиком читал документацию на симулятор. Разобрался.
Кот должен прожить жизнь без сожаления.
Re: WinAvr в вопросах и ответах
Я тут недавно разобрался с симулятором VMLAB, читал книжки по С и решил дописать функцию по выволу цифeр и символов по протоколу USART, я посторался учесть все замечания, которые мне давались. Полностью избавился от пауз _delay_, от прерываний и сделал защиту от переполнения массива в функции вывода символов. Пользовался стилем написания исходного кода AStyle. Выкладываю исходный код на всеобщее обозрение. Вдруг кому понадбится из новичков эта функция. Функция printf очень сильно увеличивает размер готовой программы. А функция, которую я написал с вашей помощью в два с половиной раза экономичней.
Код: Выделить всё
//********************************************************************************
//
// Автор : DruidCat
//
// МК : ATMega8L
//
// Компилятор : WinAVR
//
// Назначение : Выводим число и строку по USART через универсальную функцию
//
// Дата : 03.09.2012
//
//********************************************************************************
#include <avr/io.h>
#include <stdlib.h> //Вызов функции itoa, ltoa
#define F_CPU 8000000UL //Частота МК
#define USART_SPEED 9600 //Скорость USART желаемая
#define BAUD ((F_CPU/(USART_SPEED*16UL)) + 1) //Формула расчета БОД
unsigned char queueC, sendC; //Индексы текущего и переданного символа
unsigned char queue[50]; //Очередь
void
SEND_USART (char *s)
{
//Функция формирования очереди символов из строки
queueC = 0; //Текущий символ - первый
sendC = 0; //Первый символ для передачи
queue[queueC++] = 0x0D; //Добавляем в конец очереди символы
queue[queueC++] = 0x0A; //возврата каретки и переноса строки
while (*s)
{
if (queueC>50)//Если колличество символов массива больше 50, то...
{
queueC = 50;//счетчик символов в массиве равен максимальному значению 50
}
queue[queueC++] = *s++; //Просматриваем строку и помещаем в очередь символы
}
while (queueC != sendC) //Запускаем цикл передачи символов пока не будет равенство queue и sendC
{
UDR = queue[sendC++]; //Передаем текущий символ и увеличиваем счетчик переданных на 1
while ((UCSRA & (1 << UDRE)) == 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 число
while (1) //Бесконечный цикл
{
SEND_USART (CHAR_NUMBERS); //Отсылаем массив CHAR_NUMBERS в функцию SEND_USART
SEND_USART (HIGHT); //Отсылаем массив HIGHT в функцию SEND_USART
}
}Кот должен прожить жизнь без сожаления.
- Goldsmith
- Опытный кот
- Сообщения: 736
- Зарегистрирован: Пн янв 10, 2011 03:06:36
- Откуда: Ростов-на-Дону
- Контактная информация:
Re: WinAvr в вопросах и ответах
Уже вполне прилично. Но совершенству нет предела. Несколько мелких придирок:
1.Я бы не стал этого делать. Не всегда действительно необходимо переходить на новую строку. Кому нужно, сам сделает переход явно. Ну и к тому же не все терминалы требуют именно такого сочетания.
2.Зачем разрешать прерывания, для которых не установлены обработчики? В лучшем случае это бесполезно. Не так давно было обсуждение этой темы. Тем более что передача все равно производится в поллинге:
(логичнее было бы сначала дождаться готовности, а потом передавать, но в данном случае это не столь критично).
3.- название несколько сбивает с толку. Очередью традиционно называют буфер с дисциплиной FIFO (обычно кольцевой). В данном случае это просто буфер.
4. Раз уж зашла речь о буфере, и к тому же вывод полностью синхронный, можно было бы вообще отказаться от буфера. Для одних задач и 50-ти литер окажется много, и драгоценная память расходуется попусту. Для других может не хватить и сотни.
Пусть лучше функция-клиент просто передает подпрограмме вывода указатель на выводимую строку. Если этот буфер будет выделяться локально, то после завершения функции накладные расходы сведутся к нулю.
Если есть силы и желание совершенствовать дальше, теперь вполне можно замахнуться на асинхронный вывод по прерываниям. Ну и как вершина мастерства - предусмотреть возможность выбирать U(S)ART для кристаллов, которые имеют их в количестве более одного.
1.
Код: Выделить всё
queue[queueC++] = 0x0D; //Добавляем в конец очереди символы
queue[queueC++] = 0x0A; //возврата каретки и переноса строки
2.
Код: Выделить всё
UCSRB = (0 << RXCIE) | (1 << TXCIE) | (0 << RXEN) | (1 << TXEN); //Активизируем прерывание по окончание
Код: Выделить всё
UDR = queue[sendC++]; //Передаем текущий символ и увеличиваем счетчик переданных на 1
while ((UCSRA & (1 << UDRE)) == 0); //Пауза, цикл работает пока регистр данных не опустошён
3.
Код: Выделить всё
unsigned char queue[50]; //Очередь
4. Раз уж зашла речь о буфере, и к тому же вывод полностью синхронный, можно было бы вообще отказаться от буфера. Для одних задач и 50-ти литер окажется много, и драгоценная память расходуется попусту. Для других может не хватить и сотни.
Пусть лучше функция-клиент просто передает подпрограмме вывода указатель на выводимую строку. Если этот буфер будет выделяться локально, то после завершения функции накладные расходы сведутся к нулю.
Если есть силы и желание совершенствовать дальше, теперь вполне можно замахнуться на асинхронный вывод по прерываниям. Ну и как вершина мастерства - предусмотреть возможность выбирать U(S)ART для кристаллов, которые имеют их в количестве более одного.
Любой дурак может писать код. Настоящий профессионал - это тот, кто способен постоянно создавать продукт высокого качества, укладываясь при этом в бюджет.
J. Ganssle
J. Ganssle
Re: WinAvr в вопросах и ответах
Я все замечания исправил, кроме пункта №4 по указателям. Мне они даются крайне тяжело, не знаю почему. Еще с универа, когда я немного изучал С#. У меня ступор в голове происходит, когда я начинаю пользоваться указателями. 
Кот должен прожить жизнь без сожаления.
- Goldsmith
- Опытный кот
- Сообщения: 736
- Зарегистрирован: Пн янв 10, 2011 03:06:36
- Откуда: Ростов-на-Дону
- Контактная информация:
Re: WinAvr в вопросах и ответах
Так в C# указателями практически и не пользуются, слава богу. Оставлена на всякий случай лазейка для совместимости с "нативным" кодом, но используется крайне редко за ненадобностью в большинстве задач.DruidCat писал(а):Я все замечания исправил, кроме пункта №4 по указателям. Мне они даются крайне тяжело, не знаю почему. Еще с универа, когда я немного изучал С#.
Скачайте книгу Ted Jensen, Tutorial on Pointers and Arrays in C. Небольшая, но толковая, к тому же официально бесплатная. Развеет любой ступор, будете чувствовать себя среди указателей и массивов, как рыба в воде.DruidCat писал(а):У меня ступор в голове происходит, когда я начинаю пользоваться указателями.
Любой дурак может писать код. Настоящий профессионал - это тот, кто способен постоянно создавать продукт высокого качества, укладываясь при этом в бюджет.
J. Ganssle
J. Ganssle
- Goldsmith
- Опытный кот
- Сообщения: 736
- Зарегистрирован: Пн янв 10, 2011 03:06:36
- Откуда: Ростов-на-Дону
- Контактная информация:
Re: WinAvr в вопросах и ответах
Прошу прощения, еще один ляп пропустил:
Если массив в C имеет размерность N, то индексы в нем могут принимать значения 0, 1, ..., N-1. 50-й элемент массива queue на самом деле не существует, обращение к нему имеет неопределенный результат (обычно попадаем в область памяти, занятую другой переменной). Диагностика выхода за границы массива в C отсутствует, якобы в целях пущей эффективности (экономия примерно такая же, как если не ставить перила на балконах верхних этажей, пусть сами не подходят близко к краю, и последствия ее тоже аналогичны).
Поэтому следует воздержаться от записи в элементы массива с индексом больше 49. Лучше, конечно, вообще избавиться от "магического" числа 50 и определить его символическим именем либо через макрос, либо через enum.
Код: Выделить всё
...
unsigned char queue[50]; //Очередь
...
while (*s)
{
if (queueC>50)//Если колличество символов массива больше 50, то...
{
queueC = 50;//счетчик символов в массиве равен максимальному значению 50
}
queue[queueC++] = *s++; //Просматриваем строку и помещаем в очередь символы
}
...
Поэтому следует воздержаться от записи в элементы массива с индексом больше 49. Лучше, конечно, вообще избавиться от "магического" числа 50 и определить его символическим именем либо через макрос, либо через enum.
Любой дурак может писать код. Настоящий профессионал - это тот, кто способен постоянно создавать продукт высокого качества, укладываясь при этом в бюджет.
J. Ganssle
J. Ganssle


