 |
|
|
|
| Автор |
Сообщение |
AndryG Модератор
Зарегистрирован: 24.07.2006 Сообщения: 411 Откуда: Helios-3
|
Добавлено: 15 Май 2007, 10:48 Заголовок сообщения: Пример применения алгоритма Брезенхама |
|
|
Доброго дня.
По просьбе одного из форумчан ... пример применения алгоритма Брезенхама.
Получение равномерно распределенных импульсов .. типа "В N тиков таймера из десяти нужно зажечь светодиод"
Пример при N = 3. Каждая клетка - один тик. Верхний сигнал - для синхронизации. Нижний - "полезный сигнал"
И немного кода ... убрал все демонстрационные приблуды - только саму суть.
Коменты поставил ... "в графическом интерпретировании"
| Код: |
unsigned char level -- Y-координата конца линии (начало в 0,0)
#define MAXLEVEL=10 //Максимальные X и Y
if (phase == 0){ //начинаем новую линию рисовать
phase = MAXLEVEL;
delta = -(MAXLEVEL / 2);
}
delta = delta + level; //накапливаем отклонение "теоритического Y от практического"
if (delta < 0){ //Рисуем на том же Y-уровне
PULSE_OFF;
}
else{
PULSE_ON;//перескакиваем на новый Y
delta = delta - MAXLEVEL;//корректируем отклонение
}
phase = phase - 1; //новый X
|
Также хочу отметить, что сей пример построен на основе кода Ридико Леонида Ивановича, который нашел на одном из форумов.
Алгоритм Брезенхама CVAVR & Proteus В проекте увидим контроллер с двумя кнопками + & - для изменения level и осциллограф с картинкой... и терминал, на котором также видно хорошо результат работы при бОльших MAXLEVEL
_________________ AndryG |
|
| Вернуться к началу |
|
 |
AVL Знатный посетитель (>20)


Зарегистрирован: 20.09.2006 Сообщения: 52 Откуда: Коломыя UA
|
Добавлено: 18 Май 2007, 21:18 Заголовок сообщения: |
|
|
Всем привет!
Как говорил суслик из мультфильма : "Всё правильно, всё сходится, только одно не понятно, почему мне есть хочется?".
Я это к тому, что мне не понятно как Ваш пример к моей задаче приспособить.
Опишу свою задачу.
При переполнению таймера меняется логическое состояние некоторого пина порта. (PORTB.4=~PORTB.4)
После каждого переполения таймер считает со значения на единицу большего, ежели предыдущее. Инкремент. ( TCNT0=ti; ti++
И так по кругу.
Итак, частота генерации на PORTB.4 возростает с нуля до максимума и опять перескакивает на ноль.
Но что получается в жизни: сначало импульсы идут очень МЕДЛЕННО, а в конце очень БЫСТРО.
Мне ж надо что б частота подымалась ПЛАВНО.
Я умом понимаю, что мне надо селать, к примеру, что б за 1 Герц реального времени частота на девайсе подымалась, скажем на 3-4 Гц и в начале и в конце частотного диапазона. Но как ЭТО сделать практически не знаю, даже просмотрев неоднократно Ваш хелп. Подскажите, пожалуйста, как написать код для моего случая.
|
|
| Вернуться к началу |
|
 |
urry Живет здесь... (>100)


Зарегистрирован: 23.10.2006 Сообщения: 243
|
Добавлено: 19 Май 2007, 5:50 Заголовок сообщения: |
|
|
| AVL писал(а): |
Я умом понимаю, что мне надо селать, к примеру, что б за 1 Герц реального времени частота на девайсе подымалась, скажем на 3-4 Гц и в начале и в конце частотного диапазона. Но как ЭТО сделать практически не знаю, даже просмотрев неоднократно Ваш хелп. Подскажите, пожалуйста, как написать код для моего случая. |
А без "к примеру?" Время девиации. диапазон девиации, несущая ?
_________________ меня не интересует мнение людей. которые разбираются в этом вопросе. Только тех, кто сами что-то сделали (А. Энштейн) |
|
| Вернуться к началу |
|
 |
AVL Знатный посетитель (>20)


Зарегистрирован: 20.09.2006 Сообщения: 52 Откуда: Коломыя UA
|
Добавлено: 19 Май 2007, 10:19 Заголовок сообщения: |
|
|
| urry писал(а): | | AVL писал(а): |
Я умом понимаю, что мне надо селать, к примеру, что б за 1 Герц реального времени частота на девайсе подымалась, скажем на 3-4 Гц и в начале и в конце частотного диапазона. Но как ЭТО сделать практически не знаю, даже просмотрев неоднократно Ваш хелп. Подскажите, пожалуйста, как написать код для моего случая. |
А без "к примеру?" Время девиации. диапазон девиации, несущая ? |
Время - 15 секунд.
Диапазон - от нуля до 2 кГц.
Несущая - не надо.
Диапазон можно и ниже 2кгц. Это пока не существенно. Существенно, чтоб ПЛАВНО это происходило.
Зачем мне ЭТО надо?
Для многих задумок. Плавное включение света, плавный старт/стоп створок ворот, плавный разбег автомобиля и многое другое.
В конкретном решаемом мною задании это плавный разгон стрелки спидометра.
|
|
| Вернуться к началу |
|
 |
urry Живет здесь... (>100)


Зарегистрирован: 23.10.2006 Сообщения: 243
|
Добавлено: 19 Май 2007, 11:50 Заголовок сообщения: |
|
|
Для генерации прямоугольных импульсов, имхо, удобно использовать последовательный порт. Частота генерации зависит от частоты кварца , низкоскоростной/высокоростной режим и содержимого регистра SPBRG.
Допустим, нам нужно выдать 200 Герц , частота кварца – 4 мегаГерц. Естественно, это будет низкоскоросной режим.
Вычисляем содержимое регистра SPBRG по формуле
SPBRG = ((XTAL / f*2) -64)/64
Подставляем наши значения ((4000000/200*2)-64)/64 = 155,25
Как видно, значение получилось дробным. Ближайшее значение 155 и реальное значение выходной частоты (при идеальной частоте кварца, ес-но) посчитаем по этой же формуле
Получилось 200.32 Герца
Изменяем (увеличиваем ) частоту на 4 Герца, считаем значение
((4000000/204*2)-64)/64=152
Еще на 4
((4000000/208*2)-64)/64=149
Итак, закономерность нашли – 3 единицы на 4 Герца. А теперь каждую секунду будем увеличивать на 4 герца в течении 20 секунд. Частота будет изменяться с 200 до 280 Герц.
Вот так, видите, ни фика сложного . В Вашем случае несущая - несколько герц. И прирост будет посерьезней, скорее всего, нужно высокоскоростной режим. Только учтите, что этот - волшебный регистр - 1 байт, переполнять (выше 255) нельзя.
Код для демонстрации в моем любимом Хайтеке, проект в протеусе и т.д.
| Код: |
#include <pic.h>
#include <conio.h>
#define send_0 0x55 // ЧЕРЕДОВАНИЕ 0 И 1 ДЛЯ МЕАНДРА b01010101
#define nesu 155 //несущая
#define step 20 //
unsigned char sek;
unsigned char frg;
//-----------------------------------------
__CONFIG(HS & WDTDIS & LVPDIS & MCLRDIS);
interrupt void serial_tmr(void)
{
//-----------------------------------
if (TXIF && TXIE)
{
TXREG=send_0;// пересылаем чередующиеся 0 и 1 для выдачи
}
if(T0IE && T0IF)
{
T0IE=0;// запрещаем прерывания
sek++;
if (sek==20)
{
sek=0;
frg++;
if (frg == step )frg=0;
SPBRG=nesu -frg*3;
}
TMR0=60;
T0IF=0;
T0IE=1;
}
}
//----------------------------------------------
//////////////////////////main/////////
main()
{ //начало маин
CMCON=7;//выключаем компараторы
TRISA=0xff;
TRISB=0xff;
// настройка таймера
OPTION = 07; // внутреннюю частоту делим на 256 и
// подлючаем пределитель к таймеру 0
T0CS = 0; // источник - внутренняя частота
TMR0=60;// для частоты 4 мега 1 секунда
T0IE=1;
sek=0;
// настройка последовательного порта
frg=0;
SPEN=1;//разрешение работы последовательного порта
SYNC =0;//включение асинхронного режима работы
TX9=0; // выбираем 8 - битовую передачу
BRGH =0;//включаем низкоскоростной режим
SPBRG=nesu;// записываем несущую
PEIE = 1; /* разрешаем прерывания периферии */
TXIE=1;//разрешаем прерывания от передатчика
GIE = 1;// разрешаем прерывания вообче
TXREG=send_0;
TXEN=1;
for(;;) // бесконечный цикл
{
}
}
|
| Описание: |
|
 Файлообменник |
| Название файла: |
lcm.rar |
| Размер файла: |
44.94 KB |
| Скачено: |
149 раз(а) |
_________________ меня не интересует мнение людей. которые разбираются в этом вопросе. Только тех, кто сами что-то сделали (А. Энштейн) |
|
| Вернуться к началу |
|
 |
AVL Знатный посетитель (>20)


Зарегистрирован: 20.09.2006 Сообщения: 52 Откуда: Коломыя UA
|
Добавлено: 19 Май 2007, 12:33 Заголовок сообщения: |
|
|
Спасибо, но я использую Аттини13. А там нет регистра SPBRG.
В 2313 тоже нет, хоть 2313 у меня и есть но она мне не подходит по другим параметрам.
Как решить задачу имеющимися у меня средствами?
|
|
| Вернуться к началу |
|
 |
urry Живет здесь... (>100)


Зарегистрирован: 23.10.2006 Сообщения: 243
|
Добавлено: 19 Май 2007, 14:03 Заголовок сообщения: |
|
|
Но ведь уарт там есть - и как-то программируется.
Я дал идею - и показал реализацию.
В авр я не разбираюсь, но не думаю, что в корне что-то отличается. Кругом одно и то же - а в Антартиде вдобавок холодно. Я только во вторник могу посоветовать по авр - на домашнем компе по нему нет ничего.
_________________ меня не интересует мнение людей. которые разбираются в этом вопросе. Только тех, кто сами что-то сделали (А. Энштейн) |
|
| Вернуться к началу |
|
 |
AVL Знатный посетитель (>20)


Зарегистрирован: 20.09.2006 Сообщения: 52 Откуда: Коломыя UA
|
Добавлено: 19 Май 2007, 14:36 Заголовок сообщения: |
|
|
| urry писал(а): | Но ведь уарт там есть - и как-то программируется.
Я дал идею - и показал реализацию.
В авр я не разбираюсь, но не думаю, что в корне что-то отличается. Кругом одно и то же - а в Антартиде вдобавок холодно. Я только во вторник могу посоветовать по авр - на домашнем компе по нему нет ничего. |
Нет, в АтТини13 нет УАРТа. Не горит, я уже пол года делаю ЭТОТ проэкт
|
|
| Вернуться к началу |
|
 |
AndryG Модератор
Зарегистрирован: 24.07.2006 Сообщения: 411 Откуда: Helios-3
|
Добавлено: 21 Май 2007, 11:10 Заголовок сообщения: |
|
|
| Цитата: |
При переполнению таймера меняется логическое состояние некоторого пина порта. (PORTB.4=~PORTB.4)
После каждого переполения таймер считает со значения на единицу большего, ежели предыдущее. Инкремент. ( TCNT0=ti; ti++Хитрый
И так по кругу.
Итак, частота генерации на PORTB.4 возростает с нуля до максимума и опять перескакивает на ноль.
Но что получается в жизни: сначало импульсы идут очень МЕДЛЕННО, а в конце очень БЫСТРО.
Мне ж надо что б частота подымалась ПЛАВНО. |
Это не Ваша задача, а Ваше решение Вашей задачи. условие которой Вы нам не говорите!
В таком решении частота НИКОГДА не будет плавно наростать!!! Так-как Вы меняете ее в прерывании таймера, которое вызывается НЕ РАВНОМЕРНО!!! вы сами меняете время вызова этого прерывания!!!
| Цитата: | Время - 15 секунд.
Диапазон - от нуля до 2 кГц.
Несущая - не надо.
Диапазон можно и ниже 2кгц. Это пока не существенно. Существенно, чтоб ПЛАВНО это происходило.
Зачем мне ЭТО надо?
Для многих задумок. Плавное включение света, плавный старт/стоп створок ворот, плавный разбег автомобиля и многое другое.
В конкретном решаемом мною задании это плавный разгон стрелки спидометра. |
Еще одного параметра нет .. сколько "ступеней" вам нужно?
Диапазон 2кГц - период - 0,5 мс -- вот через такое время нужно вызывать обработчик в алгоритме.
MAX_COUNT - указывает число ступеней необходимых Вам.
Время, через которое нужно изменять level ... думаю, посчитаете ... точнее level нужно изменять в обработчике if (phase == 0) ... например Вы хотите получить 1000 ступеней ... значит level нужно менять КАЖДЫЙ второй раз в обработчике.
давайте к-во ступеней - сделаем.
_________________ AndryG |
|
| Вернуться к началу |
|
 |
AVL Знатный посетитель (>20)


Зарегистрирован: 20.09.2006 Сообщения: 52 Откуда: Коломыя UA
|
Добавлено: 21 Май 2007, 12:06 Заголовок сообщения: |
|
|
| Давайте сделаем 2000 ступеней. Это мне пока не существенно, вроде, потом я ж могу любые параметры поменять, главное, что б "костяк" работал.
|
|
| Вернуться к началу |
|
 |
|
|
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете голосовать в опросах Вы не можете добавлять вложения в этом форуме Вы можете просматривать вложения в этом форуме
|
|