Проект - тахометр +кнопка START-STOP engine

Обсуждаем контроллеры компании Atmel.
Ответить
Вымогатель припоя
Аватара пользователя
Сообщения: 508
Зарегистрирован: Пт фев 22, 2013 18:00:43
Откуда: Беларусь, г. Гомель

Сообщение rxstart1 »

volatile bit err;
она и есть глобальная сразу после #define идет))
Реклама
Вымогатель припоя
Аватара пользователя
Сообщения: 508
Зарегистрирован: Пт фев 22, 2013 18:00:43
Откуда: Беларусь, г. Гомель

Сообщение rxstart1 »

сейчас качаю протеус 7.8 sp2 может это поможет?
Реклама
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18785
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

rxstart1 писал(а):volatile bit err;
используйте только стандартные (и производные от них) для языка Си типы переменных - это поможет вам не только сию минуту, но и вообще по жизни программиста
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Вымогатель припоя
Аватара пользователя
Сообщения: 508
Зарегистрирован: Пт фев 22, 2013 18:00:43
Откуда: Беларусь, г. Гомель

Сообщение rxstart1 »

да кстати я не успел отписаться исправил на char и эта ошибка исчезла. Но все ровно спазибо буду иметь ввиду на будущее
Реклама
Эиком - электронные компоненты и радиодетали
Вымогатель припоя
Аватара пользователя
Сообщения: 508
Зарегистрирован: Пт фев 22, 2013 18:00:43
Откуда: Беларусь, г. Гомель

Сообщение rxstart1 »

Изменил код, подключил 8 битный таймер Timer0 настроил по переполнению (предделитель 1024, частота 8Мгц, 1сек.-30 переполнений) и ничего не работает таймер все время обнулен, не могу понять где это происходит? Нужна помощь. Проект прилагаю.
Вложения
mega16.rar
(263.1 КБ) 144 скачивания
Реклама
Вымогатель припоя
Аватара пользователя
Сообщения: 577
Зарегистрирован: Ср июн 19, 2013 08:10:48
Откуда: Москва, СПб, Липецк, Рязань

Сообщение ИС-пытатель »

А оно у Вас вообще компилируется? Или компилятор Вас матом кроет, а Вы не видите и не слышите?

Для начала

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

#define TAHO_M 8000000UL/tachValue // частота вращения коленвала об/мин
tachValue у Вас переменная. Нельзя в дефайне пользовать переменные. Только значения, которые заранее известны на этапе компиляции, т.е. константы. Либо TAHO_M делайте переменной.

К тому же заметил, что Вы везде пихаете надо и не надо volatile. Сильно плохо от этого не будет - но и хорошего мало. Volatile нужно ставить рядом с той переменной, которая помимо основной программы используется в прерывании. А уж внутри прерывания объявление переменной с модификатором volatile - вообще бессмысленно.
Далее, здесь

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

tachValue = TIM_GetTachBuf(); //берем "захваченное значение" и запоминаем
       if (tachValue>0) tachValue = 8000000UL/tachValue; //вычисляем значение частоты
Вы молодец, предусмотрели деление на ноль. Но не предусмотрели, что будет, если переменная равна нулю. У Вас получаются 0-я частота. (Хотя по логике должна быть бесконечно большая, т.е. максимальное значение)
Реклама
Вымогатель припоя
Аватара пользователя
Сообщения: 508
Зарегистрирован: Пт фев 22, 2013 18:00:43
Откуда: Беларусь, г. Гомель

Сообщение rxstart1 »

спасибо сейчас пересмотрю код, на счет объявления переменных volatile, я поначалу так и делал, но в дебаге било ошибку, что переменная вне блока памяти, поставил volatile и все ок.
Вы молодец, предусмотрели деление на ноль. Но не предусмотрели, что будет, если переменная равна нулю. У Вас получаются 0-я частота. (Хотя по логике должна быть бесконечно большая, т.е. максимальное значение)
если частота равна 0 то двигатель выключен, не понимаю суть вопроса?
Последний раз редактировалось rxstart1 Чт апр 24, 2014 19:38:28, всего редактировалось 1 раз.
Вымогатель припоя
Аватара пользователя
Сообщения: 508
Зарегистрирован: Пт фев 22, 2013 18:00:43
Откуда: Беларусь, г. Гомель

Сообщение rxstart1 »

исправил но ничего не изменилось так переменная tim2 и обнуляется (((
Вложения
mega16.rar
(261.88 КБ) 140 скачиваний
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18785
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

ИС-пытатель писал(а):Для начала

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

#define TAHO_M 8000000UL/tachValue // частота вращения коленвала об/мин
tachValue у Вас переменная. Нельзя в дефайне пользовать переменные. Только значения, которые заранее известны на этапе компиляции, т.е. константы.
для начала не надо давать неправильные советы.

в дефайне можно пользовать все, что заблагорассудится
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Вымогатель припоя
Аватара пользователя
Сообщения: 577
Зарегистрирован: Ср июн 19, 2013 08:10:48
Откуда: Москва, СПб, Липецк, Рязань

Сообщение ИС-пытатель »

Виноват! Мой косяк!)) Можно все писать. )

Вам необходимо поправить все конструкции вида

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

if (8000000UL/tachValue)
на предмет деления на 0. При делении на 0 программа зависнет. К тому же, эта конструкция всегда будет истинна при tachValue <= 8000000. Вообще мысленно прогоните свою программу при этой переменной равной 0. что у Вас получится?

Что у Вас сейчас конкретно не работает? или ничего не работает?
Вымогатель припоя
Аватара пользователя
Сообщения: 508
Зарегистрирован: Пт фев 22, 2013 18:00:43
Откуда: Беларусь, г. Гомель

Сообщение rxstart1 »

можно конечно поставить условие, но я думаю скорость работы упадет. Какие еще есть варианты?
Вымогатель припоя
Аватара пользователя
Сообщения: 577
Зарегистрирован: Ср июн 19, 2013 08:10:48
Откуда: Москва, СПб, Липецк, Рязань

Сообщение ИС-пытатель »

Скорость у Вас там бешеная. Вы этого даже не заметите. Что не работает? К тому же, 70% Ваших ресурсов отжирают операции деления.
Вымогатель припоя
Аватара пользователя
Сообщения: 508
Зарегистрирован: Пт фев 22, 2013 18:00:43
Откуда: Беларусь, г. Гомель

Сообщение rxstart1 »

Избавился вот так,

if (tachValue>12500) //двигатель не работает

но результата нет, какие еще варианты?
Вымогатель припоя
Аватара пользователя
Сообщения: 577
Зарегистрирован: Ср июн 19, 2013 08:10:48
Откуда: Москва, СПб, Липецк, Рязань

Сообщение ИС-пытатель »

:facepalm: ЧТО НЕ РАБОТАЕТ? Или вообще ничего не работает?
Вымогатель припоя
Аватара пользователя
Сообщения: 508
Зарегистрирован: Пт фев 22, 2013 18:00:43
Откуда: Беларусь, г. Гомель

Сообщение rxstart1 »

тахометр работает переключение без нажатой CLUTCH работает
не работает если нажато сцепление CLUTCH и долго удерживается кнопка START ENGINE или кратковременно тоже не пашет((
Вымогатель припоя
Аватара пользователя
Сообщения: 508
Зарегистрирован: Пт фев 22, 2013 18:00:43
Откуда: Беларусь, г. Гомель

Сообщение rxstart1 »

Под дебагом не заходит в этот кусок переменная tim2=0 ?????
if (tim2>SEC_2) // если кнопка удерживается более 2 сек.
{
if (!CLUTCH) // выжато сцепление
{
ACC=0; // выключить реле АСС <- точка останова
Вымогатель припоя
Аватара пользователя
Сообщения: 577
Зарегистрирован: Ср июн 19, 2013 08:10:48
Откуда: Москва, СПб, Липецк, Рязань

Сообщение ИС-пытатель »

rxstart1 писал(а):тахометр работает переключение без нажатой CLUTCH работает
Переключение чего?
rxstart1 писал(а):не работает если нажато сцепление CLUTCH и долго удерживается кнопка START ENGINE или кратковременно тоже не пашет((
Не работает что? Тахометр?
Вымогатель припоя
Аватара пользователя
Сообщения: 508
Зарегистрирован: Пт фев 22, 2013 18:00:43
Откуда: Беларусь, г. Гомель

Сообщение rxstart1 »

реле стартера и ign не включаются
Вымогатель припоя
Аватара пользователя
Сообщения: 577
Зарегистрирован: Ср июн 19, 2013 08:10:48
Откуда: Москва, СПб, Липецк, Рязань

Сообщение ИС-пытатель »

разбираю Вашу программу. Замечания по ходу буду добавлять.
1. Вы используете для захвата значений оборотов таймер1. Он 16-разрядный. Т.е. максимальное значение 65535. Делитель у Вас 1:1. На больших частотах вращения коленвала - это нормально. давайте посмотрим, что произойдет при запуске, когда обороты не достигли заданного значения. С какой частотой вращает стартер двигатель? вряд ли больше 100-150 оборотов в сек. + эти обороты возникают не мгновенно, а нарастают за какое-то время, хоть и малое. Итак, допустим у Вас 100 оборотов/ в мин. в какой-то период. получаем количество циклов, которое протикает через счетчик таймера = 8000000/100 = 80 000. т.к. макксимальное значение 65535, то пройдя по кругу в счетном регистре будет 14 464. Что соответствует 553 об/мин. а при 10 об/мин. в счетчике значение 4608, что соответствует 1736 об/мин.
Вам необходимо в более простом варианте увеличить коэффициент деления до 128 (с данной тактовой частотой - 256, либо в два раза уменьшаете тактовую частоту и коэффициент 64), либо вводите прерывание по переполнению этого таймера и дополнительно считаете переполнения.
2. Вот здесь правильнее будет написать

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

if (tachValue>0) 
        {   tachValue = 8000000UL/tachValue;                //вычисляем значение частоты
            k=(tachValue+50)/DIVIDER;                         // вычисляем количество диодов которые надо зажечь  
        }
Чтобы у Вас лишний раз не вычислялось k, когда нет значения с буфера захвата.
3.

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

if (tim2>SEC_2)                  // если кнопка удерживается более 2 сек.
            {
             if (!CLUTCH)                  // выжато сцепление
               {                       
                ACC=0;                     // выключить реле АСС
                IGN=!err;                  // в зависимости от исправности
                IGN_FAULT=err;             // включить реле IGN
                while (CHANGE_HEAT);       // подождать пока не погаснет лампа свечей накала
                STARTER=1;                 // крутить стартер пока нажата кнопка
                key=2;                     // положение ключа зажигания IGN
               }                           
            }
Здесь ACC=0; , но key=2;. И в результате при входе в void change_key_pos(char num) у Вас там ACC=1;, т.е. оно будет щелкать туда-сюда.
4. У каждого реле есть время включения. Неплохо было бы добавлять небольшие задержки в местах, где Вы включаете реле и ждете результата этого включения.
5. Случай отпускания кнопки.
if (8000000UL/tachValue) при tachValue = 0 программа зависнет. а при любом другом, возможном у Вас, будет всегда выполнятся. Проще просто проверять tachValue на превышение определенного значения.
6. if (tim2>SEC_05) // антидребезг
не правильно организован.
7.

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

while (tim2<SEC_10)        // крутить 10 сек. или пока не завелась
                        {
                         if (8000000UL/tachValue) STARTER=1;// крутить пока не завелась
                         else 
                          {
                           key=2;          // завелась
                           tim2=SEC_10+2;
                          } 
                         
                        }
                   if (8000000UL/tachValue)key=0;           //если не завелась потушить все приборы
даже при малых оборотах (которые, например обеспечивает сам стартер) у Вас выполнится условие и стартер тут же выключится. К тому же, он выключится нижней строкой в любом случае. Даже если завелась.
8. Кстати, я бы еще добавил какую-нить блокировку на случай, если коробка не в нейтральном положении.
Вымогатель припоя
Аватара пользователя
Сообщения: 508
Зарегистрирован: Пт фев 22, 2013 18:00:43
Откуда: Беларусь, г. Гомель

Сообщение rxstart1 »

1. По поводу таймера я не подумал. Покажите в программе как, пожалуйста. Я не разу не работал с таймером по захвату а этот кусок выдрал из программы частотомера, но она считала и выводила на дисплей и малые значения. Алгоритм подкупил тем, что считает усредненную частоту по моему 8 прерываний. Просто если как Вы говорите сделать по переполнению 8 битного счетчика тоже может возникнуть сл. ситуация: допустим угол между датчиком положения распредвала и меткой скажем 15 град. Возникает прерывание при прохождении через метку и считается частота и она в переводе на кол-во оборотов запросто может составить 1500-4500 об/мин. Т. е. стартер просто дернеться и все :( ((
2. почему антидребезг неправильно организован? Если кнопка удерживается менее полсекунды программа никуда не попадает и ничего не происходит или я неправ?
3. if (8000000UL/tachValue) STARTER=1;// крутить пока не завелась
Тут Вы правы на 100% забыл поставить :))
if (8000000UL/tachValue>640) STARTER=1;// крутить пока не завелась
4. По поводу блокировки если не на нейтрали, в этом нет смысла, ведь сцепление выжато))
5. По поводу паузы Вы абсолютно правы, я обязатьльно бы сделал ее потом, но для начала надо сделать более или менее рабочую версию, а потом можно и поизвращаться:))
6. Все таки, что не так с переменной tim2 ? Почему она обнуляется и почему программа не заходит в ручную и автоматическую заводку?
7. посмотрите последнюю версию, что я присылал я там переделал, вот например как выглядит отпускание, деления но 0 не будет
if (START_BUTTON && trig) // кнопка отпущена
{
if (tim2>SEC_05) // антидребезг
{
if (!CLUTCH) // выжато сцепление
{
//______________________
// АВТОЗАПУСК (Крутить стартер пока обороты не достигнут 640/об мин либо 10сек)
//______________________
if (tachValue>12500) //двигатель не работает
{
ACC=0; // выключить реле АСС
key=2; // положение ключа зажигания IGN
IGN=!err; // в зависимости от исправности
IGN_FAULT=err; // включить реле IGN
tim2=0; //сбросить счетчик T2
while (CHANGE_HEAT); // подождать пока не погаснет лампа свечей накала
while (tim2<SEC_10) // крутить 10 сек. или пока не завелась
{
if (tachValue>12500) STARTER=1;// крутить пока не завелась
else
{
key=2; // завелась
tim2=SEC_10+2;
}

}
if (!tachValue)key=0; //если не завелась потушить все приборы
}
}
change_key_pos(key);
}
trig=0; // сбросить триггер
}
Ответить

Вернуться в «AVR»