Материал: MPU_SU_Laboratornaya_rabota_6_Avramenok_Pshebelskaya

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

МиНОБРНАУКИ РОССИИ

Санкт-Петербургский государственный

электротехнический университет

«ЛЭТИ» им. В.И. Ульянова (Ленина)

Кафедра систем автоматического управления

Лабораторная работа №6

по дисциплине

«Микропроцессорный устройства систем управления»

Вариант 9

Студенты гр. 8491

Авраменок Д.А.

Пшебельская Р.С.

Преподаватель

Голик С.Е.

Санкт-Петербург

2020

Цель работы: Программирование процедур ввода информации через параллельный порт МК с использованием клавиатуры.

Задание: В данной работе используются навыки по программированию вывода информации на ЖКИ индикатор, полученные при выполнении предыдущей лабораторной работы. Во всех вариантах ввод исходных данных и вывод результата индицируются на ЖКИ индикаторе.

Вариант 9. Разработать калькулятор, выполняющий операцию возведения в степень целого десятичного числа. С клавиатуры вводится число, после нажатия клавиши * – показатель степени, а результат выводится после нажатия клавиши #.

  1. Схема макета, относящегося к заданию:

Р ис.1. Схема макета.

  1. Блок-схема алгоритма программы:

void LCD_cmd(unsigned char cmd):

Назначение: запись кодов в регистр команд ЖКИ.

Входные параметры: cmd - код команды.

//все разряды PORTC на выход

//выбор регистра команд RS=0

//разряды PORTD на выход

//записать команду в порт PORTC

//сформировать на выводе E строб 1-0

//передачи команды

void LCD_data(unsigned char data)

Назначение: Управление выводом на ЖКИ.

//все разряды PORTC на выход

//разряды PORTD на выход

//выбор регистра команд RS=1

//записать команду в порт PORTC

//сформировать на выводе E строб 1-0

//передачи команды

void LCD_init(void)

Назначение: инициализация ЖКИ

//все разряды PORTC на выход

// инкремент курсора, без сдвига экрана

//вывод трех команд 0x30

//разряды PORTD на выход

//включить ЖКИ и курсор, без мерцания

// очистить экран, курсор в начало

unsigned char Digit(unsigned int d, unsigned char m)

Ф ункция, которая проверяет количество разрядов числе.

//выделяем очередной разряд

//уменьшаем число в 10 раз

//выделен заданный разряд - прерываемся

unsigned char padScan(void)

Функция опроса клавиатуры.

// подача напряжения на строки

// задержка для выставления напряжения

//считывание напряжения на столбцах

//возврат цифры

//признак того, что ничего не нажато

Блок-схема основной программы:

1

2

3

//считывание первого операнда

//вывод * на ЖКИ

//считывание только *

//считывание числа. * и # игнорируются

//вывод операнда на ЖКИ

//считывание второго операнда

//считывание числа. * и # игнорируются

//вывод операнда на ЖКИ

//вывод = на ЖКИ

//считывание только #

1

2

3

//ожидание на нажатия любой кнопки для последующей очистки дисплея

//цикл вывода n-значного числа на экран ЖКИ

//очистка дисплея

//подсчет разрядов в результируемом числе

//цикл возведения в степень

//проверка первого операнда на 0

//если первый операнд равен 0, то выводим 0

  1. Текст программы на языке С:

#include <mega128.h>

#include <delay.h>

#define RS 7 // выбор регистра

#define E 6 // строб передачи

#define asterisk 10

#define sharp 11

#define noKey 12

void LCD_cmd(unsigned char cmd)

{

//[]--------------------------------------------------[]

//| Назначение: запись кодов в регистр команд ЖКИ |

//| Входные параметры: cmd - код команды |

//[]--------------------------------------------------[]

DDRC = 0xFF; // все разряды PORTC на выход

DDRD |= ((1<<E)|(1<<RS)); // разряды PORTD на выход

PORTD &= ~(1<<RS); // выбор регистра команд RS=0

PORTC = cmd; // записать команду в порт PORTC

PORTD |= (1<<E); // \ сформировать на

delay_us(5); // | выводе E строб 1-0

PORTD &= ~(1<<E); // / передачи команды

delay_ms(100); // задержка для завершения записи

}

//управление выводом на ЖКИ

void LCD_data(unsigned char data)

{

DDRC = 0xFF; // все разряды PORTC на выход

DDRD |= ((1<<E)|(1<<RS)); // разряды PORTD на выход

PORTD |= (1<<RS); // выбор регистра data RS=1

PORTC = data; // записать команду в порт PORTC

PORTD |= (1<<E); // \ сформировать на

delay_us(5); // | выводе E строб 1-0

PORTD &= ~(1<<E); // / передачи команды

delay_ms(1); // задержка для завершения записи

}

void LCD_init(void)

{

//[]--------------------------------------------------[]

//| Назначение: инициализация ЖКИ |

//[]--------------------------------------------------[]

DDRC = 0xFF; // все разряды PORTC на выход

DDRD |= ((1<<E)|(1<<RS)); // разряды PORTD на выход

delay_ms (100); // задержка для установления

// напряжения питания

LCD_cmd(0x30); // \ вывод

LCD_cmd(0x30); // | трех

LCD_cmd(0x30); // / команд 0x30

LCD_cmd(0x38); // 8 разр.шина, 2 строки, 5 ? 7 точек

LCD_cmd(0x0E); // включить ЖКИ и курсор, без мерцания

LCD_cmd(0x06); // инкремент курсора, без сдвига экрана

LCD_cmd(0x01); // очистить экран, курсор в начало

}

unsigned char Digit(unsigned int d, unsigned char m)

{

unsigned char i=5,a; //функция, которая проверяет количество разрядов числе

while(i)

{

a = d%10; //выделяем очередной разряд

if(i-- == m) break; //выделен заданный разряд - уходим

d /= 10;

} //уменьшаем число в 10 раз

return (a);

}

//функция опроса клавиатуры

unsigned char padScan(void)

{

unsigned char i,j,keys[4][3]={{1,2,3},{4,5,6},{7,8,9},{asterisk,0,sharp}};

for(i=0;i<=3;i++)

{

PORTF = 1<<i; // подача напряжения на строки

delay_ms(50); // задержка для выставления напряжения

for(j=0;j<=2;j++)

{

if((PINE & (1<<j)) !=0 ) //считывание напряжения на столбцах

{

delay_ms(25); // гашение дребезга

if((PINE & (1<<j)) !=0 )

{

return(keys[i][j]); //возврат цифры

}

}

}

}

return(noKey); //признак того, что ничего не нажато

}

void main(void)

{

//максимальное число, после нахождения его в степени может быть только в инервале(1;255) из-за выбранного типа данных

unsigned char res=1,op1=0,op2=0,i,j;

DDRF = 0x0F;

LCD_init();

while(1)

{

do

{

op1=padScan(); //считывание первого операнда

}while(op1 == noKey || op1 == sharp || op1 == asterisk); //считывание только числа. * и # игнорируются

LCD_data(op1 + '0'); //вывод операнда на ЖКИ

while(padScan() != asterisk); //считывание только *

LCD_data('*'); //вывод * на ЖКИ

do

{

op2=padScan(); //считывание второго операнда

}while(op2 == noKey || op2 == sharp || op2 == asterisk); //считывание только числа. * и # игнорируются

LCD_data(op2 + '0'); //вывод операнда на ЖКИ

while(padScan() != sharp); //считывание только #

LCD_data('='); //вывод = на ЖКИ

if(op1 != 0) //проверка первого операнда на 0

{

for(i=1;i<=op2;i++) //цикл возведения в степень

{

res = res*op1;

}

j=0;

while(Digit(res,++j) == 0); //подсчет разрядов в результируемом числе

for(i=j;i <= 5;i++) //цикл вывода n-значного числа на экран ЖКИ

{

LCD_data((Digit(res,i)) + '0');

}

}

else

{

if(op1 == 0) //если первый операнд равен 0, то выводим 0

LCD_data('0');

}

delay_ms(1000);

while(padScan() == noKey); //ожидание на нажатия любой кнопки для последующей очстки дисплея

LCD_cmd(1); //очистка дисплея

delay_ms(50);

}

}

Вывод: Используя навыки, полученные при выполнении предыдущей лабораторной работы по программированию вывода информации на ЖКИ индикатор, был разработан калькулятор, выполняющий операцию возведения в степень целого десятичного числа. С клавиатуры вводится число, после нажатия клавиши * – показатель степени, а результат выводится после нажатия клавиши #. В ходе работы были использован циклы с предусловием циклы с постусловием и циклы с условием, а так же вспомогательные подпрограммы.