Re: BASCOM AVR в вопросах и ответах
Добавлено: Вс мар 22, 2015 01:49:57
Привет Саша!
Как то не очень информативно проблема описана. Поподробней можно?
Как то не очень информативно проблема описана. Поподробней можно?
Здесь можно немножко помяукать :)
https://radiokot.ru/forum/
Ну как же нету?Tankor писал(а): а вот для DS3231 ну не могу найти
Благодарствую добрый человек. Там реально всё есть.Radan писал(а):Ну как же нету?Tankor писал(а): а вот для DS3231 ну не могу найти
А здесь смотрели? - http://bascomavr.3bb.ru/viewtopic.php?id=1279
Код: Выделить всё
$regfile = "m8def.dat"
$crystal = 8000000
$hwstack = 128
$swstack = 64
$framesize = 64
$lib "i2c_twi.lbx" ' Библиотека аппаратного I2C.
' SCL и SDA, аппаратные выводы МК!!!
Config Sda = Portc.4 ' Конфигурация вывода Sda
Config Scl = Portc.5 ' Конфигурация вывода Scl
Config Twi = 40000
Config Lcd = 16 * 2 ' Дисплей 2 строки по 16 символов
Config Lcdbus = 4
Config Lcdmode = Port
Config Lcdpin = Pin , Db4 = Portb.0 , Db5 = Portb.1 , Db6 = Portb.2 , Db7 = Portb.3 , Rs = Portb.4 , E = Portb.5
Initlcd
Cursor Off Noblink
Cls
Dim Seco As Byte
Dim Mine As Byte
Dim Hour As Byte
Dim Weekday As Byte
Dim Dat As Byte
Dim Month As Byte
Dim Year As Byte
'заводим константы на биты чтения и записи ds3231
Const Ds3231w = &HD0 'бит записи
Const Ds3231r = &HD1 'бит чтения
Const Upradress = &H0E 'адрес регистра управления
'Активируем выход часовой микросхемы 1Гц для светодиода и прерывания
I2cstart 'запись байта в регистр упрaвления
I2cwbyte Ds3231w '&B11010000
I2cwbyte Upradress '&H0E
I2cwbyte &B00100000 'start squarewav output 1Hz (низкий уровень в bit3, bit4)
I2cstop
'----------\
' DS3231 |
' | / /
' (1Hz) SQW|-3-------[1kOm]-------|<|-------> +5v
' |
'----------/
Hour = 20
Mine = 18
Seco = 4
Gosub Settime
Do
'Читаем время
Gosub Getdatetime
Cls
Lcd Hour ; ":" ; Mine ; ":" ; Seco
Waitms 500
Loop
'========== Считывание даты и времени с микросхемы DS3231 ==========
'***************************************************************************************
Getdatetime:
I2cstart
I2cwbyte Ds3231w
I2cwbyte &H00
'I2cstop
I2cstart
I2cwbyte Ds3231r
I2crbyte Seco , Ack
I2crbyte Mine , Ack
I2crbyte Hour , Ack
I2crbyte Weekday , Ack
I2crbyte Dat , Ack
I2crbyte Month , Ack
I2crbyte Year , Nack
I2cstop
'переводим данные в двоично-десятичный формат
Seco = Makedec(seco)
Mine = Makedec(mine)
Hour = Makedec(hour)
Weekday = Makedec(weekday)
Dat = Makedec(dat)
Month = Makedec(month)
Year = Makedec(year)
' ' получаем десятки/единицы часов, минут, секунд
' Des_hour = Hour / 10
' Ed_hour = Hour Mod 10
' Des_min = Mine / 10
' Ed_min = Mine Mod 10
' Des_sec = Seco / 10
' Ed_sec = Seco Mod 10
' ' получаем десятки/единицы числа, месяца, года
' Des_dat = Dat / 10
' Ed_dat = Dat Mod 10
' Des_month = Month / 10
' Ed_month = Month Mod 10
' Des_year = Year / 10
' Ed_year = Year Mod 10
Return 'возвращаемся
'==========Отправляем текущую дату в часы==========
'***************************************************************************************
Setdate:
Dat = Makebcd(dat)
I2cstart
I2cwbyte Ds3231w
I2cwbyte 4
I2cwbyte Dat
I2cstop
Month = Makebcd(month)
I2cstart
I2cwbyte Ds3231w
I2cwbyte 5
I2cwbyte Month
I2cstop
Year = Makebcd(year)
I2cstart
I2cwbyte Ds3231w
I2cwbyte 6
I2cwbyte Year
I2cstop
Return
'==========Отправляем текущие время в часы==========
'***************************************************************************************
Settime:
Hour = Makebcd(hour)
I2cstart
I2cwbyte Ds3231w
I2cwbyte 2
I2cwbyte Hour
I2cstop
Mine = Makebcd(mine)
I2cstart
I2cwbyte Ds3231w
I2cwbyte 1
I2cwbyte Mine
I2cstop
Seco = Makebcd(seco)
I2cstart
I2cwbyte Ds3231w
I2cwbyte 0
I2cwbyte Seco
I2cstop
Return
'==========Обнуляем секунды==========
'***************************************************************************************
Sec_zero:
Seco = Makebcd(0)
I2cstart
I2cwbyte Ds3231w
I2cwbyte 0
I2cwbyte Seco
I2cstop
Return
'==========Инкремент минут==========
'***************************************************************************************
Min_plus:
Mine = Mine + 1
If Mine = 60 Then Mine = 0
Mine = Makebcd(mine)
I2cstart
I2cwbyte Ds3231w
I2cwbyte 1
I2cwbyte Mine
I2cstop
Return
'==========Инкремент часов==========
'***************************************************************************************
Hour_plus:
Hour = Hour + 1
If Hour = 24 Then Hour = 0
Hour = Makebcd(hour)
I2cstart
I2cwbyte Ds3231w
I2cwbyte 2
I2cwbyte Hour
I2cstop
Return
'==========Установить день недели==========
'***************************************************************************************
Week_day:
Seco = Makebcd(0)
I2cstart
I2cwbyte Ds3231w
I2cwbyte 3
I2cwbyte Weekday
I2cstop
Return
'==========Инкремент числа==========
'***************************************************************************************
Data_plus:
Dat = Dat + 1
If Dat > 31 Then Dat = 1
Dat = Makebcd(dat)
I2cstart
I2cwbyte Ds3231w
I2cwbyte 4
I2cwbyte Dat
I2cstop
Return
'==========Инкремент месяца==========
'***************************************************************************************
Mounth_plus:
Month = Month + 1
If Month > 12 Then Month = 1
Month = Makebcd(month)
I2cstart
I2cwbyte Ds3231w
I2cwbyte 5
I2cwbyte Month
I2cstop
Return
'==========Инкремент года==========
'***************************************************************************************
Year_plus:
Year = Year + 1
If Year > 99 Then Year = 13
Year = Makebcd(year)
I2cstart
I2cwbyte Ds3231w
I2cwbyte 6
I2cwbyte Year
I2cstop
ReturnВ конец этой строки надо поставить еще один пробел - " "Мурик писал(а):Код: Выделить всё
Lcd Hour ; ":" ; Mine ; ":" ; Seco
Это не так.vanyap1 писал(а):Если секунды сбросятся из 59 в 0, то на дисплее в последнем разряде останется - 9.
И будет там оставаться, пока секунды вновь не займут два разряда.
А зачем каждый раз перед выводом информации очищать дисплей? Нравятся моргания?Мурик писал(а):Это не так.Потому что перед выводом текста, содержимое индикатора очищается.
Код: Выделить всё
$regfile = "m8def.dat" 'подключаем файл заголовков для контроллера ATmega8
$crystal = 8000000 'определяем частоту кварца/внутреннего генератора
$hwstack = 128 'аппаратный стек
$swstack = 64 'програмный стек
$framesize = 64 'размер фрейма
$lib "i2c_twi.lbx" ' Библиотека аппаратного I2C.
' SCL и SDA, аппаратные выводы МК!!!
Config Sda = Portc.4 ' Конфигурация вывода Sda
Config Scl = Portc.5 ' Конфигурация вывода Scl
Config Twi = 40000 ' Скорость работы шины I2c на аппаратном уровне
Config Lcd = 16 * 2 'дисплей 2 строки по 16 символов
'указываем конфигурацию подключения дисплея к портам МК
Config Lcdpin = Pin , Db4 = Portc.3 , Db5 = Portc.2 , Db6 = Portc.1 , Db7 = Portc.0 , E = Portc.4 , Rs = Portc.5
Cursor Off 'выключить курсор
Cls 'очистить дисплей
Config Clock = User 'работа с DS3231
Const DS3231w = &HD0 'константа адреса записи DS3231
Const DS3231r = &HD1 'константа адреса чтения DS3231
Config Date = Dmy , Separator = . 'настраиваем способ отображения даты ДДММГГ, разделитель точка
Declare Sub Month_disp 'подпрограмма перевода цифровых значений месяца в названия месяца
Dim Daysmonth As Byte 'переменная дней в месяце
Dim Month_disp_str As String * 8 'переменная месяца, выводимая на дисплей
Dim Weekday_disp As String * 7 'переменная дня недели, выводимая на дисплей
Dim Weekday_read As Byte 'переменная номера дня недели, считываемая из DS3231
Dim Weekday As Byte 'переменная номера дня недели
_hour = 14 'устанавливаем начальный час
_min = 0 'устанавливаем начальные минуты
_sec = 0 'устанавливаем начальнные секунды
Gosub Settime 'перехоод на подпрограмму записи времени в DS3231
_day = 28 'устанавливаем начальную дату
_month = 3 'устанавливаем начальный месяц
_year = 15 'устанавливаем начальный год
Gosub Setdate 'перехоод на подпрограмму записи даты в DS3231
Gosub Getdatetime 'перехоод на подпрограмму чтения данных из DS3231
Do 'начало основного цикла
Call Month_disp 'вызываем подпрограмму перевода цифровых значений месяца в названия месяца
Locate 1 , 1 'задаем позицию курсора
Lcd Time$ 'выводим на ЖКИ время, вызывая подпрограмму чтения времени из DS3231
Locate 2 , 1 'задаем позицию курсора
Lcd _day ; " " ; Month_disp_str 'выводим на ЖКИ значение переменной _day, пробел, значение переменной Month_disp
If _year < 10 Then 'если значение переменной _year < 10 то,
Lcd " 200" ; _year ; " " 'выводим на ЖКИ, пробел, 200, значение переменной _year, 4 пробела
Else 'иначе
Lcd " 20" ; _year ; " " 'выводим на ЖКИ, пробел, 20, значение переменной _year, 4 пробела
End If 'конец если
Weekday_read = Dayofweek() 'считываем номер дня недели из DS3231
Weekday_disp = Lookupstr(weekday_read , Weekdays) 'преобразовываем номер дня недели в название дня недели
Locate 1 , 10 'задаем позицию курсора
Lcd Weekday_disp 'выводим на ЖКИ значение переменной Weekday_disp
Loop 'конец основного цикла
End 'конец программы
Sub Month_disp 'подпрограмма перевода цифровых значений месяца в названия месяца
'*******************************************************************************
Select Case _month
Case 1 : Month_disp_str = "ЗЅіapЗ" 'января
Daysmonth = 31
Case 2 : Month_disp_str = "дeіpa»З" 'февраля
Daysmonth = _year And &H03 'проверяем на високосный год
If Daysmonth = 0 Then 'если год високосный (переменная Daysmonth = 0)
Daysmonth = 29 'то переменная Daysmonth = 29
Else 'иначе
Daysmonth = 28 'переменная Daysmonth = 28
End If
Case 3 : Month_disp_str = "јapїa" 'марта
Daysmonth = 31
Case 4 : Month_disp_str = "aѕpe»З" 'апреля
Daysmonth = 30
Case 5 : Month_disp_str = "јaЗ" 'мая
Daysmonth = 31
Case 6 : Month_disp_str = "ёЖЅЗ" 'июня
Daysmonth = 30
Case 7 : Month_disp_str = "ёЖ»З" 'июля
Daysmonth = 31
Case 8 : Month_disp_str = "aіґycїa" 'августа
Daysmonth = 31
Case 9 : Month_disp_str = "ceЅїЗІpЗ" 'сентября
Daysmonth = 30
Case 10 : Month_disp_str = "oєїЗІpЗ" 'октября
Daysmonth = 31
Case 11 : Month_disp_str = "ЅoЗІpЗ" 'ноября
Daysmonth = 30
Case 12 : Month_disp_str = "гeєaІpЗ" 'декабря
Daysmonth = 31
End Select
End Sub
Getdatetime: 'подпрограмма чтения данных из DS3231
'*******************************************************************************
I2cstart ' I2C START
I2cwbyte DS3231w ' константа адрес записи DS3231
I2cwbyte 0 ' начальный адрес в DS3231
I2cstart ' I2C START
I2cwbyte DS3231r ' константа адрес чтения DS3231
I2crbyte _sec , Ack ' чтение значения СЕКУНД
I2crbyte _min , Ack ' чтение значения МИНУТ
I2crbyte _hour , Ack ' чтение значения ЧАСА
I2crbyte Weekday , Ack ' чтение значения НЕДЕЛИ
I2crbyte _day , Ack ' чтение значения ДНЯ
I2crbyte _month , Ack ' чтение значения МЕСЯЦА
I2crbyte _year , Nack ' чтение значения ГОДА
I2cstop 'I2C STOP
_sec = Makedec(_sec) : _min = Makedec(_min) : _hour = Makedec(_hour) 'преобразуем все переменные в десятичный вид
_day = Makedec(_day) : _month = Makedec(_month) : _year = Makedec(_year) 'преобразуем все переменные в десятичный вид
Return 'возврат из подпрогрммы
Setdate: 'подпрограмма записи даты в DS3231
'*******************************************************************************
_day = Makebcd(_day) : _month = Makebcd(_month) : _year = Makebcd(_year) 'преобразуем все переменные в двоичный вид
I2cstart ' I2C START
I2cwbyte DS3231w ' константа адрес записи DS3231
I2cwbyte 4 ' начальный адрес в DS3231
I2cwbyte _day ' запись ДЕНЬ
I2cwbyte _month ' запись МЕСЯЦ
I2cwbyte _year ' запись ГОД
I2cstop 'I2C STOP
Return 'возврат из подпрогрммы
Settime: 'подпрограмма записи времени в DS3231
'*******************************************************************************
_sec = Makebcd(_sec) : _min = Makebcd(_min) : _hour = Makebcd(_hour) 'преобразуем все переменные в двоичный вид
I2cstart ' I2C START
I2cwbyte DS3231w ' константа адрес записи DS3231
I2cwbyte 0 ' начальный адрес в DS3231
I2cwbyte _sec ' запись СЕКУНД
I2cwbyte _min ' запись МИНУТ
I2cwbyte _hour ' запись ЧАСА
I2cstop 'I2C STOP
Return 'возврат из подпрогрммы
Weekdays:
'*******************************************************************************
Data "ЁoЅeг. " 'Понед.
Data "BїopЅёє" 'Вторник
Data "Cpeгa " 'Среда
Data "«eїіepґ" 'Четверг
Data "ЁЗїЅёеa" 'Пятница
Data "CyІІoїa" 'Суббота
Data "Bocєp. " 'Воскр.Для нее подходит код от DS1307 1 в 1 --->Tankor писал(а):Выручайте начинающего!
Еле-еле прикрутил lcd и DHT11, вроде всё работает, а вот для DS3231 ну не могу найти в качестве примера на баскоме ничего. Может у кого есть пример его использования или библиотека?
Makebcd переводит переменную в двоично-десятичный формат, это по коду вышеМурик писал(а):Вот еще код проверенный в железе. http://bascomavr.3bb.ru/viewtopic.php?id=1267#p14402
Это верно. Кроме инициализации 1 Гц, да и работа с внутренним датчиком температуры только в 3231 имеется.fedyasolder писал(а): Для нее подходит код от DS1307 1 в 1 --->
Код: Выделить всё
'Активируем выход часовой микросхемы 1Гц для светодиода и прерывания
I2cstart 'запись байта в регистр упрaвления
I2cwbyte Ds3231w '&B11010000
I2cwbyte Upradress '&H0E
I2cwbyte &B00100000 'start squarewav output 1Hz (низкий уровень в bit3, bit4)
I2cstopКод: Выделить всё
I2cwbyte &B00000000 'start squarewav output 1Hz (низкий уровень в bit3, bit4)тогда индикатор будет моргать два раза в секунду, перед каждым обновлением.Мурик писал(а):Это не так.
Потому что перед выводом текста, содержимое индикатора очищается.
Код: Выделить всё
o=o+1
if o=255 to
p=p+1
o=0
end if
if p=5 to
portd.1=1 'включаем реле
else
portd.1=0
end if
wait 10Благодарю за помощь. Потихоньку становится понятно работа этой микросхемой. По Вашему коду вопрос- а разве ds3231 не знает о количестве дней в месяце и о высокосном годе?max50 писал(а):А зачем каждый раз перед выводом информации очищать дисплей? Нравятся моргания?Мурик писал(а):Это не так.Потому что перед выводом текста, содержимое индикатора очищается.
Так попробуйте:
Sub Month_disp 'подпрограмма перевода цифровых значений месяца в названия месяца
'*******************************************************************************
Select Case _month
Case 1 : Month_disp_str = "ЗЅіapЗ" 'января
Daysmonth = 31
Case 2 : Month_disp_str = "дeіpa»З" 'февраля
Daysmonth = _year And &H03 'проверяем на високосный год
If Daysmonth = 0 Then 'если год високосный (переменная Daysmonth = 0)
Daysmonth = 29 'то переменная Daysmonth = 29
Else 'иначе
Daysmonth = 28 'переменная Daysmonth = 28
End If
Case 3 : Month_disp_str = "јapїa" 'марта
Daysmonth = 31
Case 4 : Month_disp_str = "aѕpe»З" 'апреля
Daysmonth = 30
Case 5 : Month_disp_str = "јaЗ" 'мая
Daysmonth = 31
Case 6 : Month_disp_str = "ёЖЅЗ" 'июня
Daysmonth = 30
Case 7 : Month_disp_str = "ёЖ»З" 'июля
Daysmonth = 31
Case 8 : Month_disp_str = "aіґycїa" 'августа
Daysmonth = 31
Case 9 : Month_disp_str = "ceЅїЗІpЗ" 'сентября
Daysmonth = 30
Case 10 : Month_disp_str = "oєїЗІpЗ" 'октября
Daysmonth = 31
Case 11 : Month_disp_str = "ЅoЗІpЗ" 'ноября
Daysmonth = 30
Case 12 : Month_disp_str = "гeєaІpЗ" 'декабря
Daysmonth = 31
End Select
End Sub
.
Код: Выделить всё
$regfile = "attiny13.dat"
$crystal = 8000000
Config Portb.1 = Output 'Êîíôèãóðèðóåì Ïîðò B.1 Êàê Âûõîä
Config Pinb.2 = Input 'Êîíôèãóðèðóåì Ïîðò B.1 Êàê Âõîä
Config Adc = Single , Prescaler = Auto , Reference = Avcc 'Íàñòðàèâàåì ÀÖÏ
Start Adc 'Çàïóñê ÀÖÏ
Do
If Pinb.2 = 0 Then
Portb.1 = 0
End If
If Pinb.2 = 1 Then
Portb.1 = 1
Waitms 500
Portb.1 = 0
End If
Loop ' êîíåö áåñêîíå÷íîãî öèêëà
EndКод: Выделить всё
$regfile = "attiny13.dat"
$crystal = 8000000
$hwstack = 10
$swstack = 20
$framesize = 30
Config Portb.1 = Output
Config Pinb.2 = Input
Config Adc = Single , Prescaler = Auto , Reference = Avcc
Dim L1 As Integer
Dim D As Byte
Dim T As Byte
Start Adc
Do
L1 = Getadc(3) 'получаем значение
If L1 < 500 Or Pinb.2 = 1 Then 'проверяем условие, как по АЦП, так и по порту
Waitms 200 'для задержки дребезга
If T < 10 Then T = T + 1 ' убираем таким способом возможные помехи, отсчитываем 9 раз по 0,2 сек. а после пускаем таймер, это нужно, чтоб релюхи и им подобное не шумели.
Else
If T < 10 Then T = 0 'ну если дребезг был или пульсация, обнуляем
End If
If T => 10 Then
Wait 57 'расчёт простой, 57 секунд умножить на 240 с чем то раз - получаем почти 4 часа, если нужно точнее, сам считай ))))
T = T + 1
Portb.1 = 1
Else
Portb.1 = 0
End If
If T => 253 Then ' если наприбавляли 253 (минус десять проверочных раз в начале) по 57 секунд, вырубить всё.
T = 0
End If
Loop
End
Век живи, век учисьkoms48 писал(а): ....
for var = 1 to 144
....
End