Пн авг 08, 2022 10:51:39
#include <inttypes.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>
#include "matrix.h"
//*** Пример работы с USART интерфейсом микроконтроллеров AVR ***
#define BAUDRATE 9600 // Скорость обмена данными
#define F_CPU 8000000UL // Рабочая частота контроллера
volatile unsigned char NUM = 0;
unsigned char count = 0;
unsigned char byte_receive = 0;
unsigned char i = 1;
// Функция задержки в мкс
void PAUSE_us(unsigned char time_us)
{
register unsigned char i;
for(i = 0; i < time_us; i++)
{
asm volatile(" PUSH R0 ");
asm volatile(" POP R0 ");
}
}
// Функция задержки в мс
void PAUSE_ms(unsigned int time_ms)
{
register unsigned int i;
for(i = 0; i < time_ms; i++)
{
PAUSE_us(250);
PAUSE_us(250);
PAUSE_us(250);
PAUSE_us(250);
}
}
#define RS PD2
#define EN PD3
// Функция передачи команды
void lcd_com(unsigned char p)
{
PORTA &= ~(1 << RS); // RS = 0 (запись команд)
PORTA |= (1 << EN); // EN = 1 (начало записи команды в LCD)
PORTA &= 0x0F;
PORTA |= (p & 0xF0); // старший нибл
PAUSE_us(100);
PORTA &= ~(1 << EN); // EN = 0 (конец записи команды в LCD)
PAUSE_us(100);
PORTA |= (1 << EN); // EN = 1 (начало записи команды в LCD)
PORTA &= 0x0F;
PORTA |= (p << 4); // младший нибл
PAUSE_us(100);
PORTA &= ~(1 << EN); // EN = 0 (конец записи команды в LCD)
PAUSE_us(100);
}
// Функция передачи данных
void lcd_data(unsigned char p)
{
PORTA |= (1 << RS)|(1 << EN); // RS = 1 (запись данных), EN - 1 (начало записи команды в LCD)
PORTA &= 0x0F;
PORTA |= (p & 0xF0); // старший нибл
PAUSE_us(100);
PORTA &= ~(1 << EN); // EN = 0 (конец записи команды в LCD)
PAUSE_us(100);
PORTA |= (1 << EN); // EN = 1 (начало записи команды в LCD)
PORTA &= 0x0F;
PORTA |= (p << 4); // младший нибл
PAUSE_us(100);
PORTA &= ~(1 << EN); // EN = 0 (конец записи команды в LCD)
PAUSE_us(100);
}
// Функция инициализации LCD
void lcd_init(void)
{
PAUSE_ms(50); // Ожидание готовности ЖК-модуля
// Конфигурирование четырехразрядного режима
PORTA |= (1 << PD5);
PORTA &= ~(1 << PD4);
// Активизация четырехразрядного режима
PORTA |= (1 << EN);
PORTA &= ~(1 << EN);
PAUSE_ms(5);
lcd_com(0x28); // шина 4 бит, LCD - 2 строки
lcd_com(0x08); // полное выключение дисплея
lcd_com(0x01); // очистка дисплея
PAUSE_us(100);
lcd_com(0x06); // сдвиг курсора вправо
lcd_com(0x0C); // включение дисплея, курсор не видим
}
// Функция вывода строки на LCD
void lcd_string(unsigned char command, char *string)
{
lcd_com(0x0C);
lcd_com(command);
while(*string != '\0')
{
lcd_data(*string);
string++;
}
}
// Функция передачи данных по USART
void uart_send(char data)
{
while(!( UCSRA & (1 << UDRE))); // Ожидаем когда очистится буфер передачи
UDR = data; // Помещаем данные в буфер, начинаем передачу
}
// Функция передачи строки по USART
void str_uart_send(char *string)
{
while(*string != '\0')
{
uart_send(*string);
string++;
}
}
// Функция приема данных по USART
int uart_receive(void)
{
while(!(UCSRA & (1 << RXC))); // Ожидаем, когда данные будут получены
return UDR; // Читаем данные из буфера и возвращаем их при выходе из подпрограммы
}
// Функция инициализации USART
void uart_init(void)
{
// Параметры соединения: 8 бит данные, 1 стоповый бит, нет контроля четности
// USART Приемник: Включен
// USART Передатчик: Включен
// USART Режим: Асинхронный
// USART Скорость обмена: 9600
UBRRL = (F_CPU/BAUDRATE/16-1); // Вычисляем скорость обмена данными
UBRRH = (F_CPU/BAUDRATE/16-1) >> 8;
UCSRB |= (1 << RXCIE)| // Разрешаем прерывание по завершению приема данных
(1 << RXEN)|(1 << TXEN); // Включаем приемник и передатчик
UCSRC |= (1 << URSEL)| // Для доступа к регистру UCSRC выставляем бит URSEL
(1 << UCSZ1)|(1 << UCSZ0); // Размер посылки в кадре 8 бит
}
// Прерывание по окончанию приема данных по USART
ISR(USART_RXC_vect)
{
NUM = UDR; // Принимаем символ по USART
byte_receive = 1;
uart_send(NUM); // Посылаем символ по USART
if(NUM == 'a') // Если принят символ "a", включаем светодиод
PORTB |= (1 << PB0);
if(NUM == 'b') // Если принят символ "b", выключаем светодиод
PORTB &= ~(1 << PB0);
}
// Главная функция
int main(void)
{
DDRC=0xFF;
DDRB=0xFF;
PORTC=0x00;
PORTB=0x00;
DDRA = 0b11111110;
PORTA = 0x00;
DDRD = 0b11111110;
PORTD = 0x00;
lcd_init(); // Инициализация LCD
uart_init(); // Инициализация USART
sei(); // Глобально разрешаем прерывания
str_uart_send("Initialization system\r\n"); // Передаем строку по USART
lcd_string(0x80, " AVR USART TEST "); // Выводим строку на LCD
PAUSE_ms(2500);
lcd_com(0x01); // Очищаем LCD
while(1)
{
//char k='2';
switch(NUM)
{
case '1':
TOT();
break;
case '2':
TIM();
break;
case '3':
DAY();
break;
case '4':
MTH();
break;
case '5':
RES();
break;
case '6':
COU();
break;
case '7':
c100();
break;
case '8':
c400();
break;
case '9':
c700();
break;
case '0':
BRK();
break;
case 'A':
LF();
break;
case 'B':
c200();
break;
case 'C':
c500();
break;
case 'D':
c800();
break;
case 'E':
c000();
break;
case 'F':
RF();
break;
case 'G':
c300();
break;
case 'I':
c600();
break;
case 'K':
c900();
break;
case 'L':
OK();
break;
//default: PORTA=0x00; PORTB=0x00;
}
if(byte_receive)
{
byte_receive = 0;
count++;
lcd_data(NUM); // Выводим символ на LCD
if(count > 16) // Если строка заполнена
{
count = 0;
lcd_com(0x01); // Очищаем LCD
}
}
}
}
#define ROW PORTC
#define COLUMN PORTB
char a[9]= {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x00};
char b[9]= {0xFE, 0xFD, 0xFB, 0xF7, 0xEF, 0xDF, 0xBF, 0x00};
char c100()
{
ROW=a[1];
COLUMN=b[1];
return 0;
}
char c200() //200
{
ROW=a[1];
COLUMN=b[2];
return 0;
}
char c300() //300
{
ROW=a[1];
COLUMN=b[3];
return 0;
}
char c400() //400
{
ROW=a[2];
COLUMN=b[1];
return 0;
}
char c500() //500
{
ROW=a[2];
COLUMN=b[2];
return 0;
}
char c600() //600
{
ROW=a[2];
COLUMN=b[3];
return 0;
}
char c700() //700
{
ROW=a[3];
COLUMN=b[1];
return 0;
}
char c800() //800
{
ROW=a[3];
COLUMN=b[2];
return 0;
}
char c900() //900
{
ROW=a[3];
COLUMN=b[3];
return 0;
}
char c000() //000
{
ROW=a[4];
COLUMN=b[2];
return 0;
}
char TOT() //TOT
{
ROW=a[0];
COLUMN=b[0];
return 0;
}
char TIM() //TIM
{
ROW=a[1];
COLUMN=b[0];
return 0;
}
char DAY() //TIM
{
ROW=a[2];
COLUMN=b[0];
return 0;
}
char MTH() //TIM
{
ROW=a[3];
COLUMN=b[0];
return 0;
}
char RES() //TIM
{
ROW=a[4];
COLUMN=b[0];
return 0;
}
char COU() //TIM
{
ROW=a[0];
COLUMN=b[1];
return 0;
}
char BRK() //TIM
{
ROW=a[4];
COLUMN=b[1];
return 0;
}
char LF() //TIM
{
ROW=a[0];
COLUMN=b[2];
return 0;
}
char RF() //TIM
{
ROW=a[0];
COLUMN=b[3];
return 0;
}
char OK() //TIM
{
ROW=a[4];
COLUMN=b[3];
return 0;
}
Пн авг 08, 2022 12:30:53