Микроконтроллеры, АЦП, память и т.д Темы касающиеся микроконтроллеров разных производителей, памяти, АЦП/ЦАП, периферийных модулей... |
01.07.2012, 04:35
|
|
Прохожий
Регистрация: 14.02.2011
Сообщений: 3
Сказал спасибо: 0
Сказали Спасибо 3 раз(а) в 3 сообщении(ях)
|
ATmega32 и инициализация LCD 16x2
Доброго времени суток . Прошу заранее прощения за возможный баян вопроса, но перепробовал что было возможно новичку и к сожалению самостоятельно решения не нашел.
Ситуация такова: есть ATmega32а, к нему подключаю по 4-битному интерфейсу LCD (Datasheet на него: http://www.compel.ru/datapdf/winstar...89c3f47515.pdf) таким образом:
PortA_pin0 = RS,
PortA_pin1 = R\W,
PortA_pin2 = E,
PortA_pin3 = -,
PortA_pin4 = DB4,
PortA_pin5 = DB5,
PortA_pin6 = DB6,
PortA_pin7 = DB7.
К XTAL2-1 подключен кварц на 12МГц с соответствующими конденсаторами.
А теперь сама суть. Пишу проект на CVAVR следующего содержания:
Код:
|
#include ‹mega32a.h›
#asm
.equ __lcd_port=0x1b ;PORTB
#endasm
#include ‹lcd.h›
void main(void)
{
PORTA=0x00;
DDRA=0xFF;
lcd_init(16);
lcd_puts("Hello, world!");
while (1)
{
};
} |
Полученный hex пихаю Протеусу - все отлично. Вшиваю в контроллер - ничего не отображает. Я своей наивной головой подумал, что CVAVR может меня неправильно понять с моим экраном, потому я решил под AVRStudio написать собственную инициализацию с записью следующего содержания:
Код:
|
#include ‹avr/io.h›
//порт к которому подключена шина данных ЖКД
#define PORT_DATA PORTA
#define PIN_DATA PINA
#define DDRX_DATA DDRA
//порт к которому подключены управляющие выводы
#define PORT_SIG PORTA
#define PIN_SIG PINA
#define DDRX_SIG DDRA
//номера выводов микроконтроллера
//к которым подключены управляющие выводы ЖКД
#define RS 0
#define RW 1
#define EN 2
//макросы для работы с битами
#define ClearBit(reg, bit) reg &= (~(0‹‹(bit)))
#define SetBit(reg, bit) reg |= (1‹‹(bit))
#define nop() {asm("nop");}
#define del_2 2
#define del_40 40
unsigned int i;
void delay_ms(unsigned int time) {
for (i=0;i‹time*1000;i++)
nop();
};
void delay_us(unsigned int time) {
for (i=0;i‹time*100;i++)
nop();
};
//функция записи команды
void LcdWriteCom(unsigned char data)
{
ClearBit(PORT_SIG, RS);
ClearBit(PORT_SIG, RW);
PORT_DATA = data;
SetBit(PORT_SIG, EN);
delay_us(del_2);
ClearBit(PORT_SIG, RW);
ClearBit(PORT_SIG, EN);
SetBit(PORT_SIG, RS);
}
//функция записи данных
void LcdWriteData(unsigned char data)
{
SetBit(PORT_SIG, RS);
ClearBit(PORT_SIG, RW);
PORT_DATA = data;
SetBit(PORT_SIG, EN);
delay_us(del_2);
ClearBit(PORT_SIG, RW);
ClearBit(PORT_SIG, EN);
SetBit(PORT_SIG, RS);
}
//функция инициализации
void InitLcd(void)
{
DDRX_DATA = 0xff;
PORT_DATA = 0x00;
DDRX_SIG = 0xff;
delay_ms(del_40);
PORT_SIG |= (0‹‹RW)|(0‹‹RS)|(1‹‹EN);
LcdWriteCom(0b00001100);
delay_us(del_40);
LcdWriteCom(0b00000100);
LcdWriteCom(0b00000001); // N F
delay_us(del_40);
LcdWriteCom(0b00000100);
LcdWriteCom(0b00000001); // N F
delay_us(del_40);
LcdWriteCom(0b00000000);
LcdWriteCom(0b00001111); // D C B
delay_us(del_40);
LcdWriteCom(0b00000000);
LcdWriteCom(0b00000110);
delay_us(del_40);
}
int main( void )
{
InitLcd();
LcdWriteData(0x00000100);
LcdWriteData(0x00000111);
while(1) {
nop();
}
return 0;
} |
Полученный hex не работает ни в Протеусе ни в железе. Собственно, вопрос очевиден: как заставить работать? Я уже грешным делом грешу на железо, конкретно на экран т.к. с контроллером работал и раньше, он свое отдает. Соединения проверял - все в норме, подключил как сказано, подсветка на экране в норме (хотя это и не показатель). Яркость символов регулируется переменным сопротивлением на 10к, выкручивание в обе стороны не помогает ни в какой позиции.
P.S. Fuse не менял.
Спасибо за советы
Последний раз редактировалось Lekarto; 01.07.2012 в 04:39.
Причина: забыл за FUSE-биты сказать
|
|
|
Сказали "Спасибо" Lekarto
|
|
|
01.07.2012, 07:55
|
|
Супер-модератор
Регистрация: 03.05.2007
Сообщений: 2,695
Сказал спасибо: 28
Сказали Спасибо 4,508 раз(а) в 956 сообщении(ях)
|
Re: ATmega32 и инициализация LCD 16x2
Ну, тут по соседству схожая тема, похоже, и траблы те-же. Ест...сно и советы пойдут те-же. Вам бы скооперироваться в одну ветку.
https://kazus.ru/forums/showthread.php?t=101607&page=2
Ну и в дополнение, ваш код инициализации LCD ни в какие ворота... Изначально после подачи питания LCD имеет 8-ми проводный интерфейс.
ЗЫ С утра не проснувшись намолол чепухи. Сначала надо трехнуть EN-ом на шине D4-D7 восьмибитный режим, т.е. 0x30 как минимум пару (а по даташиту классического HD44780 трижды), а затем полубайтами 0x28 - перевести в режим 4 бита, 2 строки 5х7, ну и далее все полубайтами. Но сути это не меняет, у Вас первая команда ... Ё-ооо-мобиль, вот теперь проснулся, да у вас двоичные байты в командах отзеркалены!!! Это на фига?
Последний раз редактировалось Halex07; 01.07.2012 в 13:05.
|
|
|
Сказали "Спасибо" Halex07
|
|
|
01.07.2012, 15:40
|
|
Почётный гражданин KAZUS.RU
Регистрация: 19.02.2008
Сообщений: 1,777
Сказал спасибо: 124
Сказали Спасибо 599 раз(а) в 416 сообщении(ях)
|
Re: ATmega32 и инициализация LCD 16x2
В CVAVR варианте ошибка назначения порта. В программе выбран порт В, а распаян порт А.
#asm
.equ __lcd_port=0x1b ;PORTB
#endasm
А во втором варианте, как верно подметил Halex07, используются младшие полубайты, а распаяны старшие.
|
|
|
Сказали "Спасибо" andries5
|
|
|
01.07.2012, 16:52
|
|
Прохожий
Регистрация: 14.02.2011
Сообщений: 3
Сказал спасибо: 0
Сказали Спасибо 3 раз(а) в 3 сообщении(ях)
|
ATmega32 и инициализация LCD 16x2
Сообщение от andries5
|
В программе выбран порт В, а распаян порт А.
|
Это в комменте опечатка, таньше был там на В заточен, я залез в CVAVR в файлик mega32a.h и там вычитал:
Код:
|
sfrb PINB=0x16;
sfrb DDRB=0x17;
sfrb PORTB=0x18;
sfrb PINA=0x19;
sfrb DDRA=0x1a;
sfrb PORTA=0x1b; |
Поэтому изменил на 0x1b, а коммент не подправил, каюсь, бывает такое.
Сообщение от Halex07
|
да у вас двоичные байты в командах отзеркалены!!! Это на фига?
|
В Datasheet, ссылку на который я оставил, в блок-схеме инициализации расписано именно так:
Сообщение от andries5
|
А во втором варианте, как верно подметил Halex07, используются младшие полубайты, а распаяны старшие.
|
Вот поправьте меня, если я не прав, скорее всего тут ошибаюсь очень сильно и путаюсь. Например я при таком подключении засылаю в порт А следующую команду:
Код:
|
LcdWriteCom(0b00000001); |
Вызывается процедура как было в коде указано:
Код:
|
//функция записи команды
void LcdWriteCom(unsigned char data)
{
ClearBit(PORT_SIG, RS);
ClearBit(PORT_SIG, RW);
PORT_DATA = data;
SetBit(PORT_SIG, EN);
delay_us(del_2);
ClearBit(PORT_SIG, RW);
ClearBit(PORT_SIG, EN);
SetBit(PORT_SIG, RS);
} |
В железе я получаю следующее:
1. Сброс RS на экране в 0 (PortA_pin0)
2. Сброс RW на экране в 0 (PortA_pin1)
3. Засылаем данные (0b00000001) на порт, получаем:
PortA_pin0=0
PortA_pin1=0
PortA_pin2=0
PortA_pin3=0
PortA_pin4=0
PortA_pin5=0
PortA_pin6=0
PortA_pin7=1
4. Выставляю EN = 1 (PortA_pin2=1)
5. Ждем
6. Осистка RW и EN (PortA_pin1=0 и PortA_pin2=0), устанавливаю RS=1 (PortA_pin0=1)
Я понимаю, что можно половину выкинуть и в 6-м пункте RW с такой логикой надо в 1 свести, но думаю это нектирично.
Сообщение от Halex07
|
Ну, тут по соседству схожая тема, похоже, и траблы те-же.
|
Я был там, нашел, что в CVAVR надо использовать alcd.h, прошил такой вариант - результат тот же, эта же прошивка на Протеусе не пошла. Вычитал там как протестировать LCD, завтра буду искать шнур на LPT и буду паять, тестировать. Но все же думаю проблема конкретно в инициализации.
Вопрос по ходу ибо он все равно возникнет: когда я дай Бог проинициализируюсь 4-битным режимом, то как мне засылать туда данные? Я так думаю, что придется писать процедуру приблизительно такого содержания: засылаем в нее код символа, в процедуре выставляется RS,RW в нули, старшие 4 бита ставим на шину, выставляем Е=1, ждем, затем выставляем младших 4 бита и аналогично Е=1, ждем, сбрасываем Е и конец. Так или я что-то напутал?
В очередной раз спасибо
|
|
|
Сказали "Спасибо" Lekarto
|
|
|
01.07.2012, 18:16
|
|
Почётный гражданин KAZUS.RU
Регистрация: 20.06.2006
Адрес: Украина, Запорожье
Сообщений: 7,981
Сказал спасибо: 0
Сказали Спасибо 4,939 раз(а) в 2,369 сообщении(ях)
|
Re: ATmega32 и инициализация LCD 16x2
Lekarto, зачем темы двоите - могли ж там спросить?
|
|
|
|
01.07.2012, 19:09
|
|
Прохожий
Регистрация: 14.02.2011
Сообщений: 3
Сказал спасибо: 0
Сказали Спасибо 3 раз(а) в 3 сообщении(ях)
|
Re: ATmega32 и инициализация LCD 16x2
Сообщение от jump
|
Lekarto, зачем темы двоите - могли ж там спросить?
|
То ли по собственной криворукости то ли по непониманию, но я подумал, что это разые проблемы т.к. у парня там квадраты выводит, а у меня вообще ноль, только подсветка работает и все тут. Впредь буду осмотрительней.
|
|
|
Сказали "Спасибо" Lekarto
|
|
|
Ваши права в разделе
|
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 07:34.
|
|