Материал: 1

Внимание! Если размещение файла нарушает Ваши авторские права, то обязательно сообщите нам

29

else TIMSK=0x80;

 

30

TCNT1=0;

//Обнулення таймера

31

flz=0;

//Скидання прапора затримки

32

#asm(“sei”);

//Дозволяємо переривання

33

if(kodz!=2) while(flz==0);

//

 

}

 

 

//

 

34void main (void)

{

35

unsigned char ii;

//Показник масива

36

unsigned char i;

//Допоміжний показник

37

unsigned int cods;

//Старий код

38

PORTB=0xE7;

// Порт В

39

DDRB=0x1B;

 

40

PORTD=0x7F;

//Порт D

41

DDRD=0x00;

 

42

TCCR1A=0x00;

//Таймер/Лічильник1

43

TCCR1B=0x03;

 

44

TCNT1=0;

 

//Обнулення розрахункового регістра

45

OCR1A=kzad;

//Ініціалізація регістра співпадіння

46

ACSR=0x80;

 

//Аналоговий компаратор

47

While (1)

 

 

 

{

 

 

48

m1:

while (incod() != klfree); //Очікування відпускання кнопок

49while (incod() == klfree); //Очікування натискукнопок

50ii=0;

51

m2:

#asm("cli");

//Забороняє переривання

52

 

wait(1);

//Затримка 1-го типу

53

 

codS=incod();

//Ввід коду і запис, як старого

54

 

bufr[ii++]=codS;

//Запис наступного коду в буфер

- 21 -

55

 

if (ii>=bsize) goto m4;

//Перевірка кінця буфера

56

 

wait(2),

//Затримка 2-го типу

57

m3:

if (incod() 1 = codS) goto m2; //Перевірка, чи не змінився стан

58

 

if (flz==0) goto m3;

//Перевірка прапора закінченнязатримки

59

m4:

if (PINB 7==1) goto comp,

//

 

//---------------------------------------

Запис коду в EEPROM

60

 

klen=ii;

//Запис довжини коду

61

 

for (i=0;i <ii; i++) bufe[i]=bufr[i]; //Запис всіх байтів коду

62

 

goto zamok;

//До процедури відкривання замка

 

//--------------------------------------

Перевірка коду

63

comp:

if (klen!=ii) goto ml;

//Перевірка довжини коду

64

 

for (i=0; i<ii; i++) if (bufe[i]! =bufr[i])goto m1; //Перевірка коду

 

//-------------------------------------

Відкривання замка

65

zamok:

PORTB.4=1;

//Відкриваємо замок

66

 

zamok: PORTB.4=1;

//Затримка 3-го типу

67

 

P0RTB.4=0;

//Закриваємо замок

 

}

 

 

 

}

 

 

І всі вони мають тип unsigned char. При цьому сам цей код представляє собою шістнадцятирозрядне двійкове число, старші вісім розрядів відповідають вміступортуРВ, а молодші вісім розрядіввміступортуPD(на все це накладена маска).

Починається наша програма, як і всі попередні, з приєднання бібліотечного файлу(рядок1). Далійде блокопису констант(рядки 2-5). Перша константа має

- 22 -

ім'я klfree і значення 0x77F. Це значення є код стану клавіатури при відпущених кнопках. Константа використовується в операціях порівняння.

Наступні три константи: kzad (код затримки), kandr (константа антидребезга) і bsize (розмір буфера для кодової комбінації) за своїм призначенням аналогічні відповідним константам в програмі на Асемблері. У них навіть значення однакові. Відмінність тільки в значенні константи bs iz e. У нашому випадку вона дорівнює не 60, а 30.

Чому буфер став удвічі коротше? Справа в тому, що на Асемблері буфер представляв собою набір елементів пам'яті розміром в один байт кожна. Будьяке нове значення записувалося в буфер у вигляді двох окремих байтів. У програмі на СІ в якості буфера буде використовуватися масив, що складається з шістнадцяткових елементів. Кожне значення-в такий буфер заноситься як один окремий елемент.

Урядках6-11 знаходиться блок описузмінних імасивів. Всізмінні імасиви мають свої аналоги в програмі на Ассемблері. У рядку 6 описується змінна flz, яка використовується як прапор затримки. У рядку 7 описується масив для оперативного зберігання ключової комбінації. Всізначення цього масивубудуть розміщені в ОЗУ (буфер в ОЗУ). довжина масиву вибирається рівноюbsize.

Урядках 9,10 описуються змінна і масив, які будуть зберігатися в

EEPROM. Мінлива klen призначена для зберігання довжини кодової комбінації. Масив bufе призначений для зберігання самої цієїкомбінації.

При описі змінних і масивів, які будуть розміщуватися в EEPROM, дана версія мови СІ вимагає обов'язкової їх ініціалізації. Тобто вимагає вказати значення всіх елементів по замовчуванням. Зазначені таким чином значення в процесі «прошивки »мікроконтролера потрапляють безпосередньо в EEPROM.

Якщо дотримуватися зазначені вище вимоги, то рядки 9 і10

нашої програми повинні виглядати приблизно так:

- 23 -

Якщо ми скористаємося цією редакцією команд опису, то ми отримаємо програму електронного кодового замка. У ній вже на стадії виготовлення закладена деяка початкова ключова кодова комбінація, яку, втім, в будь-який момент власник замку може змінити на нову.

Але мені цікаво показати, що можна зробити, якщо закладати код заздалегідь небажано. Якщо ви не стали вказувати початкові значення для змінної і масиву, то це не є критичною помилкою. Програма буде успішно відтрансльована,арезультуючийкодповністюпрацездатний. Єдиненезручність - повідомлення про некритичною помилку. По англійськи воно називається «Warning» (попередження). Воно буде виникати кожен раз при трансляції програми. Можна, звичайно, просто не звертати на нього увагу.

Однак більш правильно буде тимчасово відключити повідомлення про допомогу директиви #program і команди warn, як це і зроблено в програмі на лістингу 1.20. У рядку 8 висновок попереджень відключається, а в рядку 11 включається знову. відключати попередження назавжди не рекомендується. Так можна пропустити інші, важливіші попередження.

Далі в програмі починається опис всіх складових її функцій. Данапрограма складається з п'яти функцій:

дві функції обробки переривань ( рядки 12,13 та 14,15);

функція введення коду стану клавіатури ( рядки 16 - 26);

функція формування затримки ( рядки 27 - 33);

головна функція програми ( рядки 34 - 67).

Розгляд даної програми зручно починати з головної функції main.

Функція main починається з опису локальних змінних (Рядки 35-37). Крім змінної cods, призначеноїдля тимчасового зберігання коду стануклавіатури, тут визначаються ще дві допоміжні змінні з іменами i і ii. Після опису змінних

- 24 -

починаєтьсяблок ініціалізації(рядки 38-46). Блокініціалізаціїданоїпрограми по виконуваних діям повністю повторює аналогічний блок в програмі на Ассемблері.

Ці дії зводяться до налаштування портів введення-виведення, таймера і компаратора. Під час налаштування таймера не тільки вибирається його режим роботи, а й обнуляється значення рахункового регістра TCNT1(Рядок 44), а в регістр збіги OCR1A записується код затримки kzad (рядок 45).

Основний цикл програми займає рядки 47-67. Розглянемо докладніше його роботу. У рядку 48 знаходиться цикл очікування відпускання кнопок. Він являє собою порожній цикл whi1е. тіло циклу повністю відсутня. За непотрібністю не поставлені навіть фігурні дужки. Весь цикл складається лише з оператора while і вирази в круглих дужках, що визначає умову продовження цьогоциклу.

Умова проста: цикл виконується весь час, поки код стану клавіатури і константа klfree не рівні між собою. Значення константи одно коду стану клавіатури при всіх відпущених кнопках. Для визначення коду стану клавіатури використовується функція incod () .Функція incod () виконує ті ж самі деії, що однойменнапроцедуразпрограмина Асемблері. Тозчитуєстанпортів,накладає маски і застосовує при цьому Антидребезгова алгоритм. Детальніше роботу функції ми розглянемо в кінці цьогорозділу.

Як тільки всі кнопки будуть відпущені, цикл в рядку 48 завершується, і програма переходить до рядка 49, у якій знаходиться цикл очікування натискання будь-якої кнопки. Цей цикл дуже схожий на попередній. Змінилося тільки умова. Знак! = (Не дорівнює) змінений на == (дорівнює). Як тільки буде натиснута будь-яка кнопка, цикл в рядку 49 закінчується, і управління переходить до рядка 50.

Тепер пора починати цикл введення ключової кодової комбінації. Але спочатку потрібно обнулити змінну ii, яка буде використуватися як лічильник прийнятих кодів і покажчик поточного елемента в буфері bufr. Обнулення виконується в рядку 50. Цикл введення кодової комбінації займає рядки 51-

- 25 -

Источник: https://studfile.net/preview/14570694/