Перейти к содержанию

Прошу Помощи По Написанию Программ На Си


elektromonter

Рекомендуемые сообщения

Всем доброго времени суток.. Только начал изучать программирование АВР МК, пишу в AtmelStudio6 на СИ. Пару простых программ управления шаговым двигателем по опросу ножек, ацп и компаратора написал, прошил МК все работает.. Вот появилась задача сделать управление шаговым двигателем в зависимости от температуры и частоты поступающих импульсов. МК выбрал ATtiny2313. Застрял в самом начале, а именно с счетчиком Т1. Попробовал задавать временной интервал с помощью переполнения таймера Т0 с дополнительным делением частоты в обработчике прерываний и считать приходящие импульсы по внешнему прерыванию, пробовал брать за временной интервал внешние прерывания и считать количество переполнений Т0. все это моделировал в Протеусе, так как измеряемая частота низкая от 30 до 80 Гц то погрешность допускается максимум до 1-го Гц, при моделировании погрешность достигала 3-х Гц что не допустимо. Выбор пал на Т1 так как там есть режим "захвата" и защита от ложных срабатываний. Вот и бьюсь с ним вторые сутки!

Проблема в следующем: выставил я прерывание по захвату, настроил делитель на 1024, и считаю сколько раз натикает счетчик в регистр ICR1 от одного прерывания до другого, заношу значение посчитанного в переменную INT и в теле программы выполняю для (проверки правильности алгоритма мышления и написания) через оператор IF зажигание светодиода...

Тактовая частота 8 мГц. Вот и считаю 8000000/1024=7812.5 Гц тактовая частота на входе в счетчик, 1/7812.5=0.128 мс. Беру для примера частоту измеряемого сигнала 80 Гц, 1/80= период 12.5 мс. Значит за время между прерываниями в регистр он должен положить 12.5/0.128=97.65..., округляю до 98 (тут можно вроде бы как обойтись одним младшим регистром ICR1L. пробовал, таже белеберда что и с считыванием ICR1L и ICR1Н только порог на 10 Гц становится) и записываю условия функции,

надеюсь что светодиод загорится до 80 Гц и потухнет после 80 Гц. В результате протеус зажигает его до 940 Гц и тушит после.

Что не так? Где ошибка? поиск ничего вразумительного не дал!

#define F_CPU 8000000

#include <avr/io.h>

#include <util/delay.h>

#include <avr/interrupt.h>

#include <avr/signal.h>

#include <avr/portpins.h>

volatile unsigned int bufer;

SIGNAL (TIMER1_CAPT_vect)

{

bufer=ICR1L<<8;

bufer|=ICR1H;

ICR1L=0;

ICR1H=0;

TCNT1=0;

}

int main(void)

{

DDRD=(0<<PD6)|(1<<PD5)|(1<<PD4)|(1<<PD3)|(1<<PD2)|(1<<PD1)|(1<<PD0);

PORTD=0x00;

DDRB=0xFF;

PORTB=0x00;

// инициализация таймера в режиме захвата

TCCR1B=(1<<CS10)|(0<<CS11)|(1<<CS12)| //предделитель 1024

(1<<ICNC1)|(1<<ICES1);

TIMSK=1<<ICIE1;

sei();

while(1)

{

if (bufer<98)

{

PORTB=1<<PB0;

}

else

{

PORTB=0<<PB0;

}

}

}

Изменено пользователем elektromonter
Ссылка на комментарий
Поделиться на другие сайты

Реклама: ООО ТД Промэлектроника, ИНН: 6659197470, Тел: 8 (800) 1000-321

20% скидка на весь каталог электронных компонентов в ТМ Электроникс!

Акция "Лето ближе - цены ниже", успей сделать выгодные покупки!

Плюс весь апрель действует скидка 10% по промокоду APREL24 + 15% кэшбэк и бесплатная доставка!

Перейти на страницу акции

Реклама: ООО ТМ ЭЛЕКТРОНИКС, ИНН: 7806548420, info@tmelectronics.ru, +7(812)4094849

Выбираем схему BMS для корректной работы литий-железофосфатных (LiFePO4) аккумуляторов

 Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ, также как и для других, очень важен контроль процесса заряда и разряда, а специализированных микросхем для этого вида аккумуляторов не так много. Инженеры КОМПЭЛ подготовили список имеющихся микросхем и возможных решений от разных производителей. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

ForumUser: тактирование задал с предделителя на 1024, вот эта строчка-

TCCR1B=(1<<CS10)|(0<<CS11)|(1<<CS12)| //предделитель 1024

DmitryS: Студия позволяет и такую запись... пробовал и так как на ваших примерах, разници ни какой.

Но вот какая штука получилась... Перепортировал я эту программу под ATmega8 и она заработала! Ни чего не менял! только названия портов и регистр TIMSK=1<<ICIE1 в TIMSK у ATmega8 незывается TICIE1, и все! там все четко заработало по приведенному мной расчету!

Ссылка на комментарий
Поделиться на другие сайты

разници ни какой

Разница есть.

Выражение типа: PORTB=1<<PB0; означает, что в бит PB0 будет записана единица, остальные биты будут обнулены.

Выражение типа: PORTB=0<<PB0; равносильно выражению PORTB=0;

Молодых и талантливых чрезвычайно много. Целеустремлённых и готовых довести дело до конца — гораздо меньше.

Ссылка на комментарий
Поделиться на другие сайты

SIGNAL (TIMER1_CAPT_vect)

{

bufer=ICR1L<<8;

bufer|=ICR1H;

Где теги [СОDE] [/СОDE]?

Вместо SIGNAL можно писать ISR

Старший и младший байты специально местами поменяли? Может, в этом дело?

Попробовал задавать временной интервал с помощью переполнения таймера Т0 с дополнительным делением частоты в обработчике прерываний и считать приходящие импульсы по внешнему прерыванию
А чем этот вариант не устроил? Только я бы использовал Т1 для отсчета времени интервалами по 2 сек, а Т0 для входных импульсов.

Ругался на отсутствие форматирования исходного кода (включая отсутствие осмысленных комментариев и наличие неубранного после конфигуратора мусора) не менее 15 раз.

Часть моих наработок.

Ссылка на комментарий
Поделиться на другие сайты

ясно, спасибо что с портами разъяснили.

SOKPOWENEU в атмел студио теги [СОDE] [/СОDE] вроде бы как не нужну, это в cvavr они необходимы. по поводу SIGNAL я всегда и писал ISR, но оказалось при подключении файлика #include <avr/signal.h> студия понимает и SIGNAL . записывал в вектор прерываний

PORTD|=1<<PORTD1;

PORTD|=0<<PORTD1;

и смотрел на ножке осциллографом, прерывание отрабатывает исправно при каждом импульсе на ICP. Я уже на компилятор грешу. почему на меге прокатывает, а на тиньке нет?.. :unknw:

просто на тини2313 уже куплена и не одна. Да и незачем там такое количество наворотов, я когда учился на радиоконструктора то вбили в голову что элементы надо выбирать оптимально под поставленную задачу. Вот и стало это моим девизом. Зачем ставить 100А МОСФЕТ на управление релюшкой с током 0.1А?

Ссылка на комментарий
Поделиться на другие сайты

теги [CОDE] нужны не в Студии или cvavr, а на форуме, чтобы оформлялось хотя бы примерно по-человечески.

ISR - расширенная версия SIGNAL. Она позволяет назначить один обработчик на несколько векторов, разрешать прерывания в обработчике, создавать пустой обработчик (не выбрасывающий на BADISR_VECT, но и не содержащий кода, фактически, тупо reti), убрать автосохранение SREG и регистров (для ассемблерных вставок самое то). Ну и рекомендация от разработчиков: Не используйте SIGNAL в новом коде, лучше используйте ISR. man avr-libc

Do not use SIGNAL() in new code. Use ISR() instead.

PORTD|=0<<PORTD1; Эта запись бессмысленна. Сдвиг нуля на любую величину остается нулем, а логическое сложение с ним не меняет числа. Если хотите обнулить бит, используйте логическое умножение PORTD &=~(1<<PD1);, можете сложить (умножить) в столбик, чтобы убедиться.

На тини вроде есть фуз CLKDIV8. Ну и остальные фузы озвучьте.

Порядок записи байтов в двухбайтовое число точно верный? Судя по коду, вы в младший записываете старший и наоборот.

Ругался на отсутствие форматирования исходного кода (включая отсутствие осмысленных комментариев и наличие неубранного после конфигуратора мусора) не менее 15 раз.

Часть моих наработок.

Ссылка на комментарий
Поделиться на другие сайты

SOKPOWENEU могу порядок записи байтов напутать. напишите как надо пожалуйста. я с этим старшим и младшим регистром голову сломал! мне надо чтоб таймер до захвата считал в мою переменную INT bufer записывал 1,2,3,4,5,6,7,8,9,..... и так по порядку до заполнения переменной INT.

Ссылка на комментарий
Поделиться на другие сайты

ICR1H - high byte, старший, ICR1L - low, младший. Обращение к двухбайтным регистрам в AVR обычно от младшего к старшему, то есть чтение старшего байта - разрешение ядру на его перезапись. Ну и сбрасывать ICR1 не нужно, все равно в него будет TCNT1 записан.

buffer = ICR1L;
buffer |= (ICR1H<<8);
/
buffer = (ICR1H<<8) | ICR1L;

Возможно, придется использовать явное приведение ICR1H к 2-байтному типу, но вряд ли.

Ругался на отсутствие форматирования исходного кода (включая отсутствие осмысленных комментариев и наличие неубранного после конфигуратора мусора) не менее 15 раз.

Часть моих наработок.

Ссылка на комментарий
Поделиться на другие сайты

SOKPOWENEU спасибо большое за помощь! как раз и была проблема с фузами, изменил CLKDIV8 и о ч удо! Все зароботало! Я тему не буду закрывать, а то вопросов еще будет наверное много )))

Ссылка на комментарий
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Ответить в этой теме...

×   Вставлено с форматированием.   Восстановить форматирование

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

Загрузка...
  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
×
×
  • Создать...