Интересное дело...Рабочая программа для М8 не работает на М328.
Fuse-бит CKDIV8 в каком состоянии ?
Программирование ATMEL в BASCOM. |
Привет, Гость! Войдите или зарегистрируйтесь.
Вы здесь » Программирование ATMEL в BASCOM. » Связь проводная и бесп-ная, интерфейсы, протоколы » Использование модуля SIM800l
Интересное дело...Рабочая программа для М8 не работает на М328.
Fuse-бит CKDIV8 в каком состоянии ?
boida
Убери в Getline строки Case 0, и Case 13. Столкнулся с этим тоже. 328 вообще вешалась на подпрграмме Readfirstsms:, а 8 нормально работала.
'подпрограмма для разбора сообщения модуля
'=========================================================================
Sub Getline(s As String)
S = ""
Do
Buf = Inkey() 'берем символ из буфера в формате ASCII
Select Case Buf
Case 10 : If S <> "" Then Exit Do 'конец строки, значит выходит из подпрограммы
Case Else : If Buf > 31 Then S = S + Chr(buf) 'печатаемые символы начинаются с кода 32 по таблице АСКИ, из них составляем строку
End Select
Loop
End SubВ вашей программе для меня сложновато разобраться
! Вы наверное шутите !
Тем более вывода Aref у Tiny84 нет
Он есть, но в случае измерения собственного напряжения питания он не нужен
Вешается кондюк 0.1мкФ. Который Александр в своей программе заряжает, разряжает согласно даташиту.
Разряжается и заряжается внутренняя ёмкость МК, не внешняя.
Если можно чего подкорректировать в измерении АЦП, вот весь код
Коррекция показаний из-за разброса опорного 1.1v - Const Const_коэффициент_перещета_1_1v = 1100
Напряжение питания МК с точкой и всеми знаками после запятой в этой переменной - Vcc_sin
Напряжение питания МК с двумя знаками после запятой но без запятой в этой переменной - Vcc_word
'===============================================================================
Const Const_коэффициент_перещета_1_1v = 1100
'===============================================================================
$regfile = "attiny84.dat" 'Документация на МК http://ww1.microchip.com/downloads/en/D … oc8183.pdf
$crystal = 8000000
$framesize = 64
$hwstack = 64
$swstack = 64'------------------------- Настройка Watchdog --------------------------------
On Wdt Обработка_прерывания_watchdog 'Nosave ' Переход на подпрограмму обработки прерывания после переполнения таймера-счётчика Watchdog
Config Watchdog = 1024 'время срабатывания ~1сек., при соответствии $crystal и фьюзов МК ' 16 32 64 128 256 512 1024 2048 4096 8192
'===============================================================================
Config Porta.1 = Output
Pitanie Alias Porta.1
Pitanie = 1
'===============================================================================
Config Porta.2 = Output
Data_ Alias Porta.2
Data_ = 0
'===============================================================================
Dim Sendata(4) As Word 'весь блок подлежащий передаче
Dim Sch As Byte
Dim Secunda As Word
Dim L As Word At Sendata(3) Overlay '4 байт
'=========Переменные передачи======================================================================
Dim N As Byte : N = 16
Dim Байты As Byte
Dim Номер As Word At Sendata(1) Overlay : Номер = 15 '0 байт
Dim Crc As Word At Sendata(4) Overlay '5 байт
Dim Preambula As Byte
Dim Nomer_bita As Byte
Dim Odin As Word : Odin = 1500
Dim Nol As Word : Nol = 500
Dim Pausa As Word : Pausa = 500
'========Переменные 1 датчика 18В20====================================================================================================
Dim Tds1 As Integer At Sendata(2) Overlay '1 байт температура получаемая с 1 датчика в 0.1градуса. 10 = 1,0 градус
Dim Err_c1 As Bit'===============================================================================
' Н А С Т Р О Й К А программного USART
'===============================================================================Config Portb.0 = Output
Open "comb.0:4800,8,n,1" For Output As #1 ' TXD на Portb.0'===============================================================================
' Н А С Т Р О Й К А АЦП
'===============================================================================Const Channel_temperature = &B_0010_0010
Const Channel_v_bg = &B_0010_0001
Const Channel_gnd_0v = &B_0010_0000'&B_0000_0000
' || |
' || |
' || +------- Bit 3 – SM0: Sleep Mode Select Bit 3
' |+--------- Bit 4 – SM1: Sleep Mode Select Bit 4
' +---------- Bit 5 – SE: Sleep EnableConst Значение_idle = &B_0010_0000
Const Значение_adcnoise = &B_0010_1000
Const Значение_powerdown = &B_0011_0000
Const Значение_powerstandby = &B_0011_1000Config Adc = Single , Prescaler = 128 , Reference = Avcc
Start Adc
On Adc Обработка_прерывания_ацп Nosave
'Формула расчёта: 1024 * 0,99...1,21 = 1013,76...1239,04
Dim Флаг_критический_разряд As Byte
Dim Temp_ацп_avcc_word As Word : Temp_ацп_avcc_word = 0
Dim Данные_ацп_avcc_word As Word : Данные_ацп_avcc_word = 0Dim Vcc_word As Word
Dim Vcc_sin As Single'-------------- Разрешаем работу необходимых прерываний ----------------------
Enable Wdt ' Разрешаем прерывание от переполнения таймера Watchdog
'------------ Разрешаем работу всех включенных прерываний --------------------
Enable Interrupts
'===============================================================================
' Запуск и предварительная настройка
'==============================================================================='===============================================================================
' Г Л А В Н Ы Й Ц И К Л
Главный_цикл:
'===============================================================================If Secunda = 300 Then
Pitanie = 0' Adcsra.aden = 1 'Включаем АЦП
' Waitms 100
' L = Getadc(0) 'считываем канал АЦП и записываем в переменную
' L = L / 2
' L = L - 14Gosub Измерение_avcc
Print #1 , Vcc_word
Gosub 18b20
Crc = Tds1 + Номер
Crc = Crc + LFor Sch = 0 To 2
Waitms 100For Preambula = 1 To N
Data_ = 1
Waitus Odin
Data_ = 0
Waitus Odin
Next PreambulaData_ = 1
Waitms 4
Data_ = 0Gosub Peredacha_bytov
N = 8
Next Sch
N = 16
Waitms 50
Adcsra.aden = 0
Pitanie = 1
Waitms 10
Secunda = 0
End If'===============================================================================
Powerdown
Goto Главный_цикл
End
'==============================================================================='===============================================================================
Измерение_avcc:
'-------------------------------------------------------------------------------
Enable Adc
Adcsra.aden = 1 'Включаем АЦП
Waitms 250 'Ждём, пока запустится источник внутреннего опорного напряжения 1.1V, от частоты МК не зависитAdmux = Channel_gnd_0v 'Готовимся разряжать внутреннюю ёмкость МК
Waitus 70 'Ждём, пока разрядится ёмкость, рекомендовано Atmel стр.9., п.п.3.4 Band gap measurement (http://www.atmel.com/images/doc8444.pdf)!ldi R16 , Значение_adcnoise 'Выставляем, как будем спать
!sts MCUCR , R16 'Пишем в региср
!sleep 'Отправляемся спать!nop
Admux = Channel_v_bg 'Готовимся измерять Avcc (VBG) стр.145 http://ww1.microchip.com/downloads/en/D … oc8183.pdf
Waitus 70 'Время ожидания заряда ёмкости, рекомендовано Atmel стр.9., п.п.3.4 Band gap measurement (http://www.atmel.com/images/doc8444.pdf)
!ldi R16 , Значение_adcnoise 'Выставляем, как будем спать
!sts MCUCR , R16 'Пишем в региср
!sleep 'Отправляемся спать!nop
Disable Adc
'Выключаем АЦП, слишком много потребляет 'Bit 7 – ADEN: ADC Enable / Disable
Adcsra.aden = 0
'Выключаем компаратор Bit 7 – ACD: Analog Comparator Disable
Acsr.acd = 0Vcc_sin = Const_коэффициент_перещета_1_1v / Данные_ацп_avcc_word
Vcc_word = Vcc_sin * 100'-------------------------------------------------------------------------------
Return
'==============================================================================='===============================================================================
Обработка_прерывания_ацп:
'-------------------------------------------------------------------------------
!push R16!lds R16 , adcl
!sts {Данные_ацп_avcc_word} , R16!lds R16 , adch
!sts {Данные_ацп_avcc_word + 1} , R16!pop R16
!reti
'-------------------------------------------------------------------------------
Return
'==============================================================================='===============================================================================
Обработка_прерывания_watchdog:
Incr Secunda
Return
'===============================================================================
'======Обработка датчика температуры DS18B20====================================
18b20:
1wreset Pina , 3
If Err = 1 Then
Err_c1 = 1 'ставим флаг ошибки датчика
Tds1 = 32767 'если при опросе небыло ответа ставим флаг ошибки
Else
Err_c1 = 0
1wwrite &HCC , 1 , Pina , 3 'пропуск ROM(для всех)
1wwrite &H44 , 1 , Pina , 3 'конвертировать температуру(для всех)
End IfWaitms 750
'если небыло ошибки при начале конвертирования
If Err_c1 = 0 Then
1wreset Pina , 3
If Err = 1 Then
Tds1 = 32767 'если при опросе небыло ответа ставим флаг ошибки
Else 'иначе, если ошибки не было, продолжаем опрос датчика
1wwrite &HCC , 1 , Pina , 3
1wwrite &HBE , 1 , Pina , 3
Tds1 = 1wread(2 , Pina , 3)
Tds1 = Tds1 * 10
Tds1 = Tds1 \ 16
End If
End If
Return
'------------------------------------------------------------------------------------------
Peredacha_bytov:Waitus Pausa
Waitus Pausa
For Байты = 1 To 4
For Nomer_bita = 15 To 0 Step - 1 'Старшим битом вперед
If Sendata(байты).nomer_bita = 1 Then
Data_ = 1 'Передний фронт импульса передачи
Waitus Odin 'Длительность 1 1500мкС
Data_ = 0 'Задний фронт импульса передачи
Waitus Pausa 'Пауза 500мкС. Общая длительность передачи 1 (1500+500=2000мкС)
Else
Data_ = 1
Waitus Nol 'Длительность 0 500мкС
Data_ = 0
Waitus Pausa 'Общая длительность передачи 0 (500+500=1000мкС)
End If
Next Nomer_bita
Next Байты
Data_ = 1 'Передний фронт для измерения последнего бита
Waitus Nol '------
Data_ = 0 '------
Return
Железа нет, так что надо Вам пробовать, возможны проблемы по причине не соответствия документации и реального МК. Прецеденты были.
Только измерение Avcc здесь
sasha_1973
В железе проверяю код "Только измерение Avcc". Результат довольно отличный.
От 4.15 до 3.75 занижает ровно на 0.1В. То есть при 4.15 выдает 4.05, 3.75 - 3.65В.
Дальше начинает врать все меньше. Самое интересное примерно от 3.3 до 2.66 снова стабильно но уже на 0.06В. Получаем погрешность 0.04В.
Можно просто вычесть Vcc_word = Vcc_word + 8, и получиться нормальное измерение.
Дома перешил два радиодатчика вообще отлично. Правда на минимальных напряжениях нечем проверить.
Или есть еще варианы?
В asm полный 0, в этом коде ничего не понимаю.(((
Отредактировано rom-i (2019-06-05 01:43:11)
Nord
Делитель на 8 выключил, я так на тинке 13 накололся.
С программой разобрался. нужно было добавить еще по одному Getline, хотя непонятно почему..
boida
Эхо не отключено в установках SIM800? Вот строка лишняя.
Подскажите пожалуйста по оператору Format:
В смс должно передавать
1 - если число трехзначное то только его без десятичной точки и дробной части
2 - если число двухзначное то десятки, единицы, десятичная точка и десятые
3- если число однозначное то единицы, десятичная точка и десятые.
Dim Spdstr As String * 5
Dim Spd As Integer
Dim Spd_rez As Single
Dim Koef As Integer
Koef = 10
Adcc:
Spd = Getadc(0) (Считываем 429)
Spd_rez = Spd / Koef (делим на 10 429/10 = 42,9
Spdstr = Str(spd_rez) (переводим из числа в строку)
Spdstr = Format(spdstr , "###.#") (Форматируем)
Reset Watchdog
Waitms 10
Flushbuf
Return
Spdstr = "42.89999770"
Как так если у меня эта переменная вмещает всего 5 символов?
А когда Koef = 1
Spdstr = "430..0"
Отредактировано boida (2019-06-04 21:50:39)
boida
Нужны только десятые?
Для переменных Single нужно в строку переводить не Str. Spdstr = Str(spd_rez), а Spdstr = Fusing(spd_rez).
Если прописать Spdstr = Fusing(spd_rez , "format"), получиться, что надо. После запятой десятые, если нет десятых целое число.
Отредактировано rom-i (2019-06-04 22:32:49)
Подскажите пожалуйста по оператору Format
1 - если число трехзначное то только его без десятичной точки и дробной части
2 - если число двухзначное то десятки, единицы, десятичная точка и десятые
3- если число однозначное то единицы, десятичная точка и десятые.
Выполняем проверку, "скольки" значное имеем число (уже в строковом виде).
По результату выполняем форматирование (например):
If <3-значное> Then
Spdstr = Format(spdstr , "###.#")
If <2-значное> Then
Spdstr = Format(spdstr , "##.#")
If <1-значное> Then
Spdstr = Format(spdstr , "#.#")
Можно так же использовать Fusing, он работает сразу с числовыми исходными.
Отредактировано Nord (2019-06-04 22:40:31)
Подскажите пожалуйста по оператору Format
Нашел я вашу ошибку. 
И сам ее позже повторил... 
Spdstr = Format(spdstr , "###.#")
Format не использует маску "###.#", тут применяется "000.0" ! 
Подробнее тут: Операторы работы со строками
Integer, Word можно форматировать, и "#.#". Единственно будет откидывать ноли впереди идущие независимо сколько до запятой #. Например имеем Tds = 225, то Tds_str = 22.5, или Tds = 25, то Tds_str = 2.5.
Если форматировать "0.0" результат будет тотже.
Но "000.0", тогда Tds = 225, то Tds_str = 022.5, а Tds = 25, то Tds_str = 002.5. Это удобно использовать для строчных ЖК индикаторов. Строка постоянной длины, не надо делать Cls. Не будет моргухи при обнулении дисплы, а значения будут просто меняться.
Вот с Single тож помню первый раз помучился когда в строчную переводил оператором Str. Бред получается. Fusing нормально все.
Только в "маске", или как моей документации "format" нет смысла ставить перед "." больше одной #. После да. Сколько #, столько знаков.
Spdstr = Fusing(spdstr , "#.#") 'Переводим Single в String
Spdstr = Format(spdstr , "000.0") 'Делаем строку нужной длины если это нужно.
Отредактировано rom-i (2019-06-05 02:46:57)
Integer, Word можно форматировать, и "#.#".
Откуда информация ? 
Возможно, так и есть, но в официальном хелпе про это ничего нет...
Nord
Официальных источников нет. Просто в интернет большинство форматирует именно #. Проверял, нормально. Но меня больше "0" устраивают. Для вывода на LCD.
Пошел по Вашей ссылке "Операторы работы cо строками". Там Александр добавил. Но заинтересовал оператор Insertchar. Не понял как этим пользоваться.
Insertchar "1234" , 4 , "."
получаем - "123.4"
Официальных источников нет.
Официальный источник один - официальная справка Bascom.
Если у вас компилятор пропускает, то это еще ни о чем ни говорит... 
Но заинтересовал оператор Insertchar. Не понял как этим пользоваться.
Insertchar "1234" , 4 , "."получаем - "123.4"
Вставить в строку "1234", в позицию №4 символ "."
Подробнее тут: Операторы работы со строками
Спасибо за ссылку.
В ней нашел оператор который решит еще один вопрос.
Возможно понадобится отправлять смс с какой то периодичностью, например раз в час или 30 мин.
Из ссылки:
Split - разбивает строку на элементы массива.
Dim Instring As String * 15
Dim Ar(5) As Byte
Dim count As Byte
Instring = “11,22,33,44,55“
count = Split( Instring , Ar(1) , ",") ‘ результат:
count = 5
Ar(1) = 11
Ar(2) = 22
Ar(3) = 33
Ar(4) = 44
Ar(5) = 55
Получается можно сделать так:
' Периодическая отправка смс
Sendtime:
Print "AT+CCLK?" ' Текущая дата и время
Waitms 300
Gosub Getline ' читаем строку
Ti = Left(sk , 5)
Reset Watchdog
If Ti = "+CCLK" Then
Ti = Mid(sk , 17 , 8) 'вытаскиваем чч:мм:сс
Count = Split(ti , Ar(1) , ":")
' Ar(1) - часы
' Ar(2) - минуты
' Ar(3) - секунды
If Ti_str2 = "1" Then 'через 30 минут
Reset Watchdog
End If
If Ti_str2 = "2" Then 'через 60 минут
Reset Watchdog
End If
Spdstr = Format(spdstr , "#.#")
Вот так работает,, но если число целое все равно засвечивает десятичную точку и нуль в десятых.
Меня так устраивает.
Спасибо !
Spdstr = Format(spdstr , "#.#")
Вот так работает, но если число целое все равно засвечивает десятичную точку и нуль в десятых.Меня так устраивает.
Format(spdstr , "0.0") не пробовали, как того синтаксис требует ?
Или Format(spdstr , "000.0"), например ?
Не верится мне в такие промахи автора Bascom... 
Онлайн-хелп не дворники же писали...
Отредактировано Nord (2019-06-05 23:02:38)
В общем как-то так. 
У меня то же работает данный модуль sim800l 2.0 5V
Работает это все дело от AC/DC преобразователя 5В 2,4 А
https://www.chipdip.ru/product/amel12-5scjz
Какой МК ?
Upd
Не сразу разглядел... 
В вашем случае надо включить биты 43 и 21
Отредактировано Nord (2019-06-09 22:22:16)
Там по три варианта, ставить 00?
Думаю, LockBit21 - 00, этого должно хватить.
реально работающий несколько лет проект, переработан на модуль sim800L, работает не выключаясь несколько месяцев: передаёт метеоданные. Каждые 6 минут передача в интернет
Александр расскажите пожалуйста как и куда передаются данные и как их потом просмотреть?
Так же на территории есть вайфай.
Прогнозирую, что работа модуля будет обходиться не так и дешево в месяц. Хотел бы рассмотреть передачу данных через GPRS или WI-FI.
Куда и как передавать и как потом принимать эти данные.
Интересно... ни ек нельзя сделать, что бы модуль отправлял сообщения в воцап например?
Аппаратный USART работает на Sim800l. Програмно передаю второму МК мега8 данные температуры. Терминал принимает без сбоев. Но с прерыванием по RX вынянчился. Если передавать принятое, действительно иногда бред идет. Скоромть уменьшил до 9600. От МК до МК полметра провода. Питание одно, автомобильный аккум. Пульсации исключены. МК в момент приема вешается, иногда обнуляется. Может отлично работать полчаса.
Может в коде накосячил?
Железо исключено. Хотя, и собрано на макетке(уже на двух), результат один в один.
$regfile = "m8adef.dat"
$crystal = 8000000
$baud = 9600
$hwstack = 160
$swstack = 160
$framesize = 64
'=====Конфигурация дисплея
Config Lcdpin = Pin , Rs = Portd.2 , E = Portd.3 , Db4 = Portd.4 , Db5 = Portd.5 , Db6 = Portd.6 , Db7 = Portd.7
Config Lcd = 16 * 2
Initlcd
Cls
Cursor Off
Deflcdchar 1 , 7 , 5 , 7 , 32 , 32 , 32 , 32 , 32 'Градус
Deflcdchar 2 , 4 , 4 , 4 , 14 , 14 , 4 , 4 , 4 'Заслонка
Deflcdchar 3 , 14 , 10 , 10 , 10 , 30 , 14 , 14 , 4 'Термометр
'-----------------------------------------------------------------------------
Dim Шаги As Word
Dim Положение As Word
Dim Угол As Word
Dim Угол_str As String * 2
'-----------------------------------------------------------------------------
'=========================Переменные USART======================================================
On Urxc Reads
Enable Urxc
Dim Буфер_приема As String * 20
Dim Stroka As String * 20
Dim Принятый_символ As Byte
Dim Temper1 As String * 5
Dim Temper2 As String * 5
Dim Temp1 As Word
Dim Temp2 As Word
Dim Crc As String * 7
Dim Crcrx As String * 7
'===============================================================================
Config Portc.2 = Output 'Шаги
Config Portc.3 = Output 'направление вращения
Config Portc.4 = Output 'Включение драйвера ШД
'-----------------------------------------------------------------------------
Config Pinb.0 = Input
Zero Alias Pinb.0 : Portb.0 = 1
'-----------------------------------------------------------------------------
If Zero = 1 Then Gosub Обнуление
Wait 1
Enable Interrupts ' разрешаем все прерывания
'**********************************************************************************************
Do
Temper1 = Left(stroka , 4) : Temper2 = Mid(stroka , 5 , 3) : Crcrx = Right(stroka , 7)
Crc = Temper1 + Temper2
Temp1 = Val(temper1) : Temp2 = Val(temper2)
If Temp1 > 800 And Zero <> 0 Then Gosub Обнуление 'Если проебаны шаги
If Crc = Crcrx Then
Положение = Temp1 * 35
Положение = Положение / 10 'Грубо 800 * 3,5 = 2800 шагов. Где 800 это 80,0 градуса Цельсия
Положение = 2800 - Положение 'Инвертируем показания мин Т заслонка открыта
If Положение > 2800 Then Положение = 0 'Нет отрицательным величинам более 80,0
Угол = Положение / 30 '2750 Это 90 Градусов для Индикации
Gosub Indikator
If Шаги < Положение Then Gosub Plus
If Шаги > Положение Then Gosub Minus
End If
Waitms 200
Loop
'**********************************************************************************************
Indikator:
Temper1 = Format(temper1 , "000.0")
Temper2 = Format(temper2 , "00.0")
Угол_str = Str(угол)
Угол_str = Format(угол_str , "00")
Locate 1 , 1
Lcd Chr(2) ; Угол_str ; Chr(1) ; " " ; Chr(3) ; Temper1 ; Chr(1) ; "C"
Locate 2 , 1
Lcd "Komnata " ; Temper2 ; Chr(1) ; "C "
Return
'****** Вращение вправо открытие ********************************************
Plus:
Do
Reset Portc.4
Reset Portc.2
Reset Portc.3
Waitus 1000
Set Portc.2
Waitus 1000
Incr Шаги 'Увеличиваем переменную счета сделанных шагов
Loop Until Шаги = Положение 'Выходим из подпрограммы если количество сделанных шагов равня заданным
Set Portc.4
Return
'****** Вращение влево закрытие ******
Minus:
Do
Reset Portc.4
Reset Portc.2
Set Portc.3
Waitus 1000
Set Portc.2
Waitus 1000
Decr Шаги
Loop Until Шаги = Положение
Set Portc.4
Return
'****** Выход в ноль ******
Обнуление:
Do
Reset Portc.4
Reset Portc.2
Set Portc.3
Waitus 1000
Set Portc.2
Waitus 1000
Loop Until Zero = 0
Set Portc.4
Шаги = 0
Положение = 0
Return
'======Если пришло по USART==============================================================
Reads:
Принятый_символ = Udr
If Принятый_символ <> 10 Then
If Принятый_символ <> 13 Then Буфер_приема = Буфер_приема + Chr(принятый_символ)
Else
Stroka = Буфер_приема
Буфер_приема = ""
End If
ReturnАппаратный USART работает на Sim800l. Програмно передаю второму МК мега8 данные температуры. Терминал принимает без сбоев. Но с прерыванием по RX вынянчился.
Неудивительно. 
Если используете прием по прерыванию UART по модели Александра, то зачем кастрировали обработку прерывания ?
Там флаг выставлялся и прерывание отключалось.
В главном цикле по наличию флага (!) велась обработка принятого и только потом (!) прерывание включалось...
А сейчас у вас из UART'а валится все подряд.
Бедный МК пытается разобраться и у него ожидаемо едет крыша... 
Nord
У Александра для меня сильно сложные программы. Много изпользует на асм. По этому, и "кострировал" не понимая.
Вот теперь, и прошу помощи.
NordУ Александра для меня сильно сложные программы. Много изпользует на асм. По этому, и "кострировал" не понимая.
Вот тут
Исследование USART
или (то же самое) тут
https://bascomavr.bbok.ru/viewtopic.php?id=1130#p12729
Никакого Ассемблера и все закомментировано.
Верните в главный цикл и п/п обработки прерывания то, что вы выбросили.
Вы здесь » Программирование ATMEL в BASCOM. » Связь проводная и бесп-ная, интерфейсы, протоколы » Использование модуля SIM800l