Рейтинг@Mail.ru
ModBus RTU Slave на МК PIC16F886 - ДРУиД
Войти
или
Зарегистрироваться
Главная Файлы Видеоматериалы Форум
Карта сайта
Главная -> РУБРИКИ: -> Девайсы для быта -> ModBus RTU Slave на МК PIC16F886

Статья опубликована: 2015-03-06/16:34:32-admin

ModBus RTU Slave на МК PIC16F886



Modbus -это один из протоколов обмена промышленного и инженерного оборудования, был разработан фирмой Modicon в 1979 году. Modbus — открытый протокол и эта открытость является как его плюсом так и минусом.

Реализовать его на МК младшего сейства PIC не состовляет особой трудности. Первые реализации были сделаны в различных IDE для пиков и не блистали структурой и простой переноса с "камень" на "камень".

После освоения IDE от "Мелкочипа" под названием MpLab X IDE встал вопрос, как структурировать библиотеку и облегчить перенос с проекта в проект? Ответ нашелся на сайте сообщества easyelectronics.ru. Хорошая статья и была взята за основу.

Но кроме самого протокола сделаем хоть что то полезное. Есть предложение завести 2 канала АЦП, отдавать данные с них по сети (RS-485) и управлять всеми пинами порта Б.

Проект сделан в MpLab X IDE v.2.00 и использован компилятор XC8 v.1.20.

Со спецификацией протокола ModBus RTU познакомились, самое время перейти к практической части реализации.

Вот хидер файл для протокола ModBus RTU.

/*
 * Заголовочный файл протокола ModBus RTU
 */


#ifndef MODBUS_H
#define	MODBUS_H

#include "type_def.h"

/*Формируем буфер для УАРТа*/

#define BUF_SZ 50                       /*Количество байт данных фрейма Modbus*/
#define MODBUS_WRD_SZ (BUF_SZ-5)/2      /*Количество регистров в посылке*/
#define MODBUS_ADDR 1                   /*Сетевой адрес modbus устройства*/
#define OBJ_SZ 20                       /*Общее количество регистров*/

WORD_VAL res_table[OBJ_SZ];             /*Таблица регистров модбас, с которых 
                                         * происходит чтение значений пареметров*/
                                        /*установленных пользователем*/
                                        /*[0] - модбас адрес устройства, можно 
                                         * применить для конфигурирования по сети*/
                                        /*[1] - скорость передачи УАРТ, можно конфигурировать по сети*/
                                        /*[2] - значение кода АЦП канала 0*/
                                        /*[3] - значение кода АЦП канала 1*/
                                        /*[4] - команда от мастера для управления 
                                         * уровенями на порту Б, используется младший байт*/
                                        /*Так составляется карта регистров модбас устройства*/

/*УАРТ структура Modbus*/

typedef struct {
unsigned char buffer[BUF_SZ];
unsigned char rxtimer;
unsigned char rxcnt;
unsigned char txcnt;
unsigned char txlen;
unsigned char rxgap;
unsigned char delay;
unsigned char write;
} UART_DATA;

unsigned char addr;

/*Объявление прототипов функции*/

void MODBUS_SLAVE(UART_DATA *MODBUS);
unsigned int CRC16(unsigned char *ptrByte, int byte_cnt);
void TX_03(UART_DATA *MODBUS);
void TX_16(UART_DATA *MODBUS);
void TX_ERROR(UART_DATA *MODBUS,unsigned char error_type);
void TX_FRAME(UART_DATA *MODBUS);

#endif	/* MODBUS_H */

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

Структуру объявили, определили и утвердили.

В основном теле программы, проинициализируем переферию, настроим УАРТ, объявим переменные.

Вот кусочек кода "главного" сорца.

while(1){
        CLRWDT();
        if (Flag_Adc){                                  /*Как системный таймер отсчитал необходимый интервал*/
            if (Flag_Ch_Adc){
                ADCON0bits.GO_DONE=1;                   /*Запускаем преобразование*/
                while (ADCON0bits.GO_DONE) continue;
                adc_ch1.byte.HB=ADRESH;
                adc_ch1.byte.LB=ADRESL;                 /*Считываем код АЦП*/
                AN1_ON=0;                               /*Переключаем каналы*/
                res_table[3].Val=adc_ch1.Val;           /*Записываем считанный код АЦП канала 1 в таблицу регистров модбас*/
                Flag_Ch_Adc=0;
            }
            else{
                ADCON0bits.GO_DONE=1;
                while (ADCON0bits.GO_DONE) continue;
                adc_ch0.byte.HB=ADRESH;
                adc_ch0.byte.LB=ADRESL;                 /*Считываем код АЦП*/
                AN1_ON=1;                               /*Переключаем каналы*/
                res_table[2].Val=adc_ch0.Val;           /*Записываем считанный код АЦП канала 0 в таблицу регистров модбас*/
                Flag_Ch_Adc=1;
            }
            Flag_Adc=0;
        }
        /*Обработка фрейма модбас*/

        if (MODBUS.rxgap){
            MODBUS_SLAVE(&MODBUS);
            MODBUS.rxgap=0;
        }

        /*обработка записи мастера модбас*/
        if (MODBUS.write){
            PORTB=res_table[4].byte.LB;                     /*Выводим на пины порта Б команду от мастера*/

            /*...*/
            /*Здесь можно проверить, какие регистры изменились от мастера
            * и сделать соответствующие действия, например
            * запомнить новый адрес устройства в eeprom
            * eerpom_write(0,res_table[0].byte.LB);
            */
        }
    }

Проект в Proteus ISIS приложен к архиву. В протеусе можно полноценно симулировать работу нашей программы. А с помощью компонента COMPIM, виртуальным "нуль" модемным кабелем и любым ModBus сервером или дубагером реально по управлять выходами порта Б или считать показания АЦП с движка переменного резистора.

Небольшой принт скрин:

 

Остальное в файлах проекта тыц для скачивания.

 

Короткое видео:

 

 

З.Ы. Как всегда, все вопросы, пожелания, предложения складываем здесь.

 


Просмотров: 5833



Комментарии: (0)

Оставить комментарий

Да, Я Хочу Всегда Быть В Курсе Новых Событий На Сайте!

Подпишитесь прямо сейчас, и получайте обновления на свой E-Mail:

Ваш E-Mail в безопасности


Рекомендованные статьи:



Источники бесперебойного питания (ИБП) нашли широкое применение, как в быту, так и в промышленности. Они призваны обеспечить необходимым питанием оборудование из резервных источников в случае "пропажи" основного питания. Резервными источниками в таких ИБП в основном служат аккумуляторы.


Поговорим о диммере. Что это за "чудо" прибор?! Для чего он нужен в быту или в системе "умный" дом. Какие типы диммеров бывают.


РУБРИКИ:








Последняя статья:

Часть I. Статья №6. Верстка подвала – блока футтер

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

Читать далее »


Справка Обратная связь Вопросы и ответы Контакты RSS-лента © 2013-2016, ДРУиД - Дом Рационально-Умный и Душевный
Рейтинг@Mail.ru Яндекс.Метрика