реклама на сайте
подробности

 
 
> Захват в ATMega64, Помогите новичку
Tomade
сообщение Jun 18 2008, 06:49
Сообщение #1


Участник
*

Группа: Новичок
Сообщений: 23
Регистрация: 26-05-08
Пользователь №: 37 817



Помогите, пожалуйста, начинающему чайнику. Задача - сделать измеритель/индикатор скорости вращения двигателя постоянного тока (до 12 тысяч оборотов в минуту).
Для начала написал программу, которая анализирует наличие сигнала на ножке захвата ICP1 (PD4 контроллера ATMega 64L) и при его поступлении выводит на вывод PE2 импульс, который можно наблюдать на осциллографе симулятора VMLAB (это для изучения и отладки), инкрементирует текущее (произвольное) число и выводит это число на LCD cимулятора.
Что же получилось? После запуска программы около 2 секунд инициируется LCD (это нормально), на его экран выводится число 25. Затем в симуляторе подаётся импульс на PD4. По идее подпрограмма прерывания по захвату должна выработать импульс "отрицательной" полярности длительностью 5 мс, инкрементировать число 25 и вывести на экран LCD число 26. Однако происходит следующее:
после первой подачи импульса захвата на выводе PE2 генерируется импульс с задержкой около 2 сек, число 26 тоже появляется с такой же задержкой;
начиная со второго импульса захвата число 26 уже не инкрементируется, а выходные импульсы на PE2 продолжают генерироваться с такой же задержкой.
Вопросы: откуда такая задержка при подаче импульсов захвата? Почему число инкрементируется только один раз?

#include <mega64.h>
// Alphanumeric LCD Module functions
#asm
.equ __lcd_port=0x1B ;PORTA
#endasm
#include <lcd.h>
#include<stdio.h>
#include<delay.h>

// LCD display buffer
char lcd_buffer[33];
unsigned int x = 0x00;

void __vivod_LCD(void) { //Функция вывода на ЖКИ
sprintf(lcd_buffer,"%i",x); //Запись в буфер ЖКИ
lcd_clear(); //Очистка экрана ЖКИ
lcd_puts(lcd_buffer); //Вывод на ЖКИ
}

// Timer 1 input capture interrupt service routine
interrupt [TIM1_CAPT] void timer1_capt_isr(void)
{
PORTE.2=0;
delay_ms(5);
PORTE.2=1;
x++;
__vivod_LCD ();
}
void main(void)
{
// Input/Output Ports initialization
PORTA=0x00;
DDRA=0x00;
PORTD=0xFF;
DDRD=0x00;
PORTE=0xFF;
DDRE=0x0FF;
// Timer/Counter 1 initialization
// Clock source: T1 pin Falling Edge
TCCR1A=0x00;
TCCR1B=0x81;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;
OCR1CH=0x00;
OCR1CL=0x00;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x24;
ETIMSK=0x00;
// LCD module initialization
lcd_init(16);
x=25;
__vivod_LCD ();

#asm("sei")
while (1)
{
}
}
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
domowoj
сообщение Jun 18 2008, 17:17
Сообщение #2


Профессионал
*****

Группа: Участник
Сообщений: 1 548
Регистрация: 20-12-07
Из: г.Новосибирск
Пользователь №: 33 486



Достаточно измерить период вращения(N раз и произвести вероятностный анализ).
Пустить таймер в "свободное плавание" и фиксировать его значения по сигналу захвата, не забывая
контролировать сигнал переполнения счетчика, а дальше - ариХметика.
А выводить на индикатор раз в одну или две секунды, как вам угодно.
В симуляторе главное сформировать входной сигнал.


--------------------
И на камнях растут деревья!
Go to the top of the page
 
+Quote Post
Tomade
сообщение Jun 19 2008, 04:42
Сообщение #3


Участник
*

Группа: Новичок
Сообщений: 23
Регистрация: 26-05-08
Пользователь №: 37 817



Цитата(domowoj @ Jun 18 2008, 21:17) *
Пустить таймер в "свободное плавание" и фиксировать его значения по сигналу захвата...

Именно так я и хотел сделать. А так как это моя первая в жизни программа (я не программист), то, естественно, сразу ничего не получилось, потому решил делать по частям, а именно:
- убедиться, что захват при поступлении на вход ICP1 спадающего фронта импульса происходит. Для этого в подпрограмме прерывания по захвату сделал вывод на РЕ2 "отрицательного" импульса. Убедился, что эта часть работает. В симуляторе спадающий фронт формирую, замыкая на землю вход PD4 кнопкой К0 и контролируя это на осциллографе симулятора;
- вывести на ЖКИ любое сообщение, или константу, или инкрементируемое число. Здесь не имеет значения частота поступления на вход будущего устройства импульсов от датчика скорости вращения шпинделя; просто хотел убедиться, что вывод на экран ЖКИ происходит после очередного нажатия кнопки К0 симулятора, то есть после наступления события захвата. Ан нет, не получилось: кроме естественной 2-х секундной задержки при запуске программы, вызыванной инициализацией ЖКИ, откуда-то берётся примерно такая же задержка (точное её значение в рассматриваемом случае не имеет никакого значения) при каждом нажатии кнопки К0 симулятора (то есть при каждом захвате).
Где в тексте программы ошибка?
-----
Насчёт прерывания по переполнению... Это не специально, это из-за неправильной настройки генератора начального кода CVAVR. Однако существенно ли это для заданных вопросов?
Короче, забудем начальную задачу (тахометр, и не просто, а следящий за непрерывно меняющейся скоростью вращения). Вернёмся к программе в начале темы: где в ней ошибки? Откуда задержка вывода импульсов при наступлении событий захвата? Почему после первого инкрементирования и вывода на ЖКИ числа в дальнейшем выводимое на ЖКИ число не меняется, хотя импульсы на выходе РЕ2 генерируются?
Напомню, что до этой задачи, в порядке изучения микроконтроллеров AVR, я делал вывод на ЖКИ инрементируемого числа при подаче (тоже симулятором) импульса на вход INTn - и всй работало! То есть после первой и единственной примерно 2-х секундной задержки при запуске программы дальше числа на ЖКИ выводились практически без всяких задержек (визуально).
Go to the top of the page
 
+Quote Post
Палыч
сообщение Jun 19 2008, 05:20
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Цитата(Tomade @ Jun 19 2008, 07:42) *
Насчёт прерывания по переполнению... Это не специально, это из-за неправильной настройки генератора начального кода CVAVR. Однако существенно ли это для заданных вопросов?
Существенно! Прерывание по переполнению (раз оно разрещено) будет периодически происходить, и контроллер будет переходить на соответствующий вектор, но, посколько, обработчика прерывания - нет, то, обычно, транслятор заполняет такие вектора командами перехода, которые приводят контроллер на адрес 0 ("мягкий" рестарт), и контроллер начнет всё заново! Правда, я считаю, что проявления такой бяки будут несколько отличаться от того, что Вы описали в своём вопросе. Лишнее разрешённое прерывание в любом случае необходимо обязательно убрать!
Go to the top of the page
 
+Quote Post



Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 23rd July 2025 - 08:32
Рейтинг@Mail.ru


Страница сгенерированна за 0.01407 секунд с 7
ELECTRONIX ©2004-2016