Администрация форума не несёт ответственности за достоверность информации и оставляет за собой право редактировать или в особых случаях даже удалять посты без предупреждения. Спасибо за понимание.

Программирование ATMEL в BASCOM.

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.


Вы здесь » Программирование ATMEL в BASCOM. » Исходники » Нужен совет по коду на Bascom


Нужен совет по коду на Bascom

Сообщений 1 страница 9 из 9

1

Приветствую. Стоит задача выполнить следующие условия:
По D0 приходит информация в виде числа от 0 до 200 несколько раз в секунду, без стабильных интервалов.
Нужно осуществить постоянную обработку входящих данных и выполнить условия, если данные больше 80 то включать режим Alarm, если меньше то режим Normal.
В идеале режим Normal должен постоянно работать не взирая на присутствие входящих данных(только в случае > 80 меняться на Alarm) Alarm запускать нужно на 30 секунд от последнего значения > 80 не взирая на то что на входе возможно будет < 80, и после если нет входящей информации - переключить на Normal).

Смотреть сюда
Код:
$Regfile="m16def.dat"
$Crystal=1000000
$hwstack=40
$swstack=16
$framesize=32

$baud = 9600

Config Portd.0 = Input
Config PORTB.2 = Output
Config PORTB.1 = Output

Dim CheckData As Byte
Declare Sub AlarmMode ()
Declare Sub NormalMode ()
Dim s As Bit

Do

Input CheckData
IF CheckData >= 80 Then
s = 1
Call AlarmMode
Else
s = 0
Call NormalMode
End if

Loop

Sub AlarmMode ()

Do
PORTB.1 = 1
Waitms 150
PORTB.1 = 0
Waitms 150
Loop until s = 1
End sub

Sub NormalMode ()

Do
PORTB.2 = 1
Waitms 300
PORTB.2 = 0
Waitms 300
Loop until s = 0
End sub

End

1 - трудности с реализацией Input CheckData(нужен постоянный опрос и переключение)
2 - трудности с выходом из цикла NormalMode \  AlarmMode
3 - второй проект после мигания светодиодом)

Отредактировано ut87 (2016-07-22 16:56:54)

0

2

Sub AlarmMode ()
Do
PORTB.1 = 1
Waitms 150
PORTB.1 = 0
Waitms 150
Loop until s = 1
End sub
Sub NormalMode ()
Do
PORTB.2 = 1
Waitms 300
PORTB.2 = 0
Waitms 300
Loop until s = 0
End sub

0

3

ut87

Запуск Alarm и подобных штук с определенным временем действия(30 сек.) я бы делал через таймер. Случилось событие,запустился таймер,по переполнению увеличил переменную и так увеличиваем столько,сколько надо для прошествия 30 сек. Прошло 30 сек.,таймер стоп,переменную обнулить,поднять(опустить)флаг,или сделать что там нужно сделать.В случае с таймером ни в основном цикле,ни в подпрограммах не нужно делать задержки,которые тормозят всю программу.Таймер работает сам по себе.

Отредактировано Sergik07 (2016-07-21 14:55:04)

0

4

У атмеги16 есть вроде нормальный аппаратный уарт, используйте буфер приёма и отдельно обработку отсчета аларма на таймере.

0

5

ut87 написал(а):

В идеале режим Normal должен постоянно работать не взирая на присутствие входящих данных(только в случае > 80 меняться на Alarm) Alarm запускать нужно на 30 секунд от последнего значения > 80 не взирая на то что на входе возможно будет < 80, и после если нет входящей информации - переключить на Normal).

Так используйте этот режим, как основное тело программы, зачем выделять в подпрограмму ?
И в нем уже организовывайте проверку входных данных и вызов Alarm'а...

ЗЫ. Кому как привычнее, но я бы все Sub... переместил после End, иначе есть вероятность их случайного выполнения... ;)

Отредактировано Nord (2016-07-22 12:04:37)

0

6

Спасибо за советы.
Пока только знакомлюсь с баском. Настроил таймер и правильно работающую индикацию необходимых режимов,
временно входящие события настроены только один параметр.

Подскажите пожалуйста по следующему :

- что бы применить для оптимизации подпрограммы LedMode ?
- пробовал запихнуть и обработать входящие данные(Comchar и Buff ) в переменные типа Byte и Integer - пока ничего не получилось
- входящие данные частично будут отрицательные, если принимать в String то как потом конвертировать в  Integer ?
- будет диапазон входящих значений на которые нужно реагировать включением аларма, может записать их всех в массив и сравнивать?

Буду благодарен за небольшой пример создания string массива, внесение и чтение его данных

Жмякни сюда
Код:
$Regfile="m16def.dat"
$Crystal=1000000
$hwstack=40
$swstack=16
$framesize=32
$baud = 9600

Config Pind.6 = Output
Config Pinb.1 = Output

Dim A As Byte
Dim Buff As String * 3
Dim Comchar As Byte
Dim Flagbuf As Bit
Dim AlarmCount As Byte


Config Timer0 = Timer , Prescale = 256

On Timer0 LedMode
On Urxc Getchar

Enable Urxc
Enable Interrupts
Enable Timer0

Reset Flagbuf

Do

 If Flagbuf = 1 And Buff = "4" Then        ' Включаем аларм

   AlarmCount = 1

   Buff = ""

   Flagbuf = 0

 Elseif Flagbuf = 1 And Buff <> "4" Then       ' Если пришел мусор - чистим буфер, возвращаем флаг

  Buff = ""

  Flagbuf = 0

  End if

Loop

LedMode:                                                ' Два режима индикации                                            

Incr A                                                       

 If A >= 0 And A < 14 Then                     ' Обычный, постоянный режим

   Toggle Pinb.1                                             

  Elseif  A >= 15 And A < 29 Then           

   Set Pinb.1 = 0                                      
 
  Elseif A = 30 Then                                  

   A = 0                                                   


 Elseif  A <= 30 And AlarmCount <> 0 Then       ' Если включен аларм - переключаем счетчик переполнений

   A = 40                                                                ' и включаем быструю индикацию на 5 кругов, после чего 

  Elseif  A >= 40 And A < 44 And AlarmCount <> 0 Then      '  ставим аларм и счетчик в 0 

   Toggle Pinb.1                                                                       

  Elseif  A >= 49 And A < 54 And AlarmCount <> 0 Then      

    Set Pinb.1 = 0                                                                        

  Elseif A = 55 And AlarmCount <> 0 Then                             
 
    A = 40                                                                                  

    Incr AlarmCount                                                                   

  Elseif AlarmCount >= 6 Then                                                 

    AlarmCount = 0                                                                    

    A = 0                                                                                     

 end if

  Return

Getchar:                          ' Принимаем данные, кладем в буфер, поднимаем флаг

   Comchar = Inkey()

 If Comchar <> "(><)" Then

   Buff = Buff + Chr(comchar)

   Flagbuf = 1

 Endif

  Return

End

0

7

ut87 написал(а):

- входящие данные частично будут отрицательные, если принимать в String то как потом конвертировать в  Integer ?

Dim V As String
Dim A As Integer
Dim B As Single

V = входное значение      ' Принимаем значение
B = VAL ( V )                    ' Переводим из строковой в числовую форму
A = ABS ( B )                   ' Сохраняем модуль числа

ut87 написал(а):

- будет диапазон входящих значений на которые нужно реагировать включением аларма, может записать их всех в массив и сравнивать?
            Буду благодарен за небольшой пример создания string массива, внесение и чтение его данных

Строковые массивы громоздки и менее удобны в работе, тем более что оперировать будете все равно числовыми данными...
Поэтому:

DIM Arr(10) As Integer      ' Формируем пустой массив на 10 значений формата Integer

Перед заполнением массива конвертируете данные (см. выше).

Arr (x) = A                       ' Заносим в ячейку массива значение А, где х - номер ячейки массива

A = Arr (x)                       ' Читаем из ячейки (x) массива в переменную А

Возможно будут предложены более оптимальные решения, не спорю... ;)

Отредактировано Nord (2016-07-22 17:46:04)

0

8

Благодарю.

Частично застрял на обработке входящей информации. Сейчас дела обстоят так:
- принимаем в буфер строку, переводим в число, сравниваем с диапазоном значений - что то делаем, опять принимаем

Обрабатываются данные которые обозначены в нужном цифровом диапазоне. Но иногда будут приходить данные вне этого числового диапазона + символьные строки. Вот это все нужно отсортировать и чистить буфер.

Как сделать фильтр на "все кроме вот этого и этого" пока не понимаю. Прошу помощи.

0

9

ut87 написал(а):

Обрабатываются данные которые обозначены в нужном цифровом диапазоне. Но иногда будут приходить данные вне этого числового диапазона + символьные строки. Вот это все нужно отсортировать и чистить буфер.
            Как сделать фильтр на "все кроме вот этого и этого" пока не понимаю. Прошу помощи.

Числовые и символьные последовательности будут перемешаны или имеют четкий порядок ?
Если четко определены, то используйте строковые функции, которых вполне достаточно, чтоб найти и выделить любой участок строки.
Потом выполняйте преобразования.

Если вперемешку, тогда сложнее, но направление действий подобное.

Отредактировано Nord (2016-07-28 06:51:55)

0

Похожие темы


Вы здесь » Программирование ATMEL в BASCOM. » Исходники » Нужен совет по коду на Bascom