Современные технологии автоматизации» («СТА») —  журнал для квалифицированных специалистов по промышленной автоматизации Форум СТА — современные технологии автоматизации Домашняя страница
Домашняя страница форума CTA Домашняя страница форума CTA > II. АСУТП и SCADA > ПЛК и микроконтроллеры
  Активные темы Активные темы
  FAQ FAQ  Искать в форуме   Зарегистрироваться Зарегистрироваться  Вход в систему Вход в систему

ADAM5510 COM1/2

 Ответить Ответить
Автор
Сообщение
kot23rus Смотреть выпадающим
Новичок
Новичок


Присоединился: 07 Февраль 2009
Категория: Russian Federation
Online Status: Offline
Публикации: 24
Свойства публикации Свойства публикации   Ответить, цитируя автора - kot23rus Ответить, цитируя автора -  ОтветитьОтвет Прямая ссылка на эту публикацию Тема сообщения: ADAM5510 COM1/2
    Опубликовано: 07 Февраль 2009 18:25
Господа кто нибудб может подсказать как организовать обработку прерываний от контроллеров последовательного интерфейса в ПЛК ADAM5510M?
Наверх
Vel_ Смотреть выпадающим
Действительный член
Действительный член


Присоединился: 25 Апрель 2006
Категория: Russian Federation
Online Status: Offline
Публикации: 116
Свойства публикации Свойства публикации   Ответить, цитируя автора - Vel_ Ответить, цитируя автора -  ОтветитьОтвет Прямая ссылка на эту публикацию Опубликовано: 09 Февраль 2009 05:13

На asm:

public Ini_COM1, Start_COM1

DGROUP group DATA

DATA segment word public 'DATA' use16
  assume ds:DGROUP

Star_INT_0Ch dd 0  ; Адрес старого обработчика перывания 0Ch
Start_Data  db 0 ; Переменная для контроля начала передачи
    db 0
Shet_Size_Data dw 44  ; счетчик передаваемых данных
DATA  ends

SYSTEM  segment byte public 'CODE'
     assume ds:DGROUP, cs:SYSTEM

;--------------------------------------------------------------------
;;;; < Обработчик прерывания СОМ 1 > ;;;;
;--------------------------------------------------------------------
New_INT_0Ch:  ; Начало нового обработчика прерывания (0Ch)
     ; (INT 0Ch) - прерывание последовательного порта СОМ1
     ; вызывается, если порт СОМ1 получил данные.

 push ax            ; Сохранить ax в стек
 push ds            ; Сохранить ds в стек
 push dx            ; Сохранить dx в стек
 push bx            ; Сохранить bx в стек

Indet_INT:
;;;;;;{идентификация прерывания}
 mov dx, 3FAh        ; Адресс порта в dx (03FAh для чтения) - регистр 
 in al, dx   ; Считать данные из порта 03FAh в al
 and al, 07h   ; Логическое И, обнуление 3-7 бит (00000111b)
 cmp al, 2   ; Сравнение al с 2 (00000010b)-буфер передачи пуст. Сбрасывается после записи в 03F8h
 je Vix_INT   ; если равно, то на Vix_INT (прерывание по завершению передачи символа)

;;;;;;{сброс остальных прерываний}
; ---------------------------------------------------------------------------
;(сброс - пришли данные)  
 mov dx, 03F8h       ; Адресс регистра передачи данных в dx
 in al, dx   ; Считать данные из порта 03F8h в al
 jmp short $+2
;(сброс -  состояние BREAK или ошибка)
 mov dx, 03FDh       ; Адресс регистра состояние break или ошибка в dx
 in al, dx      ; сбрасываем прерывание чтением из рег. состояния линии
 jmp short $+2       ; задержка  
;(сброс - изменилось состояние модема)
 mov dx, 03FEh       ; Адресс регистра состояния линии в dx
 in al, dx          ; сбрасываем прерывание чтением из регистра
 jmp short $+2
 jmp Exit_Indet_INT ; на выход
; ---------------------------------------------------------------------------

Vix_INT: ; прерывание по завершению передачи символа

;;;;;;{передача символа}
 mov bx, Shet_Size_Data ; получаем значение счетчика
 cmp bx, 44    ; сравнение
 jge Exit_Indet_INT  ; если больше или равно, то на метку, иначе
 
 inc Shet_Size_Data  ; инкремент, увеличиваем на 1
 mov al, byte ptr Byffer_Peredahi+bx ; считываем значение из буффера передачи
 mov dx, 03F8h   ; адрес порта
 out dx, al          ; пишем в порт

;===============================
Exit_Indet_INT:   ; послать в контроллер прерывания - прерывание обработано
  mov dx, 0FF22h
  mov ax, 0Ch
  out dx, ax

 pop bx
 pop dx
 pop ds
 pop ax

  iret   ; возвращение в основную программу
;===============

; Инициализация СОМ 1
Ini_COM1 proc pascal near

 push ds        ; сохранить ds в стек
    push es        ; сохранить es в стек
    push bx        ; сохранить bx в стек
    push dx        ; сохранить dx в стек
 
 mov ax, 350Ch    ; АН = 35h, AL = номер прерывания (0Ch)
        ; (INT 0Ch) - прерывание последовательного порта СОМ1
        ; вызывается, если порт СОМ1 получил данные.
 int 21h                 ; функция DOS: определить адрес старого обработчика
                            ; (ES:BX)
 mov word ptr Star_INT_0Ch, bx   ; В bx смещение
 mov word ptr Star_INT_0Ch+2, es ; В es сегментный адресс
 mov ax, cs              ; В ax адресс сегмента из cs (cs:SYSTEM)
 mov bx, ds     ; сохраняем ds в bx
 mov ds, ax              ; Установить ds на :SYSTEM (ds:SYSTEM)
 assume ds:SYSTEM
 lea dx, New_INT_0Ch     ; Вычисление эффективного адреса New_INT_0Ch
 mov ax, 250Ch           ; АН = 25h, AL = номер прерывания (0Ch)
                         ; сегментный адрес в DS
                         ; смещение в DX
 int 21h            ; функция DOS: установить новый обработчик прерывания (0Ch)
 mov ds, bx       ; Востановить ds:DGROUP из bx
 assume ds:nothing
  
;;;;;;{запрещение прерывания}
 mov dx, 0FF28h   ; Адресс порта в dx
 in ax, dx    ; Считать данные из порта 0FF28h в ax
 and al, 0EFh   ; Логическое И, обнуление 4 бита (11101111b)
 out dx, ax    ; Записать данные (ax) в порт (dx - (0FF28h))

;;;;;;{сбрасываем регистр данных}
 mov dx, 3F8h   ; чтением из порта 03F8h
 in al, dx    ; Считать данные из порта 3F8h в al
 jmp short $+2   ; задержка

;;;;;;{сбрасываем регистр состояния линии}
    mov dx, 3FDh   ; чтением из порта 3FDh
 in al, dx    ; Считать данные из порта 3FDh в al
       ; 03FDh (для чтения) - регистр состояния линии
 jmp short $+2   ; задержка

;;;;;;{сбрасываем регистр состояния модема}
    mov dx, 3FEh   ; чтением из порта 3FDh
 in al, dx    ;
 jmp short $+2   ; задержка

;;;;{режим ввода делителя}
 mov dx, 3FBh   ;
 mov al, 80h    ; 7: бит DLAB : 1 = порты 3F8h и 3F9h в режиме ввода делителя
 out dx, al          ;
    jmp short $+2

;;;;;;(Запись в Регистр управления модемом)
 mov al, 00001100b  ; (0Ch) Запись в Регистр управления модемом
       ; 0: 1 = установить выход DTR
       ; 1: 1 = установить выход RTS
       ; 2: 1 = установить OUT1 (не используется)
       ; 3: 1 = установить OUT2 (разрешить прерывания от RS-232)
    mov dx, 3FCh
    out dx, al
    jmp short $+2

;;;;;;{младший байт делителя}
 mov dx, 3F8h
 mov al, 06h           ; скорость 19 200
                      ; задаем делитель скорости (0006h - 19200)
 out dx, al    ;
 jmp short $+2
  
;;;;;;{старший байт делителя}
 mov dx, 3F9h   ;
 mov al, 0    ; Скорость 19 200
 out dx, al         ;
 jmp short $+2

;;;;;;{буферизация FIFO}(отключаем)
    mov al, 00000000b   ; бит 0   : Разрешение использования буферизации при приеме и предаче
                        ; бит 1   : Сброс приемного буфера FIFO
                        ; бит 2   : Сброс буфера FIFO передатчика
                        ; биты 6-7: Установка значения  числа символов в приемном буфере FIFO для
                        ;           инициирования прерывания (FIFO Trigger Level)
                        ;           00 - 1 бит
    mov dx, 3FAh
    out dx, al
    jmp short $+2
   
;;;;;;{режим работы}
 mov dx, 3FBh
 mov al, 00000011b  ; Режим работы
      ; 0-1: число битов данных : 11 = 8 бит
      ; 2  : число стоп-битов   : 0 = 1 стоп бит
      ; 3-4: тип четности       : X0 = нет
      ; 5  : постоянная четность: 0 = отмена постоянной четности
      ; 6  :                    : 1 = имитировать обрыв линии
      ; 7  : бит DLAB           : 0 = порты 3F8h и 3F9h в обычном режиме
 out dx, al 
 jmp short $+2

;;;;;;(Запись в Регистр управления прерываниями)
 mov al, 00000010b ; (5) Запись в Регистр управления прерываниями
      ; 0: прерывание по приему символа
      ; 1: прерывание по завершению передачи символа
      ; 2: прерывание по обрыву линии или ошибке в линии
      ; 3: прерывание по изменению состояния модема (любой из линий CTS, DSR, RI и DCD)
 mov dx, 3F9h
 out dx, al
 jmp short $+2

; устанавливаем формат даты и времени "двоичный"
 mov al,0Bh    ; CMOS OBh - управляющий регистр В
 out 70h,al    ; порт 70h - индекс CMOS
 in al,71h    ; порт 71h - данные CMOS
 or al,00000110b  ; установить бит 1 и 2
       ; бит 1: 1/0 — 24-часовой/12-часовой режим
       ; бит 2: 1/0 — формат даты и времени двоичный/BCD
 out 71h,al    ; и записать обратно

 pop dx   ; восстановить dx основной программы
 pop bx   ; восстановить bx основной программы
 pop es       ; восстановить es основной программы  
 pop ds       ; восстановить ds основной программы

 retn
Ini_COM1 endp

;--------------------------------------------------------------------
; Подпрограмма Start_COM1 используется для передачи данных из буффера
; для передачи символов (44 байт) на дисплей
; ОПИСАНИЕ:
; Входные данные:
; DDD     (Boolean) - управляющий сигнал (запуск передачи на дисплей)
; D_day   (Integer) - день (число месяца)
; D_month (Integer) - месяц
; D_hour  (Integer) - час
; D_min   (Integer) - минут
; D_sec   (Integer) - секунд
; D_N_pehi(Integer) - номер текущей печи
; D_minus (Integer) - минус или плюс
; D_M_min (Integer) - минут до выдачи
; D_M_sec (Integer) - секунд до выдачи
; D_Tok   (Integer) - значение тока
Start_COM1 proc pascal near
   arg DDD:word, D_day:word, D_month:word, D_hour:word, D_min:word, D_sec:word, D_N_pehi:word, D_minus:word, D_M_min:word, D_M_sec:word, D_Tok:word
  
;===============================
 Push bx   ; сохраняем регистр bx
 Push dx   ; сохраняем регистр bx

 mov bx, DDD    ; получаем адрес управляющей переменной (Boolean)(1 писать, 0 не писать)
 mov al, byte ptr [bx] ; получаем значение переменной
 cmp al,0    ; сравнение
 jnz Next_Start_COM1  ; если не ноль, то на метку, иначе
 jmp Exit_Start_COM1

Next_Start_COM1:
 assume ds:DGROUP

 mov bx, D_day   ; получаем адрес переменной
 mov ax, word ptr [bx] ; получаем значение переменной
 call AL_word   ; вызываем подпрограмму
 mov ds:Date_day, ax  ; пишем в переменную

 mov bx, D_month   ; получаем адрес переменной
 mov ax, word ptr [bx] ; получаем значение переменной
 call AL_word   ; вызываем подпрограмму
 mov ds:Date_month, ax ; пишем в переменную

 mov bx, D_hour   ; получаем адрес переменной
 mov ax, word ptr [bx] ; получаем значение переменной
 call AL_word   ; вызываем подпрограмму
 mov ds:Date_hour, ax ; пишем в переменную

 mov bx, D_min   ; получаем адрес переменной
 mov ax, word ptr [bx] ; получаем значение переменной
 call AL_word   ; вызываем подпрограмму
 mov ds:Date_min, ax  ; пишем в переменную

 mov bx, D_sec   ; получаем адрес переменной
 mov ax, word ptr [bx] ; получаем значение переменной
 call AL_word   ; вызываем подпрограмму
 mov ds:Date_sec, ax  ; пишем в переменную


 mov bx, D_N_pehi  ; получаем адрес переменной
 mov ax, word ptr [bx] ; получаем значение переменной
 mov bx, 100    ; делитель
 xor dx, dx    ; обнуление dx
 div bx     ; Целочисленное деление без знака
       ; ax на bx, результат в AX, остаток в DX
 call AL_word   ; вызываем подпрограмму
 mov ds:Sotni_pehi, ah ; пишем в переменную
 mov ax, dx    ; остаток в ax
 call AL_word   ; вызываем подпрограмму
 mov ds:Des_pehi, ax  ; пишем в переменную


 mov bx, D_M_min   ; получаем адрес переменной
 mov ax, word ptr [bx] ; получаем значение переменной
 cmp ax, 99    ; сравнение
 jne D_M_min_Ne_99  ; если не равно, то на метку, иначе
 mov ds:Plus_minus, 20h ; пишем в переменную " "(пробел)
 mov ds:Plus_minus_min, 2020h ; пишем в переменную " "(два пробела)
 mov ds:Plus_minus_sec, 2020h ; пишем в переменную " "(два пробела)
 mov ds:Dvoetohie, 20h ; пишем в переменную " "(пробел)
 jmp NNNN_

D_M_min_Ne_99:
 mov bx, D_minus   ; получаем адрес переменной
 mov ax, word ptr [bx] ; получаем значение переменной
 cmp ax, 0    ; сравнение
 jnz D_minus_ne_0  ; если не ноль, то на метку, иначе
 mov ds:Plus_minus, 2Bh ; пишем в переменную "+"
 jmp Next_Plus_minus

D_minus_ne_0:
 mov ds:Plus_minus, 2Dh ; пишем в переменную "-"
Next_Plus_minus:

 mov bx, D_M_min   ; получаем адрес переменной
 mov ax, word ptr [bx] ; получаем значение переменной
 call AL_word   ; вызываем подпрограмму
 mov ds:Plus_minus_min, ax ; пишем в переменную

 mov bx, D_M_sec   ; получаем адрес переменной
 mov ax, word ptr [bx] ; получаем значение переменной
 call AL_word   ; вызываем подпрограмму
 mov ds:Plus_minus_sec, ax ; пишем в переменную
 mov ds:Dvoetohie, 3Ah ; (3A) - :

NNNN_:
 mov bx, D_Tok   ; получаем адрес переменной
 mov ax, word ptr [bx] ; получаем значение переменной
 mov bx, 100    ; делитель
 xor dx, dx    ; обнуление dx
 div bx     ; Целочисленное деление без знака
       ; ax на dx, результат в AX, остаток в DX
 call AL_word   ; вызываем подпрограмму
 cmp al, 30h    ; сравнение
 jne Ne_30h    ; если не равно, то на метку, иначе
 mov al, 20h    ; пишем " " (пробел)

Ne_30h:
 mov ds:Tok_ah, ax  ; пишем в переменную
 mov ax, dx    ; остаток в ax
 call AL_word   ; вызываем подпрограмму
 mov ds:Tok_al, ax  ; пишем в переменную

;;;;;;{передача символа}
 cmp Start_Data, 0  ; сравнение (Переменная для контроля начала передачи)
 jnz Next_peredahi  ; если не ноль, то на продолжение передачи, иначе
 
 inc Start_Data   ; инкремент (+1), начало передачи
 mov Shet_Size_Data, 1 ; записываем значение счетчика
 mov al, byte ptr ds:Byffer_Peredahi ; считываем значение из буффера передачи
 mov dx, 03F8h   ; адрес порта
 out dx, al          ; пишем в порт
 jmp Exit_Start_COM1  ; на выход
 
Next_peredahi: 
 inc Start_Data   ; инкремент (+1) чтобы раз в 256 сек. перезапускать дисплей
 mov Shet_Size_Data, 4 ; записываем значение счетчика
 mov al, byte ptr ds:Byffer_Peredahi+3 ; считываем значение из буффера передачи
 mov dx, 03F8h   ; адрес порта
 out dx, al          ; пишем в порт


Exit_Start_COM1:
;===============================
 pop dx   ; востанавливаем регистр dx
 pop bx   ; востанавливаем регистр bx
 
    ret  ;все остальное додумает ассемблер (T320+)
Start_COM1 endp

Vel
Наверх
kot23rus Смотреть выпадающим
Новичок
Новичок


Присоединился: 07 Февраль 2009
Категория: Russian Federation
Online Status: Offline
Публикации: 24
Свойства публикации Свойства публикации   Ответить, цитируя автора - kot23rus Ответить, цитируя автора -  ОтветитьОтвет Прямая ссылка на эту публикацию Опубликовано: 09 Февраль 2009 10:29

Валера, спасибо что откликнулись. Я не плохо знаю асеммблер, использовал его правда на других контроллерах, но задача стоит в том что бы разработать программу на С, так как я пишу программу не один. Скажем так есть программа в ПЛК которая думает и рулит процессом, а параллельно нужно еще организовать обмен с компом, поэтому есть желание тупо организовывать связь по прерыванию от СОМ.

Наверх
Vel_ Смотреть выпадающим
Действительный член
Действительный член


Присоединился: 25 Апрель 2006
Категория: Russian Federation
Online Status: Offline
Публикации: 116
Свойства публикации Свойства публикации   Ответить, цитируя автора - Vel_ Ответить, цитируя автора -  ОтветитьОтвет Прямая ссылка на эту публикацию Опубликовано: 09 Февраль 2009 12:44

Если Вы знаете ASM, то Вам не составит большого труда перевести все на С.

В моем коде (выдернутом из работающей программы) все ключевые моменты указаны. Рабочая прога сделана в UL 24 и EXT вставки на asm. Вы также можете использовать в С вставку obj c кодом на asm, не проблема. Можете все переделать на С.

Мое мнение: писать обработчики прерываний на С, да еще и для контроллеров (ограниченные ресурсы памяти и критичная скорость выполнения) это не есть гут (мягко выражаясь). Ведь Ваш код будет останавливать всю систему на время обработки прерывания, и чем массивнее код, тем сильнее тормоза.

Vel
Наверх
kot23rus Смотреть выпадающим
Новичок
Новичок


Присоединился: 07 Февраль 2009
Категория: Russian Federation
Online Status: Offline
Публикации: 24
Свойства публикации Свойства публикации   Ответить, цитируя автора - kot23rus Ответить, цитируя автора -  ОтветитьОтвет Прямая ссылка на эту публикацию Опубликовано: 09 Февраль 2009 12:47

Я понимаю это очень хорошо. Прерывания запустить удалось. Из ASM я обращатся к модулям не знаю как, думаю через порты но не вкурсе через какие.

Наверх
Vel_ Смотреть выпадающим
Действительный член
Действительный член


Присоединился: 25 Апрель 2006
Категория: Russian Federation
Online Status: Offline
Публикации: 116
Свойства публикации Свойства публикации   Ответить, цитируя автора - Vel_ Ответить, цитируя автора -  ОтветитьОтвет Прямая ссылка на эту публикацию Опубликовано: 10 Февраль 2009 05:53

Начнем с того, что С не имеет в своём составе функций для работы с модулями ADAM. Вы эти функции подключаете из lib. Библиотека lib - это набор объектных файлов (уже "откомпилированных") и Вы только вызываете эти функции. Отсюда вывод: В каком языке программирования Вы их используете не имеет решающего значения!

Самый простой путь, проверенный годами практики - это использовать UltroLogik. Компилятор у него сделан по человечески, не ногами. Все на TASM. компилируется в оптимальный код, бастрый и маленький. Все lib переписаны на TASM с СИ. Поэтому опрос модулей, простая логика на UL - все навороты EXT блоки на ASM. Работает "изюмительно"!!!

С 2000 г. насмотрелся на проекты наСИльников для ADAM. Простая прога с трудом влазит в контроллер, часто сам по себе перезагружается (нонсенс!!) и т.д. Так что Вам решать по какому пути идти, выбор за Вами!!!

Vel
Наверх
Semelenov Смотреть выпадающим
Действительный член
Действительный член


Присоединился: 15 Октябрь 2003
Категория: Belarus
Online Status: Offline
Публикации: 141
Свойства публикации Свойства публикации   Ответить, цитируя автора - Semelenov Ответить, цитируя автора -  ОтветитьОтвет Прямая ссылка на эту публикацию Опубликовано: 05 Апрель 2017 16:07
Приветствую Всех.
А для работы с 4 сом-портом нету случайно кода?
Наверх
tonyk Смотреть выпадающим
Новичок
Новичок


Присоединился: 21 Август 2010
Online Status: Offline
Публикации: 27
Свойства публикации Свойства публикации   Ответить, цитируя автора - tonyk Ответить, цитируя автора -  ОтветитьОтвет Прямая ссылка на эту публикацию Опубликовано: 05 Апрель 2017 20:48
Коллеги!

Не лезьте вы в прерывания на АДАМАх! Как показывает мой опыт, желание перехватывать прерывания возникает при недостаточном понимании работы этого девайса. Без обид, внимательно изучите API и переосмыслите ещё раз свои хотелки. Уверяю вас, вам не понадобятся прерывания. Сам через это прошёл.
Наверх
poison Смотреть выпадающим
Участник
Участник
Аватар

Присоединился: 02 Декабрь 2010
Online Status: Offline
Публикации: 68
Свойства публикации Свойства публикации   Ответить, цитируя автора - poison Ответить, цитируя автора -  ОтветитьОтвет Прямая ссылка на эту публикацию Опубликовано: 06 Апрель 2017 08:09
Привет!

посмотри по ссылке ниже, мы с коллегой в свое время все API переделывали там вроде есть поддержка COM4

https://github.com/Poisondo/lib-adam-5000/tree/master/src/io/sio
Наверх
Semelenov Смотреть выпадающим
Действительный член
Действительный член


Присоединился: 15 Октябрь 2003
Категория: Belarus
Online Status: Offline
Публикации: 141
Свойства публикации Свойства публикации   Ответить, цитируя автора - Semelenov Ответить, цитируя автора -  ОтветитьОтвет Прямая ссылка на эту публикацию Опубликовано: 01 Июнь 2017 13:00
Приветствую всех

2 tonic:
  Ну не используем мы в своих работах библиотеки от Адвантека - понятно это или нет?

2 poison:
  Помню я Ваш код. Взял я его тогда, переписали мы его на Паскаль.
  Но.. где-то что-то мы не доперевели - 1 и 4 комы не хотят работать параллельно ((
  Если "открыть порт-передать-закрыть" - по очереди работают, если открыть все
  и параллельная работа по всем - 2 и 3 комы работают нормально, 1 и 4 работают пару 
  секунд и зактыкаются оба.
Наверх
 Ответить Ответить

Переход на форум Права доступа на форуме Смотреть выпадающим

Bulletin Board Software by Web Wiz Forums® version 9.64
Powered by Web Wiz Forums Free Express Edition
Copyright ©2001-2009 Web Wiz