Форум программистов, компьютерный форум, киберфорум
Наши страницы
Микроконтроллеры Atmega AVR
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.90/39: Рейтинг темы: голосов - 39, средняя оценка - 4.90
Calligraff
3 / 3 / 1
Регистрация: 26.07.2013
Сообщений: 46
1

Обмен данными между МК через RS-485 (MAX487)

28.10.2015, 09:01. Просмотров 7052. Ответов 86
Метки нет (Все метки)

Доброго времени суток.

Сразу к делу:
В сообщении прикреплено фото и файл исходного кода (AtmelStudio 6) и проект в Proteus 8 Prof.

Проблема в следующем:
из МК U2 поднимаем ножку PD3, передаем данные TXD (рис.п.1) MAX487 передает другой стороне (рис.п.2), а U3 принимает RXD (рис.п.3).

Далее U3 обрабатывает данные и выдает ответ TXD (рис.п.4), MAX487 передает другой стороне (рис.п.5), но вот U2 через RXD (рис.п.6) ничего не принимает.

Помогите пожалуйста разобраться.
0
Миниатюры
Обмен данными между МК через RS-485 (MAX487)  
Вложения
Тип файла: zip project.zip (105.9 Кб, 54 просмотров)
Лучшие ответы (1)
QA
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
28.10.2015, 09:01
Ответы с готовыми решениями:

Обмен данными по RS-485 в CodeVisionAVR (на базе кода Wizard
Задача: дополнить (видоизменить) код на С (в CodeVisionAvr) , чтобы получить работу функций...

RS-485: PIC18f4620 и MAX487
Доброй ночи. Подскажите, пожалуйста, такую штуку. Разбираюсь с передачей данных посредством...

Обмен данными по UART между несколькими устройствами
Планирую собрать систему из 2 - 33 устройств обменивающимися данными между собой по UART. В систему...

Обмен данными по SPI между двумя Atemga
Пытаюсь реализовать обмен 5 байт данными между двумя Atmeg(1-Atmega165 ведущий, 2-Atmega16...

Обмен данными через COM- порт
Добрый день, пытаюсь освоить передачу данных. Отсылаю на мк скажем "1", приходит "1" и "-38"...

86
Витальич
1275 / 1182 / 174
Регистрация: 02.12.2013
Сообщений: 4,886
29.10.2015, 14:14 21
Цитата Сообщение от Calligraff Посмотреть сообщение
а какую роль в третьей схеме выполняет транзистор "КТ361"
Переключает драйвер в режим передачи. ИМХО: для ModBus и других "реальных" протоколов так делать идеологически не верно.
0
Voland_
1674 / 1060 / 102
Регистрация: 04.01.2010
Сообщений: 3,608
01.11.2015, 11:17 22
Calligraff, рекомендую для отладки кода вообще выкинуть пока что интерфейсы. подключите напрямую TX->RX, RX->TX контроллеров и напишите обмен. Затем отследите ноги управления обоих драйверов, чтобы они включались в момент передачи и выключались в момент ее завершения (флаг USORT->TXC, если подзабыли). Потом втыкайте оба драйвера RS485 и отлаживайте уже интерфейсную часть...

ЗЫ: сколько ни лепил RS485х в своих наколеночных схемах, нигде не ставил подтяжки 2к к питанию и земле... Кстати, на практике иногда схема даже с резистором 120 Ом не работает - пришлось отключать. (без него работает по сей день)...

Добавлено через 13 минут
...прошу прощения, посмотрев и код и диаграммы убедился, что Вы сделали все верно...

Единственное, что смущает на графиках - это смещение по линии RS485 при передаче сигнала в обратную сторону... То есть по виду графики должны быть одинаковой амплитуды и смещения...
ЗЫ: попробуйте другую модель драйвера rs485. скажем, max485...

Добавлено через 3 минуты
еще, я не увидел в коде где вы инициализируете ноги контроллера под UART? обычно для ноги RX включается подтяжка к плюсу (ее можно и внешнюю присобачить - хуже не будет), а для ноги TX указывается, что это выход.
1
Calligraff
3 / 3 / 1
Регистрация: 26.07.2013
Сообщений: 46
01.11.2015, 17:54  [ТС] 23
еще, я не увидел в коде где вы инициализируете ноги контроллера под UART?
UART_Init(...) - Это единственное, что у меня описывается для UARTa
Подтяжку делал сопротивлением (в недавнем сообщении в теме есть скрин), но пока убрал, дабы исключить все лишнее.

Добавлено через 16 минут
Вы правы. сейчас я тамк и сделал. пока без интерфейса и напрямую UARTом. но все равно спасибо
0
Calligraff
3 / 3 / 1
Регистрация: 26.07.2013
Сообщений: 46
02.11.2015, 18:04  [ТС] 24
С протоколом закончил. сдел по принципу ModBus, но с некоторыми изменениями (с моей точки зрения - улучшениями).
В связи с чем (дабы не плодить темы спрошу здесь, тем более что все в рамках одного проекта) есть пару вопросов:

1. Стоит ли использовать структуры? как это влияет на быстродействие и память.
2. Заметил один момент. если в цикле while(1) главной функции использовать условие if (my_flag) { .... }, где my_flug меняется где-то в программе в прерываниях, то оно не отрабатывает пока перед условием не поставить задержку хотя бы в 1 мкс.

вот этот код отрабатывает как надо:
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
........
bool my_flag = false;
........
ISR(USORT_RXC_vect)
{
   my_flag = true;
}
 
int main(void)
{
   ...
   _delay_us(1); // либо _delay_ms(1);
   if (my_flag)
   {
      ............
   }
   ...
}
а этот не попадает внутрь условия при выставлении my_flag в true во время приема по uart (в коде убрана задержка)
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
........
bool my_flag = false;
........
ISR(USORT_RXC_vect)
{
   my_flag = true;
}
 
int main(void)
{
   ...
   // _delay_us(1);
   if (my_flag)
   {
      ............
   }
   ...
}
Дак вот. Это особенность микроконтроллера или снова глюк протеуса?

3. При вычислении CRC что лучше использовать функцию с расчетом или таблицу CRC?

Спасибо за помощь.
0
02.11.2015, 18:04
Voland_
1674 / 1060 / 102
Регистрация: 04.01.2010
Сообщений: 3,608
02.11.2015, 22:40 25
Цитата Сообщение от Calligraff Посмотреть сообщение
Дак вот. Это особенность микроконтроллера или снова глюк протеуса?
Это особенность компилятора, если быть точным. Компилятор определяет, что между обращениями к этой переменной нет видимых изменений извне (то есть из прерывания), посему, предполагает, что ее значение не изменится в бесконечном цикле. Соответственно, для того, чтобы указать ему, что это ЯВНО НЕ ТАК, необходимо дописать в объявлении переменной "volatile" или заставить компилятор использовать для нее один из регистров.

Добавлено через 1 минуту
Цитата Сообщение от Calligraff Посмотреть сообщение
При вычислении CRC
как хотите. Если есть место - используйте таблицы. Если время не критично или нет места, используйте функцию.
1
Calligraff
3 / 3 / 1
Регистрация: 26.07.2013
Сообщений: 46
03.11.2015, 07:38  [ТС] 26
Цитата Сообщение от Voland_ Посмотреть сообщение
Это особенность компилятора, необходимо дописать в объявлении переменной "volatile" или заставить компилятор использовать для нее один из регистров.
Действительно, и как я забыл про "volatile"
0
Витальич
1275 / 1182 / 174
Регистрация: 02.12.2013
Сообщений: 4,886
05.11.2015, 12:55 27
Цитата Сообщение от Calligraff Посмотреть сообщение
(с моей точки зрения - улучшениями)
ой ли. Вы реализовали сброс UART(а) перед получением пакета? Что то мне подсказывает что нет, а об этом написано в спецификации ModBus.
Цитата Сообщение от Calligraff Посмотреть сообщение
Стоит ли использовать структуры? как это влияет на быстродействие и память.
практически нет, тут о реализации в компиляторе зависит, GCC - AVR сильно не копал, а в IAR например вот такой синтаксис "__regvar __no_init int counter @ 14;" приведет к принудительному размещению переменной по адресу 14 это регистр. Также во всей (ну относительно не всей) не используемой периферии можно распихать флаги. Всё это ускорит выполнения программы.
Вопрос на засыпку какой цикл выполниться быстрей?
C
1
2
for(unsigned char i = 0; i == 127; i++){}
for(unsigned char i = 127; i == 0; i--){}
0
ValeryS
Модератор
7870 / 5854 / 765
Регистрация: 14.02.2011
Сообщений: 20,120
Завершенные тесты: 1
05.11.2015, 13:29 28
Цитата Сообщение от Витальич Посмотреть сообщение
Вопрос на засыпку какой цикл выполниться быстрей?
раньше я бы с уверенностью сказал второй, поскольку сравнение с нулем происходит быстрее
типа такой (псевдо ассемблер)
Assembler
1
2
dec eax
jnz ....
а теперь с развитием архитектуры, развитием оптимизации уже не так уверен
0
Витальич
1275 / 1182 / 174
Регистрация: 02.12.2013
Сообщений: 4,886
05.11.2015, 13:34 29
Я имел ввиду AVR и Вы правы.
0
ValeryS
05.11.2015, 14:05
  #30

Не по теме:

Цитата Сообщение от Витальич Посмотреть сообщение
Я имел ввиду AVR
так и я тоже
просто ассемблер 0х86 сидит в подкорке, а для AVR надо справочник открывать:)

0
Calligraff
3 / 3 / 1
Регистрация: 26.07.2013
Сообщений: 46
11.11.2015, 15:17  [ТС] 31
Согласен, что с нулем сравнивается быстрее.

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

Подскажите пожалуйста все ли правильно или есть нюансы?
В протеусе так:
Обмен данными между МК через RS-485 (MAX487)


а как в кодевижине?
Обмен данными между МК через RS-485 (MAX487)


На сколько знаю то исторически сложилось так, что 0 - используется, а 1 - не используется
0
ValeryS
Модератор
7870 / 5854 / 765
Регистрация: 14.02.2011
Сообщений: 20,120
Завершенные тесты: 1
11.11.2015, 16:04 32
Цитата Сообщение от Calligraff Посмотреть сообщение
На сколько знаю то исторически сложилось так, что 0 - используется, а 1 - не используется
1 не запрограммированная ячейка, 0 запрограммированная
но вот что означают галочки? на разных программаторах по разному
у кого галочка это 0( то бишь запрограммированная ) у других галочка это 1

протеусом тоже можно посмотреть фъюзы, по крайней мере для частоты
вот например у тебя написано
(0100) int RC 8 MHz
0100 это и есть фъюзы частоты SCSEL
1
Calligraff
3 / 3 / 1
Регистрация: 26.07.2013
Сообщений: 46
11.11.2015, 17:23  [ТС] 33
Да да.. вот только правильно ли у меня выставлены или должно быть с точностью наоборот?
0
ValeryS
Модератор
7870 / 5854 / 765
Регистрация: 14.02.2011
Сообщений: 20,120
Завершенные тесты: 1
11.11.2015, 18:28 34
насколько помню у КодеВижен галочка равна 0
но я как делал, считывал фъюзы, там появится табличка какой в 0 какой в 1
запоминаю/ записываю
потом это все скопировать в таблицу, там есть такая кнопочка,и смотрю где стоят галочки где 0 или где 1
по крайней мере никогда не путаюсь как работает данный прогроматор
1
Calligraff
3 / 3 / 1
Регистрация: 26.07.2013
Сообщений: 46
11.11.2015, 22:34  [ТС] 35
Да, Вы правы. Галочка = 0
Кстати. нашел причину не работы на железе = Кварца контакта не было.. как всегда "сопля на плате"...
0
Voland_
1674 / 1060 / 102
Регистрация: 04.01.2010
Сообщений: 3,608
12.11.2015, 10:46 36
Цитата Сообщение от ValeryS Посмотреть сообщение
но я как делал, считывал фъюзы, там появится табличка какой в 0 какой в 1
запоминаю/ записываю
потом это все скопировать в таблицу, там есть такая кнопочка,и смотрю где стоят галочки где 0 или где 1
+1.
Насколько я помню, в CV битовые фьюзы используют инверсный тип, а небитовые (настройка клока, например) - инверсные. И это еще больше добавляет путаницы. Поэтому, вариант, предложенный выше - самый надежный.
0
Calligraff
3 / 3 / 1
Регистрация: 26.07.2013
Сообщений: 46
12.11.2015, 23:26  [ТС] 37
Может подскажите надежный и без подобных непоняток с фьюзами программу для програматора AVR910

Добавлено через 9 часов 35 минут
Присобачил к МК еще и датчик DHT11... редкостная фигня!!! стоит рядом с DS18B20 на расстоянии 4см друг от друга и разница в температуре измеряемой 5-7 градусов... интересно, а влажность тоже в точности сильно страдает?

Добавлено через 14 минут
ds18B20 = 22.5C
DHT11 T = 35
DHT11 H = 21
вот думаю не перепутал ли я Температуру с влажностью?
хотя везде на просторах интернета Нулевой байт влажность, а второй - температура

C++ (Qt)
1
2
3
4
5
6
7
8
    //check checksum
    if (bits[0] + bits[1] + bits[2] + bits[3] == bits[4]) {
        if (select == 0) { //return temperature
            return(bits[2]);
        } else if(select == 1){ //return humidity
            return(bits[0]);
        }
    }
DTH.C:
Кликните здесь для просмотра всего текста
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
/*
DHT11 Library 0x01
 
copyright (c) Davide Gironi, 2011
 
Released under GPLv3.
Please refer to LICENSE file for licensing information.
*/
 
 
#include <stdio.h>
#include <string.h>
#include <avr/io.h>
#include <util/delay.h>
 
#include "dht11.h"
 
#define DHT11_ERROR 255
 
/*
 * get data from dht11
 */
uint8_t dht11_getdata(uint8_t select) {
    uint8_t bits[5];
    uint8_t i,j = 0;
 
    memset(bits, 0, sizeof(bits));
 
    //reset port
    DHT11_DDR |= (1<<DHT11_INPUTPIN); //output
    DHT11_PORT |= (1<<DHT11_INPUTPIN); //high
    _delay_ms(100);
 
    //send request
    DHT11_PORT &= ~(1<<DHT11_INPUTPIN); //low
    _delay_ms(18);
    DHT11_PORT |= (1<<DHT11_INPUTPIN); //high
    _delay_us(1);
    DHT11_DDR &= ~(1<<DHT11_INPUTPIN); //input
    _delay_us(39);
 
    //check start condition 1
    if((DHT11_PIN & (1<<DHT11_INPUTPIN))) {
        return DHT11_ERROR;
    }
    _delay_us(80);
    //check start condition 2
    if(!(DHT11_PIN & (1<<DHT11_INPUTPIN))) {
        return DHT11_ERROR;
    }
    _delay_us(80);
 
    //read the data
    for (j=0; j<5; j++) { //read 5 byte
        uint8_t result=0;
        for(i=0; i<8; i++) {//read every bit
            while(!(DHT11_PIN & (1<<DHT11_INPUTPIN))); //wait for an high input
            _delay_us(30);
            if(DHT11_PIN & (1<<DHT11_INPUTPIN)) //if input is high after 30 us, get result
                result |= (1<<(7-i));
            while(DHT11_PIN & (1<<DHT11_INPUTPIN)); //wait until input get low
        }
        bits[j] = result;
    }
 
    //reset port
    DHT11_DDR |= (1<<DHT11_INPUTPIN); //output
    DHT11_PORT |= (1<<DHT11_INPUTPIN); //low
    _delay_ms(100);
 
    //check checksum
    if (bits[0] + bits[1] + bits[2] + bits[3] == bits[4]) {
        if (select == 0) { //return temperature
            return(bits[2]);
        } else if(select == 1){ //return humidity
            return(bits[0]);
        }
    }
 
    return DHT11_ERROR;
}
 
/*
 * get temperature (0..50C)
 */
int8_t dht11_gettemperature() {
    uint8_t ret = dht11_getdata(0);
    if(ret == DHT11_ERROR)
        return -1;
    else
        return ret;
}
 
/*
 * get humidity (20..90%)
 */
int8_t dht11_gethumidity() {
    uint8_t ret = dht11_getdata(1);
    if(ret == DHT11_ERROR)
        return -1;
    else
        return ret;
}
0
ValeryS
Модератор
7870 / 5854 / 765
Регистрация: 14.02.2011
Сообщений: 20,120
Завершенные тесты: 1
12.11.2015, 23:52 38
Цитата Сообщение от Calligraff Посмотреть сообщение
вот думаю не перепутал ли я Температуру с влажностью?
а плюнь на него и узнаешь
Цитата Сообщение от Calligraff Посмотреть сообщение
Нулевой байт влажность, а второй - температура
а первый и третий что?
0
Calligraff
3 / 3 / 1
Регистрация: 26.07.2013
Сообщений: 46
13.11.2015, 07:29  [ТС] 39
А первый и третий - А фиг его знает. толком не разбирался.. 3 часа ночи уже было не стал сильно копать.
0
ValeryS
Модератор
7870 / 5854 / 765
Регистрация: 14.02.2011
Сообщений: 20,120
Завершенные тесты: 1
13.11.2015, 17:30 40
Цитата Сообщение от Calligraff Посмотреть сообщение
А первый и третий - А фиг его знает. толком не разбирался..
так может у тебя так
0 младший байт влажности
1 старший байт влажности
2 младший байт температуры
3 старший бит температуры
ты ловишь младшие байты, а там без знания старших черте че поймать можно
0
13.11.2015, 17:30
Answers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
13.11.2015, 17:30

Обмен данными между 2 клиентами через интернет
Пожалуйста, подробно опишите, как сделать обмен данных через интернет между клиентами. На с++, или...

Обмен данными между БП и УТ на 1С 8.2 через OLE, ADO
Посоветуйте какие-нибудь статьи, книги, видео уроки по обмену данными между БП и УТ на 1С 8.2 через...

Обмен данными через указатель между потоками
Скажите, валидный ли такой код : #include &lt;iostream&gt; #include &lt;thread&gt; using namespace std;...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.