Форум программистов, компьютерный форум, киберфорум
Микроконтроллеры ATmega AVR
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.86/21: Рейтинг темы: голосов - 21, средняя оценка - 4.86
0 / 0 / 0
Регистрация: 18.03.2017
Сообщений: 43
1

Помогите реализовать передачу данных по UART или SPI

06.04.2017, 13:58. Показов 3827. Ответов 21
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Доброго времени суток, обращаюсь к вам форумчане за помощью. Требуется передать число с переменной с одного мк на другой мк и записать его в переменную 2го мк по SPI или UART (желательно по SPI) число в переменной имеет диапазон от 0 до 99999.Перепробовал уже практически все заготовки и гайды из интернета зачастую мне удавалось достичь лишь вывода данных с 1го мк, но 2й мк во всех случаях отказывался принимать данные, видимо я что-то упустил.Уповаю на вашу помощь. Из проектов с кодом даже не знаю что приложить ибо их около 10 и в каждом дикая неразбериха.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
06.04.2017, 13:58
Ответы с готовыми решениями:

SPI, не могу реализовать передачу хотя бы одного бита
Здравствуйте! Нужна помощь по SPI, не могу реализовать передачу хотя бы одного бита хоть ты...

Как реализовать передачу функции ключа или не передачу
Есть функция: bool LoadExclusion() { std::string filename = "Exclusion"; std::ifstream...

ILI9341 SPI DMA, SPI, UART библиотеки
Доброго времени, форумчане... Посоветуйте библиотек плиз... 0) Либа для работы с контроллером по...

ILI9341 SPI DMA, SPI, UART библиотеки
Доброго времени, форумчане... Посоветуйте библиотек плиз... 0) Либа для работы с контроллером по...

21
0 / 0 / 0
Регистрация: 06.12.2016
Сообщений: 155
06.04.2017, 15:21 2
И в чем проблема? где не получается? какие МК, какое подключение т.п.
0
0 / 0 / 0
Регистрация: 18.03.2017
Сообщений: 43
06.04.2017, 16:03 3
Цитата Сообщение от myshomy984
И в чем проблема? где не получается? какие МК, какое подключение т.п.
Вот допустим более удачный проэкт для UART. Я походу рукожоп и не нашел другого способа определения пойманной переменной кроме как вывода ее на LCD дисплей, если есть другие варианты то подскажите, с радостью избавлюсь от ненужного кода.
Схема в протэусе

[406 байт]

[3.21 Кб]

[3.02 Кб]
0
0 / 0 / 0
Регистрация: 06.12.2016
Сообщений: 155
06.04.2017, 16:58 4
Т.к. UART ворочает только 8bit, то перед отправкой надо разбить передаваемое число на 3 байта и отправлять этот паровозик, на приемной стороне принять и собрать.
Весь код на несколько строчек
99999 это не int, это уже будет 32 битная переменная.
создать массив на четыре однобайтных элемента
unsykned char temp[4];
uint32_t value;
переменная для передачи value
temp[0] = (value>>24)&0xFF;
temp[1] = (value>>16)&0xFF;
temp[2] = (value>>8)&0xFF;
temp[3] = value&0xFF;
вот этот массив и передать, на приемной собрать массив в число.

Код
#define F_CPU 16000000UL
#include <avr/io.h>
#include <avr/interrupt.h>

#define _9600_kbps 103
#define _19200_kbps 51
#define _38400_kbps 25
#define _76800_kbps 10
#define _250000_kbps 3
unsykned char buf_UART[4];
unsykned char count_buf=0;

void UART_init(void)
{
DDRD|=(1<<1);
PORTD|=(1<<1)|(1<<0);
UBRRH=0;
UBRRL=_38400_kbps;              //38400
UCSRC|=(1<<URSEL)|(1<<UCSZ0)|(1<<UCSZ1);
UCSRB|=(1<<TXEN)|(1<<RXEN)|(1<<RXCIE);
sei();
}

void transmit_UART(unsykned char value)
{
while((UCSRA&(1<<UDRE))==0);
UDR=value;
}
ISR(USORT_RXC_vect)
{
buf_UART[count_buf++] = UDR;
if (count_buf > 3)
{
count_buf = 0;
}
}
Вот пример, передача по флагу, прием по прерыванию что б не пропустить, только дополнить передачу 4байт в цикле
0
0 / 0 / 0
Регистрация: 18.03.2017
Сообщений: 43
06.04.2017, 17:09 5
Цитата Сообщение от myshomy984
Т.к. UART ворочает только 8bit, то перед отправкой надо разбить передаваемое число на 3 байта и отправлять этот паровозик, на приемной стороне принять и собрать.
Весь код на несколько строчек
99999 это не int, это уже будет 32 битная переменная.
создать массив на четыре однобайтных элемента
unsykned char temp[4];
uint32_t value;
переменная для передачи value
temp[0] = (value>>24)&0xFF;
temp[1] = (value>>16)&0xFF;
temp[2] = (value>>8)&0xFF;
temp[3] = value&0xFF;
вот этот массив и передать, на приемной собрать массив в число.
ловить тогда байты на другом конце я буду так?
while(1){
if(UCSRA&(1<<RXC)){
number[i]=RXC;
i++;
}
}
0
0 / 0 / 0
Регистрация: 06.12.2016
Сообщений: 155
06.04.2017, 17:16 6
нет вот последняя функция прерывания для ловли
Код
ISR(USORT_RXC_vect)
{
buf_UART[count_buf++] = UDR;
if (count_buf > 3)
{
count_buf = 0;
//конец посылки, можно собирать принятое
}
}
код для обоих МК одинаковый, связь двухсторонняя, что еще для счастья надо?
Есть прерывание по приему, если посылок нет МК занимается своими делами, что то пришло отвлекся...
зачем циклы на ожидания и проверки бестолковые
0
0 / 0 / 0
Регистрация: 18.03.2017
Сообщений: 43
06.04.2017, 17:42 7
В деле с АВР я новичок поэтому я многого еще не знаю но задачу выполнить нужно.Плюс к этому сижу я уже 7й час за пк и ищу информацию и пытаюсь что то написать, мозги уже кипят.

Код
#define F_CPU 16000000UL
#include <avr/io.h>
#include <avr/interrupt.h>

#define _9600_kbps 103
#define _19200_kbps 51
#define _38400_kbps 25
#define _76800_kbps 10
#define _250000_kbps 3
unsykned char buf_UART[4];
unsykned char count_buf=0;

void UART_init(void)
{
DDRD|=(1<<1);
PORTD|=(1<<1)|(1<<0);
UBRRH=0;
UBRRL=_38400_kbps;              //38400
UCSRC|=(1<<URSEL)|(1<<UCSZ0)|(1<<UCSZ1);
UCSRB|=(1<<TXEN)|(1<<RXEN)|(1<<RXCIE);
sei();
}

void transmit_UART(unsykned char value)
{
while((UCSRA&(1<<UDRE))==0);
UDR=value;
}
ISR(USORT_RXC_vect)
{
buf_UART[count_buf++] = UDR;
if (count_buf > 3)
{
count_buf = 0;
}
}
int main (void){
unsykned char temp[4];
uint32_t value;
value=84651;
int count=0;
temp[0] = (value>>24)&0xFF;
temp[1] = (value>>16)&0xFF;
temp[2] = (value>>8)&0xFF;
temp[3] = value&0xFF;
UART_init();
while(1){
if(count<4){
transmit_UART(temp[count]);
count++;
}
}
}
Так реализуется отправка?

Эту часть я что то вообще не понял.Как ее использовать.
Код
ISR(USORT_RXC_vect)
{
buf_UART[count_buf++] = UDR;
if (count_buf > 3)
{
count_buf = 0;
//конец посылки, можно собирать принятое
}
}
Я наверное вас уже достал но прошу помогите пожалуйста.
0
0 / 0 / 0
Регистрация: 06.12.2016
Сообщений: 155
06.04.2017, 19:45 8
отправка:
Код
transmit_UART(число 8бит);
, функция сама сделает все необходимое
часть
Код
ISR(USORT_RXC_vect)
функция обработки прерывания приема по уарт
работает сама по себе, если что приходит по уарту она аппаратно сама вызовется
внутри нее счетчик на принятие 4 байта.
принятые байты складываются в массив
Код
buf_UART[]
Код
if (count_buf > 3)
{
count_buf = 0;
//конец посылки, можно собирать принятое
//здесь пишем что делать после принятия 4 байт по UART
}
0
0 / 0 / 0
Регистрация: 27.03.2012
Сообщений: 57
06.04.2017, 19:55 9
а как будете синхронизироваться с началом посылки? Вдруг приемник начал принимать с третьего байта?
Может в старшем нибле передавать номер цифры, а в младшем саму цифру от 0 до 9 ?
0
0 / 0 / 0
Регистрация: 06.12.2016
Сообщений: 155
06.04.2017, 20:04 10
я показал самый простой путь по обмену. а синхронизация и контроль ошибок это уже отдельная тема.
добавить код начала пару байт, код конца, контрольную сумму и т.п.
0
0 / 0 / 0
Регистрация: 18.03.2017
Сообщений: 43
07.04.2017, 01:19 11
Есть еще такой вопрос как мне убедиться в том что 2й мк словил нужное число как мне дебагать все это дело(вывести визуально переменную)?
0
0 / 0 / 0
Регистрация: 06.12.2016
Сообщений: 155
07.04.2017, 01:30 12
как душе угодно, хоть на LCD, хоть на семисегментник диодный, хоть на лампы, хоть терминалом контролировать.
Можно прикрутить еще контрольную сумму и если сумма сошлась моргнуть диодом, и т.п.
Код
transmit_UART(253);
transmit_UART(254);
for(i=0;i<4;i++)
{
transmit_UART(temp[i]);
}
transmit_UART(temp[0]^temp[1]^temp[2]^temp[3]): //контрольная сумма, седьмым байтом для контроля
//на приемной стороне целосности посылки
на приемной стороне:
Код
ISR(USORT_RXC_vect)
{
buf_UART[count_buf++] = UDR;
if((buf_UART[count_buf-1] == 253)&&(buf_UART[count_buf] == 254))
//значит словили начало передачи
{
count_buf = 0; //обнуляем счетчик
flag_nachalo = 1;
}
if ((count_buf > 4)&&(flag_nachalo == 1))
{
count_buf = 0;
flag_nachalo = 0;
if(buf_UART[5] == buf_UART[0]^buf_UART[1]^buf_UART[2]^buf_UART[3])
{
//моргаем диодом сообщая что пакет принят целый и без ошибок
}
}
}
0
0 / 0 / 0
Регистрация: 18.03.2017
Сообщений: 43
07.04.2017, 14:35 13
Почему то выходит кривая передача ну или я кривой.Передаю простое число 253, а на терминале вижу или "х" или "Ў" а бывает и вовсе пусто, причем в терминале выставил baud 38400 как и в проекте. Порты подключил след образом RXD>TXD | TXD>RXD.
Настройки мк в протеусе

Код
UART_init();   //инициализировал юарт
_delay_ms(100);   //сделал задержку чтоб режим установился
transmit_UART(253);   // передаю число
0
0 / 0 / 0
Регистрация: 06.12.2016
Сообщений: 155
07.04.2017, 17:53 14
в терминале в какой кодеровке прием? явно не в DEC))) ASCII либо?
и fuse под внешний кварц на 16MHz?
0
0 / 0 / 0
Регистрация: 18.03.2017
Сообщений: 43
07.04.2017, 18:40 15
Срабатывает прерывание но не выполняется условие
Код
if((buf_UART[count_buf-1] == 253)&&(buf_UART[count_buf] == 254))
0
0 / 0 / 0
Регистрация: 06.12.2016
Сообщений: 155
07.04.2017, 18:52 16
это условие отлавливания последовательности 253,254 что бы отловить начало передачи
0
0 / 0 / 0
Регистрация: 18.03.2017
Сообщений: 43
07.04.2017, 18:54 17
Цитата Сообщение от myshomy984
в терминале в какой кодеровке прием? явно не в DEC))) ASCII либо?
и fuse под внешний кварц на 16MHz?
как изменить кодовый прием в терминале?
кварца внешнего нет, разве нельзя задать в настройках мк 16Мгц?
если я правильно понял то Clock frequency задает частоту мк в протэусе как на скрыне
0
0 / 0 / 0
Регистрация: 18.03.2017
Сообщений: 43
07.04.2017, 19:14 18
Цитата Сообщение от myshomy984
в терминале в какой кодеровке прием? явно не в DEC))) ASCII либо?
и fuse под внешний кварц на 16MHz?
щас прилепил кварцы выставил частоту, если даже допустим терминал криво отображает то почему не срабатывает условие начала данных?
само прерывание срабатывает, проверку выполнил втыканием команды на включение диода в разные части условий в прерывании.
0
0 / 0 / 0
Регистрация: 06.12.2016
Сообщений: 155
07.04.2017, 19:26 19
Протеус не знаю, я в железе только
0
0 / 0 / 0
Регистрация: 18.03.2017
Сообщений: 43
07.04.2017, 20:05 20
А с spi можете помочь?
Как реализуется инициализация для mostir, slave?
Как отправить число, как словить число?
0
07.04.2017, 20:05
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
07.04.2017, 20:05
Помогаю со студенческими работами здесь

Реализовать передачу данных
Есть 10 компьютеров. Один из них &quot;главный&quot; (сервер). Нужно сделать так что бы остальные 9...

Реализовать передачу - прием информации. С одного ПК на другой, реализовать нужна с помощью (winapi с++). Нужна информация или книги
Необходимо реализовать передачу - прием информации. С одного ПК на другой, реализовать нужна с...

Не получается реализовать передачу данных в БД со страницы
Добрый день. Есть сайт, сюда выгружается БД в виде таблицы, все работает хорошо. Значения меняются...

Как реализовать передачу данных между БД?
Доброго времени суток. Имеется БД1 в которой сотрудники пишут &quot;Служебные записки&quot;, &quot;Заявки на...

Реализовать прием/передачу данных по последовательному COM порту
Доброго времени суток, товарищи! Имеется задача реализовать прием/передачу данных по...

Как реализовать передачу данных между аккаунтами?
Всем привет. Даже не знаю в какой раздел поместить вопрос У меня есть сайт на локалке, в нем...

Как реализовать передачу данных между клиентом и сервером
прошу помощи... Нужно создать приложение с сборками: -site - клиент -objects- сборка с...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru