LCD_16X02_Atmega8

Тут обсуждаем все что связано с микроконтроллерами.

Модератор: gurvinok

AVRIK
Сообщения: 119
Зарегистрирован: 24 сен 2016, 11:25

Re: LCD_16X02_Atmega8

Сообщение AVRIK » 10 апр 2017, 09:08

Здравствуйте Алексей! Надеемся что у вас все хорошо!

Аватара пользователя
gurvinok
Сообщения: 1473
Зарегистрирован: 02 мар 2013, 09:18
Откуда: Москва

Re: LCD_16X02_Atmega8

Сообщение gurvinok » 10 апр 2017, 21:18

Загруз по полной. Нет времени на видео. Пока я не снял видео, можно глянуть сюда. Правда там программа написана в CVAVR, но суть та же. Главное обратить внимание на функции библиотеки stdio.h
Если долго мучиться, может быть получится.

AVRIK
Сообщения: 119
Зарегистрирован: 24 сен 2016, 11:25

Re: LCD_16X02_Atmega8

Сообщение AVRIK » 10 апр 2017, 23:21

Спасибо! Удачи в делах! Мы вас ждем! 8-)

AVRIK
Сообщения: 119
Зарегистрирован: 24 сен 2016, 11:25

Re: LCD_16X02_Atmega8

Сообщение AVRIK » 12 апр 2017, 10:19

Алексей здравствуйте!
Учел ваши подсказки и обсуждения на форуме, пошарился в даташите, и сотворил код, красиво но не рабочая!!!
Если найдете пару минут для не путевого ученика, просмотрите пожалуйста и подскажите на чем прокололся. Задача простая, установить мигающий курсор в верхний левый угол. Модуль MT-16S2H

Код: Выделить всё

/*
 * _8_6.c
 * Atmega8
 * Created: 29.03.2017 5:54:22
 *  Author: SUN
 */ 

#define F_CPU 7372800UL
#include <avr/io.h>
#include <avr/delay.h>
#include <stdio.h>
#define D4  PINC2
#define D5  PINC3
#define D6  PINC4
#define D7  PINC5
#define RS  PINC0
#define E   PINC1
//-----------------------------------------------------
void lcd_set (void)
   {
	_delay_ms(20);                            // настройка 4-битного режима
	PORTC|=(1<<D5)|(1<<D4);
	_delay_us(40);
	PORTC|=(1<<D5)|(1<<D4);
	_delay_us(40);
	PORTC|=(1<<D5)|(1<<D4);
	_delay_us(40);

	
	PORTC|=(1<<D5);                          //  установка параметров       
	PORTC|=(1<<D7);                          //
		
	PORTC&=0x42;                             //выключаем дисплей /21-по условию начальной установки модуля, AO D4 D5 D6 D7= 00000 не ме-
	PORTC|=(1<<D7);                          // няе значения "Е" и reset,6-ой пин портаС. Итог=100010=42.  R/W на массе=запись в дисплей.
	
	PORTC&=0x42;                            //очищаем экран   
	PORTC|=(1<<D4);                         //
	
	PORTC&=0x42;                            //режим ввода данных
	PORTC|=(1<<D6)|(1<<D5);                 //
	}
int main(void)
{
	DDRC=0xFF;
	PORTC=0x00;
	lcd_set;
	
	//----------------------------------------------
	
	
	PORTC|=(1<<E);
	PORTC&=~((1<<D4)|(1<<D5)|(1<<D6)|(1<<D7));         //ввод старшего полубайта команды модуля 0b00001110; (displey ON/OFF control)
	_delay_us(40);                                                 
	PORTC&=~(1<<E);
	
	
	PORTC|=(1<<E);
	PORTC|=(1<<D7)|(1<<D6)|(1<<D5);                    //ввод младщего полубайта команды модуля               
	_delay_us(40);
	PORTC&=~(1<<E);
								
   while(1)
    {
        asm("nop");
    }
}
Вложения
Снимок.PNG

Аватара пользователя
gurvinok
Сообщения: 1473
Зарегистрирован: 02 мар 2013, 09:18
Откуда: Москва

Re: LCD_16X02_Atmega8

Сообщение gurvinok » 13 апр 2017, 14:53

Код: Выделить всё

#define D4  PINC2
#define D5  PINC3
#define D6  PINC4
#define D7  PINC5
#define RS  PINC0
#define E   PINC1
Может все таки PINC заменить на PORTC? PINC это чтение порта, а не запись в него.
Если долго мучиться, может быть получится.

AVRIK
Сообщения: 119
Зарегистрирован: 24 сен 2016, 11:25

Re: LCD_16X02_Atmega8

Сообщение AVRIK » 13 апр 2017, 19:20

Заменить не проблема, но в чем смысл!
По моему разумению, когда я пишу #define D4 PINC2 я подразумеваю что в случае записи в коде D4, компилятором она будет читаться как PINC2, и если я запишу PORTC|=(1<<D7), компилятор поймет что на пине 5 порта С, лог"1". Думаю ход мысли правильный, но понимает ли так мою запись компилятор? Как видно нет!
Ладно, делаю как вы сказали:
Прописываю #define D4 PORTC.2
и.т.д. все дефаины.
В результате выдает кучу ошибок с одним текстом: expected ')' before numeric constant
я счастлив!!!
Только вот не знаю как от этого счастья избавиться!

Аватара пользователя
gurvinok
Сообщения: 1473
Зарегистрирован: 02 мар 2013, 09:18
Откуда: Москва

Re: LCD_16X02_Atmega8

Сообщение gurvinok » 14 апр 2017, 22:45

Код: Выделить всё

// Активация LCD дисплея 16х2
#define DDR_RS	DDRС	// Порт на котором будет RS
#define DDR_E	 DDRС	// Порт на котором будет E
#define DDR_D4	DDRС	// Порт на котором будет D4
#define DDR_D5	DDRС	// Порт на котором будет D5
#define DDR_D6	DDRС	// Порт на котором будет D6
#define DDR_D7	DDRС	// Порт на котором будет D7

#define PORT_RS	PORTС	// Порт на котором будет RS
#define PORT_E	 PORTС	// Порт на котором будет E
#define PORT_D4	PORTС	// Порт на котором будет D4
#define PORT_D5	PORTС	// Порт на котором будет D5
#define PORT_D6	PORTС	// Порт на котором будет D6
#define PORT_D7	PORTС	// Порт на котором будет D7

#define RS		0		// Пин на котором будет RS
#define E		 1		// Пин на котором будет E
#define D4		2		// Пин на котором будет D4
#define D5		3		// Пин на котором будет D5
#define D6		4		// Пин на котором будет D6
#define D7		5		// Пин на котором будет D7


// Макросы
#define E_SET()		(PORT_E |= (1 << E))		// Е в единицу
#define E_RESET()	 (PORT_E &= ~(1 << E))	  // Е в ноль
#define RS_COM()	  (PORT_RS &= ~(1 << RS))	// Запись команды
#define RS_DATA()	 (PORT_RS |= (1 << RS))	 // Запись данных

// Подготовка данных для вывода на дисплей
void lcd_out(char data)
{
	if(data & 0x01)
	{
		PORT_D4 |= (1 << D4);
	}
	else
	{
		PORT_D4 &= ~(1 << D4);
	}
	if(data & 0x02)
	{
		PORT_D5 |= (1 << D5);
	}
	else
	{
		PORT_D5 &= ~(1 << D5);
	}
	if(data & 0x04)
	{
		PORT_D6 |= (1 << D6);
	}
	else
	{
		PORT_D6 &= ~(1 << D6);
	}
	if(data & 0x08)
	{
		PORT_D7 |= (1 << D7);
	}
	else
	{
		PORT_D7 &= ~(1 << D7);
	}
}

// Функция передачи команды дисплею
void lcd_com(char com)
{	
	RS_COM();				 // Вывод команды
	lcd_out(com);			// Вывод данных на пины
	E_SET();				  // Выставить Е
	E_RESET();				// Сбросить Е
	_delay_ms(4);			// После команды пауза
}

//-------------------------------------------------------------------------
//	Функция инициализации дисплея
//	Получаемые аргументы:
//			char lcd
//			0 - Позиция левый верхний угол, курсор не выводится
//			1 - Позиция левый верхний угол, курсор мигает в виде всего символа
//			2 - Позиция левый верхний угол, курсор в виде подчеркивания
//			3 - Позиция левый верхний угол, курсор в виде подчеркивания и мигает символ
//-------------------------------------------------------------------------
void lcd_init(char lcd)
{
	DDR_RS |= (1 << RS);
	DDR_E  |= (1 << E);
	DDR_D4 |= (1 << D4);
	DDR_D5 |= (1 << D5);
	DDR_D6 |= (1 << D6);
	DDR_D7 |= (1 << D7);
	
	switch (lcd)
	{
		case 0: lcd = 0x0C; break;
		case 1: lcd = 0x0D; break;
		case 2: lcd = 0x0E; break;
		case 3: lcd = 0x0F; break;
	}
	
	_delay_ms(20);		// После включения питания подождать 20 мс
	
	lcd_com(0x03);		// Переход в 4-х битный режим
	_delay_us(40);
	lcd_com(0x03);		// Переход в 4-х битный режим
	_delay_us(40);
	lcd_com(0x03);		// Переход в 4-х битный режим
	_delay_us(40);
	lcd_com(0x02);		// Переход в 4-х битный режим
	_delay_us(40);
	lcd_com(0x02);		// Установка параметров
	lcd_com(0x08);		// Установка параметров
	lcd_com(0x00);		// Выключаем дисплей
	lcd_com(0x08);		// Выключаем дисплей
	lcd_com(0x00);		// Очищаем дисплей
	lcd_com(0x01);		// Очищаем дисплей
	lcd_com(0x00);		// Устанавливаем режим ввода данных
	lcd_com(0x06);		// Устанавливаем режим ввода данных
	lcd_com(0x00);		// Включаем дисплей с выбранным курсором
	lcd_com(lcd);		// Включаем дисплей с выбранным курсором
}

//-------------------------------------------------------------------------
//	Функция отправки байта данных дисплею
//	Принимаемый аргумент:
//			char data
//			Передаваемый байт
//-------------------------------------------------------------------------
void lcd_char_out(char data)
{
	RS_DATA();							   // Передача данных
	
	lcd_out(data >> 4);					// Передача старших 4 бит
	E_SET();
	E_RESET();
	
	lcd_out(data & 0x0F);				// Передача младших 4 бит
	E_SET();
	E_RESET();
	
	_delay_ms(4);						  // После командная пауза
}

//-------------------------------------------------------------------------
//	Функция вывода строки
//	Принимаемый аргумент:
//			char *str
//			Указатель на массив заканчивающийся нулевым символом.
//-------------------------------------------------------------------------
void lcd_str_out(char *str)
{
	while((*str) != '\0')
	{
		lcd_char_out(*str);
		str++;
	}
}
Если долго мучиться, может быть получится.

Аватара пользователя
gurvinok
Сообщения: 1473
Зарегистрирован: 02 мар 2013, 09:18
Откуда: Москва

Re: LCD_16X02_Atmega8

Сообщение gurvinok » 23 апр 2017, 00:29

Вот кино про ЖК дисплей.
Если долго мучиться, может быть получится.

AVRIK
Сообщения: 119
Зарегистрирован: 24 сен 2016, 11:25

Re: LCD_16X02_Atmega8

Сообщение AVRIK » 25 апр 2017, 00:22

Алексей, спасибо за фильм!
Я пока разбираюсь с вашим предыдущим файлом по теме подключения дисплея, но фильм ваш конечно же очень актуален глядя на шаг вперед! От Оскара вам привет!
С уважением!

AVRIK
Сообщения: 119
Зарегистрирован: 24 сен 2016, 11:25

Re: LCD_16X02_Atmega8

Сообщение AVRIK » 25 апр 2017, 01:04

Вот еще о чем хотел у вас поинтересоваться!
Ваш код от 14 апреля по теме подготовки дисплея к работе в 4-битном режиме я переписал в студию 6.0. После компиляции выдала такую, не понятную мне ошибку.
Как это понять? В чем ошибка?
Ошибка PORT undeclared(first...) указывает в коде место где пишется PORT_4D|=(1<<D4); как я понимаю, #define DDR_D4 DDRC не воспринимается компилятором, о чем и свидетельствует "аварийный" цвет DDRC. Подскажите что исправлять?
Вложения
Снимок.PNG

Ответить