МиНОБРНАУКИ РОССИИ
Санкт-Петербургский государственный
электротехнический университет
«ЛЭТИ» им. В.И. Ульянова (Ленина)
Кафедра систем автоматического управления
Лабораторная работа №6
по дисциплине
«Микропроцессорный устройства систем управления»
Вариант 9
Студенты гр. 8491 |
|
Авраменок Д.А. Пшебельская Р.С. |
Преподаватель |
|
Голик С.Е. |
Санкт-Петербург
2020
Цель работы: Программирование процедур ввода информации через параллельный порт МК с использованием клавиатуры.
Задание: В данной работе используются навыки по программированию вывода информации на ЖКИ индикатор, полученные при выполнении предыдущей лабораторной работы. Во всех вариантах ввод исходных данных и вывод результата индицируются на ЖКИ индикаторе.
Вариант 9. Разработать калькулятор, выполняющий операцию возведения в степень целого десятичного числа. С клавиатуры вводится число, после нажатия клавиши * – показатель степени, а результат выводится после нажатия клавиши #.
Схема макета, относящегося к заданию:
Р
ис.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
Текст программы на языке С:
#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);
}
}
Вывод: Используя навыки, полученные при выполнении предыдущей лабораторной работы по программированию вывода информации на ЖКИ индикатор, был разработан калькулятор, выполняющий операцию возведения в степень целого десятичного числа. С клавиатуры вводится число, после нажатия клавиши * – показатель степени, а результат выводится после нажатия клавиши #. В ходе работы были использован циклы с предусловием циклы с постусловием и циклы с условием, а так же вспомогательные подпрограммы.