Страница 3 из 4
Re: SiLabs c8051f314 + LCD DV16210 Не могу понять в чем проб
Добавлено: Ср июл 27, 2011 12:01:04
Vlad0o
Здравствуйте.
я тут еще на силабовском форуме описал свою проблему. Там тоже никому не понравилась фишка с задержкой. Мне тоже там посоветовали избавиться от "delay loop". и переходить на таймеры. но с таймерами сложнее) сейчас разбираюсь с таймерами.
Немного порыскав там, я перешел сюда
http://8052.com/ . там таких как я, у которых ниче с ЛСД не получается много)
Попытался проверить вот эту часть :
lcdport = (c & 0x0F) << 4; //send lower-order nibble
LCD_EN = 1;
Delay(50);//200microseconds
LCD_EN = 0; //LCD_STROBE;
lcdport = (c & 0xF0); // send higher-order nibble
LCD_EN = 1;
Delay(50);//200microseconds
LCD_EN = 0;//LCD_STROBE;
на свободном порту P2 там где у меня реле стоят. в итоге пришел к выводу что все таки в этой части получается так что Delay() напрочь убивают. задержку я чуть ли не на пару секунд ставил, а светодиоды релюшек на доли секунды вспыхивали и гасли, причем все одновременно.
2 Left Radio: спасибо, я обязательно проверю это вариант задержки
ЗЫ Это дело я не забросил. результат непременно напишу

Re: SiLabs c8051f314 + LCD DV16210 Не могу понять в чем проб
Добавлено: Ср июл 27, 2011 12:31:58
МитяРа
Хороший ресурс, сам с него много чего скачивал..
Щас посмотрел, там в разделе Си-программ, есть такая библиотечка:
http://8052.com/codelib/codelib/files/F ... S12887.zip может оттуда выдернуть нужные кусочки..
Re: SiLabs c8051f314 + LCD DV16210 Не могу понять в чем проб
Добавлено: Ср июл 27, 2011 16:59:25
Left Radio
Код который я привел 100% работает, сам похожим пользуюсь при инициализации TFT LCD с контроллером HX8352, как на C8051F326 так и на STM32 везде работает как надо

И если задержка предполагается использоваться только для инициализации ЖК то таймеры Вам и нафиг не нужны. Ну а если уж так хочется по таймеру пожалуйста:
Код: Выделить всё
#define SYSCLK 12000000 // System clock frequency in Hz
void T0_Wait_ms (unsigned char ms)
{
TCON &= ~0x30; // Stop Timer0; Clear TF0
TMOD &= ~0x0f; // 16-bit free run mode
TMOD |= 0x01;
CKCON |= 0x04; // Timer0 counts SYSCLKs
while (ms) {
TR0 = 0; // Stop Timer0
TH0 = -(SYSCLK/1000 >> 8); // Overflow in 1ms
TL0 = -(SYSCLK/1000);
TF0 = 0; // Clear overflow indicator
TR0 = 1; // Start Timer0
while (!TF0); // Wait for overflow
ms--; // Update ms counter
}
TR0 = 0; // Stop Timer0
}
Только нужно учитывать что тут миллисекунды рассчитаны для 12МГц МК, для 24МГц нужно поменять строчку #define SYSCLK 12000000 на #define SYSCLK 24000000.
Re: SiLabs c8051f314 + LCD DV16210 Не могу понять в чем проб
Добавлено: Вс июл 31, 2011 17:26:18
Vlad0o
Спасибо, МитяРа, за ссылку на архив, я думал что все ЛСД примеры оттуда скачал

Оказывается, что нет.
Сижу до сих пор разбираюсь, пока немного другим делом был занят.
Самое интересное что я нашел это то что в примерах инициализации ЛСД для силабс есть одна особенность порт по которому отправляются команды каждый раз отдельно переводится в режим Push Pull при каждой отправки данных (эт на основе
http://www.silabs.ru/pubs/G14.pdf этой главы и того самого архива с 8052.сом), а я всего один раз переводил в этот режим при инициализации портов. возможно фишка в этом и есть.
Re: SiLabs c8051f314 + LCD DV16210 Не могу понять в чем проб
Добавлено: Пн авг 01, 2011 09:31:38
МитяРа
Vlad0o писал(а):есть одна особенность порт по которому отправляются команды каждый раз отдельно переводится в режим Push Pull при каждой отправки данных
Могу предположить, что это делается для опроса бита готовности индикатора..
Если его не опрашивать, то и порт каждый раз перенастраивать нет необходимости..
С этим индикатором есть два основных метода работы:
а) После посыла команды, опрашиваем бит готовности индикатора, а потом посылаем следующую команду.. или
б) После посыла команды формируем соответствующую задержку по длительности большую, чем время обработки команды индикатором..
Ты с задержками-то разобрался, у тя они правильно формируются, как те пушистый
Left Radio подсказал..
Re: SiLabs c8051f314 + LCD DV16210 Не могу понять в чем проб
Добавлено: Пн авг 01, 2011 15:27:14
Vlad0o
#include "C8051F310.h"
sbit LED1 = P2^1;
volatile unsigned long tmpCnt;
void OSCILLATOR_Init (void);
void PORT_Init (void);
void Delay (unsigned int); //задержка в миллисекундах
void main (void)
{
PCA0MD &= ~0x40;// WDTE = 0 (clear watchdog timer
// enable)
PORT_Init(); // Initialize Port I/O
OSCILLATOR_Init (); // Initialize Oscillator
while(1)
{
LED1 = 1;
Delay(1000);
LED1 = 0;
Delay(1000);
}
}
void OSCILLATOR_Init (void)
{
OSCICN |= 0x03; // Configure internal oscillator for
// its maximum frequency (24.5 Mhz)
}
void PORT_Init (void)
{
P2MDOUT = 0x02;
XBR1 = 0x40; // Enable crossbar and enable
}
void Delay (unsigned int ms)
{
for (tmpCnt = 0; tmpCnt<(ms * 25000); tmpCnt++);
}
что то не очень получается пока с задержкой. я менял значения выделенные жирным. 1000мс при 25000, не очень похоже на одну секунду, слишком уж быстро. Потом решил увеличить задержку до 10с (10 000 подставить). Ситуация изменилась визуально (и на слух) частота уменьшилась, но это не то что 10 с, это даже не 1 секунда.
Менял 25000 на 2500... еще быстрей мигал.
Еще сейчас ради эксперимента поставил 2500 и менял Delay(
1000); добавляя каждый раз 0. дошел до Delay(10000000); но все равно слишком быстро работает, мигает раз в 800мс, даже не за секунду.

непонятно
Re: SiLabs c8051f314 + LCD DV16210 Не могу понять в чем проб
Добавлено: Вс авг 07, 2011 22:45:32
Ser60
Я думаю, что проблема в выражении (ms * 25000): переменная ms типа int (2 байта) и пихать 10000000 в процедуру Delay не имеет смысла. Более того, 25000 тоже int, каково и их произведение. Т.е. произведение не может превысить 64000 (примерно) . После вычисления произведения оно расширяется до 32-битного типа long для сравнения с tmpCnt но результат расширения тоже не более 64000. Короче, попробуйте написать задержку так:
void Delay (unsigned int ms)
{
unsigned long tmp;
tmp = ((unsigned long) ms) * 25000;
for (tmpCnt = 0; tmpCnt<tmp; tmpCnt++);
}
Re: SiLabs c8051f314 + LCD DV16210 Не могу понять в чем проб
Добавлено: Вт авг 09, 2011 00:43:59
Left Radio
Vlad0o писал(а):Самое интересное что я нашел это то что в примерах инициализации ЛСД для силабс есть одна особенность порт по которому отправляются команды каждый раз отдельно переводится в режим Push Pull при каждой отправки данных
Тут дело в чем, при передаче данных в ЖК Вы переводите порт в Push Pull и отправляете данные( к примеру последние от правленые данные были 0010), затем перенастраиваете порт как вход и читаете данные с ЖК, но хотя порт и настроен на вход он все равно имеет состояние 0010 и данные будут приниматься только по 3-му биту(там где 1) остальные биты будут притянуты к земле последними посланными данными в порт и в независимости чего там передает ЖК там все равно будут нули. То есть хотя порт и настроен на вход он все равно работает как выход с открытым коллектором.
Правильное управление портом, к примеру используем старшие 4 бита P1, запись в порт:
P1MDOUT = F0; //настройка на выход
lcd_write(DATA);
lcd_write(DATA);
Чтение:
P1MDOUT = 0; //Настраиваем на вход
P1 = 0xFF; //Сбрасываем биты порта одновременно включая подтягивающие рез.
LCD_DATA = P1; //Непосредственно чтение
Vlad0o писал(а):дошел до Delay(10000000);
Ето бестолку, так как тип передаваемого значения
unsigned int то передача в функцию значения большего 65535 не имеет смысла. Я не знаю каким компилятором Вы пользуетесь возможно ваш компилятор преобразует результат вычисления (ms * 25000) в
unsigned int а не в
unsigned long так как переменная ms имеет тип
unsigned int, попробуйте так:
void Delay (unsigned int ms)
{
for (tmpCnt = 0; tmpCnt<((unsigned long)ms * 25000); tmpCnt++);
}
Re: SiLabs c8051f314 + LCD DV16210 Не могу понять в чем проб
Добавлено: Пн авг 29, 2011 13:14:24
Vlad0o
Спасибо. буду учиться/делать дальше.
МитяРа, если еще интересно, то это ссылка на схему.
http://goo.gl/54HlU
Re: SiLabs c8051f314 + LCD DV16210 Не могу понять в чем проб
Добавлено: Пн авг 29, 2011 13:58:12
МитяРа
Vlad0o писал(а):то это ссылка на схему.
С работы не открывается - посмотрю из дома..
Удачи.. заходи, если что..
Re: SiLabs c8051f314 + LCD DV16210 Не могу понять в чем проб
Добавлено: Пн авг 29, 2011 14:20:59
Vlad0o
Re: SiLabs c8051f314 + LCD DV16210 Не могу понять в чем проб
Добавлено: Пн авг 29, 2011 14:22:20
МитяРа
Vlad0o писал(а):должна открыться
Дома посмотрю, с работы сайты типа радикала и прочих - закрыты..
Re: SiLabs c8051f314 + LCD DV16210 Не могу понять в чем проб
Добавлено: Вс окт 16, 2011 14:19:40
Vlad0o
Здравствуйте! Я вернулся
Не смейтесь. Но инициализацию LCD проходит! УРА!!! Это я просто опять нашел свободное время и осциллограф. С осциллографом все становится намного проще особенно для тех кто не сильно разбирается в Си.
Вот как я прохожу инициализацию:
Код: Выделить всё
DB4 = 0;
DB5 = 0;
DB6 = 0;
DB7 = 0;
LCD_RS = 0; // write control bytes
LCD_E = 0;
Delay(2000);// power on delay 15ms
Delay(2000);
//Set LCD_DATA to high nibble of Software Reset
//LCD_DATA = (LCD_DATA&0x0F)|0x30;
DB4 = 1;
DB5 = 1;
DB6 = 0;
DB7 = 0;
LCD_E = 1;
Delay(50); // Wait 5ms
LCD_E = 0; // Write data to display
Delay(1000); // Wait 5ms
LCD_E = 1;
Delay(50);
LCD_E = 0; // Write data to display again (SW Reset)
Delay(1000); // Wait 5ms
LCD_E = 1;
Delay(50);
LCD_E = 0; // Write data to display again (SW Reset)
Delay(1000); // Wait 5ms
// Set LCD_DATA to high nibble of Function Set (4Bit)
//LCD_DATA = (LCD_DATA&0x0F)|0x20;
DB4 = 0;
DB5 = 1;
DB6 = 0;
DB7 = 0;
LCD_E = 1;
Delay(50);
LCD_E = 0; // Write data to display
Delay(500);
// Set LCD_DATA to high nibble of Function Set : 4 bit, 2 lines, 5*7 font
//LCD_DATA = (LCD_DATA&0x0F)|0x20;
DB4 = 0;
DB5 = 1;
DB6 = 0;
DB7 = 0;
LCD_E = 1;
Delay(5);
LCD_E = 0; // Write data to display
// Set LCD_DATA to lower nibble of Function Set : 4 bit, 2 lines, 5*7 font
//LCD_DATA = (LCD_DATA&0x0F)|0x80;
DB4 = 0;
DB5 = 0;
DB6 = 0;
DB7 = 1;
LCD_E = 1;
Delay(5);
LCD_E = 0; // Write data to display
Delay(500); // Wait 400µs
// Set LCD_DATA to high nibble of Display On/Off Control : display off, cursor off, don?t blink
//LCD_DATA = (LCD_DATA&0x0F)|0x00;
DB4 = 0;
DB5 = 0;
DB6 = 0;
DB7 = 0;
LCD_E = 1;
Delay(5);
LCD_E = 0; // Write data to display
// Set LCD_DATA to lower nibble of Display On/Off Control : display off, cursor off, don?t blink
//LCD_DATA = (LCD_DATA&0x0F)|0x80;
DB4 = 0;
DB5 = 0;
DB6 = 0;
DB7 = 1;
LCD_E = 1;
Delay(5);
LCD_E = 0; // Write data to display
Delay(500); // Wait 400µs
// Set LCD_DATA to high nibble of Clear Display
//LCD_DATA = (LCD_DATA&0x0F)|0x00;
DB4 = 0;
DB5 = 0;
DB6 = 0;
DB7 = 0;
LCD_E = 1;
Delay(5);
LCD_E = 0; // Write data to display
// Set LCD_DATA to lower nibble of Clear Display
//LCD_DATA = (LCD_DATA&0x0F)|0x10;
DB4 = 1;
DB5 = 0;
DB6 = 0;
DB7 = 0;
LCD_E = 1;
Delay(5);
LCD_E = 0; // Write data to display
Delay(1000); // Wait 5ms
// Set LCD_DATA to high nibble of Entry Mode Set : increment DD-RAM address, move cursor
//LCD_DATA = (LCD_DATA&0x0F)|0x00;
DB4 = 0;
DB5 = 0;
DB6 = 0;
DB7 = 0;
LCD_E = 1;
Delay(5);
LCD_E = 0; // Write data to display
// Set LCD_DATA to lower nibble of Entry Mode Set : increment DD-RAM address, move cursor
//LCD_DATA = (LCD_DATA&0x0F)|0x60;
DB4 = 0;
DB5 = 1;
DB6 = 1;
DB7 = 0;
LCD_E = 1;
Delay(5);
LCD_E = 0; // Write data to display
Delay(500); // Wait 400µs
Понятное дело что это не дело. так по одному фигачить.... но пока по другому ниче не получается.
Сейчас с помощью все того же осциллографа я проверял вот эту функцию:
Код: Выделить всё
void lcd_write(unsigned char c)
{
LCD_DATA = (c & 0x0F) << 4; //send lower-order nibble
LCD_E = 1;
Delay(50);//200microseconds
LCD_E = 0; //LCD_STROBE;
LCD_DATA = (c & 0xF0); // send higher-order nibble
LCD_E = 1;
Delay(50);//200microseconds
LCD_E = 0;//LCD_STROBE;
}
Но не полностью, а по частям. начиная с этого:
lcd_write(0x30); // 0011 0000
void lcd_write(unsigned char c)
{
LCD_DATA = (c & 0xF0); // send higher-order nibble. DB7=0 DB6=0 DB5=1 DB4=1
}
т.e. должно прийти так DB7=0 DB6=0 DB5=1 DB4=1
проверял.... ничего подобного. "1" приходит только на DB7, на остальных нули.
Что может быть не так?
Re: SiLabs c8051f314 + LCD DV16210 Не могу понять в чем проб
Добавлено: Вс окт 16, 2011 19:40:14
Ser60
Приклейте полный текст программы, надо посмотреть инициализацию портов и определение переменной LCD_DATA.
Re: SiLabs c8051f314 + LCD DV16210 Не могу понять в чем проб
Добавлено: Пн окт 17, 2011 07:24:42
Vlad0o
Код: Выделить всё
#include <C8051F310.H>
#include <stdio.h>
// Pin Declarations
//----------------------
#define LCD_DATA P3 // data port (P3^1;P3^2;P3^3;P3^4)
sbit LCD_RS = P1^3;
sbit LCD_E = P1^4;
sbit DB4 = P3^1;
sbit DB5 = P3^2;
sbit DB6 = P3^3;
sbit DB7 = P3^4;
volatile unsigned long tmpCnt;
//-----------------------------------------------------------------------------
// Function Prototypes
//-----------------------------------------------------------------------------
void lcd_init(void); //LCD init
void OSCILLATOR_Init (void);
void PORT_Init (void);
void lcd_write(unsigned char);
void Delay (unsigned int);
//-----------------------------------------------------------------------------
// main() Routine
//-----------------------------------------------------------------------------
void main (void)
{
PCA0MD &= ~0x40;// WDTE = 0 (clear watchdog timer
// enable)
OSCILLATOR_Init ();
PORT_Init ();
while(1)
{
Delay(3000);
LCD_E = 1;
lcd_write(0x96) ;//вводил всякие значения.
Delay(3000);
lcd_write(0x00) ;
LCD_E = 0;
}
}
void OSCILLATOR_Init (void)
{
OSCICN |= 0x03; // Configure internal oscillator for
}
void PORT_Init (void)
{
DB4 = 0;
DB5 = 0;
DB6 = 0;
DB7 = 0;
P1MDOUT |= 0x18; //P1.4, P1.3
P1MDOUT = 0x00;
P3MDOUT |= 0x1E; // P3.1, P3.2, P3.3, P3.4
P3MDOUT = 0x00;
XBR0 = 0x09; //sysclk
XBR1 = 0x40; // Enable crossbar and enable
// weak pull-ups
}
void Delay (unsigned int ms)
{
unsigned long tmp;
tmp = ((unsigned long) ms) * 5;
for (tmpCnt = 0; tmpCnt<tmp; tmpCnt++);
}
void lcd_write(char c)
{
LCD_DATA = (c & 0x0F) << 4; //send lower-order nibble
}
LCD_E - нормально сигналы отдает.
Re: SiLabs c8051f314 + LCD DV16210 Не могу понять в чем проб
Добавлено: Пн окт 17, 2011 07:46:20
Ser60
Я не понял смысл следующих действий:
P1MDOUT |= 0x18; //P1.4, P1.3
P1MDOUT = 0x00;
Вторая строчка сбрасывает биты установленные в первой.
P3MDOUT |= 0x1E; // P3.1, P3.2, P3.3, P3.4
P3MDOUT = 0x00;
Аналогично и здесь. В итоге порт P3 (LCD_DATA) после обнуления P3MDOUT работает в режиме оpen-drain, тогда как должен быть в push-pull. Помимо этого, надо скипануть биты порта P1 использованные для связи с LCD в регистре P1SKIP, чтобы подключить соответствующие биты порта на выход. Установите у себя Configuration Wizard (загружается с сайта silabs.com), если проблема разобраться с портами по даташиту.
Более того, инструкция
LCD_DATA = (c & 0x0F) << 4;
записывает данные не в те биты порта, которые задекларированы для связи с LCD (P3.1 - P3.4), а в P3.4 - P3.7 (?!)
Re: SiLabs c8051f314 + LCD DV16210 Не могу понять в чем проб
Добавлено: Пн окт 17, 2011 10:12:10
Vlad0o
Визард стоит. без него было бы вообще туго.
Про то что порты работают в режиме open-drain я так сказать осознавал. Потому что в режиме push-pull (P3MDOUT = 0x1E; P1MDOUT = 0x18;) сигнал был третьего состояния (если я правильно понял показания осциллографа).
Про "скипануть порты" я не знал. И почему то в визарде тоже не видел. возможно не там смотрел. надо было в даташит смотреть.
Инструкция LCD_DATA = (c & 0x0F) << 4;
порт
7 6 5 4 3 2 1 0
"с" - байт данных (не 0 и 1 просто чтоб было понятнее куда и что смещается)
7 6 5 4 3 2 1 0
после инструкции LCD_DATA = (c & 0x0F) << 4;
3 2 1 0 _ _ _ _
Я правильно понял?
мне не же надо сделать так:
после инструкции LCD_DATA = (c & 0x0F) << 1;
_ _ _ 3 2 1 0 _
тогда как для старшего полубайта:
LCD_DATA = (c & 0xF0) >> 3;
_ _ _ 7 6 5 4 _
ДА?
Re: SiLabs c8051f314 + LCD DV16210 Не могу понять в чем проб
Добавлено: Пн окт 17, 2011 10:17:27
Vlad0o
Port I/O initialization consists of the following steps:
Step 1. Select the input mode (analog or digital) for all Port pins, using the Port Input Mode
register (PnMDIN).
Step 2. Select the output mode (open-drain or push-pull) for all Port pins, using the Port Output
Mode register (PnMDOUT).
Step 3. Select any pins to be skipped by the I/O Crossbar using the Port Skip registers (PnSKIP).
Step 4. Assign Port pins to desired peripherals.
Step 5. Enable the Crossbar (XBARE = ‘1’).
Не знаю как я пропустил..
Только P1 или все надо еще P3?
P1SKIP = 0x18; //P1.4, P1.3
P3SKIP = 0x1E; // P3.1, P3.2, P3.3, P3.4
Re: SiLabs c8051f314 + LCD DV16210 Не могу понять в чем проб
Добавлено: Пн окт 17, 2011 11:11:46
Vlad0o
Отлично!!! Проверил отдельно "инструкцию" и заскипил первый порт. Сигналы идут.
СПАСИБО!
осталось только собрать все в одну кучу!)
Re: SiLabs c8051f314 + LCD DV16210 Не могу понять в чем проб
Добавлено: Пн окт 17, 2011 15:34:18
Ser60
Извините, я только что проснулся... Да, сдвиг данных сейчас сделан верно. Порт P3 скиповать не надо, т.к. он не управляется через cross-bar и всегда используется только для I/O. Для него и P3SKIP регистра не существует. Поздравляю с прогрессом!