А правильно ли я понял программу?!

Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
Ответить
Аватара пользователя
olovo
Первый раз сказал Мяу!
Сообщения: 23
Зарегистрирован: Вт янв 31, 2012 22:43:10

А правильно ли я понял программу?!

Сообщение olovo »

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

Код: Выделить всё

//модель мегии
#include <mega2313.h>
//частота кристала
#define _hz 4000000
//
//----------
interrupt(SIG_OVERFLOW1) // тут обрабатываем прерывание от таймера
{
//
TCNT1 = 0x10000 - (_hz/1024);   // 65536(число переполнения таймера так как он 16бит) - частоту разделив на 1024 получаем 3906 - это насчитает таймер за секунду
PORTB ^= 0x01;  //1 - т.е. в регистре у нас 00000001 и на ноге РСВ0 у нас напряжение
//
}
//----------
int main(void)
{
//
DDRB = 0x01;  //направление передачи , в регистре 00000001, т.е. нога РСВ0 эявляется выходом
//для мазохизма пользуем сложный таймер  Т/С1 в котором есть регистры сравнений
TCCR1A =0;  // TCCR1A - заносим в регистр 0, отключаем ШИМ
TCCR1B = 5; // TCCR1B - ставим 5 или 101 (в регисьре значащие 3 разряда 0-2)  тем самым устанавливая частоту тактирования таймера системная/10254 это 3906  тактов в секунду при частоте 4000000
TCN1 = 0x10000 - (_hz/1024);   // ложим в регистр 61630 что б сработало на следующую секунду после запуска
TIFR = 0; //сбрасываем флаги прерываний
TIMSK = 0x80; // пишем в регистр 10000000 , разрешаем прерывание Т/С1
GIMSK = 0;  // запрещаем внешние прерывания
sei();     //прерывания разрешены
while(1);    //ждём прерывания таймера (сидим в бесконечном цыкле)
//
}
Реклама
Аватара пользователя
Engineer_Keen
Друг Кота
Сообщения: 3870
Зарегистрирован: Пт янв 29, 2010 10:27:40
Откуда: Москва

Re: А правильно ли я понял программу?!

Сообщение Engineer_Keen »

olovo писал(а)://модель мегии
#include <mega2313.h>

:shock: это какая-такая мега??? Может все-таки тини?
Теперь что касается чисто АВР:
olovo писал(а):TCNT1 = 0x10000 - (_hz/1024); // 65536(число переполнения таймера так как он 16бит) - частоту разделив на 1024 получаем 3906 - это насчитает таймер за секунду

TIMER1 - 16 битный, больше чем 0xFFFF в него не положишь, компилятор или ругнется или скорее всего тупо обрежет лишние биты и получите вы там голый 0.
olovo писал(а):тем самым устанавливая частоту тактирования таймера системная/10254

/1024, внимательнее...
olovo писал(а):TIFR = 0; //сбрасываем флаги прерываний

Флаги сбрасываются записью "1", читайте даташит.
olovo писал(а):пишем в регистр 10000000

или 128 или 0х80 или 0b10000000, а то не понятно какая система счисления...
Реклама
Аватара пользователя
urry
Сверлит текстолит когтями
Сообщения: 1262
Зарегистрирован: Пн дек 08, 2008 10:58:48
Откуда: Винница
Контактная информация:

Re: А правильно ли я понял программу?!

Сообщение urry »

TIMER1 - 16 битный, больше чем 0xFFFF в него не положишь, компилятор или ругнется или скорее всего тупо обрежет лишние биты и получите вы там голый 0.

здесь, кстати, правильно, но применение неверное,конечно. :)
Для вычисления значения таймера для требуемой частоты при переполнении используется формула
TIMER1 =65536 - Fin/Fout , где Fin - входная частота на таймер с учетом всех пределителей, Fout - требуемая частота.
Аватара пользователя
Engineer_Keen
Друг Кота
Сообщения: 3870
Зарегистрирован: Пт янв 29, 2010 10:27:40
Откуда: Москва

Re: А правильно ли я понял программу?!

Сообщение Engineer_Keen »

Да, совсем забыл что так можно частоту настраивать, последнее время просто использую для этого режим СТС...
Реклама
Эиком - электронные компоненты и радиодетали
Аватара пользователя
olovo
Первый раз сказал Мяу!
Сообщения: 23
Зарегистрирован: Вт янв 31, 2012 22:43:10

Re: А правильно ли я понял программу?!

Сообщение olovo »

Engineer_Keen
1. 10254 :)) имел ввиду 1024
2. TCNT1 = 0x10000 - (_hz/1024); - вот тут прошу пояснить. мои мысли 0х10000 (65536 в десятичной) таймер посчитает 65535 и при следующем +1 обнулится. вот от него и высчитывается необходимое начальное значение таймера чтоб сбрасывался он каждую секунду, вызывая прерывание. и ещё просьба пояснить в чём неправильное использование такой конструкции?
3. TIFR = 0; - тут как понимаю в регистр флагов прерываний пишется как раз таки 0,а ноль во всех системах это ноль. как можно сбросить флаги занеся туда 1?????????
4. за системы счислений впредь буду использовать 0bХХХХХХХХ и 0хХХХХХХХХ
Реклама
Аватара пользователя
olovo
Первый раз сказал Мяу!
Сообщения: 23
Зарегистрирован: Вт янв 31, 2012 22:43:10

Re: А правильно ли я понял программу?!

Сообщение olovo »

//модель мегии
#include <tiny2313.h>
тини так указывается? кодю в код вижин 2,6
Реклама
Аватара пользователя
olovo
Первый раз сказал Мяу!
Сообщения: 23
Зарегистрирован: Вт янв 31, 2012 22:43:10

Re: А правильно ли я понял программу?!

Сообщение olovo »

Код: Выделить всё

//модель мегии
#include <tiny2313.h>
//частота кристала
#define _hz 4000000
//
//----------
interrupt [SIG_OVERFLOW1] // тут обрабатываем прерывание от таймера
{
//
TCNT1 = 0x10000 - (_hz/1024);   // 65536(число переполнения таймера так как он 16бит) - частоту разделив на 1024 получаем 3906 - это насчитает таймер за секунду
PORTB ^= 0x01;  //1 - т.е. в регистре у нас 00000001 и на ноге РСВ0 у нас напряжение
//
}
//----------
int main(void)
{
//
DDRB = 0x01;  //направление передачи , в регистре 00000001, т.е. нога РСВ0 эявляется выходом
//для мазохизма пользуем сложный таймер  Т/С1 в котором есть регистры сравнений
TCCR1A =0;  // TCCR1A - заносим в регистр 0, отключаем ШИМ
TCCR1B = 5; // TCCR1B - ставим 5 или 101 (в регисьре значащие 3 разряда 0-2)  тем самым устанавливая частоту тактирования таймера системная/1024 это 3906  тактов в секунду при частоте 4000000
TCN1 = 0x10000 - (_hz/1024);   // ложим в регистр 61630 что б сработало на следующую секунду после запуска
TIFR = 0; //сбрасываем флаги прерываний
TIMSK = 0x80; // пишем в регистр 10000000 , разрешаем прерывание Т/С1
GIMSK = 0;  // запрещаем внешние прерывания
sei();     //прерывания разрешены
while(1);    //ждём прерывания таймера (сидим в бесконечном цыкле)
//


При компиляции ругается на interrupt [SIG_OVERFLOW1]
Error: C:\Documents and Settings\User\Desktop\ledD.c(7): undefined symbol 'SIG_OVERFLOW1'
Интересно какой же неопределённый символ в SIG_OVERFLOW1??? ведь SIG_OVERFLOW1 как понимаю из умных книжек - как раз таки и есть название прерывания которое инициализирует счетчик Т/С1 при сбросе в 0
Аватара пользователя
Engineer_Keen
Друг Кота
Сообщения: 3870
Зарегистрирован: Пт янв 29, 2010 10:27:40
Откуда: Москва

Re: А правильно ли я понял программу?!

Сообщение Engineer_Keen »

olovo писал(а):2. TCNT1 = 0x10000 - (_hz/1024); - вот тут прошу пояснить.

Тут все верно, это я неправильно прочитал...
olovo писал(а):3. TIFR = 0; - тут как понимаю в регистр флагов прерываний пишется как раз таки 0,а ноль во всех системах это ноль. как можно сбросить флаги занеся туда 1?????????

Вот именно так и не можно а нужно. Если нужно сбросить все флаги то писать надо соответственно 0b11111111, такая особенность АВР.
olovo писал(а):Интересно какой же неопределённый символ в SIG_OVERFLOW1???

Может как-то по -другому называется или в другом файле находится?
Аватара пользователя
olovo
Первый раз сказал Мяу!
Сообщения: 23
Зарегистрирован: Вт янв 31, 2012 22:43:10

Re: А правильно ли я понял программу?!

Сообщение olovo »

:) кто кодит в CV! огромная просьба подсказать где лежат в нём эти файлы
Engineer_Keen писал(а):
olovo писал(а):Интересно какой же неопределённый символ в SIG_OVERFLOW1???

Может как-то по -другому называется или в другом файле находится?
Аватара пользователя
vitalik_1984
Поставщик валерьянки для Кота
Сообщения: 2482
Зарегистрирован: Пт авг 27, 2010 05:57:06
Откуда: Тюмень
Контактная информация:

Re: А правильно ли я понял программу?!

Сообщение vitalik_1984 »

Находятся они в месте под названием мастер кода, я вообще поражаюсь, есть мастер, трудно спросить у него?
Это такая серого цвета шестеренка где то в середине панели инструментов.
тупо выбираем контроллер, ставим галку на нужном прерывании, нажимаем на просмотр(кнопка в виде лупы левее такой же шестеренки как до этого нажали) и копируем нужную часть.

Этот символ не определен, потому что этому вектору нужно еще назначить подпрограмму, в которой будет происходить обработка, тело подпрограммы есть, а объявления то нет!
И тем более в CVAVR векторы по другому называются, отлично от даташита.
В поисках истины человек развивается.
Аватара пользователя
olovo
Первый раз сказал Мяу!
Сообщения: 23
Зарегистрирован: Вт янв 31, 2012 22:43:10

Re: А правильно ли я понял программу?!

Сообщение olovo »

Изображение
Где же эта шестерёнка то? :shock:
Аватара пользователя
YS
Друг Кота
Сообщения: 7518
Зарегистрирован: Вс мар 29, 2009 22:09:05
Контактная информация:

Re: А правильно ли я понял программу?!

Сообщение YS »

Код: Выделить всё

interrupt(SIG_OVERFLOW1)


Это стиль объявления прерываний для GCC, и то устаревший - сейчас используется макрос ISR(). Как объявить прерывание в CV - смотрите в туториалах.

Код: Выделить всё

PORTB ^= 0x01;  //1 - т.е. в регистре у нас 00000001 и на ноге РСВ0 у нас напряжение


Это операция "исключающее или", проводимая над портом и значением 0x01. Каждый раз при выполнении этого кода состояние ножки будет меняться на противоположное. Это простой способ помигать диодом.
Разница между теорией и практикой на практике гораздо больше, чем в теории.
Аватара пользователя
olovo
Первый раз сказал Мяу!
Сообщения: 23
Зарегистрирован: Вт янв 31, 2012 22:43:10

Re: А правильно ли я понял программу?!

Сообщение olovo »

УРА! скомпилилось

Код: Выделить всё

//модель мегии
#include <tiny2313.h>
//частота кристала
#define _hz 4000000
//
//----------
interrupt [TIM1_OVF] void timer1(void)// тут обрабатываем прерывание от таймера
{
//
TCNT1 = 0x10000 - (_hz/1024);   // 65536(число переполнения таймера так как он 16бит) - частоту разделив на 1024 получаем 3906 - это насчитает таймер за секунду
PORTB ^= 0x01;  //1 - т.е. в регистре у нас 00000001 и на ноге РСВ0 у нас напряжение
//
}
//----------
void main(void)
{
//
DDRB = 0x01;  //направление передачи , в регистре 00000001, т.е. нога РСВ0 эявляется выходом
//для мазохизма пользуем сложный таймер  Т/С1 в котором есть регистры сравнений
TCCR1A =0;  // TCCR1A - заносим в регистр 0, отключаем ШИМ
TCCR1B = 5; // TCCR1B - ставим 5 или 101 (в регисьре значащие 3 разряда 0-2)  тем самым устанавливая частоту тактирования таймера системная/1024 это 3906  тактов в секунду при частоте 4000000
TCNT1 = 0x10000 - (_hz/1024);   // ложим в регистр 61630 что б сработало на следующую секунду после запуска
TIFR = 0; //сбрасываем флаги прерываний
TIMSK = 0x80; // пишем в регистр 10000000 , разрешаем прерывание Т/С1
GIMSK = 0;  // запрещаем внешние прерывания
#asm
sei     //прерывания разрешены
#endasm
while(1);    //ждём прерывания таймера (сидим в бесконечном цыкле)
//
Аватара пользователя
vitalik_1984
Поставщик валерьянки для Кота
Сообщения: 2482
Зарегистрирован: Пт авг 27, 2010 05:57:06
Откуда: Тюмень
Контактная информация:

Re: А правильно ли я понял программу?!

Сообщение vitalik_1984 »

olovo писал(а):Где же эта шестерёнка то? :shock:

У, как все запущено...
Качайте новую версию
Еще есть довольно понятный учебник по CVAVR.
Лебедев пособие для начинающих CVAVR
zhv
Родился
Сообщения: 1
Зарегистрирован: Вт дек 18, 2012 03:45:35

Re: А правильно ли я понял программу?!

Сообщение zhv »

olovo писал(а):...
TCN1 = 0x10000 - (_hz/1024); // ложим в регистр 61630 что б сработало на следующую секунду после запуска
.....

Где это видно из кода, что кладётся 61630?
Вообще мне, как начинающему, непонятно выражение у Лебедева на стр. 456
TCN1 = 0x10000 - (htal/1024/fmovie)
Как это понять? Делим частоту процессора htal на предделитель1024 и получаем частоту на входе в таймер (тактирования). Вроде понятно. Но затем это делится на fmovie- частоту, с которой должно происходить прерывание. И что получается? Когда одну частоту делишь на другую? А затем это выражение в скобках (htal/1024/fmovie) ещё и вычитаешь из числа 0x10000? И что получаем? Вообще-то догадываюсь что это число с которого счётчик начинает считать. Но арифметику не улавливаю. Проясните пожалуйста.
Аватара пользователя
Engineer_Keen
Друг Кота
Сообщения: 3870
Зарегистрирован: Пт янв 29, 2010 10:27:40
Откуда: Москва

Re: А правильно ли я понял программу?!

Сообщение Engineer_Keen »

zhv писал(а):Где это видно из кода, что кладётся 61630?

0x10000=65536, _hz=4000000
TCN1 = 65536 - 4000000 / 1024 = 61629.75 ~ 61630
zhv писал(а):Делим частоту процессора htal на предделитель1024 и получаем частоту на входе в таймер (тактирования). Вроде понятно. Но затем это делится на fmovie- частоту, с которой должно происходить прерывание.

Да, чтобы получить такое значение счетчика, что считая с него, переполнение (следовательно и прерывание) произойдет с нужной нам частотой (fmovie). Арифметика такая: допустим нам нужно Fmovie=25Гц, тогда:
TCNT1=65536-4000000/1024/25=65380
получается что таймер начинает считать с 65380, и до переполнения, он просчитает: 65536-65380=156 тактов, один такт=1/(4000000/1024)=0.000256с, следовательно прерывание произойдет через 0.000256*156=0.0399с, что соответствует частоте 1/0.0399=25Гц.
Аватара пользователя
vitalik_1984
Поставщик валерьянки для Кота
Сообщения: 2482
Зарегистрирован: Пт авг 27, 2010 05:57:06
Откуда: Тюмень
Контактная информация:

Re: А правильно ли я понял программу?!

Сообщение vitalik_1984 »

olovo писал(а):Где же эта шестерёнка то? :shock:

В вашей версии это шляпа волшебника :)))
Ответить

Вернуться в «Разные вопросы по МК»