С чего начать программировать микроконтроллеры?

Здесь принимаются все самые невообразимые вопросы... Главное - не стесняйтесь. Поверьте, у нас поначалу вопросы были еще глупее :)
Аватара пользователя
SeregaT
Генеральный секретарь МЯУ
Сообщения: 18852
Зарегистрирован: Пн сен 03, 2007 18:24:27
Откуда: Россия. Омск.
Контактная информация:

Сообщение SeregaT »

Вот. Написал бета версию проги (пока задействован только один концевик и в некоторых местах совмещены каналы на поднимание и опускание)
#include <mega8>
#include <delay>

// Declare your global variables here

void main(void)
{
int i; // описание переменной "і" как целое число Int - (Integer)
PORTD=0x00; //Выставляем все выходы порта D на 0, то есть, выключаем весь порт D
DDRD=0xFF; //Делаем порт D, как выход, чтобы на выходах порта было напряжение 5В
while (1)
{
PORTD.0=1; // Упор поднимается
PORTD.1=1; // Подача доски
while (!PINB.1==0); // Доска на месте
PORTD.1=0; // Подача выключается
delay_ms(500); // Задержка 0,5 сек
PORTD.2=1; // Подача пилы
delay_ms(2000); // Задержка 2 сек
PORTD.2=0; // Пила выключается и опускается
delay_ms (500); // Задержка 0,5 сек
PORTD.3=1; // Направляющая поднимается
delay_ms (500); // Задержка
PORTD.4=1; // Толкатель толкает доску под пресс
delay_ms (500); // Задержка
PORTD.4=0; // Толкатель отходит
delay_ms (500); // Задержка
PORTD.5=1; // Боковой пресс прижимает доску к упору
delay_ms (300); // Задержка
PORTD.6=1; // Верхний пресс прижимает доску
delay_ms (500); // Задержка
PORTD.7=1; // Давит торцевой гидравлический пресс
delay_ms (2000); // Задержка
for (i = 0; i<15 ; i++) // Работает верхний пресс
{
PORTD.6=1; // Прижим
delay_ms(700); // Задержка
PORTD.6=0; // Ослабление
delay_ms(170); // Задержка
PORTD.6=1; // Прижим
}
PORTD.7=0; // Торцевой пресс отходит
delay_ms (2000); // Задержка
PORTD.6=0; // Верхний пресс поднимается
PORTD.5=0; // Боковой пресс отходит
delay_ms (500); // Задержка
PORTD.0=0; // Упор опускается
delay_ms (1000); // Задержка
PORTD.5=1; // Боковой пресс выталкивает доску в накопитель
delay_ms (500); // Задержка
PORTD.5=0; // Боковой пресс отходит
PORTD.3=0; // Направляющая опускается
delay_ms (500); // Задержка
// На начало программы
}
};

Прога работает нормально. В общем кое-что уже стало понятно :)
Последний раз редактировалось SeregaT Пт фев 13, 2009 15:26:03, всего редактировалось 2 раза.
Аватара пользователя
Барсик
Друг Кота
Сообщения: 3459
Зарегистрирован: Ср сен 27, 2006 16:18:57

Сообщение Барсик »

SeregaT писал(а):...Из ваших двух ответов собрал один и всё заработало...
....
while (!PINB.1==0);
....


Если Вы ждёте лог. 0, то while (!PINB.1==0); работать будет, но это лёгкий садизм. :) Лучше писать так:
while (PINB.1);
Будет работать точно так же. Или так:
while (PINB.1==1);
Аватара пользователя
SeregaT
Генеральный секретарь МЯУ
Сообщения: 18852
Зарегистрирован: Пн сен 03, 2007 18:24:27
Откуда: Россия. Омск.
Контактная информация:

Сообщение SeregaT »

А в чём разница? Я так понимаю, если написать 0, то сработает если я подам на вывод минус, а если поставить 1, то на вывод надо подавать плюс?
В данном случае мне минус даже удобнее (если бы применять в реале), а вот с индукционных и оптических датчиков надо чтобы был плюс.
Барсик писал(а):Будет работать точно так же.

Что-то не работала.
Или так:
while (PINB.1==1);

А так не пробовал...

P.S. Попробовал, не работает. Тогда прога без сигнала начинает работать дальше. А как тогда сделать чтобы срабатывало от +5В?

P.P.S. Оказывается забыл ! вначале убрать. Действительно, работает точно так-же, тоесть нужен логический 0. Разницу не уловил.
Аватара пользователя
Барсик
Друг Кота
Сообщения: 3459
Зарегистрирован: Ср сен 27, 2006 16:18:57

Сообщение Барсик »

SeregaT писал(а):...если я подам на вывод минус....

То микроконтроллер (или вход в лучшем случае) сгорит нафиг. На вход можно подавать только положительное напряжение величиной от нуля до напряжения питания. От величины этого напряжения зависит, что считает микроконтроллер при опросе состояния входа - 1 или 0. Если напряжение выше некоторого порога, то будет считана 1, если ниже некоторого порога, то будет считан 0.
Если у Вас на входе высокий уровень (лог. 1), а Вы ждёте, пока появится низкий (лог. 0), то следует писать while (PINB.1);
Если у Вас на входе низкий уровень (лог. 0), а Вы ждёте, пока появится высокий (лог. 1), то следует писать while (!PINB.1);

Кстати, на входе можно включить внутренний подтягивающий резистор, который подтягивает вход к +5 вольтам. Если вход висит в воздухе, то будет считываться лог. 1. А если вход посадить на землюто будет считываться лог. 0.
Последний раз редактировалось Барсик Пт фев 13, 2009 17:46:36, всего редактировалось 1 раз.
Аватара пользователя
SeregaT
Генеральный секретарь МЯУ
Сообщения: 18852
Зарегистрирован: Пн сен 03, 2007 18:24:27
Откуда: Россия. Омск.
Контактная информация:

Сообщение SeregaT »

Барсик писал(а):То микроконтроллер (или вход в лучшем случае) сгорит нафиг. На вход можно подавать только положительное напряжение величиной от нуля до напряжения питания.

Ну я имел ввиду минус питания, тоесть 0 (включал через резистор)
Если у Вас на входе высокий уровень (лог. 1), а Вы ждёте, пока появится низкий (лог. 0), то следует писать while (PINB.1);
Если у Вас на входе низкий уровень (лог. 0), а Вы ждёте, пока появится высокий (лог. 1), то следует писать while (!PINB.1);

А как сделать, чтобы на входе был низкий уровень? Когда я пишу (!PINB.1), то программа не ждёт сигнала а продолжает работу, как будто сигнал уже был.
Кстати, я заметил (когда делал для логического 0), что срабатывает даже от простого прикосновения к выходу (и даже от прикосновения пластмассовой линейкой). Вылечилось путём подачи +5 В через резистор 10 Ком. Но я вот что подумал, если +5 В не подавать, то наверное таким образом можно сделать сенсорные кнопки?
Аватара пользователя
Барсик
Друг Кота
Сообщения: 3459
Зарегистрирован: Ср сен 27, 2006 16:18:57

Сообщение Барсик »

SeregaT писал(а):...А как сделать, чтобы на входе был низкий уровень?

Посадить вход на землю через резистор.

SeregaT писал(а):...наверное таким образом можно сделать сенсорные кнопки?

Запросто. Только надо придумать такую цепь на входе, чтобы они срабатывали от пальца, но не срабатывали от помех... Что-нибудь вроде RC цепочки.
Аватара пользователя
SeregaT
Генеральный секретарь МЯУ
Сообщения: 18852
Зарегистрирован: Пн сен 03, 2007 18:24:27
Откуда: Россия. Омск.
Контактная информация:

Сообщение SeregaT »

Барсик писал(а):Посадить вход на землю через резистор.

А, тоесть посадить на землю через резистор, а в программе написать (!PINB.1), а в качестве сигнала подавать +5 В. Надо попробовать.
Аватара пользователя
SeregaT
Генеральный секретарь МЯУ
Сообщения: 18852
Зарегистрирован: Пн сен 03, 2007 18:24:27
Откуда: Россия. Омск.
Контактная информация:

Сообщение SeregaT »

А вот такой вопрос:
Как сделать так, чтобы при подаче сигнала на PINB.1, появлялся сигнал на PORTD.1. А при подаче сигнала на PINB.2, сигнал появлялся на PORTD.2?
Ну тоесть чтобы не последовательно все команды шли, а либо так, либо по другому (типа как ветвящийся алгоритм).
Аватара пользователя
Барсик
Друг Кота
Сообщения: 3459
Зарегистрирован: Ср сен 27, 2006 16:18:57

Сообщение Барсик »

Что-то я нифига не понял, что Вы хотите.
Чтобы при подаче сигнала на PINB.1, появлялся сигнал на PORTD.1 надо написать:
PORTD.1 = PINB.1;
PORTD.2 = PINB.2;
И засунуть это в цикл, чтобы опрос портов происходил достаточно часто. Если Ваша программа занята чем-то другим и не может опрашивать эти порты, то необходимо использовать прерывания. Организовать прерывания от таймера, чтобы они происходили с нужной Вам частотой, и засунуть в обработчик прерывания эти строчки.
А насчёт "ветвящегося алгоритма" я ваще ничего не понял, что Вы имели в виду.
Аватара пользователя
SeregaT
Генеральный секретарь МЯУ
Сообщения: 18852
Зарегистрирован: Пн сен 03, 2007 18:24:27
Откуда: Россия. Омск.
Контактная информация:

Сообщение SeregaT »

Барсик писал(а):Что-то я нифига не понял, что Вы хотите.

Ну вот например дошла программа до определённой строки и остановилась (ждёт сигнала). Если сигнал поступил на PINB.1, то выполняется одна чатсть программы, а если на PINB.2, то выполняется другая часть.
Аватара пользователя
SeregaT
Генеральный секретарь МЯУ
Сообщения: 18852
Зарегистрирован: Пн сен 03, 2007 18:24:27
Откуда: Россия. Омск.
Контактная информация:

Сообщение SeregaT »

И еще:
Имеется ЖК дисплей WINSTAR WHC0802B-NGA-CT. Инфы по этому дисплею я нифига не нашёл, знаю только что там 16 выводов и микросхема. Каким способом можно разобраться, как его подключать?
И что вообще с ним можно сделать для начала? (Ну чисто для обучения. На практике мне от этого дисплея пока ничего не надо).
Аватара пользователя
Барсик
Друг Кота
Сообщения: 3459
Зарегистрирован: Ср сен 27, 2006 16:18:57

Сообщение Барсик »

Так бы сразу и написали бы. Для подобных случаев существует конструкция "Switch". Странно, но в "Руководство полного идиота по программированию (на языке Си)" ссылку на которое http://lib.ru/CTOTOR/starterkit.txt давал Pippeytz, я ничего не нашёл про "Switch". Вероятно, полные идиоты эту конструкцию не используют... Но мы то с Вами другие...

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

unsigned char i = 0;
while (1)
    {
   
    // ждём лог. 1 на одном из входов
    do
    {
        i = PINB; // считали все выводы сразу
        i = i & 0b00001110; // маскируем разряды, которые нам не нужны
    }while(!i); // будет крутиться в цикле, пока на одном из выводов PINB.1, PINB.2, PINB.3
                // не появится лог. 1
   
    // Где-то вылезла лог. 1. Разбираемся где именно.
    // если на PINB.1, то значение i будет 2
    // если на PINB.2, то значение i будет 4
    // если на PINB.3, то значение i будет 8
    switch (i)
    {
    case 2:
        // значит лог. 1 появилась на PINB.1
        // выполняем соответствующий кусок кода
        PORTD.1 = 1; // например.
        // вообще, здесь можно писать много всего...   
    break; //всё, что надо сделали, вывалваемся из switch
    case 4:
        // значит лог. 1 появилась на PINB.2
        // выполняем соответствующий кусок кода
        PORTD.2 = 1; // например.
        // вообще, здесь можно писать много всего...   
    break; //всё, что надо сделали, вывалваемся из switch
    case 8:
        // значит лог. 1 появилась на PINB.3
        // выполняем соответствующий кусок кода
        PORTD.3 = 1; // например.
        // вообще, здесь можно писать много всего...   
    break; //всё, что надо сделали, вывалваемся из switch
       
    default:
        // а это тот самый случай, кода вылезло нечто не предусмотренное
        // предыдущими случаями. Можно ничего не писать, а можно написать
        // интрукции и на этот случай
    } // это конец оператора switch
   
    // дальше программа продолжается с этого места
    // .....................
   
    };
Аватара пользователя
SeregaT
Генеральный секретарь МЯУ
Сообщения: 18852
Зарегистрирован: Пн сен 03, 2007 18:24:27
Откуда: Россия. Омск.
Контактная информация:

Сообщение SeregaT »

Спасибо, вроде кое-что понял, попробую...
Аватара пользователя
SeregaT
Генеральный секретарь МЯУ
Сообщения: 18852
Зарегистрирован: Пн сен 03, 2007 18:24:27
Откуда: Россия. Омск.
Контактная информация:

Сообщение SeregaT »

Что-то не совсем понял про эту Switch. При компиляции ошибки не находит, но программа не работает. Тоесть не реагирует на сигналы. В чём причина, так и не понял. Даже попробовал не свою прогу, а вот то, что Вы написали (просто скопировал как есть), эффект тот-же.
Cat_CooLeR
Опытный кот
Сообщения: 732
Зарегистрирован: Пт авг 22, 2008 16:59:43
Контактная информация:

Сообщение Cat_CooLeR »

Со Switch все просто:

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

switch(i)
{
case 3: PORTB.1=1; break; //Если i равно 3 то выполняем PORTB.1=1, и вываливаем из скрипта
}
Это замена такому

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

if (i==3) {PORTB.1=1;}

Просто со свитч легче.
Аватара пользователя
SeregaT
Генеральный секретарь МЯУ
Сообщения: 18852
Зарегистрирован: Пн сен 03, 2007 18:24:27
Откуда: Россия. Омск.
Контактная информация:

Сообщение SeregaT »

А как определить, чему равно значение i ?
Аватара пользователя
ploop
Модератор
Сообщения: 13490
Зарегистрирован: Ср ноя 26, 2008 16:34:25
Откуда: Тамбовская обл.

Сообщение ploop »

Предлагаю тему в соответствующий раздел. Очень много интересного собралось, при том по-порядку.
Аватара пользователя
Барсик
Друг Кота
Сообщения: 3459
Зарегистрирован: Ср сен 27, 2006 16:18:57

Сообщение Барсик »

SeregaT писал(а):А как определить, чему равно значение i ?

Прикрутите к CodeVisionAVR отладчик AVR Studio. И получите массу удовольствий. В том числе можно будет смотреть значения переменных.
Как это сделать, написано в http://pro-radio.ru/controllers/6585/

SeregaT писал(а):...что Вы написали (просто скопировал как есть), эффект тот-же.

Ещё бы. Это же не вся программа, а фрагмент. И не просто фрагмент, а иллюстрация. Кстати, там нигде нет, чтобы выходы порта D устанавливались в ноль.
Аватара пользователя
SeregaT
Генеральный секретарь МЯУ
Сообщения: 18852
Зарегистрирован: Пн сен 03, 2007 18:24:27
Откуда: Россия. Омск.
Контактная информация:

Сообщение SeregaT »

Барсик писал(а):Кстати, там нигде нет, чтобы выходы порта D устанавливались в ноль.

У меня это было. Я же то-же скопировал как фрагмент к работающей программе, предварительно убрав всё лишнее :) Ну думаю разберусь.
Аватара пользователя
SeregaT
Генеральный секретарь МЯУ
Сообщения: 18852
Зарегистрирован: Пн сен 03, 2007 18:24:27
Откуда: Россия. Омск.
Контактная информация:

Сообщение SeregaT »

Гляньте пожалуйста, вот где тут может быть ошибка?
#include <mega8>
#include <delay>
// Declare your global variables here
unsigned char i = 0;
void main(void)
{
PORTD=0x00; //Выставляем все выходы порта D на 0, то есть, выключаем весь порт D
DDRD=0xFF; //Делаем порт D, как выход, чтобы на выходах порта было напряжение 5В
while (1)

// ждём лог. 1 на одном из входов
do
{
i = PINB; // считали все выводы сразу
i = i & 0b00001110; // маскируем разряды, которые нам не нужны
}while(!i); // будет крутиться в цикле, пока на одном из выводов PINB.1, PINB.2, PINB.3
// не появится лог. 1

switch(i)
{
case 2: PORTD.1=1; break; //Если i равно 2 то выполняем PORTB.1=1, и вываливаем из скрипта
}
};

Тоесть если я правильно понял, то при подаче сигнала на PINB.1 (да вообще-то пробовал все PIN), должен появиться сигнал на PORTD.1 (не появился).
В той программе, которую написал Барсик я смог добиться, чтобы загорались светодиоды (причём не совсем те, что я ожидал), и не всегда. Тоесть можно было тыкать в три порта повсякому и иногда светодиоды загорались.
Ответить

Вернуться в «Теория»