Category: Начинаем программировать

October 12, 2019 siteprovisor No comments exist

Программируем по настоящему. Загадочные регистры

Немного о том, что знают настоящие не “ардуино-зависимые” программисты о микроконтроллерах

И еще о том, зачем в школе мучают булевой алгеброй

Регистры процессора (микроконтроллера) — блок ячеек памяти, образующий сверхбыструю оперативную память внутри процессора. Есть регистры, используемые самим процессором для вычислений, например, при выборке из памяти очередной команды она помещается в регистр команд, а при выборке переменных они помещаются в регистры операндов.

Но в микроконтроллере есть ещё и другие регистры – хранящие настройки разных периферийных устройств. С ними в основном и имеет дело программист. Например регистр PORTB, хранящий состояние выводов (пинов), или регистр DDR, хранящий настройки, находятся ли выводы (пины) в состояние входа или выхода.

 

Регистр – это служебная очень быстрая память, например ячейки по 8, 16 бит, к которой можно обратиться по адресу. В МК работает программа, которая управляет его функционированием в соответствии с настройками, хранящимися в этих регистрах. (Например, частота ЦПУ, скорость обмена по СОМ порту – UART и проч.)

Конфигурировать регистры будем булевыми операциями – AND (&) и OR(|).

Ну, говорить о том, что представлять содержание регистра удобнее всего в шестнадцатеричной или двоичной системе не будем.

Также умолчим о возможности калькулятора (вид->инженерный) переводить числа между разными системами

.

Вот таблица истинности – правила двоичной арифметики, ну это уж почти всем известно

Ну раз регистр это просто ячейка, например, из 8 бит, то выставим в регистре с именем PORTB восемь единичек:

Или все нули:

А теперь, как выставить 1 в первом бите (обратите внимание на нумерацию битов в регистре – начинается 0), не изменив состояние других – при помощи OR (операция выполняется побитово):

Как же выставить 0 в любом бите – при помощи AND

Выставляем 0 в первом бите, не изменив состояние других – при помощи AND (операция выполняется побитово):

Вот целый курс по программированию МК AVR “правильно” таким hard core способом, который в общем то и используют настоящие разработчики (customelectronics.ru)

Зажжем диод на ардуино, заодно попрактикуемся с регистрами.

Заглянув в datasheet на микроконтроллер ATmega8 семейства AVR (да, да, именно такой и в вашей ардуине), в ужасе ничего не понимаешь понимаешь, что выходы соответствуют трем портам B, C, D – PB0-5, PC0-5, PD0-7. В Arduino эти названия переименованы в цифровые выводы D0-D13 и аналоговые входы A0-A5.

Выводы управляются регистрами PORTх и DDRх.

Например, вывод PB5 управляется пятым битом в регистрах PORTB (состояние вывода – 0 или 1, 0В или 5В) и DDRB (настройка вывода – на вход(0) и выход(1));

Итак, чтобы подать 1 (5В) на 13 пин ардуино (PB5):

Вот так просто

May 6, 2017 finereader No comments exist

Основные операторы – Switch, break, continue

Оператор switch

 

Конструкция switch…case управляет процессом выполнения программы, позволяя задавать альтернативный варианты, которые будут выполняться при разных условиях. Оператор switch сравнивает значение переменной (var) со значением, определенном в операторах case. Когда найден оператор case, значение которого равно значению переменной, выполняется программный код для этого case. Ключевое слово break является командой выхода из оператора case. Синтаксис следующий:

 

switch (var)

{

case 0:

// код для выполнения

break;

case 1:

// код для выполнения

break;

case 2:

// код для выполнения

break;

default:

// код для выполнения

break;

}

Оператор break

 

Оператор break используется для принудительного выхода из циклов do, for или while, не дожидаясь завершения цикла по условию. Он также используется для вы¬хода из оператора switch.

 

for (x = 0; x < 255; x ++)

{

sens = analogRead(sensorPin);

// выходим из цикла, если есть сигнал с датчика sens = 0;

if (sens == 0) {

break;

}

}

Оператор continue

 

Оператор continue пропускает оставшиеся операторы в текущем шаге цикла. Вместо них выполняется проверка условного выражения цикла, которая происходит при каждой следующей итерации.

 

for (x = 0; x < 255; x ++) {

// если истина то прыгаем сразу на следующую итерацию цикла

if (x > 40 && x < 120) {

continue;

}

}

May 6, 2017 finereader No comments exist

Основные операторы – Операторы цикла for while

Оператор for

Конструкция for используется для повторения блока операторов, заключенных в фигурные скобки. Счетчик приращений обычно используется для приращения и завершения цикла.

Заголовок цикла for состоит из трех частей:

for (initialization; condition; increment)

{операторы, выполняющиеся в цикле}

// Затемнение светодиода с использованием ШИМ-вывода

int PWMpin = 10;

void setup() {;}

void loop() {

for (int i=0; i <= 255; i++)

{

   analogWrite(PWMpin, i);

   delay(10);

}

 

Оператор while

Оператор while будет вычислять в цикле непрерывно и бесконечно до тех пор, пока выражение в круглых скобках не станет равно логическому ЛОЖНО. Синтаксис следующий:

while(выражение)

{

// операторы

}

int i=0;

while(i<100)

{

   // операторы

   i++;

}

May 6, 2017 finereader No comments exist

Основные Операторы – Оператор if…else

Оператор if используется в сочетании с операторами сравнения, он проверяет, достигнута ли истинность условия — например, превышает ли входное значение заданное число.

Формат оператора if следующий:


 

if (Variable > 50)

{

   // выполнять действия

}

 

Конструкция if..else позволяет сделать выбор “либо, либо”. Например:


 

if (pin==HIGH)

{

doFun1();

}

else

{

doFun2();

}

May 6, 2017 finereader No comments exist

Типы данных

Компилятор Arduino определяет следующие типы данных:

Массивы

(Массивы (arrays) — именованный набор однотипных переменных с доступом к отдельным элементам по их индексу)

int mylnts [ 6 ];

int myPins[ ] = { 2, 4, 8, 3, 6 };

int mySensVals[ 6 ]  = { 2, 4, -8, 3, 2 };

char message[ 6 ]    = “hello”;

 

Индексация массива начинается с 0.

Присваивание значения элементу массива: mySensVals[0] = 10;

Получение значения массива по индексу: x = mySensVals[4];

В примере символ звездочки после объявления типа “char*” указывает на то, что это массив указателей. Это необходимо для задания двумерного массива.

char* myStrings[] = { “string 1”, “string 2”, “string 3” };

for (int i = 0; i < 6; i++){

Serial.println( myStrings[ i ] );

}

Текстовая строка String:

char Str1[15];

char Str2[8]   = { ‘a’,’r’,’d’,’u’,’I’,’n’,’o’ };

char Str4[ ]    = “arduino”;