Добрый день всем! Нужна помощь в написании части кода для манипулятора телеграфного радиомаяка. Задача в том, что есть некий буфер (переменная), в который(ую) сдвигается по одному символу из другой переменной, в которую заранее записано сообщение. В буфере должен находиться только один символ. Пробовал командой left сдвигать в цикле for-to-next - ничего толкового не получилось - в буфер сдвигаются символы однин за одним.
Телеграфный радиомаяк
Сообщений 1 страница 16 из 16
Поделиться22011-03-23 11:49:30
я делал что-то подобное: постоянно выдавалось некое сообщение
Могу прислать. Там ничего гениального:
в DATA внесены данные (1, 0, пауза, начало и конец сообщения)
Последовательно считывается и передается по кругу, с определенной паузой
Делал под ATTiny13a
Поделиться32011-03-23 13:24:34
Да, Александр, если не сложно, пришлите пожалуйста. Буду очень признателен.
Поделиться42011-03-23 13:44:03
есть некий буфер (переменная), в который(ую) сдвигается по одному символу из другой переменной, в которую заранее записано сообщение
Сообщение можно хранить в массиве и не двигать данные, а просто изменять индекс массива.
Будет тоже самое, но намного проще реализуемое.
Поделиться52011-03-23 14:45:38
Да, Александр, если не сложно, пришлите пожалуйста. Буду очень признателен.
Проверяйте почту
Поделиться62011-03-23 21:25:34
Вот написал демо-программу маяка. Посмотрите, может можно как-то оптимизировать код? Слишком много переходов на подпрограммы получается.
$sim
$regfile = "attiny2313.dat"
$crystal = 8000000
$baud = 9600
'----------
Config Lcd = 16 * 1
Config Lcdpin = Pin , Rs = Portb.7 , E = Portb.6 , Db4 = Portb.5 , Db5 = Portb.4 , Db6 = Portb.3 , Db7 = Portb.2
Config Portb.0 = Output
Cursor Off
Manipul Alias Portb.0
Const Dot = 150
Const Dash = 450
Const _space = 150
Dim Number_word As Integer , Morseword As String * 1 , Morseletters As Byte
'----------------------------
Cls
Do
'-----
For Number_word = 0 To 2 'здесь указываем сколько у нас букв в сообщении
Morseword = Lookupstr(number_word , Words) 'берем буквы из массива
If Morseword = "A" Then Gosub A 'переходим на соотв-е подпрограммы,
If Morseword = "B" Then Gosub B 'чтобы выдавать на PORTB.0 (Manipul)
If Morseword = "C" Then Gosub C 'нужные комбинации точек и тире
'и так далее до буквы Z, цифр 0-9 и знаков / - = .,
Next Number_word
'-----
Loop
End 'end program
'------------Формирование точки и тире------------
Tochka:
Set Manipul 'установить лог. 1 на PORTB.0
Waitms Dot 'передать точку
Reset Manipul 'установить лог.0
Waitms _space 'передать пробел
Lcd "*"
Return
Tire:
Set Manipul
Waitms Dash
Reset Manipul
Waitms _space
Lcd "-"
Return
'--------------Формирование букв-----------------
'--a
A:
Gosub Tochka
Gosub Tire
Cls
Return
'--b
B:
Gosub Tire
Gosub Tochka
Gosub Tochka
Gosub Tochka
Cls
Return
'--c
C:
Gosub Tire
Gosub Tochka
Gosub Tire
Gosub Tochka
Cls
Return
Words:
Data "A" , "B" , "C" 'Сообщение "ABC", которое требуется передать
Поделиться72011-03-23 22:30:23
я же Вам прислал готовое, как раз под маяк и делалось...
у меня тоже память не экономится (задачи не было - мк только и делает, что выдает поачки), но код - нагляднее
Поделиться82011-03-23 23:36:52
Александр, еще раз спасибо Вам, разобрался с Вашей программой. Мне еще работать и работать над собой
Единственное что я хотел еще добавить - дать возможность пользователю по RS232 самому записывать в память МК сообщения.
Поделиться92011-03-23 23:42:30
это надо полностью менять алгоритм прграммы
я тоже хотел, но потом отказался: Не было необходимости 
придется делать иное кодирование точек, пауз и тире, иначе в память МК (энергонезависимую) можно будет грузить не более 256\512 знаков
А если подойти по-уму, то раза в 4 больше 
Я даже конвертер набросал: пишешь на ПК текст, программа его преобразует в мой внутренний формат и загружает в МК
Но потом всё забросил
Поделиться102011-03-24 00:14:28
Не спец в маяках, но если 128 байт eeprom * 8 = 1024 бит. Каждый бит либо (.) либо (-) циклически читаем еепром и каждый бит выводим куда нужно (меняем значение на порту). Вместо пробела - несколько 000й. + запись eeprom из uart.
Поделиться112011-03-24 00:54:52
придется делать иное кодирование точек, пауз и тире, иначе в память МК (энергонезависимую) можно будет грузить не более 256\512 знаков
Что мешает "прикрутить" копеечную микруху 24Cxx или подобную?
Поделиться122011-03-29 20:28:08
Вот немного модифицированная программа маяка Александра Д. Изменены: время задержки для точек/тире/пауз, добавлена пауза между словами в предложении, равная 7 точкам, итп по мелочам. Вопрос по коду в цикле DO-LOOP. По нажатию кнопки на выводе 2 порта D, начинает выполняться подпрограмма STPRG. А как вернуться из нее обратно в цикл DO-lOOP? Пробовал по прерыванию INT0 - ничего хорошего не вышло, не работает (пример брал из pdf-ки по Bascom). Есть какие-нибудь варианты?
$crystal = 8000000
$hwstack = 8
$swstack = 8
$framesize = 16
Lamp Alias Portb.0 'индикатор передачи
Cw_out Alias Portb.1 'выход "манипуляция" - к ГВЧ
Tx_out Alias Portb.2 'выход на PTT передатчика
Const T = 150 ' Точка = 0
Const M = 450 ' Тире (Минус) =1
Const P = 450 ' Пауза между буквами
Const D = 150 ' Пауза между точками\тире
Const Pw = 1050 ' пауза между словами
Dim N As Byte
'Enable Interrupts
'Enable Int0
Config Portb.0 = Output ' Output
Config Portb.1 = Output
Config Portb.2 = Output
Config Portd.2 = Input
Set Portd.2
Wait 1
Main:
Do
Debounce Pind.2 , 0 , Stprg , Sub 'переход в режим автомат. мультиплексирования по нажатию
Loop
End
Stprg:
Portb = 0
Restore Data1
Nachalo:
Tx_out = 1
Read N
If N = 0 Then ' Точка
Lamp = 1
Cw_out = 1
Waitms T
Lamp = 0
Cw_out = 0 ' Выкл лампу
Waitms D ' Пауза между точками\тире
End If
If N = 1 Then ' Тире (Минус)
Lamp = 1
Cw_out = 1
Waitms M
Lamp = 0 ' Выкл лампу
Cw_out = 0
Waitms D ' Пауза между точками\тире
End If
If N = 9 Then Waitms P ' пауза между буквами\символами
If N = 8 Then Waitms Pw ' пауза между словами
If N = 111 Then
Lamp = 0
Cw_out = 0
Tx_out = 0
Wait 3 ' Конец предложения
Restore Data2
End If
If N = 222 Then
Lamp = 0
Cw_out = 0
Tx_out = 0
Wait 3 ' Конец предложения
Restore Data3
End If
If N = 255 Then
Lamp = 0 ' Конец
Cw_out = 0
Tx_out = 0
Wait 3
Goto Stprg
End If
Goto Nachalo
Return
' +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Data1:
Data 1 , 0 , 1 , 0 , 9 , 1 , 1 , 0 , 1 , 8 , 1 , 0 , 1 , 0 , 9 , 1 , 1 , 0 , 1 , _
111
Data2:
Data 0 , 0 , 0 , 0 , 0 , 8 , 0 , 0 , 0 , 0 , 0 , 8 , 0 , 0 , 0 , 0 , 0 , _
222
Data3:
Data 1 , 1 , 1 , 1 , 1 , 8 , 1 , 1 , 1 , 1 , 1 , 8 , 1 , 1 , 1 , 1 , 1 , _
255
Поделиться132011-03-30 01:42:39
Давно не занимался в васике)) Чет пописать захотелось. Поэтому захотелось заморочится с твоей проблемкой. Вот держи код, который последовательно и слитно выбивает "АБВГДЕЖЗИКЛМНО "
Осталось дописать сигнальную лампочку, хотя ее можно тупо дублировать с точками и тере. Ну и прога для компа нужна которая составляла бы послание из последовательности нолей и единиц и разбивала полученный масив по байтам... но эт ты уже сам
'P-a-h-a@yandex.ru
' За единицу времени принимается длительность одной точки.
' Длительность тире равна трём точкам.
' Пауза между знаками в букве — одна точка
' между буквами в слове — 3 точки
' между словами — 7 точек.
$regfile = "m8def.dat"
$crystal = 8000000
Dim I As Integer , Byte_morze As Byte , S As Byte
Config Portb = Output : Morze_out Alias Portb.1 'выход тире и точек последовательно на portb.1
Do
Restore Dta ' говорим из какой таблици нужно производить чтение
For I = 1 To 17 ' начало цикла его количество = кол-ву байт в таблице
Read Byte_morze ' поочереди читаем байт и присваиваем его переменной Byte_morze
For S = 8 To 1 Step -1 ' цикл в котором каждый бит в зависимости 0 или еденица выводится на порт б1
Morze_out = Byte_morze.s ' вкл/выкл порта б1
Waitms 150 ' время задержки точки
Next
Next
Loop
End
Dta:
Data &B10111000 , &B11101010 , &B10001011 , &B10111000 , &B11101110 , &B10001110 , &B10100010 , &B00101010 , &B11111101 , &B11010100 ,
Data &B01010001 , &B11010111 , &B01000101 , &B11010100 , &B01110111 , &B00011101 , &B00011101 , &B11011100 , &B0пояснение к DTA 10111000 'А точка, пауза между знаками=точке, тире=3*точка,пауза после буквы=3*точка 111010101000 'Б 101110111000 'В 111011101000 'Г 1110101000 'Д 1000 'Е 101010111 'Ж 11101110101000 'З 101000 'И 11101011101000 'К 101110101000 'Л 1110111000 'М 11101000 'Н 11101110111000 'О выше в Dta все совмещаем в одну длинную строку и делим по байтам (по 8 символов)
Поделиться142011-03-30 05:59:31
еще одна идея для более компактного сжатия.
В кратце все делаем также
берем побитно спрашиваем
1й бит (.)? если да то печатаем точку с межсимвольным пробелом, если нет то печатаем межсимвольный пробел
2й бит (-)? если да то печатаем тире с межсимвольным пробелом, если нет то ничего не печатаем
3й бит (.)? если да то печатаем точку с межсимвольным пробелом, если нет то печатаем межсимвольный пробел
4й бит (-)? если да то печатаем тире с межсимвольным пробелом, если нет то ничего не печатаем
и так далее в зависимости от чета/нечета бита
короче нужно нам один межбуквенный пробел(= 3 межсимвольных пробела) - эт будет выглядеть как 000000
нужно тире, три пробельчика(каждый=длинне точки) и точка :
010001
|||||||___байт7 точка? - да - ставим точку и пробельчик
||||||____байт6 тире? - нет - ничего не ставим
|||||_____байт5 точка? - нет - ставим прбельчик
||||______байт4 тире? - нет - ничего не ставим
|||_______байт3 точка?- нет - ставим прбельчик
||________байт2 тире? - да - ставим тире и пробельчик
|_________байт1 точка? - нет - ставим прбельчик
вышло
_ - _ _ _ . _
в общем вот такая идея. Набрал и думаю будет ли код таким то макаром увеличиватся или уменьшатся то?)))))))
ЗЫ Если в предыдущем посте
Morze_out = Byte_morze.s ' вкл/выкл порта б1
Waitms 150 ' время задержки точки
заменить на
If Byte_morze.s = 1 Then Sound Morze_out , 200 , 450 Else Waitms 150
то будет прям писк выдавать на выходе)))
Отредактировано Pasha (2011-03-30 06:38:18)
Поделиться152011-03-30 16:24:35
Павел, спасибо за еще один вариант программы! А все-таки как быть с кнопкой, нажав на которую произойдет выход из цикла? Например это нужно для того чтобы можно было остановить передачу, и перейти на какую-нибудь другую подпрограмму (например настроек итд).
Поделиться162011-03-30 22:47:04
как вариант
'P-a-h-a@yandex.ru
' За единицу времени принимается длительность одной точки.
' Длительность тире равна трём точкам.
' Пауза между знаками в букве — одна точка
' между буквами в слове — 3 точки
' между словами — 7 точек.
$regfile = "m8def.dat"
$crystal = 8000000
Dim I As Integer , Byte_morze As Byte , S As Byte
Config Portb = Output : Morze_out Alias Portb.1 'выход тире и точек последовательно на portb.1
Config Pinc.1 = Input : Set Portc.1 ' конфигурируем порт на вход и вкл внутренний подтягивающий резистор
Config Pinc.2 = Input : Set Portc.2
Config Pinc.3 = Input : Set Portc.3
Config Timer1 = Timer , Prescale = 8 : On Timer1 Bootons : ' конфигурируем таймер 1 и назначаем подпрограмму которая выполняется при переполнении таймера (все время будет приостанавливатся основной цикл и программа будет переходить на проверку не нажаты ли кнопки)
Enable Interrupts : Enable Timer1 ' разрешаем прерывания и таймер 1
Do
Restore Dta ' говорим из какой таблици нужно производить чтение
For I = 1 To 17 ' начало цикла его количество = кол-ву байт в таблице
Read Byte_morze ' поочереди читаем байт и присваиваем его переменной Byte_morze
For S = 8 To 1 Step -1 ' цикл в котором каждый бит в зависимости 0 или еденица выводится на порт б1
Morze_out = Byte_morze.s ' вкл/выкл порта б1
Waitms 150 ' время задержки точки
' If Byte_morze.s = 1 Then Sound Morze_out , 200 , 450 Else Waitms 150 если закоментировать две предыдущих строки и раскоментировать эту то будет писк выдавать
Next
Next
Loop
End
Dta:
Data &B10111000 , &B11101010 , &B10001011 , &B10111000 , &B11101110 , &B10001110 , &B10100010 , &B00101010 , &B11111101 , &B11010100 ,
Data &B01010001 , &B11010111 , &B01000101 , &B11010100 , &B01110111 , &B00011101 , &B00011101 , &B11011100 , &B00000000
Bootons:
Stop Timer1 'останавливаем таймер
If Pinc.1 = 0 Then Gosub Booton1 ' если кнопка нажата - переходим к подпрограмме Alarm
If Pinc.2 = 0 Then Gosub Booton2
If Pinc.3 = 0 Then Gosub Booton3
Bitwait Pinc.1 , Set ' просто ждем чтоб отпустили кнопку, если за время ее удержания подпрограмма успела выполнится
Bitwait Pinc.2 , Set 'ждем пока не отпустят кнопку
Bitwait Pinc.3 , Set
Start Timer1 'запускаем таймер
Return
Booton1: ' подпрограмма Alarm
' что то делаем
Return 'возвращаемся откуда нас сюда прислали
Booton2:
' что то делаем
Return
Booton3:
' что то делаем
Return
'(
10111000 'А точка, пауза между знаками=точке, тире=3*точка,пауза после буквы=3*точка
111010101000 'Б
101110111000 'В
111011101000 'Г
1110101000 'Д
1000 'Е
101010111 'Ж
11101110101000 'З
101000 'И
11101011101000 'К
101110101000 'Л
1110111000 'М
11101000 'Н
11101110111000 'О
выше в Dta все совмещаем в одну длинную строку и делим по байтам(по 8 символов)
')