ОТЧЕТ По лабораторной работе № 1 Микропроцессорные системы в науке и производстве Ввод числа в стенд SDK 1.1 Преподаватель Студент ЦЕЛЬ РАБОТЫ Цель работы: Получить навыки программирования микроконтроллера семейства MCS-51 на языке C и работы в среде Keil μ Vision IDE; освоить методы формирования целых чисел и отображения их при вводе цифр с клавиатуры стенда SDK 1.1. 2 ЛИСТИНГ РАЗРАБОТАННОЙ ПРОГРАММЫ //подключение библиотеки #include "ADuC812.h" ----------------------//адреса регистров: ----------------------- //страница памяти, в которой #define MAXBASE 0x08 отображены регистры ПЛИС //адрес регистра для работы с #define SV 0x07 линейкой светодиодов #define KB 0x00 //адрес регистра клавиатуры #define DATA_IND 0x01 //адрес регистра шины данных ЖКИ //адрес регистра управления #define C_IND 0x06 ЖКИ ----------------------//запись байта в регистр ПЛИС: ----------------------void WriteMax (unsigned char xdata *RegNum, unsigned char Value) { //ввод переменной oldDPP со unsigned char oldDPP = DPP; значением DPP (регистр указатель страницы данных) DPP = MAXBASE; //присваивание регистру значения MAXBASE //передача значения Value в *RegNum = Value; ячейку с адресом RegNum DPP = oldDPP; //восстановление DPP } 3 регистра --------------------------------------------------------------------------------//чтение байта из регистра ПЛИС: --------------------------------------------------------------------------------unsigned char ReadMax (unsigned char xdata *RegNum) { //ввод переменной oldDPP со unsigned char oldDPP = DPP; значением DPP (регистр указатель страницы данных) //ввод переменной Value со unsigned char Value = 0; значением равным нулю DPP = MAXBASE; регистру //присваивание значения MAXBASE //передача Value = *RegNum; значения из ячейки с адресом RegNum в переменную Value //восстановление DPP = oldDPP; регистра DPP //возврат значения Value return Value; } --------------------------------------------------------------------------------//опрос клавиатуры и определение кода нажатой клавиши: --------------------------------------------------------------------------------unsigned char KB_GetKey(void) { //введение unsigned char ValueOut = 0x01; переменной ValueOut и приравнивание её к единице в теричной системе 4 шестнадца- unsigned char ValueIn; переменной //введение ValueIn unsigned char i; //введение переменной i unsigned char KeyCode = 0xFF; //введение переменной KeyCode и приравнивание её к числу FF шестнадца- теричной системы, обозначающей то, что ни одна из клавиш не нажата //проведение for (i=0; i<4; i++) следующих действий при переменной i, равной нулю, при увеличении данной переменной на единицу каждый цикл до момента, пока она не станет равной четырем { --------------------------------------------------------------------------------//запись инверсного значения переменной ValueOut в регистр KB: --------------------------------------------------------------------------------WriteMax (KB, ~ ValueOut); --------------------------------------------------------------------------------//запись в переменную ValueIn инверсного прочитанного значения регистра KB после побитового «И» с шестнадцатеричным числом F0: --------------------------------------------------------------------------------ValueIn = ~(ReadMax (KB)) & 0xf0; --------------------------------------------------------------------------------//если значение переменной if(ValueIn > 0) ValueIn больше нуля то 5 { --------------------------------------------------------------------------------//запись в переменную KeyCode значения переменной i при побитовом «ИЛИ» смещения на некоторые количества позиций вправо значения переменной ValueIn при побитовом «И» с некоторыми шестнадцатеричными числами: --------------------------------------------------------------------------------KeyCode = i | ((ValueIn & 0x20) >> 3)| ((ValueIn & 0x40) >> 3)| ((ValueIn & 0x80) >> 4)| ((ValueIn & 0x80) >> 5); --------------------------------------------------------------------------------//выход из цикла break; } ValueOut = ValueOut << 1; //приравнивание переменной ValueOut её же значения, смещенного на одну позицию влево } //возврат return KeyCode; значения переменной KeyCode } --------------------------------------------------------------------------------//перекодировка кода нажатой клавиши в соответствующий код символа ASCII: --------------------------------------------------------------------------------char KB_DecodeArray [] = "123A456B789C*0#D"; --------------------------------------------------------------------------------//возврат значения нажатой клавиши: --------------------------------------------------------------------------------6 unsigned char KB_Decode (unsigned char KeyCode) { return KB_DecodeArray[KeyCode]; //возврат значения декодирования } --------------------------------------------------------------------------------//обмен данными с ЖКИ для формирования строба E, фиксирующего информацию на шине данных: --------------------------------------------------------------------------------void LCD_Strobe (unsigned char RW, unsigned char RS) { unsigned int i; //введение переменной i unsigned char temp; //введение переменной temp temp = (RS << 2) | (RW << 1); //запись в переменную temp значений бита переключения типа информации, смещенного на две позиции влево, и значения бита переключения шины данных ЖКИ, смещенного на одну позицию влево, объединённых побитовым «ИЛИ» WriteMax (C_IND, temp | 1); //установка строба E WriteMax (C_IND, temp); //сброс строба for (i = 0; i < 300; i++) continue; //задержка на исполнения команды } --------------------------------------------------------------------------------//вывод любого символа на ЖКИ: 7 время --------------------------------------------------------------------------------void LCD_putChar(char Ch) { //запись выводимого символа WriteMax (DATA_IND, Ch); в регистр //обмен данными с ЖКИ, при LCD_Strobe (0, 1); RW = 0, RS = 1 (запись данных) } --------------------------------------------------------------------------------//позиционирование курсора на ЖКИ: --------------------------------------------------------------------------------void LCD_GotoXY (unsigned char x, bit y) { ---------------------------------------------------------------------------------//запись в регистр позиции курсора: ---------------------------------------------------------------------------------WriteMax (DATA_IND, 0x80 | (x + ((y) ? 0x40 : 0))); //обмен данными с ЖКИ, при LCD_Strobe (0, 0); RW = 0, RS = 0 (запись команды) } --------------------------------------------------------------------------------//очистка ЖКИ: --------------------------------------------------------------------------------void LCD_Clear (void) { //введение переменной i unsigned int i; 8 //запись единицы в регистр WriteMax (DATA_IND, 1); (команда очистки дисплея) //обмен данными с ЖКИ, при LCD_Strobe (0, 0); RW = 0, RS = 0 (запись команды) //задержка на время испол- for (i = 0; i < 200; i++); нения команды } --------------------------------------------------------------------------------//вывод строки, состоящей из букв латинского алфавита, цифр и различных знаков: --------------------------------------------------------------------------------void LCD_putString(char *s) { //цикл адреса строки для while (*s) вывода //вывод LCD_putChar (*s++); строки на ЖКИ, представляющий собой адрес строки, увеличенный на единицу } --------------------------------------------------------------------------------//вывод на ЖКИ целого числа: ---------------------------------------------------------------------------------void LCD_PutInt (unsigned int Value) { //введение переменной str с char str [6]; размером, равным шести 9 //введение char *buffer; переменной со значениями адреса буфера приемопередатчика //запись в переменную buffer buffer = &str; значений массива str //запись в переменную buffer buffer += 5; его же значений, увеличенных на пять //обнуление адреса буфера *buffer = 0; приемопередатчика //цикл, пока значение Value do не станет равным нулю { *--buffer = Value % 10 + '0'; //запись в переменную buffer 10% от значения переменной Value с добавленным нулем //запись в переменную Value Value /= 10; её же значения, деленного на 10 } while (Value != 0); //условия окончания цикла LCD_putString (buffer); //вывод на ЖКИ строки с массивом buffer } --------------------------------------------------------------------------------//вывод на ЖКИ "Введите число:": --------------------------------------------------------------------------------void KB_Vivod1(void) { 10 //введение переменной i unsigned int i; char str[16] = {'B', 0x0B3, 'e', 0x0E3, 0x0B8, 0x0BF, 'e', ' ', 0x0C0, 0x0B8, //введение переменной, раз- 'c', 0x0BB, 'o', ':', ' ', '\0'}; мер которой равен 16, и запись в неё "Введите число:" LCD_Clear (); //очистка ЖКИ LCD_GotoXY (1, 0); //позиционирование курсора на втором знаке первой строки //цикл, for (i = 0; str[i]; i++) при увеличении переменной i на единицу { //вывод на ЖКИ "Введите LCD_putChar (str[i]); число:" } } --------------------------------------------------------------------------------//вывод на ЖКИ "Ввод завершен": --------------------------------------------------------------------------------void KB_Vivod2(void) { //введение переменной i unsigned int i; char str[15] = {'B', 0x0B3, 'o', 0x0E3, ' ', 0x0B7, 'a', 0x0B3, 'e', 'p', 0x0C1, 'e', //введение переменной, раз- 0x0BD, ' ', '\0'}; мер которой равен 15, и запись в неё "Ввод завершен" //очистка ЖКИ LCD_Clear (); 11 //позиционирование курсора LCD_GotoXY (1, 0); на втором знаке первой строки //цикл, for (i = 0; str[i]; i++) при увеличении переменной i на единицу { //вывод LCD_putChar (str[i]); на ЖКИ "Ввод завершен" } } --------------------------------------------------------------------------------//вывод нажатых цифр на ЖКИ и сборка конечного числа: --------------------------------------------------------------------------------unsigned int KB_Chislo(void) { unsigned int i; //введение переменной i unsigned char b = 0xAA; //введение равной переменной значению b, AA в шестнадцатеричной системе //введение переменной Cod, unsigned char Cod = 0x00; равной нулю в шестнадцатеричной системе unsigned int Cod2; //введение переменной Cod2 Cod2 = 0; //приравнивание переменной Cod2 к нулю //бесконечный цикл while (1) { 12 //запись в переменную b кода b = KB_GetKey(); нажатой клавишы после опроса клавиатуры //запись WriteMax (SV, b); в регистр SV значения переменной b (кода нажатой клавиши в регистр управления светодиодной линейкой) //если if (b != 0x0FF) нажата какая-либо клавиша { Cod = KB_Decode (b); //запись в переменную Cod значения перекодированного кода нажатой клавиши) --------------------------------------------------------------------------------//если нажатая клавиша соответствует цифрам: --------------------------------------------------------------------------------if ((Cod >= 0x030) && (Cod <= 0x039) { --------------------------------------------------------------------------------//если набранная последовательность цифр не больше максимально разрешенного значения или при наборе последовательности цифр, равной 6553, следующая набранная цифра имеет значение менее шести: --------------------------------------------------------------------------------if ((Cod2 < 6553) || ((Cod2 == 6553) && (Cod < 0x036))) { --------------------------------------------------------------------------------//вывод на ЖКИ перекодированного значения нажатой клавиши: --------------------------------------------------------------------------------13 LCD_putChar (Cod); --------------------------------------------------------------------------------//добавление нажатой цифры в конец уже имеющегося набранного числа: --------------------------------------------------------------------------------Cod2 = Cod2 * 10 + Cod - 0x030; --------------------------------------------------------------------------------} } //если нажата клавиша «#» if (b == 0x00E) { //выход из цикла break; } for (i = 0; i < 10000; i++); //задержка на время исполнения команды } } //возврат return Cod2; значения переменной Cod2 } --------------------------------------------------------------------------------//вывод заданных фраз и чисел согласно алгоритму работы: --------------------------------------------------------------------------------void main(void) { unsigned int i; //введение переменной i unsigned int x; //введение переменной x while (1) //бесконечный цикл { 14 //вывод на ЖКИ «Введите KB_Vivod1(); число:» //задержка for (i = 0; i < 10000; i++); на время исполнения команды //позиционирование курсора LCD_GotoXY (1, 1); на втором знаке второй строки //приравнивание переменной x = KB_Chislo(); x к значению команды KB_Chislo (вывод на ЖКИ цифр в процессе набора и сборка конечного числа) //вывод KB_Vivod2(); на ЖКИ «Ввод завершен» //позиционирование курсора LCD_GotoXY (5, 1); на шестом знаке второй строки //вывод на ЖКИ собранного LCD_PutInt (x); окончательного числа //задержка for (i = 0; i < 60000; i++); на исполнения команды } } --------------------------------------------------------------------------------- 15 время ОПИСАНИЕ РАБОТЫ ПРОГРАММЫ Блок-схема работы программы представлена на рисунке 1. Рисунок 1 – Блок-схема разработанной программы Разработанная программа инициализирует ЖКИ и клавиатуру, после чего выводит на ЖКИ надпись «Введите число:», опрашивает клавиатуру, нажата ли какая-либо из клавиш, производит проверку, является ли нажатая клавиша числом, после чего выводит нажатое число на ЖКИ и повторяет цик л. Весь набор набранных цифр собирается в единое число, одновременно с че м проводится проверка этого числа на то, входит ли оно в разрешенный диапозон, результатом чего является невозможность ввода числа, выходящего за пределы разрешенной области чисел. Если же нажата была клавиша «#», то собирания результирующего числа прекращается, а на экран выводится надпись «Ввод завершен» вместе с получившимся натуральным числом, не выходящим за разрешенный диапазон, обусловленный разрядностью стенда. Через некоторый промежуток времени, достаточный для регистрации резуль16 тата, ЖКИ очищается и позволяет повторить процесс набора цифр нового числа. Результат работы программы, загруженной в стенд SDK 1.1, представлен на рисунках 2 – 4. Рисунок 2 – Начало работы программы Рисунок 3 – Ввод числа Рисунок 4 – Результат работы программы 17 ЗАКЛЮЧЕНИЕ Таким образом, результатом выполненной работы стала программа, блок схема работы которой представлена на рисунке 1, была проведена проверка программы на конкретных значениях, в ходе которой нарушений, которые могут привести к ошибке, не обнаружено. В дальнейшем данный код может использоваться для решения прикладных задач автоматизации или научных исследований. 18