Консультация № 187752
01.03.2014, 07:29
134.64 руб.
01.03.2014, 13:08
0 12 1
Здравствуйте! Прошу помощи в следующем вопросе: нужно компилировать в Bascom-AVR программу, что я делаю не так, выдает ошибки.

Обсуждение

Неизвестный
01.03.2014, 07:39
общий
Что-то программа не скачивается - может перезалить надо.
Неизвестный
01.03.2014, 10:32
общий
$regfile = "m32def.dat"
$crystal = 16000000
$baud = 19200
$hwstack = 64
$swstack = 64
$framesize = 100


Declare Sub Getline(s As String)
Declare Sub Flushbuf()

Config Serialin = Buffered , Size = 60
Config 1wire = Portd.3 'сюда лепим 18b20

Enable Interrupts


'подключение светодиода
'======================================================================================
Config Porta.2 = Output
Led Alias Porta.2
Led = 0


'вход для контроля включенности модуля
'===========================================================================================
Config Portd.4 = Input
Vkl Alias Pind.4


'пин для включения модуля
'======================================================================================
Config Portd.5 = Output
Powerkey Alias Portd.5
Powerkey = 0


'выход для удаленного управления
'===========================================================================================
Config Portd.6 = Output
Outpin Alias Portd.6
Outpin = 0


'вход для подключения датчика движения
'===========================================================================================
Config Portd.7 = Input
Pir Alias Pind.7







'--------------------------------------------------------------------------------------
Dim Number As String * 11 'номер телефона
Dim Temp As String * 10
Dim Temp1 As String * 10
Dim Temp2 As String * 10
Dim Rs As Byte
Dim A As Byte
Dim S As String * 50
Dim B As Byte
Dim R As Byte
Dim Z As String * 15
Dim Sms_num As String * 2 'порядковый номер смс
Dim Stmp As String * 1
Dim Sms As String * 120
Dim Otvet As String * 160 'сообщение, которое модуль будет отправлять
Dim Sk As String * 66
Dim Tmr As Byte
Dim Sms_val As Byte

Dim F As Byte
Dim Error As Byte 'переменная считающая попытки достучаться до модуля перед перезагрузкой
Dim U As Byte 'счетчик пустых циклов, если переполнился то выход из цикла подпрограммы getline
Dim Loadpin As Bit 'значение пина выхода под нагрузку
Dim Pirsend As Bit 'переменная для разрешения отправки сообщения по срабатыванию датчика движения
Dim Loadpinstr As String * 3
Dim Pirstr As String * 1
Dim Pirsendstr As String * 3

Pirsend = 1 'запрет отсыла сообщений


Dim T As Byte 'температура
Dim Sign As String * 5 'знак температуры
Dim Byte0 As Byte
Dim Byte1 As Byte
Dim T1 As Byte
Dim T2 As Byte
Dim Tstr As String * 4

Dim Numb As Byte
Dim Connect As String * 6 'уровень сигнала
Dim Connectvar As Byte 'уровень сигнала в числовом значении
Dim Operator As String * 20
Dim Date_str As String * 20
Dim Time_str As String * 20



'---------------------------------------------------------------------------------------
Const Phonenumber = "+7908390хххх" 'номер на который будут отправляться смс




'подключение I/O дисплея 3310
'========================================================================================
'========================================================================================
Config Porta.5 = Output 'D/C (pin 4)
D3310dc Alias Porta.5

Config Porta.6 = Output 'SCE (pin 5)
D3310ce Alias Porta.6

Config Porta.7 = Output 'Reset (pin 8)
D3310re Alias Porta.7

'конфигурируем SPI в программном режиме. SCLK (pin 2) - PORTA.3; SDA (pin 3) - PORTA.4; Din не используется
Config Spi = Soft , Din = Porta.1 , Dout = Porta.4 , Ss = None , Clock = Porta.3

Dim Vers As String * 14
Vers = "Rev.121021.5d"

'инициализация Spi
Spiinit

$include "3310init.bas"

'инициализация SPI
Call D3310reset
Call D3310init
Call D3310clear



'поехали

$include "sim900.bas" 'включение и верификация модуля



'предварительные настройки
'********************************************************
Led = 1
Print "AT+CMGF=1" 'включаем текстовый формат сообщений
Waitms 50
Print "AT+CLIP=1" 'определение номера входящего вызова
Wait 3
Led = 0
Flushbuf


Call D3310clear




'###########################################################################
'Основная программа
'###########################################################################

Do

Led = 1
Gosub Checkmodule 'проверка работоспособности модуля
Gosub Readsms 'проверка буфера на наличие входящего сообщения
Gosub Readfirstsms 'читаем первую смс, если есть
Gosub Checksms 'выполняем подпрограмму с смс
Gosub Operator 'идентификатор оператора
Gosub Connect 'уровень сигнала
Gosub Time_date 'время и дата
Gosub 18b20 'температура с датчика
Gosub Sensor
Led = 0

Wait 10

Loop

End

$include "3310end.bas"
$include "3310bmp1.bas"
'$include "3310bmp2.bas"






'подпрограмма для разбора сообщения модуля
'=============================================================================
Sub Getline(s As String)
S = ""
Do

B = Inkey() 'берем символ из буфера в формате ASCII
Select Case B
Case 0 'возвращает в случае пустого буфера
Case 13 'возврат каретки (Enter), заместо него можно поставить пробел
Case 10 : If S <> "" Then Exit Do 'конец строки, значит выходит из подпрограммы
Case Else : If B > 31 Then S = S + Chr(b) 'печатаемые символы начинаются с кода 32 по таблице АСКИ, из них составляем строку
End Select




Loop
End Sub

'очистка буфера
'=============================================================================
Sub Flushbuf()
Waitms 100
Do
B = Inkey() 'забираем все из буфера
Loop Until B = 0
End Sub





'Подпрограмма для чтения смс
'=============================================================================
Readsms:
R = Ischarwaiting() 'проверка наличия сообщения в буфере
If R = 1 Then
Getline Sk 'уходим на подпрограмму и смотрим что пришло
Z = Left(sk , 4) 'вытаскиваем левые 4 символа

If Z = "+CMT" Then 'если +СМТ, значит пришло смс которое надо прочитать
Sms_num = Right(sk , 2) 'смотрим какая по счету смс
Stmp = Left(sms_num , 1) 'смотрим первый символ слева
If Stmp = "," Then
Sms_num = Right(sk , 1) 'если там "," значит берем первый символ справа. это и будет номером пришедшего смс
End If
Wait 1
Number = ""
Print "AT+CMGR=" ; 'команда на чтение смс
Print Sms_num 'отправляем номер смски которую надо прочитать
Waitms 10
Getline Sk
Waitms 10
Getline Sk
Number = Mid(sk , 22 , 12) 'достаем номер с которого пришла смска
Sms = Sk 'здесь первая строка ответа
Waitms 10
Getline Sk 'смотрим, что в этой смс
Sms = Sk
Sms = Left(sms , 14) 'берем только первые 14 символов из смс (по кол-ву знакомест в строке)

Do
Led = 0
Waitms 100
Led = 1
Waitms 50
Incr F
Loop Until F = 10 'десять раз мигнем сетодиодом
F = 0

Call D3310position(0 , 2) 'выведем на дисплей номер с которого пришла смс и ее содержимое
Call D3310print( " ")
Call D3310position(0 , 2)
Call D3310print(number)

Call D3310position(0 , 3)
Call D3310print( " ")
Call D3310position(0 , 3)
Call D3310print(sms)

Print "AT+CMGDA=" ; Chr(34) ; "DEL ALL" ; Chr(34) 'удаление смс

End If

Waitms 100
Flushbuf 'очищаем буфер

End If

Return






'обработка команд из входящей смс
'======================================================================================================
Checksms:

If Sms = "0" Then 'если в пришедшей смс ноль, тогда выключим нагрузку
Outpin = 0
Loadpin = 0
Loadpinstr = "Off"
Sms = ""
Call D3310position(0 , 3)
Call D3310print( "Load OFF ")

End If

If Sms = "1" Then 'если единица, тогда включим нагрузку
Outpin = 1
Loadpin = 1
Loadpinstr = "ON"
Sms = ""
Call D3310position(0 , 3)
Call D3310print( "Load ON ")

End If

If Sms = "2" Then 'если двойка, модуль позвонит нам
Gosub Atd
Sms = ""
Number = ""
Call D3310position(0 , 2)
Call D3310print( " ")
Call D3310position(0 , 3)
Call D3310print( " ")
End If

If Sms = "3" Then 'если тройка, модуль запросит баланс и пришлет нам ответ
Gosub Balanse
Sms = ""
Number = ""
Call D3310position(0 , 2)
Call D3310print( " ")
Call D3310position(0 , 3)
Call D3310print( " ")
End If

If Sms = "4" Then 'если в смс содержится 4, отправим обратно ответ с температурой
Gosub 18b20
Otvet = Sign + Tstr
Gosub Sendsms
Flushbuf
End If

If Sms = "5" Then
Pirsend = 0 'даем разрешение отправлять смс при срабатывании датчика движения
Sms = ""
End If

If Sms = "6" Then
Pirsend = 1 'запрещаем отправлять смс при срабатывании датчика движения
Sms = ""
End If

If Sms = "?" Then 'если придет знак вопроса отправим в ответ полное состояние модуля
Otvet = "SIM900D" + Chr(10) + "Temp:" + Sign + Tstr + Chr(10) + "Load:" + Loadpinstr + Chr(10) + "PIR sensor:" + Pirstr + Chr(10) + "Send SMS from sensors:" + Pirsendstr
Gosub Sendsms
Sms = ""
End If


Return







'подпрограмма отправки смс
'=============================================================================
Sendsms:
Print "AT+CMGS=" ; Chr(34) ; Phonenumber ; Chr(34)
Waitms 200
Print Otvet ; Chr(26)

Print Chr(26);
Wait 1
Print Chr(13)
'мигнем светодиодом

Do
Led = 0
Waitms 100
Led = 1
Waitms 50
Incr F
Loop Until F = 10
F = 0

Return



'чтение данных с датчика
'********************************************************
18b20:
1wreset
If Err = 1 Then
T = 255
Sign = "error"
Call D3310position(0 , 1)
Call D3310print(sign)
Return
Else
1wwrite &HCC
1wwrite &H44
Waitms 750
1wreset
1wwrite &HCC
1wwrite &HBE
Byte0 = 1wread()
Byte1 = 1wread()
If Byte1 > 248 Then
Byte0 = &HFF - Byte0
Byte1 = &HFF - Byte1
Sign = "-"
Else
Sign = "+"
End If
T1 = Byte0 / 16
T2 = Byte1 * 16
T = T1 + T2

If Sign = "-" Then
T = T1 + 1
End If
If Sign = "+" And T = 0 Then
Sign = " "
End If
End If

Tstr = Str(t)
Tstr = Format(tstr , 00)


Call D3310position(0 , 1)
Call D3310print( " ") 'очистка второй строки

Call D3310position(0 , 1)
Call D3310print(sign)
Call D3310position(1 , 1)
Call D3310print(tstr)
Call D3310position(3 , 1)
Call D3310print( "°C")

Return



'Информация об операторе
'=====================================================================
Operator:

Print "AT+COPS?" 'опрос модуля на подключенного оператора

Waitms 500
Getline Sk
Waitms 100
Getline Sk
Operator = Sk
Operator = Mid(operator , 12 , 9)

Call D3310position(0 , 0)
Call D3310print( " ")

Call D3310position(0 , 0)
Call D3310print(operator)

Flushbuf

Return



'Информация об уровне сигнала
'=====================================================================
Connect:

Call D3310position(11 , 0)
Call D3310print( "^") 'отрисовка значка антенны

Print "AT+CSQ" 'уровень сигнала

Waitms 300
Getline Sk
Waitms 100
Getline Sk
Connect = Sk

Connect = Mid(connect , 7 , 2)
Connectvar = Val(connect)

Call D3310position(12 , 0)
Call D3310print( " ")

If Connectvar > 0 And Connectvar < 4 Then 'отрисовка уровня сигнала
Call D3310position(12 , 0)
Call D3310print( "> ")
Elseif Connectvar > 4 And Connectvar < 9 Then
Call D3310position(12 , 0)
Call D3310print( "< ")
Elseif Connectvar > 9 And Connectvar < 15 Then
Call D3310position(12 , 0)
Call D3310print( "<@")
Elseif Connectvar > 15 And Connectvar < 32 Then
Call D3310position(12 , 0)
Call D3310print( "<&")

Elseif Connectvar = 0 Or Connectvar = 99 Then
Call D3310position(12 , 0)
Call D3310print( "$")

End If


Flushbuf


Return






'узнаем время и дату
'================================================================================
Time_date:

Print "AT+CCLK?"

Waitms 400
Getline Sk

Waitms 400
Getline Sk

Date_str = Mid(sk , 9 , 8)

Call D3310position(0 , 5)
Call D3310print( " ")

Call D3310position(0 , 5)
Call D3310print(date_str) 'вывод даты на дисплей

Time_str = Mid(sk , 18 , 5)

Call D3310position(0 , 4)
Call D3310print( " ")


Call D3310position(0 , 4) 'вывод времени на дисплей
Call D3310print(time_str)

Flushbuf

Return





'подпрограмма дозвона модуля по номеру
'========================================================================================
Atd:

Print "ATD" ; Phonenumber ; ";"

Waitms 100
Call D3310position(0 , 2)
Call D3310print( " ")
Call D3310position(0 , 2)
Call D3310print( "Звоним на")
Call D3310position(0 , 3)
Call D3310print( " ")
Call D3310position(0 , 3)
Call D3310print(phonenumber)
Wait 20
Flushbuf

Return


'узнаем баланс
'=================================================================================
Balanse:

Call D3310position(0 , 2)
Call D3310print( " ")
Call D3310position(0 , 2)
Call D3310print( "Запрос баланса")
Call D3310position(0 , 3)
Call D3310print( " ")


Print "ATD*100#"
Wait 1
Getline Sk
Getline Sk
Getline Sk
Otvet = Sk
Gosub Sendsms

Flushbuf

Return


'проверка работоспособности модуля, если не проходит перезагружаем модуль
Checkmodule:

Call D3310position(0 , 3)
Call D3310print( " ")

If Loadpin = 0 Then
Call D3310position(0 , 3)
Call D3310print( "Load OFF ")
Loadpinstr = "Off"
Else
Call D3310position(0 , 3)
Call D3310print( "Load ON ")
Loadpinstr = "ON"
End If



If Vkl = 0 Then 'если здесь ноль, то все гуд - модуль SIM900D включен
Call D3310position(0 , 2)
Call D3310print( " ")
Call D3310position(0 , 2)
Call D3310print( "SIM900D ON ")


Else 'а вот если 1, значит модуль вырубился - надо перезагрузить
Call D3310position(0 , 2)
Call D3310print( " ")
Call D3310position(0 , 2)
Call D3310print( "SIM900D OFF")

Wait 2
If Vkl = 1 Then 'проверяем еще раз и если там по прежнему 1 перезагрузим
Goto Pwrmodule
Else
End If
End If

Flushbuf

Waitms 10
Return



'опрос датчика движения
'========================================================================================
Sensor:

If Pir = 1 Then 'если на входе единица - значит сработал датчик движения

Call D3310position(6 , 1)
Call D3310print( "Дат. 1 ")
Pirstr = "1"

Wait 1

If Pirsend = 0 Then 'если передача разрешена
Otvet = "Alarm!"
Call D3310position(0 , 1)
Call D3310print( " ")
Call D3310position(0 , 1)
Call D3310print( "Отправка SMS ")
Gosub Sendsms 'отправляем смс о срабатывании датчика движения
Pirsend = 1 'запрещаем последующую передачу сообщения
End If

Else

Call D3310position(6 , 1)
Call D3310print( "Дат. 0 ")
Pirstr = "0"

End If

If Pirsend = 0 Then
Call D3310position(13 , 1)
Call D3310print( " ")
Pirsendstr = "Yes"
Else
Call D3310position(13 , 1)
Call D3310print( "!") 'если отправка смс запрещена выведем значек уведомления на дисплей
Pirsendstr = "No"
End If

Flushbuf
Waitms 10

Return


'принудительное чтение первой смс из памяти
'это необходимо если прошляпили приход смс, во время выполнения одной из подпрограмм
'==========================================================================================
Readfirstsms:


Print "AT+CMGR=1" 'команда на чтение смс
Waitms 10
Getline Sk
Waitms 10
Getline Sk
Number = Mid(sk , 22 , 12) 'достаем номер с которого пришла смска
Sms = Sk 'здесь первая строка ответа
Sms = Left(sms , 4)

If Sms = "+CMG" Then

Waitms 10
Getline Sk 'смотрим, что в этой смс
Sms = Sk
Sms = Left(sms , 14) 'берем только первые 14 символов из смс (по кол-ву знакомест в строке)

Do
Led = 0
Waitms 100
Led = 1
Waitms 50
Incr F
Loop Until F = 10 'десять раз мигнем сетодиодом
F = 0

Call D3310position(0 , 2) 'выведем на дисплей номер с которого пришла смс и ее содержимое
Call D3310print( " ")
Call D3310position(0 , 2)
Call D3310print(number)

Call D3310position(0 , 3)
Call D3310print( " ")
Call D3310position(0 , 3)
Call D3310print(sms)

Print "AT+CMGDA=" ; Chr(34) ; "DEL ALL" ; Chr(34) 'удаление всех смс

End If

Waitms 100
Flushbuf 'очищаем буфер

Return
Прикрепленные файлы:
8eee6fe4de910fa707cac13d48c471f1.zip
Неизвестный
02.03.2014, 08:03
общий
А подробнее можно, где и что за ошибки выдает компилятор?
Неизвестный
02.03.2014, 09:32
общий
Доброго времени суток Дмитрий, программный код не мой, взят с сайта http://avrproject.ru/, хочу поэкспериментировать с модулем sim900 и avr микроконтроллерами, бейсик чуть-чуть знаком, я открываю в программе Bascom файл прогамма.bas и компилирую, программа начинает ругаться, попробуйте сами. Подскажите пожалуйста, как должна выглядеть программа, чтобы не возникали ошибки, например Error : 97 Line : 10 SUB or FUNCTION must be DECLARED first [D3310RESET].
Неизвестный
02.03.2014, 11:48
общий
02.03.2014, 11:53
Данная ошибка означает что компилятор не может найти описание процедуры D3310reset.
Вроде по тексту все правильно и должно работать: единственно, меня смущает положение строки $include 3310init.bas" в программе - попробуйте перенести ее в начало текста модуля перед строкой 'подключение I/O дисплея 3310
Это конечно не мое дело, но может быть вам с чего-нибудь попроще начать эксперименты - например с того же дисплея 3310 - научиться его подключать, текст выводить и др. а уже потом усложнять программу и подключить SIM900.
Неизвестный
02.03.2014, 14:21
общий
Спасибо за подсказку, ну я бы не обращался за помощью на этот сайт, хочу понять ошибки в программе. Строки поменял, вылазит ошибка Error : 46 Line : 11 Assignment error [D3310RE:0 0:112].
Неизвестный
02.03.2014, 22:47
общий
Разобрался в чем было дело: в программе в нескольких местах дублируются имена меток и имена переменных. Bascom этот факт не устраивает, возможно программа написана для другого компилятора, который более лояльно относится к таким вещам.
В приложении исправленные файлы.
Прикрепленные файлы:
a8d959f414d715da612a5642dc6ec98d.zip
Неизвестный
03.03.2014, 18:10
общий
Проверьте пожалуйста программу - если все OK - оформлю ответом.
Неизвестный
04.03.2014, 08:34
общий
Спасибо Дмитрий, код компилируется, проверить могу только на реальном железе, да ошибка 61 метки не найдены, оформляйте ответом. В следующем вопросе, когда задам, можете помочь? Нужно эту программу, переписать без дисплея. Ну, это уже потом.
Неизвестный
04.03.2014, 12:36
общий
Дмитрий спасибо, оформляйте ответом.
Неизвестный
04.03.2014, 13:27
общий
это ответ
Здравствуйте, Анатолий!

В программе в нескольких местах совпадают имена меток и переменных. Компилятор bascom-avr не допускает наличия таких "вольностей" и не компилирует программу. Возможно программа писалась под другой компилятор, который разрешает такое дублирование.
В приложении исправленная, с учетом данного ограничения, программа.
Прикрепленные файлы:
Неизвестный
04.03.2014, 13:30
общий
Думаю смогу помочь, ломать, как известно, не строить - лишнее уберем.
Форма ответа