Перейти к содержанию

Помогите С Uart В Attiny2313


Рекомендуемые сообщения

Добрый день ребят! Помогите пожалуйста с реализацией кода на Attimy2313A с UART

Написал вот такой кодик по примерам:

#define F_CPU 8000000UL
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <stdio.h>
#include <stdlib.h>
//макросы вычисления скорости
#define BAUD 19200
#define UBRR_VAL F_CPU/8/BAUD-1
void usart_init(unsigned int speed)
{
// устанавливаем скорость Baud Rate: 9600
UBRRH=(char)(speed>>8);
UBRRL=(char) speed;
UCSRA=0x00;
UCSRB|=(1<<RXEN);// Разрешение работы приемника
UCSRB|=(1<<TXEN); //Разрешение работы передатчика
UCSRB|=(1<<RXCIE);// Разрешение прерываний по приему
// Установка формата посылки: 8 бит данных, 1 стоп-бит
UCSRC=(1<<UCSZ1)|(1<<UCSZ0);
}

//выводим принятый байт на порт
ISR(USART0_RX_vect)
{ PORTB=UDR;
_delay_ms(100);
UDR = PORTB; // "ЭХО"

}
int main(void)
{

usart_init(UBRR_VAL);//инициализация модуля
sei();
DDRB= 0b11111111; //вывод на все пины порта B
while(1);
{
}

Цель текущего кода: принять и отправить по прерыванию. Пробовал тестить в протеусе, что то неочень получается. данные приходят но криво. Приколы с таблицой ASCII я уже просек, поэтому пробовал отправлять с зажатым альтом цифры. Результат неутешил.

Конечный код должен принимать подряд 2 байта, где 1- содержит ИД устройства , если BlockID == 1 байту (где BlockID - const), то второй байт кидаем на PORTB

Главный вопрос, работает ли мой код и как принимать подряд 2 байта в одном прерывании??

Пишу в Atmel Studio 7

Баудрэйт 19200 бод

Частота мк 8МГц

Ссылка на комментарий
Поделиться на другие сайты

Реклама: ООО ТД Промэлектроника, ИНН: 6659197470, Тел: 8 (800) 1000-321

20% скидка на весь каталог электронных компонентов в ТМ Электроникс!

Акция "Лето ближе - цены ниже", успей сделать выгодные покупки!

Плюс весь апрель действует скидка 10% по промокоду APREL24 + 15% кэшбэк и бесплатная доставка!

Перейти на страницу акции

Реклама: ООО ТМ ЭЛЕКТРОНИКС, ИНН: 7806548420, info@tmelectronics.ru, +7(812)4094849

О работает!! Стоило макрос подсчета выкинуть и цифру подставить... Хорошо, а как принимать 2 байта в 1 прерывании? Или Сначало принять 1 подождать 2 мс и принять второй?

int Mess1_ID;

int Mess2_Val;

ISR(USART0_RX_vect)

{ Mess1_ID = UDR;

_delay_ms(10);

Mess2_Val = UDR;

if (Mess1_ID == BlockID)

{ PORTB = Mess2_Val;

}

Мне так кажется, что я могу упустить байт следующий.

Ссылка на комментарий
Поделиться на другие сайты

Особенности хранения литиевых аккумуляторов и батареек

Потеря емкости аккумулятора напрямую зависит от условий хранения и эксплуатации. При неправильном хранении даже самый лучший литиевый источник тока с превосходными характеристиками может не оправдать ожиданий. Технология, основанная на рекомендациях таких известных производителей литиевых источников тока, как компании FANSO и EVE Energy, поможет организовать правильный процесс хранения батареек и аккумуляторов. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

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

Изменено пользователем Mishany
Ссылка на комментарий
Поделиться на другие сайты

Выбираем схему BMS для корректной работы литий-железофосфатных (LiFePO4) аккумуляторов

 Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ, также как и для других, очень важен контроль процесса заряда и разряда, а специализированных микросхем для этого вида аккумуляторов не так много. Инженеры КОМПЭЛ подготовили список имеющихся микросхем и возможных решений от разных производителей. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

Мда... собрал на макетке, подключил Arduino UNO R3 к Attiny2313A, что то непашет...

Вот код на Attiny2313a

#define F_CPU 8000000UL
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <stdio.h>
#include <stdlib.h>

void usart_init(unsigned int speed)
{
UBRRH=(char)(speed>>8);
UBRRL=(char) speed;
UCSRA=0x00;
UCSRB|=(1<<RXEN);// Разрешение работы приемника
UCSRB|=(1<<TXEN); //Разрешение работы передатчика
UCSRB|=(1<<RXCIE);// Разрешение прерываний по приему
// Установка формата посылки: 8 бит данных, 1 стоп-бит
UCSRC=(1<<UCSZ1)|(1<<UCSZ0);
}
int BlockID = 0b00000001;
int UMESS[2];
int i = 0;
//выводим принятый байт на порт
ISR(USART0_RX_vect)
{ UMESS[i]=UDR;
i++;
if (i==2)
{ if (UMESS[0]==BlockID)
{ PORTB = UMESS[1]; }
i=0;
}
}
int main(void)
{

usart_init(25);//инициализация модуля
sei();
DDRB= 0b11111111; //вывод на все пины порта B
while(1);
{
}

}

А вот на Ардуино

void setup() {
// put your setup code here, to run once:
Serial.begin(19200);
}
void loop() {
// put your main code here, to run repeatedly:
Serial.write(0b00000000);
delay(5);
Serial.write(0b11111111);
delay(100);
Serial.write(0b00000001);
delay(5);
Serial.write(0b11111111);
delay(100);
Serial.write(0b00000001);
delay(5);
Serial.write(0b00000000);
delay(100);
}

Первую пару посылок мк должен проигнорить.

После второй и третьей пары посылок от ардуино, должен зажечся порт B и потухнуть, но ничего непроисходит. Порт всегдя в 0, хотя от Arduino байты идут. Что может быть не так??

Изменено пользователем IntelXerox
Ссылка на комментарий
Поделиться на другие сайты

перед заполнение надо отлавливить каждый байт на поиск BlockID и только после заполнять массив, и еще добавить CRC байт в конце для контроля правильность посылки байт.

Ссылка на комментарий
Поделиться на другие сайты

перед заполнение надо отлавливить каждый байт на поиск BlockID и только после заполнять массив, и еще добавить CRC байт в конце для контроля правильность посылки байт.

Это невозможно, так как второй байт, который содержит Value, может варьировать от 0 до 254, тоесть может совпадать с BlockID. А про CRC впервые слышу, можно поподробней?))

Ссылка на комментарий
Поделиться на другие сайты

если надо передат1 байт:

1 байт - ID устройства если их несколько на шине висит

2 байт - данные

3 байт - CRC контрольная сумма байт3=байт1^байт2 для проверки переданной посылки, так правильнее будет особенно если передавать более 1 байта данных

если CRC не сходится - ошибка передачи, запрос на повтор передачи.

делал ретранслятор на 2313 UART передача 110 байт пакет с 10 CRC с подменой значений.

/*
SELFPRGEN = [ ]
DWEN = [ ]
EESAVE = [X]
SPIEN = [X]
WDTON = [ ]
BODLEVEL = DISABLED
RSTDISBL = [ ]
CKDIV8 = [ ]
CKOUT = [ ]
SUT_CKSEL = EXTXOSC_8MHZ_XX_14CK_4MS1
EXTENDED = 0xFF (valid)
HIGH = 0x9F (valid)
LOW = 0xEF (valid)
2->RX вход
3->TX выход
4,5-> Кварц 20MHz, 2x12pF
6->вход SET
7->вход CRUISE
8->вход //
9->вход //
*/
#define F_CPU 20000000UL
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#define RX_ON UCSRB=0b10010000
#define TX_ON UCSRB=0b00001000
#define SET (PIND&(1<<2))
#define CRUISE (PIND&(1<<3))
void nalog(void);
void uart_puts(unsigned char c);
unsigned char maska;
unsigned char i,j,dat,a,b;
unsigned char data[10][11];
void UART_init(void)
{
DDRD|=(1<<1)|(1<<4)|(1<<5);
PORTD|=(1<<1)|(1<<0)|(1<<2)|(1<<3);
UBRRH=0;		   //14400
UBRRL=86;
UCSRC|=(1<<UCSZ0)|(1<<UCSZ1)|(1<<UPM1)|(1<<UPM0);
UCSRB|=(1<<RXEN)|(1<<RXCIE)|(1<<TXEN);
}

ISR(USART_RX_vect)
{
dat=UDR;
maska|=(1<<2);
if (dat==160)
{
 maska|=(1<<1);
 i=0;
 j=0;
}
}
void nalog(void) //функци обработки массива
{
for (i=1;i<10;i=i+2) //перебор каждого нечетного пакета
{
 data[i][3]=data[i][3]^b; //наложение SET
 data[i][4]=data[i][4]^a; //наложение CRUISE
 data[i][10]=data[i][1]^data[i][2]^data[i][3]^data[i][4]^data[i][5]^data[i][6]^data[i][7]^data[i][8]^data[i][9]; //контрольная сумма
}
maska|=(1<<0); //разрешить передачу UART
}
void uart_puts(unsigned char c)
{
while((UCSRA&(1<<UDRE))==0);
UDR=c;
}
int main(void)
{
maska=0;
UART_init();
sei();
while(1)
{
 if (CRUISE!=0)
 {
  a=32;
 }
 else
 {
  a=0;
 }
 if (SET!=0)
 {
  b=8;
 }
 else
 {
  b=0;
 }
 if ((maska&(1<<0))!=0)
 {
  for (j=0;j<10;j++)
  {
   _delay_ms(2);
   for (i=0;i<11;i++)
   {
 uart_puts(data[j][i]);
   }
  }
  RX_ON;
  maska&=~(1<<0);  //запретить передачу UART
 }
if ((maska&(1<<2))!=0)
{
 if ((maska&(1<<1))!=0)
 {
  data[j][i++]=dat;
  if (i>10)
  {

   if (j==9)
   {
 i=0;
 maska&=~(1<<1);
 TX_ON;
 nalog();
   }
   else
   {
 j++;
 i=0;
   }
  }
  maska&=~(1<<2);
 }
}
}
}

Изменено пользователем Mishany
Ссылка на комментарий
Поделиться на другие сайты

Хмм... ща попробую. Если у меня работает ЮАРТ я могу задействовать PORTD 2-5?

Хочу вывести на ногу сигнал если контрольная сумма неверна и попробовать снова...

Ссылка на комментарий
Поделиться на другие сайты

UART занимает только 2 порта, на остальные не влияет

еще можно вылавливать пару байт ID/data по таймауту пары пускать через задержку....

вместо ардуны лучше эксперементировать на PC через терминал и переходник USB-UART

Изменено пользователем Mishany
Ссылка на комментарий
Поделиться на другие сайты

кажется я понял в чем трабл.... Фьюзы заводские стоят же.... как при помощи Sina прог прошить фьюзы на 8 мгц)) а помот перепрошить, что бы кварц подключить на 8

Ссылка на комментарий
Поделиться на другие сайты

Со фьюзами все норм, а все равно ничего не получается... уже разучился и светодиодом моргать или я не понимаю как работать с этими регистрами?

while(1);

{

PORTD |= 1<<PORTD6;

_delay_ms(100);

PORTD |= 1<<PORTD6;

_delay_ms(100);

}

Как нужно корректно устанавливать 1 бит во всем регистре?

Ссылка на комментарий
Поделиться на другие сайты

О отлично, теперь светодиод моргает, точка с запятой была после введения цикла из-зи этого тело цикла и не прорабатывало. Пробую сделать CRC проверку... компилятор ругается... как правильно оформить этот кусок кода?


ISR(USART0_RX_vect)
{ UMESS[i]=UDR;
i++;
if (i==3)
{ if (UMESS[0]^UMESS[1] == UMESS[2])
{
if (UMESS[0]==BlockID)
{ PORTB = UMESS[1]; }
} else  {
PORTD |= (1<<6);
_delay_ms(200);
PORTD &= ~(1<<6);
}
i=0;
} 
 }




Пояснение: после приема всех трех байтов идет проверка CRC байта, если тот верный, то выполняем код дальше. Если нет,то горим красным светодиодом на PD6 и завершаем код прерываний (обнуляем переменную после эксплуотации)

Ссылка на комментарий
Поделиться на другие сайты

хотя бы так: было куча ошибок, и код хотя бы форматируй, а то не читаем..

ISR(USART0_RX_vect)
{
UMESS[i]=UDR;
i++;
if (i>1)
{
if ((UMESS[0]^UMESS[1]) == UMESS[2])
{
if (UMESS[0]==BlockID)
{
PORTB = UMESS[1];
}
else
{
PORTD |= (1<<6);
_delay_ms(200);
PORTD &= ~(1<<6);
}
// i=0;
}
i=0;
}
}

так будет более правильно (не нагружая прерывание):

uint8_t BlockID,flag,i;
ISR(USART0_RX_vect)
{
UMESS[i++] = UDR; //инкоимент i послежнее действие в этом операторе
if (i>1) //если i=2 приняли 3 байта
{
 i = 0;
 flag = 1;
}
}
int main(void)
{
//настройка перефирии
sei();//глобально разрешаем прерывания
while(1)
{
 if (flag == 1)
 {
  if ((UMESS[0]^UMESS[1]) == UMESS[2])
   {
   if (UMESS[0]==BlockID)
 {
 PORTB = UMESS[1];
 }
   else
 {
 PORTD |= (1<<6);
 _delay_ms(200);
 PORTD &= ~(1<<6);
 }
   }
  flag = 0;
 } 
}
}

Изменено пользователем Mishany
Ссылка на комментарий
Поделиться на другие сайты

Вообщем, собрал снова на макетке с исправлением всех замечаний и ошибок, подрубил Ардуино, предварительно результат проверки CRC вывел на второй светодиод. Получается 1 показывает что МК не повис, а второй сигналит где битые байты... Ошибок много, 20% он все таки принимает как верные, вот только сигнала на порте PORTB так и нет...

ISR(USART0_RX_vect)
{ UMESS[i]=UDR;
i++;
if (i==3)
{ if ((UMESS[0]^UMESS[1]) == UMESS[2])
 {
  if (UMESS[0]==BlockID)
  { PORTB = UMESS[1]; }
 } else  {
   PORTD |= (1<<5);
   _delay_ms(10);
   PORTD &= ~(1<<5);
   }
 i=0;
}
 }

int main(void)
{

usart_init(25);//инициализация модуля
sei();
DDRB= 0b11111111; //вывод на все пины порта B
DDRD|=(1<<6)|(1<<5);
while(1)
 {
 PORTD |= (1<<6);
 _delay_ms(10);
 PORTD &=~(1<<6);
 _delay_ms(500);



 }

}

Пояснение: Прерывание работает как и раньше, принимает 3 байта по счетчику i, когда тот равен 3, то сверяем байты, если не битые выполняем управление портом B, если битые - сигнализируем светодиодом.

В Мэйне инициализация портов как выходы и в бесконечном цикле дергаем светодиод, сигнализируя, что мы еще живы.

Ссылка на комментарий
Поделиться на другие сайты

i==3 это означает что должно приняться 4 байта, а если вдруг i=4 как поведет себя программа?

использование задержки в прерывании это ужас...

скобки фигурные кто будет исправлять?:

{ PORTB = UMESS[1]; }

} else {

Изменено пользователем Mishany
Ссылка на комментарий
Поделиться на другие сайты

i == 3 - все верно, так как перед сравнением идет инкремент i++ поэтому когда принят третий байт, идет i++ и i уже содержит 3, а скобки не заметил, ща поправим))

Задержки в прерывании я просчитал, у Arduino тоже стоят задержки между байтами 20мс , а между пакетами 500мс)

стоп, так скобки правильные...

if (проверяем CRC)
{
  if (проверяем ИД)
         { включаем/выключаем портБ
         }
} else {

морг... морг

}

Ссылка на комментарий
Поделиться на другие сайты

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

Светодиод не моргает в тоже время как светодиод ошибки передачи молчит, получается, что тинка из-за РЦ генератора пропускает те байты и это значит, что тело ифы "Если верно" совершенно не выполняется, те условие

if ((UMESS[0]^UMESS[1]) == UMESS[2])

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

Вот код Ардуинки если понадобится)

void loop() {
 // put your main code here, to run repeatedly:
Serial.write(1); //1 й байт ИД
delay(20);
Serial.write(255);  //2 байт Валуе
delay(20);
Serial.write(254); // 3 байт КСОР
delay(1000);
Serial.write(1); //1 байт
delay(20);
Serial.write(0); //2 байт
delay(20);
Serial.write(1); //3 байт ксор
delay(1000);
}

Изменено пользователем IntelXerox
Ссылка на комментарий
Поделиться на другие сайты

прием сработает при посылке 4 байта если отправить 3 байта условие не сработает либо будет постоянный сдвиг

так работает?

ISR(USART0_RX_vect)

{

PORTB = UDR;

}

Изменено пользователем Mishany
Ссылка на комментарий
Поделиться на другие сайты

если горит весь порт то прием не правильный скорее всего, в UDR может быть постоянно 0xFF - будет гореть весь порт, для начала надо проверить правильность передачи одного байта, и только потом думать о передачи посылок.

скорее всего не совпадает скорость

подключение правильное?

Rx --> Tx

Tx --> Rx

каждую сек в цикле на ардуне передавать 1, 2, 4, 8, 16, 32, 64, 128 должен получиться бегущий огонек.

Изменено пользователем Mishany
Ссылка на комментарий
Поделиться на другие сайты

тогда вот пробуй:

#define F_CPU 8000000UL
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
void proverka(void);
unsigned char flag=0,BlockID=1;
unsigned char i,temp;
unsigned char data[3];// массив для хранения {ID, DATA, CRC}
void UART_init(void)
{
//личные настройки UART
}
void PORTS_init(void)
{
//личные настройки портов
}
ISR(USART_RX_vect)
{
temp=UDR;
flag|=(1<<2);
//далее отлавливаем свой ID, и запускаем заполнение массива в основном цикле.
if ((temp==BlockID)&&((flag&(1<<0))==0))
{
 flag|=(1<<1)|(1<<0);
 i=0;
}
}
void proverka(void) //функци обработки массива
{
if (data[2] == (data[0]^data[1]))
{
 //делаем чтото, если контрольная сумма сошлась...
}
else
{
  //делаем чтото, если ошибка контрольной суммы
}
}
int main(void)
{
PORTS_init();
UART_init();
sei();
while(1)
{
if ((flag&(1<<2))!=0)
{
 //условие ожидания ID
 if ((flag&(1<<1))!=0)
 {
  data[i++]=temp;
  if (i>2)
  {
 i=0;
 flag&=~((1<<1)|(1<<0));//сбрасывайм флаг для отлавливания ID
 proverka();
  }
  flag&=~(1<<2);
 }
}
}
}

Ссылка на комментарий
Поделиться на другие сайты

А что за флаги? интересно как работает код...

я кс делал простой цикл от 0 до 255 и посылал, так я проверил, что передача идет и тинька ее принимает... Вернулся к коду и просто выводил 2 байт без проверки ИД и CRC, заметил, что тинка работает несинхронно с ардуинкой, иногда принимая байт Value за ИД байт

использовать задержки в прерывании, реально, не очень хорошо))))))

Ссылка на комментарий
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.
Примечание: Ваш пост будет проверен модератором, прежде чем станет видимым.

Гость
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Ответить в этой теме...

×   Вставлено с форматированием.   Восстановить форматирование

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

Загрузка...
  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
  • Сообщения

    • ОБР выходников.
    • Это "классика жанра".  Аналоговые стабилизаторы поэтому до сих пор еще существуют, потому что они не дают импульсных помех. Даже если после импульсного понижающего стабилизатора поставить аналоговый, все равно идет генерация от катушек трансформаторов. Если вы в это время налаживаете какой-то прибор у которого полезный сигнал измеряется единицами милливольт, например вход радиоприемника, то представьте себе источник помех рядом. Задавить такой источник помех не так просто. Иначе можно было бы просто использовать полностью импульсный блок питания и не возиться с тем чтобы обеспечить малую разность напряжения на регулирующем транзисторе. Самый простой вариант - это автоматическое переключение обмоток как в схеме Шелестова.
    • Доброго времени суток, такой вопрос от чайника. Как то собрал, настроил, играет, радует меня данный усилитель, не смотря на то что кто то нет нет да булыжник в огород подкинет (не понимаю зачем правда). Играло все на горемычной соло1, с выдранной родной начинкой, увы пока не разжился чем то поинтереснее, я даже как то и не обращал внимание вот на такой пункт:  Важное уточнение. При работе усилителя с нагрузкой сопротивлением 4 Ом, напряжение питания усилителя не должно превышать +/- 38 В. Эксплуатация усилителя при большем питающем напряжении, допускается исключительно при работе с нагрузкой сопротивлением не менее 6 Ом. Вопрос: с чем связанно ограничение. Только прошу не много раскрытый ответ, нежели "потому что гладиолус ©".  Зы. питание AC30 -> шоттки (ну были в загашнике вот и поставил) ->  DC на х.х. 45. просад до 42-43х. БП 35тыр мкФ. 
    • Небольшое дополнение. 1. UотсVT2 иUотсVT4 должно быть не менее 1,8В.   2.Точность подержания тока можно увеличить, если увеличить сопротивление R3. Предположим, нам нужен ток 0,5А, при R3= 1ом вместо 0,5ом. Тогда UR3=0,5*1=0,5В; UотсVT2=UотсVT4=2* UR3 =1В; UотсVT1=UотсVT=3* UотсVT4=3В; R1 примерно 1,2ком Точность поддержания тока значительно возрастает, но и мощность на R3 возрастает в 2 раза. Если, конечно,  я не ошибаюсь в расчете.
    • Мужик имеет мастерскую, и, как минимум, один недешёвый такой станок, но городит какую-то дичь из канистр. Блин, возьми ты чуть больше фанеры и сделай нормальный, аккуратный ящик, а не эту шляпу.  С учётом ещё того, что упаковочная тара от химии максимально экономная и по толщине стенок недалеко ушла от полиэтиленового мешка, а нормальная канистра сама по себе стОит, как готовый ящик для инструмента. Ну и да, если ко мне припрётся мастер с таким "кейсом", наши трудовые отношения закончатся ещё на пороге.
    • Интересно, что тема с маркерной фразой:  делает в разделе по профессиональным ремонтам? Деградируем?
  • Похожий контент

×
×
  • Создать...