roboforum.ru

Технический форум по робототехнике.
Текущее время: 02 дек 2024, 17:52

Часовой пояс: UTC + 4 часа




Начать новую тему Ответить на тему  [ Сообщений: 30 ]  На страницу 1, 2  След.
Автор Сообщение
 Заголовок сообщения: Помогите с таймерами пожалуйста =)
СообщениеДобавлено: 07 янв 2010, 02:02 
Не в сети
Аватара пользователя

Зарегистрирован: 13 фев 2009, 18:37
Сообщения: 28
Откуда: Петрозаводск
Вобщем на меге16 мигаю 3 светодиодами в 2 разных режимах, все они стоят на PORTA(выход) на 0, 2, 4 ногах. Есть так же входы на PORTB, 0 нога pull-up, к ней кнопка соединяющая с землей. При нажатии кнопки должно переходить из одного режима в другой , но не переходит =( помогите разобраться, только начинаю осваивать все. Почему то не работает условие PINB==0b00000001 (проверка высокого уровня на нулевой ноге) . Может что-то не понял пока, помогите! Без нажатия кнопки ничего вобще не мигает, не выполняется ни одно условие в циклах while , ну, разьве что while (1 ) :D
Код:
#define F_CPU 4000000UL  // 4 MHz
   #include <avr/io.h>
   #include <avr/delay.h>
   
   int main(void)              // начало основой программы
   {
   
   DDRA = 0xff; //выходы
   DDRB=0x00; //входы
  PORTB=0b00000001 ;  //pull-up на нулевую ногу
   
   
unsigned int i ;
while (1)
{



while (PINB == 0b00000001) {      // пока на нулевой ноге 1       
for (i=0; i<5; i++)
{


PORTA = 0b00000001;   //Быстрое мигание 5 раз
_delay_ms(10);
PORTA = 0x00 ;
_delay_ms(10);


}

PORTA = 0b00010000; // медленное мигание 1 раз
_delay_ms(100);
PORTA = 0x00 ;
_delay_ms(100);

   
}     


while (PINB ==0b00000000) {   //пока все ноги на нуле         
PORTA = 0b00000001 ;
_delay_ms(6);
PORTA = 0x00;
_delay_ms(6);
PORTA = 0b00000100 ;    //мигание поочереди 3 светодиодами
_delay_ms(6);
PORTA = 0x00;
_delay_ms(6);
PORTA = 0b00010000 ;
_delay_ms(6);
PORTA = 0x00;
_delay_ms(6);


   
}     
}   
}


Последний раз редактировалось Ramzez 09 янв 2010, 19:51, всего редактировалось 1 раз.

Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Помогите с вводом
СообщениеДобавлено: 07 янв 2010, 02:05 
Не в сети
Аватара пользователя

Зарегистрирован: 06 окт 2004, 18:01
Сообщения: 24218
Откуда: Ебург
прог. языки: C++ / PHP / 1C
ФИО: Антон Ботов
Потому что проверка высокого уровня на 0 ноге делается так:
(PINB & 0x01 != 0)

_________________
Проект [[Open Robotics]] - Универсальные модули для построения роботов


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Помогите с вводом
СообщениеДобавлено: 07 янв 2010, 02:05 
Не в сети
отсылающий читать курс
Аватара пользователя

Зарегистрирован: 06 ноя 2005, 04:18
Сообщения: 14195
Откуда: Москва
Советую ножку к кнопке подключать через резистор 200-500 Ом.

_________________
Читайте !


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Помогите с вводом
СообщениеДобавлено: 07 янв 2010, 02:08 
Не в сети
Аватара пользователя

Зарегистрирован: 13 фев 2009, 18:37
Сообщения: 28
Откуда: Петрозаводск
Спасибо большое за исправление! но с такой логикой у меня туго на начальном уровне, хотелось бы как нибуть попроще если можно, можете хотябы обьяснить почему не работает PINB == 0b00000001 ? результат же истина получается вроде как


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Помогите с вводом
СообщениеДобавлено: 07 янв 2010, 02:18 
Не в сети
отсылающий читать курс
Аватара пользователя

Зарегистрирован: 06 ноя 2005, 04:18
Сообщения: 14195
Откуда: Москва
Потому что вы все ножки опрашиваете а вам одну надо.

Поcмотрите Си для микроконтроллеров - там есть примерчики и толкование - http://proavr.narod.ru/05.htm

_________________
Читайте !


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Помогите с вводом
СообщениеДобавлено: 07 янв 2010, 02:23 
Не в сети
Аватара пользователя

Зарегистрирован: 13 фев 2009, 18:37
Сообщения: 28
Откуда: Петрозаводск
Но, насколько я понимаю, даже если опрашивать все ножки, выражение должно быть истинно , или для while нужно как то по-другому действовать? просто увидел гдето пример с if
Код:
#include <avr/io.h>
#include <util/delay.h>

int main(void)
{
    DDRB = 0xFF;
    PORTC = 0xFF;
    while(1)
    {
        if(PINC == 0xFF){
            PORTB = 0x00;
        }else{
            PORTB = 0xFF;
        };
    };
    return 0;
}


тут вроде тоже все опрашивают и пример из учебника, вот я и сделал по аналогии


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Помогите с вводом
СообщениеДобавлено: 07 янв 2010, 02:58 
Не в сети
отсылающий читать курс
Аватара пользователя

Зарегистрирован: 06 ноя 2005, 04:18
Сообщения: 14195
Откуда: Москва
но у вас то кнопка не ко всему порту подключена а к одной ножке.

_________________
Читайте !


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Помогите с вводом
СообщениеДобавлено: 09 янв 2010, 19:49 
Не в сети
Аватара пользователя

Зарегистрирован: 13 фев 2009, 18:37
Сообщения: 28
Откуда: Петрозаводск
Спасибо, вроде разобрался =)
Помогите теперь пожалуйста понять таймеры, очень хочется сделать ШИМ чтобы управлять серво, но пока не понятно как это происходит. Читаю курс AVR123 не могу разобраться,там сразу слишком много информации для начинающего, вчера весь вечер разбирался с битами, что и куда устанавливается, помог только даташит на русском к меге 128. пишу на WIN AVR , поэтому частенько приходится перелопачивать все что нахожу под свой компилятор(не всегда получается, все используют свои библиотеки и макросы. даже не обьявляя их в коде и порой это запутывает до конца). А конкретный вопрос вот в чем, не могли бы вы подсказать алгоритм установки таймера , без кода, а может просто словами (или блок схемой) , и про прерывания и какую роль в них играет таймер (как взаимодействует с ними). КодВизард не кактит, хочется самому втыкнуть как все это работает :oops: для начала на примере 8 битного, пожалуйста :)

Код:
DDRD=0x20; // 00100000 PD5(OC1A)-PWM Timer1 OUT
// ножку PD5 назначить выходом


// Настройка TIMER1 для генерации ШИМ

//TIMER1 initialize
//prescale:1  clock 7.37 MHz
// WGM: 7) PWM 10bit fast, TOP=0x03FF
// actual value: 7200,000Hz (100,0%)
// последнее - это частота ШИМ сигнала

TCCR1B = 0x00; //stop Timer

TCNT1H = 0xFC; // 11111100 
TCNT1L = 0x01; // 00000001 

/* значение в 16 битном регистре OCR1A определяет величину генерируемого ШИМ сигнала на ножке PD5 - если поделить ее  на 10.23 то получим PWM в процентах*/

OCR1AH = 0x03; // PWM(PD5) = OCR1A / 10.23
OCR1AL = 0xFF; // 0x03FF это число 1023

/* регистр OCR1A состоит из двух 8-ми битных регистров OCR1AH и OCR1AL запись в них нужно проводить в указанной последовательности! */

OCR1BH = 0x03;
OCR1BL = 0xFF;

ICR1H = 0x03;
ICR1L = 0xFF;

TCCR1A = 0x83; // 10000011 

TCCR1B = 0x09; // 00001001 - start Timer

// Теперь ШИМ 100% - т.е. на ножке PD1 лог. "1"


Буду по порядку задавать вопросы:
1)
Код:
TCCR1B = 0x00; //stop Timer
-таймер остановлен, не работает пока его настраивают дальше? зачем это делается, если он выключен?

2)
Код:
TCNT1H = 0xFC; // 11111100 
TCNT1L = 0x01; // 00000001

, в этом регистре пишем до куда считать , получается до 64513, вроде понятно =)

3)
Код:
/* значение в 16 битном регистре OCR1A определяет величину генерируемого ШИМ сигнала на ножке PD5 - если поделить ее  на 10.23 то получим PWM в процентах*/

OCR1AH = 0x03; // PWM(PD5) = OCR1A / 10.23
OCR1AL = 0xFF; // 0x03FF это число 1023
вот тут очень непонятно, почему он определяет велечину генерируемого ШИМ ?
небольшое отступление:
я имею таковое представление о работе таймера в качестве ШИМ. прошу направьте на путь истинный =)
TCNT увеличивается , пока не сравняется с регистром OCR. Как только он сравнивается с ним, происходит прерывание, в нем на определенный порт выводится 1, потом 0, и от паузы между ними зависит велечина ШИМ, но как она может зависеть от велечины OCR не понятно, я думал что OCR определяет период, прошу подсказать =)

4)
Код:
OCR1BH = 0x03;
OCR1BL = 0xFF;


Это второй регистр сравнения, какую функцию он выполняет, если его значение такое же как и у первого?

Отступление:
Кажется я начинаю понимать суть, но нужно знать еще тонкости. В этом примере на выходе мы получаем 100% шим, может быть потому, что 2 регистра сравнения имеют одинаковые значения?


5)
Код:
ICR1H = 0x03;
ICR1L = 0xFF;
регистр захвата, что это и с чем его едят? какую функцию он здесь выполняет? можно линк на страницу даташита, буду не против, так же буду благодарен если на русский даташит атмеги 128



6)
Код:
TCCR1A = 0x83; // 10000011 

TCCR1B = 0x09; // 00001001 - start Timer

Почему тут 2 регистра управления, как я понял, одним таймером? чем они отличаются? или они обьеденены в один?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Помогите с вводом
СообщениеДобавлено: 09 янв 2010, 20:16 
Не в сети
отсылающий читать курс
Аватара пользователя

Зарегистрирован: 06 ноя 2005, 04:18
Сообщения: 14195
Откуда: Москва
Конкретно пример управления servo сервами на Си есть в задаче 13 курса по AVR - http://proavr.narod.ru/z13.htm - кода там совсем не много по-моему.

Настройка таймеров в задачах 6 и 8 - http://proavr.narod.ru/06.htm

Русский даташит на ATmega128 можно увидеть внизу странички 2 курса - Устройство микроконтроллера AVR - http://proavr.narod.ru/02.htm - прямо смотрите разделы по таймерам или по тем модулям которые вас интересуют.

Добавлено спустя 5 минут 34 секунды:
Ramzez писал(а):
Читаю курс AVR123 не могу разобраться, там сразу слишком много информации для начинающего


Много ? да вы ж еще до ВТОРОЙ странички не дошли если спрашиваете где даташит на мегу128 на русском ! ибо не заметить этого просто не возможно :Bravo: скрин ниже.
-

Добавлено спустя 5 минут 37 секунд:
Ramzez писал(а):
КодВизард не кактит, хочется самому втыкнуть как все это работает


Мастер ни как не может помешать втыкать, он ведь сам не включается. Ко всему коду он дает коментарии обычно и ГАВНОЕ - ни кто вам не мешает, а я в курсе даже рекомендую обязательно по даташиту разобрать что делает каждая строка кода созданого мастером.

Мастер просто помогает когда вы этого желаете и умеете объяснить ему что вы желаете получить.

Добавлено спустя 2 минуты 46 секунд:
Re: Помогите с таймерами пожалуйста =)
Ramzez писал(а):
Код:
TCCR1A = 0x83; // 10000011 
TCCR1B = 0x09; // 00001001 - start Timer

Почему тут 2 регистра управления, как я понял, одним таймером? чем они отличаются? или они обьеденены в один?

2 регистра потому что битов для управления этим таймером надо более 8 и в один регистр их не поместить. Отличаются они названием, назначением и адресом.

Добавлено спустя 3 минуты 27 секунд:
Re: Помогите с таймерами пожалуйста =)
Ramzez писал(а):
1)
Код:
TCCR1B = 0x00; //stop Timer
-таймер остановлен, не работает пока его настраивают дальше? зачем это делается, если он выключен ?
Обычно останавливают так как тиканье может вызвать не нужные события - например установку флаго в прерываний.
Остановка не обязательна, это воля программиста как и вся прога целиком на его совести.

2)
Код:
TCNT1H = 0xFC; // 11111100 
TCNT1L = 0x01; // 00000001

, в этом регистре пишем до куда считать , получается до 64513, вроде понятно =)[/quote]

Вы не верно поняли, это как раз сам счетчик таймера, просто можно и в него вписывать числа если надо чтоб он от нужного вам числа начал счет.

Добавлено спустя 3 минуты 8 секунд:
Re: Помогите с таймерами пожалуйста =)
по п. 3 - у тамера МНОГО режимов счета, если посмотреть в даташите или в мастере компилятора ICC - задача 6 курса - то около 16 режимов вроде. И в этих режимах разные регистра и числа определяют перод и события возникающие по ходу счета.

По PWM ШИМ - задача 8 курса.

Добавлено спустя 2 минуты 58 секунд:
Re: Помогите с таймерами пожалуйста =)
Ramzez писал(а):
можно страницу даташита о регистре


откройте PDF и в поиск вставьте название регистра - он вам найдет его быстро, лтбо в закладках слева по оглавлению пройдитесь.

Как работать с даташитом - страница 1 курса.


Вложения:
avr proavr.narod.ru atmega.png
avr proavr.narod.ru atmega.png [ 39.22 КиБ | Просмотров: 2190 ]

_________________
Читайте !
Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Помогите с таймерами пожалуйста =)
СообщениеДобавлено: 09 янв 2010, 20:57 
Не в сети
Аватара пользователя

Зарегистрирован: 13 фев 2009, 18:37
Сообщения: 28
Откуда: Петрозаводск
непонятки у нас возникают с вами )
даташит на мегу скачан русский, я по нему выяснял что делают биты, наприммер в TCCR, но не могу найти про ICR , просил дать номер странички где можно про него почитать )

В том то и проблема, что где я не ищу ШИМ на си, там везде засунут UART, передача данных на комп или сразу 8 серво, а нужно то всего одно чтобы разобраться! а когда поймешь одно, можно и 8 будет делать самому. Я прочитал весь курс AVR123, и про серво читал) но , к сожалению не понял, поэтому решил создать эту темку о помощи =)

Знаний у меня пока хватило мигать светодиодами в разных режимах по кнопкам, сделал программную реализацию ШИМ, смог управлять серво приводом (поворачивать плавно из крайнего левого положения в правое) , так же получилось сделать прерывание. Следующий шаг -таймеры, основная проблема в непонимании синтаксиса других программистов

Добавлено спустя 11 минут 57 секунд:
Я был бы очень вам благодарен, если бы вы обьяснили на примере одной сервы настройку таймера и ШИМ , без всякой обвески , например чтобы передвинуть серво в одно единственное положение, это будет отправной точкой в дальнейшем изучении МК для меня, моего товарища и еще многих, поскольку запрос на форуме "управление серво" выдает очень много однообразных тем, где всем дают линки на AVR123 .

Так же не могли бы вы подсказать, стоит ли мне дальше использовать WIN AVR , или переходить на CVAVR , с его мастером генерирования начального кода?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Помогите с таймерами пожалуйста =)
СообщениеДобавлено: 09 янв 2010, 21:21 
Не в сети
Аватара пользователя

Зарегистрирован: 25 июл 2009, 16:35
Сообщения: 104
Откуда: Ессентуки
прог. языки: ASM , Lisp , C# :)
ФИО: Алексей
Для начала разберись с начинкой контроллера, правда придётся прочитать много скучных букав.
Пример с 1 сервой : насраиваеш таймер в режим нормал и выставляеш необходимое время через которое вызывается прерывание , потом ставиш на ноге нужный уровень, а в прерывании возвращаеш ногу в исходное сосотяние. и т.д..(Если ошибся поправте)
А когда серв много строиться конвеер(RTOS)...

_________________
Алокоголизм - излечим, пьянство - нет.
Peace-death.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Помогите с таймерами пожалуйста =)
СообщениеДобавлено: 09 янв 2010, 22:08 
Не в сети
отсылающий читать курс
Аватара пользователя

Зарегистрирован: 06 ноя 2005, 04:18
Сообщения: 14195
Откуда: Москва
Ramzez писал(а):
стоит ли мне дальше использовать WIN AVR , или переходить на CVAVR , с его мастером генерирования начального кода?


Конечно используйте WinAVR, а пока учитесь мастера CVAVR и ICC вам помогут.

Пример в мастере cvavr 2 настройка AVR под servo

1) выбираешь чип мега16 и частоту 4 Мгц

2) таймер 1 настраичваешь на счет 500 Кгц т.е. за 20 мС он насчитает до 10 000 - это число занесем ( после генрации кода вручную ) в регистр ICR1 - таймер будет постоянно считать от 0 до 10000 и снова с нуля ...

3) вкл. выход ШИМ "А" OC1A не инвертированый. Теперь когда таймер будет в "0" на выходе OC1A будет появляться "1" а когда таймер досчитает до OCR1 то на OC1A появится "0".

4) 2 мкС будет 1 тик таймера при частоте 500 Кгц

Значит для среднего положения сервы надо вписать: 1500 мкС / 2 мкС = 750 ( это 2eeh) в OCR1

левое положение servo OCR1 = 550; правое положение servo OCR1 = 950;

5) Теперь - "Програм Превью" при генерации кода мастер предложит назначить ножку ШИМ выходом - жми ОК.

Зашуршало в PROTEUS !


Вложения:
servo.png
servo.png [ 98.05 КиБ | Просмотров: 2139 ]
Комментарий к файлу: файл мастера кода CVAVR 2
servo.rar [2.89 КиБ]
Скачиваний: 10

_________________
Читайте !


Последний раз редактировалось avr123.nm.ru 09 янв 2010, 22:40, всего редактировалось 1 раз.
Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Помогите с таймерами пожалуйста =)
СообщениеДобавлено: 09 янв 2010, 22:29 
Не в сети
Аватара пользователя

Зарегистрирован: 13 фев 2009, 18:37
Сообщения: 28
Откуда: Петрозаводск
Большое всем спасибо! буду пробовать !


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Помогите с таймерами пожалуйста =)
СообщениеДобавлено: 09 янв 2010, 22:43 
Не в сети
отсылающий читать курс
Аватара пользователя

Зарегистрирован: 06 ноя 2005, 04:18
Сообщения: 14195
Откуда: Москва
Проект в CVAVR 2 и скрин мастера с настройкой таймер AVR для управления servo


Вложения:
Комментарий к файлу: Проект в CVAVR 2 таймер AVR для управления servo
servo.rar [18.52 КиБ]
Скачиваний: 12
avr_servo.png
avr_servo.png [ 52.68 КиБ | Просмотров: 2140 ]

_________________
Читайте !
Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Помогите с таймерами пожалуйста =)
СообщениеДобавлено: 10 янв 2010, 20:02 
Не в сети
Аватара пользователя

Зарегистрирован: 13 фев 2009, 18:37
Сообщения: 28
Откуда: Петрозаводск
Вот что у меня получилось для WIN AVR , начальный код генерировал CVAVR, потом переносил )
Пока еще не проверял на практике ( с эмуляторами не стал разбираться пока )

Код:
#define F_CPU 1000000UL  // 1 MHz
   #include <avr/io.h>
   #include <avr/interrupt.h>

// Declare your global variables here

void main(void)
{

PORTD=0x00;     
DDRD=0x20;    //выход таймера
DDRA = 0xff; //выходы
DDRB=0x00; //входы
PORTB=0b00000001 ;  //pull-up на нулевую ногу

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 125,000 kHz
// Mode: Normal top=FFFFh
// OC1A output: Set
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer 1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0xC0;
TCCR1B=0x02;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x09;
ICR1L=0xc4;
OCR1AH=0x00;
OCR1AL=0xBC;
OCR1BH=0x00;
OCR1BL=0x00;

// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer 2 Stopped
// Mode: Normal top=FFh
// OC2 output: Disconnected
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;

// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
// INT2: Off
MCUCR=0x00;
MCUCSR=0x00;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x00;

// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;

while (1)
{

while(PINB & 0x01 != 0) {      //пока нажата кнопка
if (OCR1AL<250)        //если серво не в крайнем правом положении
{
OCR1AL++;             //разворот вправо
PORTA = 0b00000001;  //синий светодиод
}

}

if (OCR1AL>140)      //если серво не в крайнем левом положении
{
OCR1AL--;            //разворот влево
PORTA=0b00010000;    //красный светодиод
}
}
}


Вопрос: обязателен ли данный кусок кода
Код:
// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
// INT2: Off
MCUCR=0x00;
MCUCSR=0x00;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x00;

// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;

если прерывания, вроде как, в таймере я не использовал ?

Добавлено спустя 3 минуты 2 секунды:
Прога должна при нажатии кнопки перегонять серво постепенно из крайнего левого в крайнее правое положение, при этом загораются соответствующие светодиоды на выходах PORTB=00010001


Последний раз редактировалось Ramzez 10 янв 2010, 21:14, всего редактировалось 4 раз(а).

Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 30 ]  На страницу 1, 2  След.

Часовой пояс: UTC + 4 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 15


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB
phpBB SEO