Форум программистов, компьютерный форум, киберфорум
Наши страницы
Микроконтроллеры Atmega AVR
Войти
Регистрация
Восстановить пароль
Другие темы раздела
Atmega AVR микроконтроллер Работа с SRAM (AT90S2313) http://www.cyberforum.ru/avr/thread1562997.html
СodeVisionaAVR Записать в кодах МК AT90S2313 программу, которая: - Записывает в ячейку SRAM1 константу FE; - Переписывает содержание SRAM1 в регистр с номером 0; - Начальный адрес программы...
Atmega AVR микроконтроллер Подскажите по написанию программы для ультразвуковой ванночки, AtmelStudio 6 Здравствуйте я начал изучать язык си немного начал понимать и решил попробовать написать программу для своей ультразвуковой ванночки у неё слетела программа. Принцип хочу сделать такой есть три... http://www.cyberforum.ru/avr/thread1561104.html
Бегущая строка на MAX7219 Atmega AVR микроконтроллер
Доброго времени суток Делаю светодиодное табло, С использованием матриц 8х8 и Max7219. Проблема обстоит в том что никак не получается добавить эффект плавно движущийся строки. #include...
Atmega AVR микроконтроллер Программа "бегущий огонь" на ATMEGA
Написать программу для отображения передвижения двух светодиодов подключенных к порту МК. Направление передвижения определяется нажатием кнопок на основной плате (кнопка1-влево, кнопка2- вправо).
Atmega AVR микроконтроллер Работа с UART (Си, ATtiny 2313) http://www.cyberforum.ru/avr/thread1555551.html
Дорогие формчане и знатаки по микроконтролёрам я Новичок в этом деле. У меня есть вопрос, есть кусок кода в котором записываю принитые данные с Uart в массив и проверяю каждый елемент массива на...
Atmega AVR микроконтроллер Контроль семисегментника через сдвиговый регистр (ATMega8) подскажите, пожалуйста, нужно управлять 7 сегментным индикатором через регистр. Не могу никак разобраться подробнее
Calligraff
3 / 3 / 1
Регистрация: 26.07.2013
Сообщений: 46
28.10.2015, 20:33  [ТС] 0

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

28.10.2015, 20:33. Просмотров 6138. Ответов 86
Метки (Все метки)

Ответ

Код:

для AtMega16 по схеме:
Кликните здесь для просмотра всего текста
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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
#define F_CPU 8000000UL
 
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <string.h>
#include <stdio.h>
 
char c_DEVICE_UID[8] = {'C', 'O', 'N', 'T', 'R', 'O', 'L', 'L'};    // S-TPH/01
char c_DEVICE_MAC[4] = {0x01, 0x01, 0x01, 0x01};
#define DEVICE_UID                  c_DEVICE_UID
#define DEVICE_MAC                  c_DEVICE_MAC
 
#define RS485_SETBIT(x,y)           ( x |= ( 1 << y ) )
#define RS485_CLRBIT(x,y)           ( x &= ~( 1 << y ) )
#define RS485_PORT                  PORTD
#define RS485_CONTROL               PD3          // управление приемом/передачей RS485
#define RS485_TR                    RS485_SETBIT(RS485_PORT,RS485_CONTROL) // Установить RE DE в 1. Отправка
#define RS485_RS                    RS485_CLRBIT(RS485_PORT,RS485_CONTROL) // Установить RE DE в 0. Прием
 
// Usart makros of speed
#define USORT_BAUD                  9600
#define UBRR_VAL                    F_CPU / 16 / USORT_BAUD - 1
// USORT Receiver buffer
#define DATA_REGISTER_EMPTY         ( 1 << UDRE )
#define RX_COMPLETE                 ( 1 << RXC )
#define FRAMING_ERROR               ( 1 << FE )
//#define PARITY_ERROR              ( 1 << UPE )
#define DATA_OVERRUN                ( 1 << DOR )
#define RX_ADDRESS_SIZE             4
#define RX_DATA_SIZE                16
#define RX_BUFFER_SIZE              1 + RX_ADDRESS_SIZE + RX_DATA_SIZE + 1
#define USORT_STARTPACKET           0x0A
#define USORT_STOPPACKET            0x0B
// This flag is set on USORT Receiver buffer overflow
unsigned char ex_rx_index;
char ex_rx_buffer_adr[RX_ADDRESS_SIZE];
char ex_rx_buffer_cmd;
char ex_rx_buffer_dat[RX_DATA_SIZE];
bool ex_rx_buffer_overflow = false;
bool ex_rx_enable = false;
bool ex_rx_data_complite = false;
 
// LED ON
void LEDLAMP_ON(unsigned int n_pin)
{
    PORTC |= ( 1 << n_pin );
}
 
// LED OFF
void LEDLAMP_OFF(unsigned int n_pin)
{
    PORTC &= ~( 1 << n_pin );
}
 
void UART_Init (unsigned int speed)
{
    // Устанавливаем скорость Baud Rate
    UBRRH = (unsigned char)( speed >> 8 );
    UBRRL = (unsigned char) speed;
    UCSRA = 0x00;
    
    // Hазрешение работы передатчика
    UCSRB = ( 1 << TXEN ) | ( 1 << RXEN ) | (1 << RXCIE ) | (1 << TXCIE );
    
    //Установка формата посылки: 8 бит данных, 1 стоп-бит
    //UCSRC = (1 << USBS) | (3<<UCSZ0);
 
    /* Set frame format: 8data, 2stop bit */
    UCSRC = (1<<URSEL)|(1<<USBS)|(3<<UCSZ0);
    _delay_ms(50);
}
 
// Send to UART
void UART_Send_Char (char data_tx)
{
    while ( !( UCSRA & (1<<5)) ) {}
    RS485_TR;
    UDR = data_tx;
}
 
// Send to UART
void UART_SendString (char data_tx[])
{
    int i;
    int len;
    len = strlen( data_tx );
    for (i=0; i < len; i++) {
        UART_Send_Char(data_tx[i]);
    }
}
 
ISR(USORT_TXC_vect)
{
    RS485_RS; // Установить RE DE в 0. Прием
}
 
void USORT_SendPacket(char rx_device_mac[4], char rx_buffer_cmd, char rx_buffer_dat[RX_DATA_SIZE])
{
    char tmp_tx_data[RX_BUFFER_SIZE];
    sprintf(tmp_tx_data, "%c%c%c%c%c%c%s%c",    USORT_STARTPACKET,
                                                rx_device_mac[0],
                                                rx_device_mac[1],
                                                rx_device_mac[2],
                                                rx_device_mac[3],
                                                rx_buffer_cmd,
                                                rx_buffer_dat,
                                                USORT_STOPPACKET);
    UART_SendString(tmp_tx_data);
}
 
ISR(USORT_RXC_vect)
{
    char status, data;
    unsigned char sub_rx_index;
    status = UCSRA;
    data = UDR;
    if ((status & (FRAMING_ERROR /*| PARITY_ERROR */| DATA_OVERRUN))==0)
    {
 
        if (data == USORT_STARTPACKET)
        {
            memset(ex_rx_buffer_adr, 0, sizeof(ex_rx_buffer_adr));
            ex_rx_buffer_cmd = 0;
            memset(ex_rx_buffer_dat, 0, sizeof(ex_rx_buffer_dat));
            ex_rx_index=0;
            ex_rx_enable = true;
            ex_rx_data_complite = false;
            
        }
        
        if ( (data == USORT_STOPPACKET) && (ex_rx_enable == 1) )
        {
            ex_rx_enable = 0;
            ex_rx_data_complite = true;
        }
        
        if (ex_rx_enable == 1)
        {
            if ( (ex_rx_index >= 0) && (ex_rx_index <= 4) )
            {
                ex_rx_buffer_adr[ex_rx_index] = data;
                if (ex_rx_index == 4)
                {
                    if ( !strcat(ex_rx_buffer_adr, DEVICE_MAC) )
                    {
                        ex_rx_enable = 0;
                        ex_rx_data_complite = false;
                    }
                }
                ++ex_rx_index;
            } else if (ex_rx_index == 5)
            {
                ex_rx_buffer_cmd = data;
                ++ex_rx_index;
            } else if (ex_rx_index > 5)
            {
                sub_rx_index = ex_rx_index - 6;
                ex_rx_buffer_dat[sub_rx_index] = data;
                ++ex_rx_index;
            }
 
            if (ex_rx_index >= RX_BUFFER_SIZE)
            {
                ex_rx_enable = false;
                ex_rx_buffer_overflow=1;
            }
            
        }
        
    }
}
 
void ExchangeUART(char rx_buffer_cmd, char rx_buffer_dat[RX_DATA_SIZE])
{
LEDLAMP_ON(0);
    char tmp_rx_buffer[RX_DATA_SIZE];
    if (rx_buffer_cmd == 0xA2) // Активация устройства
    {
 
        memset(tmp_rx_buffer, 0, sizeof(tmp_rx_buffer));
        sprintf(tmp_rx_buffer, "%s", "GOOD!!!");
        
        //USORT_SendPacket(DEVICE_MAC, 0xA2, tmp_rx_buffer);
    }
}
 
int main(void)
{
    UART_Init(UBRR_VAL);
    
    DDRD |= ( 1 << PD3);
    RS485_RS; // Установить RE DE в 0. Прием
    
    DDRC |= ( 1 << PC0);
    
    char rx_device_mac[4] = {0x01, 0x01, 0x01, 0x01};
    
    sei();
    
    while(1)
    {
        _delay_ms(1500);
        memset(ex_rx_buffer_dat, 0, sizeof(ex_rx_buffer_dat));
        
        
        USORT_SendPacket(rx_device_mac, 0xA1, ex_rx_buffer_dat);
        _delay_ms(15);
        if (ex_rx_data_complite)
        {
            ex_rx_data_complite = false;
            ExchangeUART(ex_rx_buffer_cmd, ex_rx_buffer_dat);
        }
    }
}


для AtMega8 по схеме:

Кликните здесь для просмотра всего текста
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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
#define F_CPU 8000000UL
 
 
 
char c_DEVICE_UID[8] = {'S', '-', 'T', 'P', 'H', '/', '0', '1'};    // S-TPH/01
char c_DEVICE_MAC[4] = {0x01, 0x01, 0x01, 0x01};
#define DEVICE_UID                  c_DEVICE_UID
#define DEVICE_MAC                  c_DEVICE_MAC
 
 
 
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <string.h>
#include <stdio.h>
 
#define RS485_SETBIT(x,y)           ( x |= ( 1 << y ) )
#define RS485_CLRBIT(x,y)           ( x &= ~( 1 << y ) )
#define RS485_PORT                  PORTD
#define RS485_CONTROL               PD3          // управление приемом/передачей RS485
#define RS485_TR                    RS485_SETBIT(RS485_PORT,RS485_CONTROL) // Установить RE DE в 1. Отправка
#define RS485_RS                    RS485_CLRBIT(RS485_PORT,RS485_CONTROL) // Установить RE DE в 0. Прием
 
 
// Usart makros of speed
#define USORT_BAUD                  9600
#define UBRR_VAL                    F_CPU / 16 / USORT_BAUD - 1
// USORT Receiver buffer
#define DATA_REGISTER_EMPTY         ( 1 << UDRE )
#define RX_COMPLETE                 ( 1 << RXC )
#define FRAMING_ERROR               ( 1 << FE )
//#define PARITY_ERROR              ( 1 << UPE )
#define DATA_OVERRUN                ( 1 << DOR )
#define RX_ADDRESS_SIZE             4
#define RX_DATA_SIZE                16
#define RX_BUFFER_SIZE              1 + RX_ADDRESS_SIZE + RX_DATA_SIZE + 1
#define USORT_STARTPACKET           0x0A
#define USORT_STOPPACKET            0x0B
// This flag is set on USORT Receiver buffer overflow
unsigned char ex_rx_index;
char ex_rx_buffer_adr[RX_ADDRESS_SIZE];
char ex_rx_buffer_cmd;
char ex_rx_buffer_dat[RX_DATA_SIZE];
bool ex_rx_buffer_overflow = false;
bool ex_rx_enable = false;
bool ex_rx_data_complite = false;
 
// LED ON
void LEDLAMP_ON(unsigned int n_pin)
{
    PORTC |= ( 1 << n_pin );
}
 
// LED OFF
void LEDLAMP_OFF(unsigned int n_pin)
{
    PORTC &= ~( 1 << n_pin );
}
 
void UART_Init (unsigned int speed)
{
    // Устанавливаем скорость Baud Rate
    UBRRH = (unsigned char)( speed >> 8 );
    UBRRL = (unsigned char) speed;
    UCSRA = 0x00;
    
    // Hазрешение работы передатчика
    UCSRB = ( 1 << TXEN ) | ( 1 << RXEN ) | (1 << RXCIE ) | (1 << TXCIE );
    
    //Установка формата посылки: 8 бит данных, 1 стоп-бит
    //UCSRC = (1 << USBS) | (3<<UCSZ0);
 
    /* Set frame format: 8data, 2stop bit */
    UCSRC = (1<<URSEL)|(1<<USBS)|(3<<UCSZ0);
    _delay_ms(50);
}
 
// Send to UART
void UART_Send_Char (char data_tx)
{
    while ( !( UCSRA & (1<<5)) ) {}
    RS485_TR;
    UDR = data_tx;
}
 
// Send to UART
void UART_SendString (char data_tx[])
{
    int i;
    int len;
    len = strlen( data_tx );
    for (i=0; i < len; i++) {
        UART_Send_Char(data_tx[i]);
    }
}
 
ISR(USORT_TXC_vect)
{
    RS485_RS; // Установить RE DE в 0. Прием
}
 
void USORT_SendPacket(char rx_device_mac[4], char rx_buffer_cmd, char rx_buffer_dat[RX_DATA_SIZE])
{
    char tmp_tx_data[RX_BUFFER_SIZE];
    sprintf(tmp_tx_data, "%c%c%c%c%c%c%s%c",    USORT_STARTPACKET,
                                                rx_device_mac[0],
                                                rx_device_mac[1],
                                                rx_device_mac[2],
                                                rx_device_mac[3],
                                                rx_buffer_cmd,
                                                rx_buffer_dat,
                                                USORT_STOPPACKET);
    UART_SendString(tmp_tx_data);
}
 
ISR(USORT_RXC_vect)
{
    char status, data;
    unsigned char sub_rx_index;
    status = UCSRA;
    data = UDR;
    //LEDLAMP_ON(0);
    if ((status & (FRAMING_ERROR /*| PARITY_ERROR */| DATA_OVERRUN))==0)
    {
 
        if (data == USORT_STARTPACKET)
        {
            memset(ex_rx_buffer_adr, 0, sizeof(ex_rx_buffer_adr));
            ex_rx_buffer_cmd = 0;
            memset(ex_rx_buffer_dat, 0, sizeof(ex_rx_buffer_dat));
            ex_rx_index=0;
            ex_rx_enable = true;
            ex_rx_data_complite = false;
            
        }
        
        if ( (data == USORT_STOPPACKET) && (ex_rx_enable == 1) )
        {
            ex_rx_enable = 0;
            ex_rx_data_complite = true;
        }
        
        if (ex_rx_enable == 1)
        {
            if ( (ex_rx_index >= 0) && (ex_rx_index <= 4) )
            {
                ex_rx_buffer_adr[ex_rx_index] = data;
                if (ex_rx_index == 4)
                {
                    if ( !strcat(ex_rx_buffer_adr, DEVICE_MAC) )
                    {
                        ex_rx_enable = 0;
                        ex_rx_data_complite = false;
                    }
                }
                ++ex_rx_index;
            } else if (ex_rx_index == 5)
            {
                ex_rx_buffer_cmd = data;
                ++ex_rx_index;
            } else if (ex_rx_index > 5)
            {
                sub_rx_index = ex_rx_index - 6;
                ex_rx_buffer_dat[sub_rx_index] = data;
                ++ex_rx_index;
            }
 
            if (ex_rx_index >= RX_BUFFER_SIZE)
            {
                ex_rx_enable = false;
                ex_rx_buffer_overflow=1;
            }
            
        }
        
    }
}
 
void ExchangeUART(char rx_buffer_cmd, char rx_buffer_dat[RX_DATA_SIZE])
{
    char tmp_rx_buffer[RX_DATA_SIZE];
    if (rx_buffer_cmd == 0xA1) // Активация устройства
    {
        memset(tmp_rx_buffer, 0, sizeof(tmp_rx_buffer));
        //sprintf(tmp_rx_buffer, "%s", DEVICE_UID);
        //sprintf(tmp_rx_buffer, "%c", '!');
        LEDLAMP_ON(0);
        USORT_SendPacket(DEVICE_MAC, 0xA2, tmp_rx_buffer);
    }
}
 
int main(void)
{
    UART_Init(UBRR_VAL);
    
    DDRD |= ( 1 << PD3);
    RS485_RS; // Установить RE DE в 0. Прием
    
    DDRC |= ( 1 << PC0) | ( 1 << PC1);
    //_delay_ms(1000);
    //LEDLAMP_ON(0);
    //_delay_ms(1000);
    //LEDLAMP_OFF(0);
    
    sei();
    
    while(1)
    {
        _delay_ms(1);
        if (ex_rx_data_complite)
        {
            ex_rx_data_complite = false;
            ExchangeUART(ex_rx_buffer_cmd, ex_rx_buffer_dat);
        }
    }
}



raxp, на второй картинке +5В - это разные источники, или они замкнуты

Вернуться к обсуждению:
Обмен данными между МК через RS-485 (MAX487)
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
28.10.2015, 20:33
Готовые ответы и решения:

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

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

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

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

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

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