Администрация форума не несёт ответственности за достоверность информации и оставляет за собой право редактировать или в особых случаях даже удалять посты без предупреждения. Спасибо за понимание.

Программирование ATMEL в BASCOM.

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.


Вы здесь » Программирование ATMEL в BASCOM. » Исходники » Помогите с запуском LCD 4x20 по i2c


Помогите с запуском LCD 4x20 по i2c

Сообщений 121 страница 150 из 210

121

bst r16, 7              -  Сохраним бит из регистра Т
*bld r25, PCF_E1   -  Загрузить бит из Т в регистр

ВОПРОС: а "*" звёздочка зачем???

0

122

При использовании портов в вашей библиотеке вы должны использовать .equ чтобы указать адрес:

Таким образом, библиотека менеджер знает адрес порта во время компиляции.
В качестве альтернативы предшествовать мнемоническую с * так код не будет скомпилирован в Lib.
Адрес регистра будет решен во время выполнения в этом случае.

Ничего не понял.

0

123

Т.е. любое обращение к ОТНОСИТЕЛЬНЫМ адресам переменных нужно предварять символом "*" ... так чтоли?

0

124

Здравствуйте! Позволю себе вставить свои "пять копеек". Вот мой вариант работы с индикатором по I2C. Используется библиотека lcd_pcf8574.lib. Плюс к этому часы ds1302 и dht11.


'--------------------------- Указываем тип МК и его частоту ------------------------------
$regfile = "m328pdef.dat"
$crystal = 16000000
$baud = 9600
'-----------------------------------------------------------------------------------------
'------------- Указываем размер аппаратного, программного стека и размер фрейма ----------
$hwstack = 80
$swstack = 80
$framesize = 64
'-----------------------------------------------------------------------------------------
'-------------------------- Подключаем библиотеку для работы с индикатором ---------------
$lib "lcd_pcf8574.lib"                                      '
'-----------------------------------------------------------------------------------------
'-------------------- Резервируем константы для работы с индикатором ---------------------
Config I2cdelay = 1                                         ' Задержка линии I2C
Config Scl = Portc.5                                        ' Конфигурим I2c Scl
Config Sda = Portc.4                                        ' Конфигурим I2c Sda
Config Lcd = 16 * 2                                         ' Конфигурация экрана - число символов\число строк

Const Pcf8574_lcd = &H4E                                    ' Адрес индикатора
Const Pcf_e2_is_output = 1                                  '
Const Pcf_rw_is_output = 1                                  '
'-----------------------------------------------------------------------------------------
' -------------------Раскидываем пины индикатора по ножкам PCF8574 -----------------------
Const Pcf_rs = 0
Const Pcf_rw = 1
Const Pcf_e1 = 2
Const Pcf_e2 = 3
Const Pcf_d4 = 4
Const Pcf_d5 = 5
Const Pcf_d6 = 6
Const Pcf_d7 = 7
'-----------------------------------------------------------------------------------------
'---------------------- Резервируем переменные для работы с индикатором ------------------
Dim _out_rw As Byte
Dim _out_e2 As Byte
Dim _lcd_e As Byte
'------------- названия переменных НЕ МЕНЯТЬ!!! ------------------------------------------
'------------ выбираем режим работы индикатора--------------------------------------------
_lcd_e = 128                                                '64=E2 (вывод в 3-ю и 4-ю строки) 128=E1 (вывод в 1-ю и 2-ю строки) 192=E1+E2 (вводим в 4 строки)
_out_rw = 0                                                 '0 - пишем в индикатор информацию, 1 - читаем из индикатора
_out_e2 = 1                                                 ' управляем подсветкой 1 - включено, 0 - выключено
'-----------------------------------------------------------------------------------------
'---------------------- Настраиваем АЦП --------------------------------------------------
'Config Adc = Single , Prescaler = Auto , Reference = Avcc
'Start Adc
'Dim W As Word , Channel As Byte , Temp As Single , Q As Integer , W1 As Word
'=========================================================================================
'====================== Работаем с датчиком температуры и влажности ======================
Declare Sub Get_th(t As Byte , H As Byte)                   'Объявляем подпрограмму для работы с датчиком температуры и влажности

'подключение датчика к PortD.6
Dht_put Alias Portd.6
Dht_get Alias Pind.6
Dht_io_set Alias Ddrd.6

Dim T As Byte                        'перееменная для хранения температуры
Dim H As Byte                        'переменная для хранения влажности
Dim Crc As Byte                      'переменная для хранения байта четности
Dim Mybyte As Byte
Dim Sensor_data As String * 40    'сюда будут записываться данные отсылаемые датчиком
Dim Tmp_str8 As String * 8
Dim Count As Byte                    'переменная для подсчета принятых бит

Set Dht_io_set
Set Dht_put
'=========================================================================================

'================== Работаем с часами DS1302 =============================================
Config Portc.0 = Output
Config Portc.1 = Output

Ds_rst Alias Portc.0
Ds_sck Alias Portc.1
Ds_data Alias Portc.2
Ds_io Alias Pinc.2

Declare Sub Ds1302_write(byval Clockcommand As Byte , Writebyte As Byte)
Declare Sub Ds1302_read(byval Clockcomand As Byte , Readbyte As Byte)

Dim B1 As Byte

'=========================================================================================

'---------------------- Резервируем остальные переменные ---------------------------------
Dim Cnt As Byte , _sec As Byte , _min As Byte , _hour As Byte , _time As String * 12
Dim _time_old As String * 12
'-----------------------------------------------------------------------------------------

'--------------------ОСНОВНАЯ ПРОГРАММА --------------------------------------------------
Cls

Lcd "   METEO-v1.0   "
Wait 2

Do
   Waitms 100
   Incr Cnt
     If Cnt > 50 Then
       Call Get_th(t , H)   'Вызываем не чаще одного раза в секунду
       Cnt = 0
     End If

   Call Ds1302_read(&H81 , _sec)
   Call Ds1302_read(&H83 , _min)
   Call Ds1302_read(&H85 , _hour)

   _time = "    "
   B1 = Makedec(_hour)
   If B1 < 10 Then _time = _time + " "
   _time = _time + Str(b1) + ":"
   B1 = Makedec(_min)
   If B1 < 10 Then _time = _time + "0"
   _time = _time + Str(b1) + ":"
   B1 = Makedec(_sec)
   If B1 < 10 Then _time = _time + "0"
   _time = _time + Str(b1)

   If _time <> _time_old Then
       'Print _time
       Cls
       Lcd " T: " ; T ; "C  " ; "P: " ; H ; "%"
       Print " T: " ; T ; "C  " ; "P: " ; H ; "%"
       Lowerline
       Lcd _time
       Print _time
       _time_old = _time
   End If
Loop

End                                                         'end program

'========================== Подпрограмма работы с DHT11 =================================
'===== Код позаимствован с http://avrproject.ru/publ/kak_podkljuch … r/2-1-0-72
''(порядок действий определен по техническому описанию)
Sub Get_th(t As Byte , H As Byte)

Count = 0
Sensor_data = ""
Set Dht_io_set                                         'делаем PD.6 выходом
Reset Dht_put                                          'прижимаем шину к земле
Waitms 25                                              'ждем не менее 18мс

Set Dht_put                                            'отпускаем шину
Waitus 40
Reset Dht_io_set                                       'делаем PD.6 входом
Waitus 40                                              'ждем 40 мкс
If Dht_get = 1 Then                                    'если на нем по прежнему 1
    H = 1                                               'значит датчик не ответил
    Exit Sub                                            'выходим из подпрограммы
End If

'если датчик ответил и прижал шину к земле продолжаем работу
  Waitus 80                                             'ждем еще 80 мкс
  If Dht_get = 0 Then                                   'если на линии по прежнему 0
    H = 2                                               'значит датчик сошел с ума
    Exit Sub                                            'выходим из подпрограммы
  End If

'если все нормально и датчик ответил правильно, тогда продолжаем

  While Dht_get = 1 : Wend                'ждем пока на шине появится 1

   Do                                     'начинаем принимать 40 бит данных
    While Dht_get = 0 : Wend              'ждем появления на шине 0
    Waitus 30                             'после появления 0 ждем 30мкс
     If Dht_get = 1 Then                  'если на шине 1
       Sensor_data = Sensor_data + "1"    'записываем в переменную эту единицу
       While Dht_get = 1 : Wend           'и ждем пока датчик отправит следующий бит
       Else                               'иначе, если там был 0
       Sensor_data = Sensor_data + "0"    'записываем этот 0 в переменную
     End If
    Incr Count                            'увеличиваем счетчик на 1
   Loop Until Count = 40                  'повторяем пока счетчик не досчитает до 40

   Set Dht_io_set
   Set Dht_put

'начинаем раскладывать полученные данные

   Tmp_str8 = Left(sensor_data , 8)                'берем левые 8 символов переменной
   H = Binval(tmp_str8)                            'это целая часть влажности

   Tmp_str8 = Mid(sensor_data , 17 , 8)            'вытаскиваем 8 символов из середины
   T = Binval(tmp_str8)                            'это целая часть температуры

   Tmp_str8 = Right(sensor_data , 8)               'правые 8 символов
   Crc = Binval(tmp_str8)                          'проверочные данные

'проверка контрольной суммы

   Mybyte = T + H                      'складываем значение температуры и влажности
   If Mybyte <> Crc Then               'если контрольная сумма не сошлась
      H = 3                            'значит полученные данные не верны
   End If

End Sub
'====================== Конец процедуры работы с DHT11 ==================================

'-------------------------------------------------------------------------------
'Процедура записи слова и данных в DS1302
'-------------------------------------------------------------------------------
Sub Ds1302_write(byval Clockcommand As Byte , Writebyte As Byte)
   Config Ds_data = Output
   Set Ds_sck
   Reset Ds_io
   Set Ds_rst
   Reset Ds_sck
   Reset Ds_rst
   Waitus 5
   Set Ds_rst
   Waitus 5                                                 'tcc =4us, CE to clock setup time
     Shiftout Ds_data , Ds_sck , Clockcommand , 3 , 8 , 2
     Shiftout Ds_data , Ds_sck , Writebyte , 3 , 8 , 2
   Reset Ds_sck
   Waitus 5
   Reset Ds_rst
   Waitus 5
End Sub

'-------------------------------------------------------------------------------
'Процедура чтения данных из DS1302
'-------------------------------------------------------------------------------
Sub Ds1302_read(byval Clockcomand As Byte , Readbyte As Byte)
  Dim A As Byte
  Config Ds_data = Output
  Set Ds_sck
  Set Ds_io
  Set Ds_rst
  Reset Ds_sck
  Reset Ds_rst
  Waitus 5
  Set Ds_rst
  Waitus 5
    Shiftout Ds_data , Ds_sck , Clockcomand , 3 , 8 , 3
  Config Ds_data = Input
  Set Ds_sck
  Reset Ds_io
  Set Ds_rst
    Shiftin Ds_io , Ds_sck , Readbyte , 2 , 8 , 3
  Reset Ds_rst
  Waitus 5
  Rotate Readbyte , Left , 1
End Sub


http://s7.uploads.ru/t/advzX.jpg

Отредактировано kara1126 (2015-10-24 06:32:02)

0

125

Намана. А на асме?

0

126

Здравствуйте друзья.
Помогите разобраться, почему в Протеусе не работает данный код?
Поправьте, если что не так.

С такой конфигурацией pcf8574 в "железе" у меня все работает, в Протеусе нет.
На платке распаян PCF8574T, ноги 1, 2, 3 подтянуты к 1, дисплей LCD16x4.
В "железе" заработало с библиотекой "lcd_pcf8574.lib" и адресом индикатора &H4E.
Проблема в том, что надо делать прибор дальше, подсоединять следующие датчики,
а промоделировать в Протеусе я его не могу. А то, что работает в Протеусе - не работает на столе с моим железом.

Скрытый текст:

Для просмотра скрытого текста - войдите или зарегистрируйтесь.

Скрытый текст:

Для просмотра скрытого текста - войдите или зарегистрируйтесь.

Отредактировано VlGD (2016-02-14 19:51:35)

0

127

VlGD написал(а):

Проблема в том, что надо делать прибор дальше, подсоединять следующие датчики,
а промоделировать в Протеусе я его не могу. А то, что работает в Протеусе - не работает на столе с моим железом.

Посмотрите здесь

0

128

VlGD написал(а):

В железе работает адрес &H4E, в Протеусе &H7E.


И что Вам мешает сменить адрес PCF8574 ?

0

129

Поменял в Протеусе микросхему pcf8574А на pcf8574 (в библиотеке есть такая оказывается и вроде с нужным адресом).
Const Pcf8574_lcd = &H4E
Сигналы с нее на LCD при моделировании, видно что идут, но LCD молчит.
Что-то в коде похоже я не дописал для Протеуса.

Отредактировано VlGD (2016-02-15 17:34:55)

0

130

Удалось запустить программу в железе и в Протеусе с платкой pcf8574, у которой адрес &H4E.
Библиотеку использовал  "lcd_pcf8574_9.lib".
Пины такие:
  Const Pcf_rs = 0
  Const Pcf_bl = 1
  Const Pcf_e1 = 2
  Const Pcf_e2 = 3
'-------------------
  Const Pcf_d4 = 4
  Const Pcf_d5 = 5
  Const Pcf_d6 = 6
  Const Pcf_d7 = 7
'-------------------

Вопрос: есть ли возможность тут программно включать-выключать подсветку (контакт e2), как это срабатывает в железе с библиотекой "lcd_pcf8574.lib",
и если да, то что нужно написать в коде для управления контактом e2 для библиотеки "lcd_pcf8574_9.lib"?
Сейчас контакты e1 и e2, судя по Протеусу, работают синфазно, одинаково.

в "lcd_pcf8574.lib" было так:
........
Dim _out_e2 As Byte
_out_e2 = 0                       'управляем подсветкой дисплея. 1- вкл, 0- выкл
.....

Программа

'--------------------------- Указываем тип МК и его частоту ------------------------------
$regfile = "m8def.dat"
$crystal = 8000000

'-------------------------------------------------------------------------------
  $lib "lcd_pcf8574_9.lib"              'Подключаем библиотеку
'-------------------------------------------------------------------------------

  Config Portd.6 = Output
  Led_out Alias Portd.6

'-----------------------   Конфигурация шины I2c   -----------------------------
Config Scl = Portc.5                    ' Конфигурим I2c Scl
Config Sda = Portc.4                    ' Конфигурим I2c Sda
Config I2cdelay = 2

'---------------------   Конфигурация используемого LCD   ----------------------
  Config Lcd = 16 * 4

  Const 1_индикатор = &H4E              ' Адрес PCF8574A первого LCD
  Dim Pcf8574_lcd As Byte
  Pcf8574_lcd = 1_индикатор

'-------------------------   Используемые переменные   -------------------------

  Dim _lcd_e As Byte
  Dim _backlight As Byte

'-------   Раскидываем пины индикатора по ножкам PCF8574 или PCF8574A   --------

  Const Pcf_rs = 0
  Const Pcf_bl = 1
  Const Pcf_e1 = 2
  Const Pcf_e2 = 3
'-------------------
  Const Pcf_d4 = 4
  Const Pcf_d5 = 5
  Const Pcf_d6 = 6
  Const Pcf_d7 = 7
'-------------------

'-------------------------------------------------------------------------------
Const Pcf_e2_is_output = 1             ' 0=E2 для LCD ; 1= управляемый выход
Const Pcf_bl_is_output = 1             ' 0= не использован ; 1= управляемый выход
'-------------------------------------------------------------------------------

  _lcd_e = 192                          ' 64=E2 (3 & 4 stering) 128=E1 (1 & 2 string) 192=E1+E2 (all 4 strings)
  _backlight = 0                        'initial Backlight state
'-------------------------------------------------------------------------------

'-------------   Инициализация шины I2c   ----------------------------

  I2cinit
  Waitms 10

'-----------------   Инициализируем все LCD индикаторы   -----------------------

  Initlcd

  Do
    _out_e2 = 0                 'хотелось бы вкл. подсветку
    Locate 1 , 1
    Lcd "123456789"           'что-то печатаем

    Wait 2
    Toggle Led_out             'мигнем светодиодом
    _out_e2 = 0                 'хотелось бы откл. подсветку
    Loop

End

Отредактировано VlGD (2016-02-15 17:33:14)

0

131

Хоть стреляйте, не могу понять, в чём проблема.

Благодаря Mrshilov, выложены готовые варианты (1 вариант; 2 вариант; 3 вариант), просто бери и пользуйся, и всё равно умудряются чего-то напутать.

Спрашивается, на кой ляд, это всё выкладывается, если постоянно одни и те-же грабли.

0

132

Mrshilov написал(а):

Вы же сами назначили подсветку на порт1:
Код:
Const Pcf_bl = 1


Ребята, я тут не большой спец, извините пож. Я думал, что в этой библиотеке "lcd_pcf8574_9.lib" константа "Const Pcf_bl=1" отвечает за ногу RW, а не за подсветку. На 1-м порту у меня контакт RW дисплея. Без строчки Const Pcf_bl = 1 ни на столе, ни в Протеусе ничего не работает.
На 3-м порту- управление подсветкой не прямо, а через транзистор вроде, на 16-ю ногу LCD.

Mrshilov написал(а):

Тогда при чем тут "контакт e2"? Управляйте подсветкой как положено:
Код:

_backlight = 1


Я не знаю, к сожалению,  как положено в "lcd_pcf8574_9.lib". При установке  "_backlight = 1" в любом месте кода на LCD пусто.
Я попытался по аналогии с библиотекой lcd_pcf8574.lib. Там бало так:

Const Pcf_e2_is_output = 1
Const Pcf_e2 = 3
Dim _out_e2 As Byte
а дальше в любом месте программы так:
Toggle _out_e2

sasha_1973, спасибо вам за помощь! Проблема в том, что в проекте, что работает и в протеусе и на столе с библиотекой  "lcd_pcf8574_9.lib" я не знаю как включать-выключать подсветку с третьего порта pcf8574, не знаю какие константы и переменные установить и менять. То, что пробовал - не катит.

С библиотекой "lcd_pcf8574.lib" на столе включается-выключается, НО не эмулируется Протеусом.
Перепаивать или перерезать дорожки пока не буду.
Спасибо Вам за терпение, я разберусь.
Платка такая:
http://s6.uploads.ru/t/QJ6wE.jpg

Отредактировано VlGD (2016-02-16 17:15:47)

0

133

VlGD написал(а):

Перепаивать или перерезать дорожки пока не буду.

Вот Ваш вариант, просто выпаять штырёк, и, как говориться, --"усё будет у порядке".

+1

134

Народ есть исходник рабочий для синтезатора кв трансивера, управляет DDS AD 9850, есть чёткий исходник, и я ну ни как не могу сделать  что бы у меня жки работало через PCF по I2c,  у меня голова взрывается,  пример беру, тестовая программка, всё работает, выводит буквы на экран, как только назначаю порты в исходнике на управление, закачиваю прошивку , ничего не отображает, что за такое, помогите кто, уже вторые сутки бьюсь

0

135

Народ помогите с протеусом - LCD2004  в  железе высвечивает все 4 строки
а в протеусе 1 и 3

0

136

Если кому надо вот инициализация LCD2004 все 4 строки

    LCD_RW_0;
    _delay_us(15);
   lcd_putbyte(0x32, LCD_COM); // без этой команды железо работает а протеус нет
    _delay_us(100);
    lcd_putbyte(0x28, LCD_COM); // команда
_delay_us(100);
    lcd_putbyte(0x08, LCD_COM); // команда
_delay_us(10);
    lcd_putbyte(0x01, LCD_COM); // команда
_delay_us(10);
    lcd_putbyte(0x06, LCD_COM); // команда
    _delay_us(10);
    lcd_putbyte(0x0C, LCD_COM); // команда

0

137

-NMi- написал(а):

нефиг там пин выковыривать, исправьте в либе 1 строчку и всё!

_Send_to_LCD:
push r25
push r26    ; Register 26 ab auf den Stack
push r27    ; Register 27 ab auf den Stack
mov r25,_temp1
BST  r25, 0    ; Bit0 aus _temp1 ins T-Bit
*BLD  _temp1, PCF_D4    ; Das T-Bit wird in _temp2 an Position PCD_D4 geschrieben
  BST  r25, 1    ; Bit1 aus _temp1 ins T-Bit
*BLD  _temp1, PCF_D5    ; Das T-Bit wird in _temp2 an Position PCD_D5 geschrieben
BST  r25, 2    ; Bit2 aus _temp1 ins T-Bit
*BLD  _temp1, PCF_D6    ; Das T-Bit wird in _temp2 an Position PCD_D6 geschrieben
BST  r25, 3    ; Bit3 aus _temp1 ins T-Bit
*BLD  _temp1, PCF_D7    ; Das T-Bit wird in _temp2 an Position PCD_D7 geschrieben
BST  r25, 4    ; Bit4 aus _temp1 ins T-Bit
*BLD  _temp1, PCF_RS    ; Das T-Bit wird in _temp2 an Position PCD_RS geschrieben
*lds r25,{_backlight}      ; read backlight state
bst r25, 0           ; save it state in T register
*bld _temp1, PCF_BL      ; copy state to register
set
*BLD  _temp1, PCF_E2    ; set E2
        clt
*BLD  _temp1, PCF_E1    ; RESET E1
clr r25
bst r16, 6
*bld r25, PCF_E2
bst r16, 7
*bld r25, PCF_E1


Речь идёт о добавлении команды clt?

Отредактировано beginer (2016-04-27 12:42:42)

0

138

Да, у меня ДАВНЫМ ДАВНО все это работает. И I2C шину тоже запустил БЕЗ морганий! Вклучаем МОЗГ и всё работает даже без резисторов.

0

139

Нашел подробное описание подключения LCD 1602 по I2C интерфейсу http://radiolaba.ru/microcotrollers/pod … feysu.html , по сути то же самое что и LCD 4x20, может кому будет полезно

0

140

Всем рабочего кода!
Пробегал мимо и увидел эту тему. Недавно попался мне экранчик 20х4 с напаянной на него платой контроллера i2c на чипе 8574А. Люди, неужели все настолько обленились что неохота посмотреть datasheet на этот чип. Там на самом видном месте указано что по умолчанию адрес у чипа 8574А - &b01111110 (или &h7E), а у чипа 8574 - &b00100111 (или &h27).
Разумеется умолчание сохраняется только если на китайской плате не напаяны перемычки.
Так вот вчера захотелось мне подружить восьмую мегу с этим экранчиком.
Не заморачиваясь с поиском библиотек я решил написать самодельные сабы для управления.
Если подумать, код можно оптимизировать, но в меге 8 он занимает всего 28% - места еще много...
Код работает в протеусе 8.5 и в железе. Умеет гасить и зажигать подсветку, включать и выключать курсор, писать на экранчике в разных строках. Комменты я пишу на английском, так проще соблюдать правильность кодировки при переносе кода в протеус. Пользуйтесь на здоровье.
Да, и самое главное: прежде чем писать что код нерабочий, проверьте подключение портов на совпадение с моим вариантом.

Код:
'-----------------------------------------------------------------
'                     (c) 2011 c@rsoft
'                device on mega8 I2C 20x4 LCD
'-----------------------------------------------------------------
'connection
'pcf8574A               LCD module
'P0(LSB)                RS
'P1                     R/W
'P2                     E
'P3                     Backlight LED
'P4                     DB4
'P5                     DB5
'P6                     DB6
'P7(MSB)                DB7
'-----------------------------------------------------------------

$regfile = "m8def.dat"
$crystal = 16000000
'$baud = 2400
$hwstack = 32
$swstack = 10
$framesize = 40

$lib "i2c_twi.lbx"

'config I2C
Config Scl = Portc.5
Config Sda = Portc.4
I2cinit
Config Twi = 400000
'**********

'config ports

'************

'set address for i2c LCD
Const Addr_lcd = &B01111110
'***********************

'dim vars
Dim Commee As Byte                                          'command with E = 1 (enabled EE)
Dim Commed As Byte                                          'command with E = 0 (disabled ED)
Dim Dat As String * 20
Dim Value As Byte
Dim Vmsb As Byte
Dim Vlsb As Byte
Dim Stprint As Byte
Dim Mstp As Byte
Dim Lstp As Byte
Dim Pw As Byte
Dim Bl As Byte
Dim Cur As Byte
'********

Declare Sub Wr_lcd_init(byval Commee As Byte , Byval Commed As Byte)
Declare Sub Prnt_lcd(value As Byte)
Declare Sub Make_ascii(byval Dat As String * 20)            'make ASCII and set cursor position
Declare Sub Curonoff(byval Cur As Byte)
Declare Sub Backlight(byval Bl As Byte)


Waitms 50                                                   'wait for LCD load

'init lcd
'init 8bit data 3 times
Commee = &B00110100
Commed = &B00110000
Call Wr_lcd_init(commee , Commed)
Waitms 5
Commee = &B00110100
Commed = &B00110000
Call Wr_lcd_init(commee , Commed)
Waitus 110
Commee = &B00110100
Commed = &B00110000
Call Wr_lcd_init(commee , Commed)
Waitus 110
'**********************

Commee = &B00100100
Commed = &B00100000
Call Wr_lcd_init(commee , Commed)
Waitus 110

Commee = &B00100100
Commed = &B00100000
Call Wr_lcd_init(commee , Commed)
Waitus 110
Commee = &B10000100
Commed = &B10000000
Call Wr_lcd_init(commee , Commed)
Waitus 110

Commee = &B00000100
Commed = &B00000000
Call Wr_lcd_init(commee , Commed)
Waitus 110
Commee = &B11110100
Commed = &B11110000
Call Wr_lcd_init(commee , Commed)
Waitus 110

Commee = &B00000100
Commed = &B00000000
Call Wr_lcd_init(commee , Commed)
Waitus 110
Commee = &B00010100
Commed = &B00010000
Call Wr_lcd_init(commee , Commed)
Waitms 2

Commee = &B00000100
Commed = &B00000000
Call Wr_lcd_init(commee , Commed)
Waitus 110
Commee = &B01100100
Commed = &B01101000
Call Wr_lcd_init(commee , Commed)
'********

Waitms 1

'for example print I2C LCD on 1st line LCD
Dat = "I2C LCD 20x4"
Stprint = 0                                                 'move cursor to 1st line (&h00)
Call Make_ascii(dat)
'*******************************************
'for example print "Line2" on 2nd line LCD
Dat = "Line2"
Stprint = 64                                                'move cursor to second line (&h40)
Call Make_ascii(dat)
'***************************************
'for example print "Line3" on 3rd line LCD
Dat = "Line3"
Stprint = 20                                                'move cursor to 3 line (&h14)
Call Make_ascii(dat)
'****************************************
'for example print "Line4" on 4th line LCD
Dat = "Line4"
Stprint = 84                                                'move cursor to 4 line (&h54)
Call Make_ascii(dat)
'********************************************

Call Curonoff(0)                                            'by this you turn off the Cursor
'Call Curonoff(1)                                            'by this you turn on the Cursor

'Call Backlight(0)                                           'by this you turn off the backlight
Call Backlight(1)                                           'by this you turn on the backlight

Do
   'you code here

Loop

End

Sub Wr_lcd_init(byval Commee As Byte , Byval Commed As Byte)
  I2cstart
  I2cwbyte Addr_lcd
  I2cwbyte Commee                                           'command with E=1
  I2cstop
  Waitus 1100
  I2cstart
  I2cwbyte Addr_lcd
  I2cwbyte Commed                                           'same command with E=0
  I2cstop
End Sub

Sub Prnt_lcd(value As Byte)
  Vlsb = Value
  Shift Value , Right , 4
  Shift Value , Left , 4
  Vmsb = Value
  Shift Vlsb , Left , 4
  'send MSB+data
  Value = &B1101
  Vmsb = Vmsb + Value
  I2cstart
  I2cwbyte Addr_lcd
  I2cwbyte Vmsb
  I2cstop
  Value = &B1001
  Shift Vmsb , Right , 4
  Shift Vmsb , Left , 4
  Vmsb = Vmsb + Value
  I2cstart
  I2cwbyte Addr_lcd
  I2cwbyte Vmsb
  I2cstop
  '*************
  'send LSB+data
  Value = &B1101
  Vlsb = Vlsb + Value
  I2cstart
  I2cwbyte Addr_lcd
  I2cwbyte Vlsb
  I2cstop
  Value = &B1001
  Shift Vlsb , Right , 4
  Shift Vlsb , Left , 4
  Vlsb = Vlsb + Value
  I2cstart
  I2cwbyte Addr_lcd
  I2cwbyte Vlsb
  I2cstop
  '************
End Sub

Sub Make_ascii(byval Dat As String * 20)
  Dim I As Byte
  Dim L As Byte
  Dim Sv As String * 1
  'set position
  Stprint = Stprint + &B10000000
  Lstp = Stprint
  Shift Stprint , Right , 4
  Shift Stprint , Left , 4
  Mstp = Stprint
  Shift Lstp , Left , 4
  'send MSB+data
  Stprint = &B1100
  Mstp = Mstp + Stprint
  I2cstart
  I2cwbyte Addr_lcd
  I2cwbyte Mstp
  I2cstop
  Shift Mstp , Right , 4
  Shift Mstp , Left , 4
  Stprint = &B1000
  Mstp = Mstp + Stprint
  I2cstart
  I2cwbyte Addr_lcd
  I2cwbyte Mstp
  I2cstop
  '*************
  'send LSB+data
  Stprint = &B1100
  Lstp = Lstp + Stprint
  I2cstart
  I2cwbyte Addr_lcd
  I2cwbyte Lstp
  I2cstop
  Shift Lstp , Right , 4
  Shift Lstp , Left , 4
  Stprint = &B1000
  Lstp = Lstp + Stprint
  I2cstart
  I2cwbyte Addr_lcd
  I2cwbyte Lstp
  I2cstop
  Waitms 5
  '*************
  '************
  L = Len(dat)
  For I = 1 To L
   Sv = Mid(dat , I , 1)
   Value = Asc(sv)
   Call Prnt_lcd(value)
   Waitus 100
  Next I
End Sub

Sub Curonoff(byval Cur As Byte)
   If Cur = 1 Then
     'cursor on
     Commee = &B00001100
     Commed = &B00001000
     Call Wr_lcd_init(commee , Commed)
     Waitus 110
     Commee = &B11011100
     Commed = &B11011000
     Call Wr_lcd_init(commee , Commed)
     Waitus 110
     '*********
   Else
     'cursor off
     Commee = &B00001100
     Commed = &B00001000
     Call Wr_lcd_init(commee , Commed)
     Waitus 110
     Commee = &B11001100
     Commed = &B11001000
     Call Wr_lcd_init(commee , Commed)
     Waitus 110
     '**********
   End If
End Sub

Sub Backlight(byval Bl As Byte)
   If Bl = 1 Then
      I2cstart
      I2cwbyte Addr_lcd
      I2cwbyte &B00001000
      I2cstop
   Else
      I2cstart
      I2cwbyte Addr_lcd
      I2cwbyte &B00000000
      I2cstop
   End If
End Sub

кстати, а разработчики Bascom решили прекратить поддержку этого замечательно простого компиллятора?

Отредактировано coder (2017-03-20 13:22:12)

0

141

$lib "i2c_twi.lbx"
Вот тут тогда тоже нужно править или самому заново написать библиотеку  :'(
Всё дело в том, что эта библиотека не отрабатывает ошибки шины и зависает наглухо! Попробуйте запустить несколько утройств на шине I2C и выдернуть питание или SCL или SDA при работе - получите зависон.

0

142

Ваше предположение неверно.
зависнуть МК в зависимости от наличия присоединенной библиотеки i2c_twi.lbx или от ее отсутствия в коде не может.

Даже больше скажу: наличие этой библиотеки не влияет на зависание программы микроконтроллера в принципе.

Я в своем примере подключил библиотеку i2c_twi.lbx для экономии кода. Баском при ее наличии использует хардовый TWI микроконтроллера. Без нее TWI эмулируется программно. В обоих случаях код будет работать правильно.

Зависание i2c !ТЕОРЕТИЧЕСКИ! возможно только в случае, когда Вы в коде укажете ACK через запятую после аргумента в команде i2cwbyte или после команды i2crbyte. Еще раз повторю - теоретически. У меня на практике такого ни разу не было, правда я и не пытался на горячую с шины i2c девайсы или подтягивающие резисторы сдергивать. И даже пробовать нехочу.

Предлагаю внимательно ознакомиться с алгоритмами и процессами взаимодействия устройств по шине i2c(TWI)

Так что, Bascom еще поддерживается разработчиками?

Отредактировано coder (2017-03-21 13:34:17)

0

143

coder написал(а):

Так что, Bascom еще поддерживается разработчиками?

Этот вопрос лучше переадресовать производителю: http://www.mcselec.com/
Но судя по жизни на форуме и выпускаемых новых версий баскома (как подарок под НГ) - видимо да.

0

144

coder написал(а):

Ваше предположение неверно.

Зависание i2c !ТЕОРЕТИЧЕСКИ! возможно только в случае, когда Вы в коде укажете ACK через запятую после аргумента в команде i2cwbyte или после команды i2crbyte.
У меня на практике такого ни разу не было, правда я и не пытался на горячую с шины i2c девайсы или подтягивающие резисторы сдергивать. И даже пробовать нехочу.


Предлагаю внимательно ознакомиться с алгоритмами и процессами взаимодействия устройств по шине i2c(TWI)

А я предлагаю делать простенький скетч из PCF8574 и DS3231. Ничего сложного там в коде нет, можно Сашины проекты взять уже готовые и компильнуть. Использовать ТОЛЬКО хардварный I2С!!!

Потом я предлагаю НАГЛЫМ ОБРАЗОМ ДЁРГАТЬ питание, шины, землю и тд. и ЧТОБЫ КОД генерировал в это время прочерки на дисплее вместо температуры и времени. И, ОСОБЕННО ВАЖНО, чтобы код имел способность к выходу из критической ситуации по WDT или ещё какими средствами и ПОСЛЕ ПОДКЛЮЧИНИЯ или ВОССТАНОВЛЕНИЯ ШИНЫ код работал как будто ничего и не было!!!

Потом я предложу изучить ассемблер, залезть в библиотеку i2c_twi.lbx и посмотреть ХОТЯ-БЫ вот на ЭТО:     (и найти косяк)
;generate I2C stop
_i2c_stop:
  Ldi r20, &B10010100                 ; perform stop
* out twcr,r20
_i2c_stop_1:
* In r20,twcr
;;;* Sbrc r20,twint                      ; skip if twint is cleared
* Sbrc r20,twsto                      ; skip if twsto is cleared
Rjmp _i2c_stop_1
Ret

А ещё не плохо бы увидеть ВИДЕО с наглыми попытками помешать шине нормально функционировать.

А... много что а... но попозже!  Жду ответа.

0

145

Я не знаю что такое Сашины проекты. Но наверное это не важно.

Предполагаю что ваша i2c_twi.lbx от какой-то кривой сборки Bascom'а, созданной непонятным горе-хакером.
Всвязи с содержанием запостированного Вами куска позволю себе предположить что и лицензии от Bascom и от i2c у Вас нет...
У меня лицензионная версия Bascom и i2c_twi. В моей i2c_twi.lbx такого куска нет.
Мне показалось что здесь собрались люди, увлеченные программированием в Bascom. Увлеченные настолько, что готовы поддержать производителя покупкой лицензии потому что этот компилятор действительно хорош для 8битных атмелов. Потому, что люди, создавшие его потратили часть своей жизни и оценили эти затраты, предложив цену за пользование своим трудом.
Пока я пару лет назад не перешел на stm32, я очень активно пользовался Bascom'ом, купил лицензию на сам компилятор и на дополнения к нему. И сейчас к нему возвращаюсь, когда хочется покодить тиньки и меги.
Я профессиональный программист. Мне неприятны любители хаченой халявы. Из-за таких людей я вынужден тратить лишнее время в своих проектах придумывая средства защиты.

0

146

coder написал(а):

позволю себе предположить что и лицензии от Bascom и от i2c у Вас нет...

Для I2C Master отдельная лицензия не нужна. Библиотека распространяется в составе дистрибутива, в т. ч. в демо версии. I2C Slave это отдельная тема и к этой отношения не имеет.

0

147

-NMi- поставьте себе демо вместо хаченой версии и не разглагольствуйте об ошибках разработчиков Bascom, наличие которых вы нашли в непонятно откуда взятых библиотеках.

0

148

coder написал(а):

Я не знаю что такое Сашины проекты. Но наверное это не важно.
Я профессиональный программист.


Странно такое слышать от профессионала...
А как же вы будете смотреть в глаза заказчику, у которого глюкнет шина I2C от какой-либо неисправности???

И главный вопрос - если в вашей проге наглым образом создать помеху на шине она "переварит" сей казус?

0

149

в глаза заказчиков я редко смотрю, разве что при подписании договора в моем городе.
Но Вашу аллегорию я понял)
Смотреть буду по разному...
если я писал только код, а железо собирал кто-то другой - неморгая.
если я делал устройство целиком, то не знаю... такого еще не было. Наверное смотреть буду со смущением.

На главный вопрос я прямо ответить не могу. Мой подход к написанию кода не позволяет.
Поясню - я считаю что при столь малом количестве памяти программ (особенно в тиньках) нет необходимости безрассудно расходовать ее на написание обработчиков ошибок. Надо правильно собирать железо!
И еще - я считаю что если устройство хоть на секунду перестает выполнять свои функции, то лучше его переделать, а не писать обработчик ошибки и продлевать жизнь калеке.

Немного не в тему, но...
Предположим МК связан по i2c с устройствами: память, термометр, барометр, гигрометр, экран, часы, МК.
Попробуйте поразмыслить к чему в этой связке приведет периодически появляющаяся ошибка шины i2c, пусть даже МК ее обработает и продолжит выполнение кода. И ответьте на вопрос - чего будут стоить данные с ошибками (или неполные данные) если это коммерческий проект.

0

150

-NMi- написал(а):

_i2c_stop:
  Ldi r20, &B10010100                 ; perform stop
* out twcr,r20
_i2c_stop_1:
* In r20,twcr
;;;* Sbrc r20,twint                      ; skip if twint is cleared
* Sbrc r20,twsto                      ; skip if twsto is cleared
Rjmp _i2c_stop_1
Ret

У меня версия конечно не последняя (этого года), но то, что стоит, в себе не содержит код 1 в 1. Возможно в новых версиях эту проблему устранили.

0


Вы здесь » Программирование ATMEL в BASCOM. » Исходники » Помогите с запуском LCD 4x20 по i2c