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

 
 
> Захват в 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
Tomade
сообщение Jun 19 2008, 06:24
Сообщение #5


Участник
*

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



Цитата(Палыч @ Jun 19 2008, 09:20) *
Существенно! Прерывание по переполнению... будет периодически происходить, и контроллер будет переходить на ... "мягкий" рестарт...

Так вот где собака зарыта!
Сделал по-вашему и... заработало! Так, пожалуй, с вашей помощью на старости лет программистом заделаюсь 08.gif . Спасибо!
Однако пойду дальше...
Go to the top of the page
 
+Quote Post
Палыч
сообщение Jun 19 2008, 06:59
Сообщение #6


Гуру
******

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



Хотелось бы Вас предупредить: не увлекайтесь симуляторами! В симуляторах удобно проверить кусок программы (исключительно логику работы или правильность вычислений), или, например, определить время выполнения участка программы. Но! На правильность симулирования периферии контроллера возлагать надежды не стоит. Несколько лет назад напрочь отказался от использования VMLAB из-за обнаруженных в нём глюков с симулированием периферии контроллера (таймеры, USART). Наверное, ошибки симулирования разработчиками устраняются, но, при этом скорее всего появляются новые. Настоятельно рекомендую обзавестись JTAG'ом, и, проверять всё с помощью JTAG + макетка + AVRStudio. Тут уж глюков симулятора, естественно, нет ни каких!
Go to the top of the page
 
+Quote Post



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

 


RSS Текстовая версия Сейчас: 21st July 2025 - 09:35
Рейтинг@Mail.ru


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