bst r16, 7 - Сохраним бит из регистра Т
*bld r25, PCF_E1 - Загрузить бит из Т в регистр
ВОПРОС: а "*" звёздочка зачем???
Программирование ATMEL в BASCOM. |
Привет, Гость! Войдите или зарегистрируйтесь.
Вы здесь » Программирование ATMEL в BASCOM. » Дисплеи и индикация » Помогите с запуском LCD 4x20 по i2c
bst r16, 7 - Сохраним бит из регистра Т
*bld r25, PCF_E1 - Загрузить бит из Т в регистр
ВОПРОС: а "*" звёздочка зачем???
При использовании портов в вашей библиотеке вы должны использовать .equ чтобы указать адрес:
Таким образом, библиотека менеджер знает адрес порта во время компиляции.
В качестве альтернативы предшествовать мнемоническую с * так код не будет скомпилирован в Lib.
Адрес регистра будет решен во время выполнения в этом случае.
Ничего не понял.
Т.е. любое обращение к ОТНОСИТЕЛЬНЫМ адресам переменных нужно предварять символом "*" ... так чтоли?
Здравствуйте! Позволю себе вставить свои "пять копеек". Вот мой вариант работы с индикатором по 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
Отредактировано kara1126 (2015-10-24 06:32:02)
Намана. А на асме?
Здравствуйте друзья.
Помогите разобраться, почему в Протеусе не работает данный код?
Поправьте, если что не так.
С такой конфигурацией pcf8574 в "железе" у меня все работает, в Протеусе нет.
На платке распаян PCF8574T, ноги 1, 2, 3 подтянуты к 1, дисплей LCD16x4.
В "железе" заработало с библиотекой "lcd_pcf8574.lib" и адресом индикатора &H4E.
Проблема в том, что надо делать прибор дальше, подсоединять следующие датчики,
а промоделировать в Протеусе я его не могу. А то, что работает в Протеусе - не работает на столе с моим железом.
Отредактировано VlGD (2016-02-14 19:51:35)
Проблема в том, что надо делать прибор дальше, подсоединять следующие датчики,
а промоделировать в Протеусе я его не могу. А то, что работает в Протеусе - не работает на столе с моим железом.
Посмотрите здесь
В железе работает адрес &H4E, в Протеусе &H7E.
И что Вам мешает сменить адрес PCF8574 ?
Поменял в Протеусе микросхему pcf8574А на pcf8574 (в библиотеке есть такая оказывается и вроде с нужным адресом).
Const Pcf8574_lcd = &H4E
Сигналы с нее на LCD при моделировании, видно что идут, но LCD молчит.
Что-то в коде похоже я не дописал для Протеуса.
Отредактировано VlGD (2016-02-15 17:34:55)
Удалось запустить программу в железе и в Протеусе с платкой 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 * 4Const 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 'хотелось бы откл. подсветку
LoopEnd
Отредактировано VlGD (2016-02-15 17:33:14)
Вы же сами назначили подсветку на порт1:
Код:
Const Pcf_bl = 1
Ребята, я тут не большой спец, извините пож. Я думал, что в этой библиотеке "lcd_pcf8574_9.lib" константа "Const Pcf_bl=1" отвечает за ногу RW, а не за подсветку. На 1-м порту у меня контакт RW дисплея. Без строчки Const Pcf_bl = 1 ни на столе, ни в Протеусе ничего не работает.
На 3-м порту- управление подсветкой не прямо, а через транзистор вроде, на 16-ю ногу LCD.
Тогда при чем тут "контакт 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" на столе включается-выключается, НО не эмулируется Протеусом.
Перепаивать или перерезать дорожки пока не буду.
Спасибо Вам за терпение, я разберусь.
Платка такая:
Отредактировано VlGD (2016-02-16 17:15:47)
Перепаивать или перерезать дорожки пока не буду.
Вот Ваш вариант, просто выпаять штырёк, и, как говориться, --"усё будет у порядке".
Народ есть исходник рабочий для синтезатора кв трансивера, управляет DDS AD 9850, есть чёткий исходник, и я ну ни как не могу сделать что бы у меня жки работало через PCF по I2c, у меня голова взрывается, пример беру, тестовая программка, всё работает, выводит буквы на экран, как только назначаю порты в исходнике на управление, закачиваю прошивку , ничего не отображает, что за такое, помогите кто, уже вторые сутки бьюсь
Народ помогите с протеусом - LCD2004 в железе высвечивает все 4 строки
а в протеусе 1 и 3
Если кому надо вот инициализация 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); // команда
нефиг там пин выковыривать, исправьте в либе 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)
Да, у меня ДАВНЫМ ДАВНО все это работает. И I2C шину тоже запустил БЕЗ морганий! Вклучаем МОЗГ и всё работает даже без резисторов.
Нашел подробное описание подключения LCD 1602 по I2C интерфейсу http://radiolaba.ru/microcotrollers/pod … feysu.html , по сути то же самое что и LCD 4x20, может кому будет полезно
Всем рабочего кода!
Пробегал мимо и увидел эту тему. Недавно попался мне экранчик 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)
$lib "i2c_twi.lbx"
Вот тут тогда тоже нужно править или самому заново написать библиотеку
Всё дело в том, что эта библиотека не отрабатывает ошибки шины и зависает наглухо! Попробуйте запустить несколько утройств на шине I2C и выдернуть питание или SCL или SDA при работе - получите зависон.
Ваше предположение неверно.
зависнуть МК в зависимости от наличия присоединенной библиотеки i2c_twi.lbx или от ее отсутствия в коде не может.
Даже больше скажу: наличие этой библиотеки не влияет на зависание программы микроконтроллера в принципе.
Я в своем примере подключил библиотеку i2c_twi.lbx для экономии кода. Баском при ее наличии использует хардовый TWI микроконтроллера. Без нее TWI эмулируется программно. В обоих случаях код будет работать правильно.
Зависание i2c !ТЕОРЕТИЧЕСКИ! возможно только в случае, когда Вы в коде укажете ACK через запятую после аргумента в команде i2cwbyte или после команды i2crbyte. Еще раз повторю - теоретически. У меня на практике такого ни разу не было, правда я и не пытался на горячую с шины i2c девайсы или подтягивающие резисторы сдергивать. И даже пробовать нехочу.
Предлагаю внимательно ознакомиться с алгоритмами и процессами взаимодействия устройств по шине i2c(TWI)
Так что, Bascom еще поддерживается разработчиками?
Отредактировано coder (2017-03-21 13:34:17)
Так что, Bascom еще поддерживается разработчиками?
Этот вопрос лучше переадресовать производителю: http://www.mcselec.com/
Но судя по жизни на форуме и выпускаемых новых версий баскома (как подарок под НГ) - видимо да.
Ваше предположение неверно.
Зависание 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
А ещё не плохо бы увидеть ВИДЕО с наглыми попытками помешать шине нормально функционировать.
А... много что а... но попозже! Жду ответа.
Я не знаю что такое Сашины проекты. Но наверное это не важно.
Предполагаю что ваша i2c_twi.lbx от какой-то кривой сборки Bascom'а, созданной непонятным горе-хакером.
Всвязи с содержанием запостированного Вами куска позволю себе предположить что и лицензии от Bascom и от i2c у Вас нет...
У меня лицензионная версия Bascom и i2c_twi. В моей i2c_twi.lbx такого куска нет.
Мне показалось что здесь собрались люди, увлеченные программированием в Bascom. Увлеченные настолько, что готовы поддержать производителя покупкой лицензии потому что этот компилятор действительно хорош для 8битных атмелов. Потому, что люди, создавшие его потратили часть своей жизни и оценили эти затраты, предложив цену за пользование своим трудом.
Пока я пару лет назад не перешел на stm32, я очень активно пользовался Bascom'ом, купил лицензию на сам компилятор и на дополнения к нему. И сейчас к нему возвращаюсь, когда хочется покодить тиньки и меги.
Я профессиональный программист. Мне неприятны любители хаченой халявы. Из-за таких людей я вынужден тратить лишнее время в своих проектах придумывая средства защиты.
позволю себе предположить что и лицензии от Bascom и от i2c у Вас нет...
Для I2C Master отдельная лицензия не нужна. Библиотека распространяется в составе дистрибутива, в т. ч. в демо версии. I2C Slave это отдельная тема и к этой отношения не имеет.
-NMi- поставьте себе демо вместо хаченой версии и не разглагольствуйте об ошибках разработчиков Bascom, наличие которых вы нашли в непонятно откуда взятых библиотеках.
Я не знаю что такое Сашины проекты. Но наверное это не важно.
Я профессиональный программист.
Странно такое слышать от профессионала...
А как же вы будете смотреть в глаза заказчику, у которого глюкнет шина I2C от какой-либо неисправности???
И главный вопрос - если в вашей проге наглым образом создать помеху на шине она "переварит" сей казус?
в глаза заказчиков я редко смотрю, разве что при подписании договора в моем городе.
Но Вашу аллегорию я понял)
Смотреть буду по разному...
если я писал только код, а железо собирал кто-то другой - неморгая.
если я делал устройство целиком, то не знаю... такого еще не было. Наверное смотреть буду со смущением.
На главный вопрос я прямо ответить не могу. Мой подход к написанию кода не позволяет.
Поясню - я считаю что при столь малом количестве памяти программ (особенно в тиньках) нет необходимости безрассудно расходовать ее на написание обработчиков ошибок. Надо правильно собирать железо!
И еще - я считаю что если устройство хоть на секунду перестает выполнять свои функции, то лучше его переделать, а не писать обработчик ошибки и продлевать жизнь калеке.
Немного не в тему, но...
Предположим МК связан по i2c с устройствами: память, термометр, барометр, гигрометр, экран, часы, МК.
Попробуйте поразмыслить к чему в этой связке приведет периодически появляющаяся ошибка шины i2c, пусть даже МК ее обработает и продолжит выполнение кода. И ответьте на вопрос - чего будут стоить данные с ошибками (или неполные данные) если это коммерческий проект.
_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. Возможно в новых версиях эту проблему устранили.
Вы здесь » Программирование ATMEL в BASCOM. » Дисплеи и индикация » Помогите с запуском LCD 4x20 по i2c