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

Круиз-контроль для Mitsubishi Grandis Atmega8535


Гость еще один max

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

// Timer/Counter 2 initialization
1--// Clock source: System Clock
2--// Clock value: 7,813 kHz
3--// Mode: Normal top=FFh
4--// OC2 output: Disconnected
5--ASSR=0x00;
6--TCCR2=0x07;
7--TCNT2=0x00;
8--OCR2=0x00;
...
// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x80;

В прерывании таймера_2 пишу

speed_temp=TCNT0;
9-- TCNT0=0x00;
10--TCNT2=0x00;

.......макс привет вот посмотри я инициализировал точно так же как и ты таймер 2 с твоими значениями....

.......смотрим на рисунки... проба_1 ( смотрел по графу...забил твои значения и настройки таймера он эти весчи очь точна рисует )....чтот я не вижу ни каких тамо задержек на 40 милисекунд....(в подпрограмме тупо меняю состояние выхода а значит каждый горб или впадина должна быть по твоим расчётам 40 мс....а тут гдето 33 милисекунд всего...маловато....протиф 40 то!!!(утеряно будет идет 1/3 импульсов а значит неправильная скорость будет высчитана) ... сам таймер тоесть его значение взято максимальное тоесть он считает от 0 все 256 цикла и этого мало что бы получить требуемую задержку...

... значит вижу два выхода...или понизить частоту работы всего мк и поставить 1 мегагерц и взять входную поменьше частоту таймера (например 3906 гц)...или при 8мгц отпараметрить 16-ти разрядный таймер тоесть таймер 1...)

......в подпрограмму он вываливается(в основной каторая whille(1) нету ничего пустая...вся программа висит в обработчике прерывания таймера 2 и она работает значит у тя она тоже работает...но толька не так как ты от неё хотел..промежуток задержки не точно 40 мс а на 7 мс меньше ).....и возможно поэтому, када ты ему заказывал считать по задержке програмной(а их кодевизард правильно расчитывает согласно указаной ему в гинераторе начальн кода от опорной частоты мк)...то тамо у тя всё выглядит весьма корректно

...теперь дальше....что бы корректно считывать значения из регистра таймера 0...

1)--нужно запретить ему после входа в подпрограмму таймера 2 ...продолжать принимать данные со счётного входа....у тя этого нету...ты прост берешь и кидаешь из него в переменую.!!! это не есть хорошо...

2)--- остановить таймер 2 и занова залить туда значение для счёта......

3)---считать данные с счетного регистра т0...

4)---разрешить приём данных на счётный вход ....

5)---запустить таймер 2 на счёт....

6) выход из подпрогораммы обработчика прерывания т2....

...примерно так ....

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

....вернёмся к рисункам... 1 снята по настройке таймера 2 с твоими параметрами.....по графику видна время изменения из одного состояния в тругой занимает 33 мс(в подпроге тупо менял состояние бита)

....рисунок проба_40_мс----я настроил по другому.....частоту взял опорную мк 1 мГЦ таймера 2 --3906 Гц....по графику осцила видно один горб составляет практически 40 мс...значение для таймера 2 --100...

..как уже говарил на верху ..если опорная для проца нужна все таки 8 мгц...то есть два решения этой проблемы

..первое использовать 16-ти разрядный таймер.... второе, если использовать 8 разрядный таймер то нужно в подпроге сделать цикл чтоб он считал 2 раза.....по 20 мс...и после этого только начинал делать то что нужно согласно поставленой задачи....

дополню ....если в подпрогу забить счет внешних импульсов и ты уверен что у тя на вход счётный нормальный сигнал прилетает понятный мк то должно все работать согласно настройкам таймеров....+ если на саму платку в машине нет наводок и по питанию всё идет гут а то непонятных багов мона наловить...

post-5671-1277752749_thumb.jpg

post-5671-1277752781_thumb.jpg

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

  • Ответов 218
  • Создана
  • Последний ответ

Топ авторов темы

Топ авторов темы

Изображения в теме

Женя, привет! все понял, спасибо в который раз. Кварц напаян 8 МГц, пока менять не буду. Таймер_1 не задействован, значит буду на нем основывать прерывания для подсчета скорости.

Посмотри, что я нашел, как раз для таких как я:

_https://eugenemcu.ru/publ/5-1-0-49#auto_t1,t3

Внизу статьи есть прямо калькулятор для расчета младшего и старшего бита для регистра сравнения. У меня вот что получается:

1. Введите тактовую частоту микроконтроллера, МГц: 8

2. Выберите коэффициент предделителя таймера: 256

Биты SCn предделителя:

SCn0=0;

SCn1=0;

SCn2=1;

Частота тактирования таймера: 31250 Гц

Результаты:

Длительность одного такта таймера, мкс ... 32

Число тактов для заданного интервала ..... 1250

Число тактов (округлённо до целого) ....... 1250 (MSB=4, LSB=226)

Реальный интервал для принятого числа тактов, мс ....... 40

Погрешность в результате округления, % ....... 0

 

Посмотри, пожалуйста инициализацию таймера_1:

Здесь был спойлер.
#include <mega8535.h>



// Timer 1 output compare A interrupt service routine

interrupt [TIM1_COMPA] void timer1_compa_isr(void)

{

// Place your code here



}


// Declare your global variables here



void main(void)

{

// Declare your local variables here



// Input/Output Ports initialization

// Port A initialization

// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In 

// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T 

PORTA=0x00;

DDRA=0x00;



// Port B initialization

// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In 

// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T 

PORTB=0x00;

DDRB=0x00;



// Port C initialization

// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In 

// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T 

PORTC=0x00;

DDRC=0x00;



// Port D initialization

// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In 

// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T 

PORTD=0x00;

DDRD=0x00;



// Timer/Counter 0 initialization

// Clock source: System Clock

// Clock value: Timer 0 Stopped

// Mode: Normal top=FFh

// OC0 output: Disconnected

TCCR0=0x00;

TCNT0=0x00;

OCR0=0x00;



// Timer/Counter 1 initialization

// Clock source: System Clock

// Clock value: 31,250 kHz

// Mode: Normal top=FFFFh

// OC1A output: Discon.

// OC1B output: Discon.

// Noise Canceler: Off

// Input Capture on Falling Edge

// Timer 1 Overflow Interrupt: Off

// Input Capture Interrupt: Off

// Compare A Match Interrupt: On

// Compare B Match Interrupt: Off

TCCR1A=0x00;

TCCR1B=0x04;

TCNT1H=0x00;

TCNT1L=0x00;

ICR1H=0x00;

ICR1L=0x00;

OCR1AH=0x04;

OCR1AL=0xE2;

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=0x10;



// Analog Comparator initialization

// Analog Comparator: Off

// Analog Comparator Input Capture by Timer/Counter 1: Off

ACSR=0x80;

SFIOR=0x00;



// Global enable interrupts

#asm("sei")



while (1)

  {

  // Place your code here



  };

}

 

Можешь загнать в свой протеус и посмотреть прерывание правильно посчитано?

Касаемо помехозащищенности. Пока багов не наблюдается. Тем более я при прошивке поставил фьюз какой-то, который отвечает за устойчивость работы, но увеличивает энергопотребление. Импульсы с датчика скорости идут от 0 до 4,96 вольт, располагаться все это дело будет между стальными щитами защиты основного ЭБУ, там 2-х миллиметровая сталюка снизу и сверху, прикрученная к корпусу. Так что коробочка без надобности. Даже в тестовом варианте прототип не сбоит, а он выведен метровым кабелем в перчаточный ящик. Нормально!

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

Привет Макс...прежде загнал твои данные в калькулятор всё получилось правильно...потом все это безобразие проверил в проте....значит как и заказывали получилось ровна 40 мс....скрины прилагаю...(atmega_t16_1 - 2).....по графику все четка так же по осцилу ..замечаний нету...

....как говарил я выше....выкладываю другой вариант(proba_40_ms_t8)....получения 40 мс...при использовании 8разрядного таймера....листинг тамо виден и несложен....какой выбирать?......на ваше усмотрение...ва втором случае просто..в первом ну очень просто ...+во втором сэкономили 16-ти разрядн таймер....да забыл сказать....всё было обкатано при опорной частоте кварца 8 мГЦ...

post-5671-1277811559_thumb.jpg

post-5671-1277811575_thumb.jpg

post-5671-1277811640_thumb.jpg

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

Привет Макс...прежде загнал твои данные в калькулятор всё получилось правильно...потом все это безобразие проверил в проте....значит как и заказывали получилось ровна 40 мс....скрины прилагаю...(atmega_t16_1 - 2).....по графику все четка так же по осцилу ..замечаний нету...

....как говарил я выше....выкладываю другой вариант(proba_40_ms_t8)....получения 40 мс...при использовании 8разрядного таймера....листинг тамо виден и несложен....какой выбирать?......на ваше усмотрение...ва втором случае просто..в первом ну очень просто ...+во втором сэкономили 16-ти разрядн таймер....да забыл сказать....всё было обкатано при опорной частоте кварца 8 мГЦ...

Листинг там только обработчик виден, и все. Ты флаг где увеличиваешь? Я так и не нашел.

Но не суть, смысл понятен. Ошибок у меня было две: в Протеусе ставил чип по умолчанию, а там стоит 1 МГц, потому у меня и не срасталась задержка с расчетом, и второе - не сбрасывал счетный таймер в ноль, потому он у меня по первому циклу считал правильно, а потом нес пургу.

Переделал прошивку, по дороге домой проверю.

Я почему просил тебя в Протеусе проверить - систему переставлял на прошлой неделе, у меня ж винда в виртуалке, я для чистоты снес все, а виртуалку еще не поставил. Благо на работе есть где еще поставить. Поставил, тоже проверил. Все-таки великое дело этот Протеус, без него сколько бы раз пришлось прошивать и бегать туда-сюда. Я и так намотался, пока константы устанавливал, уже бензина нажег наверное на стоимость фирменного круиза :smile:

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

....Погрешность в результате округления, % ....... 0.....

...не макс...такая погрешность наврятли будет...толька если в теории.. .кода таймер сработает по прерыванию...ну допустим как у тя в результате сравнения....он выставляет флаг этого прерывания...далее процер выполняет команду на каторой было обнаружено прерывание...(а это 1-3 такта ну взависимости от команды)...апосля в стеке откладывает адрес куда прыгнуть чтоб вернуться назад в место откуда была вызвана подпрога после обработки прерыв..

...далее идет команда перехода (типа "JMP-адрес"-прыжок в место иде лежит прога обработчик подпроги.) из адреса вектора прерывания...это ещё 2 такта мк...после перехода в попрограмму пару команд обслуживания наподобие той что занова кидает в счетный регистр занова значение(ну тут вазможны уже варианты)..и толька патом обробатыаем что то...как видишь...со времени срабатывания проходит некоторое время....

 

Добавлено после раздумий:

макс тамо все живет в подпрограмме прерывания...смотри сразу ..чуть выше обработчика подпрограммы таймера я инициализировал пременную с именем ..int flag_ready=2;....и в самой подпрограмме после реинициализации таймера ниже делаю этой переменой декремент..а после её опрашиваю на предмет нуля...если нуль то сработало 2 прерывания таймера .каждый каторый по 20 мс...ну и выполняю что мне надо:

if (flag_ready==0)

{

flag_ready=2;---обязательный фрагмент... реинициализировать флаг ...на следующее срабатывание...

if (PORTD.0==0)---а это уже действия на результат что таймер посчитал паложенное кол во раз...

PORTD.0=1;

else PORTD.0=0;

};

...если не ноль просто выхожу из подпрораммы....

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

Понял, я бы совсем по другому делал. Чувствуется веяние ассемблера :smile:

Погрешность "0" имелась в виду изначальные условия работы таймера_1. Конечно в реалии все это фикция, и из-за пропущенных тактов процессора, и от того какой фронт считает счетчик, и от скорости. Там же не идеальный меандр. Но я думаю, что если отслеживать будет не 40, а 41 км/ч, никто не обидится...

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

Понял, я бы совсем по другому делал. Чувствуется веяние ассемблера :smile:

Погрешность "0" имелась в виду изначальные условия работы таймера_1. Конечно в реалии все это фикция, и из-за пропущенных тактов процессора, и от того какой фронт считает счетчик, и от скорости. Там же не идеальный меандр. Но я думаю, что если отслеживать будет не 40, а 41 км/ч, никто не обидится...

 

Э, Макс!

Я за твоей работай наблюдаю! :smile: Делай ХОРОШО, ПЛОХО само получится.

Шучу.

Привет! :smile:

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

а как бы ты сделал по другому делись мыслями....учится всем полезно..))...

...с асмом думал расрощался.... ан нет....недавичи попросили программу сваять на хитрые часы....на ат89с2051...хароший процер.....на нем лучше и легче считать такты и подгонять подпограммы критичные ко времени....у него нету 2ух уровневого дешифратора команд...поэтому более прогнозируемо подсчитать это все....

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

2alexander59 Йес, сэр! Будем стараться, сэр!

Привет, дружище! Наблюдай, потом (зимой), может заинтересуешься контроллерами, помогу чем могу с точки зрения "новичок - новичку"

2nightmare Жень, да просто цикл "for=0 to 2" сделал бы. Я ж с точки зрения простого понимания всегда рассуждаю, а оригинальные решения меня сначала ошарашивают, потом восхищают, а потом я ими пользуюсь как само собой разумеющееся

2hippo64 Вот видимо с неправильной организацией прерываний все и не работает... Не работает на практике то, что мы днем наваяли! Вот даже не знаю, весь код приводить или фрагменты только... Наверное пока только фрагменты.

Инициализация таймеров:

// Timer/Counter 0 initialization
// Clock source: T0 pin Falling Edge
// Mode: Normal top=FFh
// OC0 output: Disconnected
TCCR0=0x06;
TCNT0=0x00;
OCR0=0x00;


// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 31,250 kHz
// Mode: Normal top=FFFFh
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer 1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: On
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x04;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x04;
OCR1AL=0xE2;
OCR1BH=0x00;
OCR1BL=0x00;

 

Таймер прерываний:

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

 

Сам обработчик прерывания:

// Timer 1 output compare A interrupt service routine
interrupt [TIM1_COMPA] void timer1_compa_isr(void)
{
// Place your code here
  speed_cur=TCNT0;
  TCNT0=0x00;
  TCNT1H=0x00;
  TCNT1L=0x00;
}

 

Переменная speed_cur содержит текущую скорость далее используется в программе.

Так вот, в Протеусе все работает! Конструкция выдает совершенно такой же результат, как и в теле программы:

//Speed
  TCNT0=0x00;
  delay_ms(timer);
  speed_cur=TCNT0;

 

А в натуре вот хрен! Что там происходит внутри, фиг знает, но режим 2 не включается, а это значит что в той переменной совсем не показания скорости...

Володя, что ты там говорил про правильный вход и выход в/из прерывания? Я почему-то думал что препроцессор должен все правильно сам расставить, сохранить стек, регистры и все потом восстановить...

Самое непонятно, что Протеус дает добро :smile:

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

Йа лошаро...

Не хватало самую малость, глобально разрешить прерывания:

// Global enable interrupts
#asm("sei")

А все от того,что проект создавал не заново, а рихтовал предыдущие, и вставлял по частям код... Построчное сравнение помогло.

Все заработало :smile:

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

привет макс.... вот када чегот и не работает приводи весь код полносью частями не есть хорошо...ак смотреть та..чего тамо к чему..

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

..столька багов уйдет само сабой прост....

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

Гость
Эта тема закрыта для публикации ответов.
  • Последние посетители   0 пользователей онлайн

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

×
×
  • Создать...