Форум программистов, компьютерный форум, киберфорум
Наши страницы
Микроконтроллеры Atmega AVR
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.70/10: Рейтинг темы: голосов - 10, средняя оценка - 4.70
Salah_ad_Din
0 / 0 / 0
Регистрация: 18.10.2015
Сообщений: 7
1

Работа с UART (Си, ATtiny 2313)

18.10.2015, 19:35. Просмотров 2012. Ответов 21
Метки нет (Все метки)

Дорогие формчане и знатаки по микроконтролёрам я Новичок в этом деле. У меня есть вопрос, есть кусок кода в котором записываю принитые данные с Uart в массив и проверяю каждый елемент массива на значение. Вопрос такой, почему я не могу проверять больше двух элементов если я массив увеличиваю на 3 елемента и записываю 3 елемента, Жду ваших советов Заранее спасибо!
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//Подпрограмма обработки прерывания
ISR(USORT_RX_vect)
{
   uint8_t i,tmp[2]; // uint8_t i,tmp[3];
   
   for (i=0;i<2;i++) //for (i=0;i<3;i++)
   {
     tmp[i] =UDR ;    
   }
   
  if (tmp[0]=='q'&&tmp[1]=='c')// if (tmp[0]=='q'&&tmp[1]=='c'&&tmp[2]=='a')
    {
         PORTB^= (1<<1);
        
        
            }
   
 
}
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
18.10.2015, 19:35
Ответы с готовыми решениями:

ATtiny 2313
Добрый день, возникли трудности с работой с МК. Это мой первый практический опыт в паянии и работе...

Attiny 2313 не прошивается
Attiny 2313 пытаюсь прошить через arduino nano но ни как не могу подключил тут на nano есть...

AtTiny 2313, прерывания
Доброго времени суток. Решил освоить программирование МК и сразу же столкнулся с проблемой, которую...

Термостат на ATTiny 2313
Собираю термостат в Протеусе на Attiny 2313. Имеется код на ассемблере (5.txt) но компилятор...

ATtiny 2313. Контроль освещения
Требуется написать программу на Assembler или на С++ Программа не для рабочего микропроцессора,...

21
pyzhman
796 / 488 / 68
Регистрация: 15.05.2012
Сообщений: 2,774
18.10.2015, 20:49 2
Принят байт - сработало прерывание - вы объявили массив (чистый) - заполнили его принятым байтом - сравниваете его с 'q', потом с 'c' - если он и 'q', и 'c', то инвертируете первый бит в порте В - выходите из обработчика прерывания.
И с чего вы решили, что не можете проверять больше двух элементов? Да хоть 100500. Правда, толку от такого сравнения - ноль. Ну не может одно число быть и другим, и третьим.
0
Salah_ad_Din
0 / 0 / 0
Регистрация: 18.10.2015
Сообщений: 7
18.10.2015, 21:10  [ТС] 3
получаетьса мне надо сделать вот тким образом и сравнивать
C++
1
uint8_t i,tmp[3]={q,c,a};
если я вас првильно понял и сравнивать их с пришедшими елементами?
0
pyzhman
796 / 488 / 68
Регистрация: 15.05.2012
Сообщений: 2,774
18.10.2015, 21:39 4
Не известна конечная цель вашей программы. Насколько я понял - нужно сравнивать принятые байты с некими символами. Так объявите глобальный массив. В него и засовывайте принятые байты. И там уже сравнивайте.
Впрочем, в своем понимании вашей задачи я могу ошибаться. Левел телепатии не тот. Всего лишь 53-го уровня.
1
Salah_ad_Din
0 / 0 / 0
Регистрация: 18.10.2015
Сообщений: 7
20.10.2015, 21:31  [ТС] 5
все работает только при отпровление команды из двух букв. В принципе мне хватает но хотелось бы что команда содержала чуть больше букв. Да и это думаю не важно. Вот мой код если я что то не правильно сделал скажите. Заранее спасибо!))
C++
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
#define F_CPU 8000000L
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>//Библиотека прерываний
#include <string.h>
#include <avr/pgmspace.h>
int i;
char tmp[2]; 
//Подпрограмма обработки прерывания
ISR(USORT_RX_vect)
{  
    for (i=0;i<2;i++)
   {
     tmp[i] =UDR;    
   }
  if (tmp[0]=='a'&&tmp[1]=='c')//ca
    {
         PORTB^= (1<<1);
                        } 
}
 
void USORT_Init( unsigned int ubrr)//Инициализация модуля USORT attiny2313
{
  UBRRH = (uint8_t)( ubrr >> 8); 
  UBRRL = (uint8_t)( ubrr);
  // enable receive and transmit
  UCSRB = (1 << RXEN) | (1 << TXEN) | (1 << RXCIE);
  // set frame format
  UCSRC = (1 << USBS) | (3 << UCSZ0);   // asynchron 8n1
}
int main( void )
{
DDRB |=(1<<1);// DDRB = 0xff;
PORTB &=~(1<<1);  
DDRB &=~(1<<4);
PORTB |=(1<<4);
 //Скорость USORT 1200 при кварцевом генераторе 8MHz
USORT_Init (51);
sei();//разрешаем глобально прерывания   
while(1)
{
if ((PINB & (1<<PB4))==0)
{
                 _delay_ms(10); //задержка для защиты от дребезга
                 while((PINB & (1<<PB4))==0);
                 //Ждем, когда отпустят кнопку
                 _delay_ms(10); //задержка для защиты от дребезга
                 PORTB^= (1<<1);
}
}
}
0
paskal
450 / 299 / 28
Регистрация: 15.08.2011
Сообщений: 931
20.10.2015, 23:01 6
Цитата Сообщение от Salah_ad_Din Посмотреть сообщение
Вопрос такой, почему я не могу проверять больше двух элементов
Потому что все байты сразу не приходят. Вам надо добавить цикл ожидания наличия следующего байта.
1
Salah_ad_Din
0 / 0 / 0
Регистрация: 18.10.2015
Сообщений: 7
21.10.2015, 19:48  [ТС] 7
Вы бы не могли кинуть код с примером как это реализовать. Заране Спасибо!)
0
pyzhman
796 / 488 / 68
Регистрация: 15.05.2012
Сообщений: 2,774
22.10.2015, 20:31 8
Еще раз:
Цитата Сообщение от pyzhman Посмотреть сообщение
Не известна конечная цель вашей программы.
1
Salah_ad_Din
0 / 0 / 0
Регистрация: 18.10.2015
Сообщений: 7
23.10.2015, 15:06  [ТС] 9
Уточню) как мне реализовать код чтобы приходило не по одному елементу а строка слов. Как например команда VKLpin0 например так. Просто с одним елементом тоже можно обойтись. Но Хотелось бы для себя знать как это можно былобы реализовать)
0
pyzhman
796 / 488 / 68
Регистрация: 15.05.2012
Сообщений: 2,774
23.10.2015, 17:18 10
Сначала принимаете посылку и складываете ее в массив принятый_массив[n]. Как только прием закончен (по определенной длине (количеству символов) либо по признаку конца посылки) осуществляйте сравнение.
1
Voland_
1694 / 1038 / 98
Регистрация: 04.01.2010
Сообщений: 3,517
23.10.2015, 17:42 11
Salah_ad_Din, вам забыли разжевать, что прерывание UART'а приходит не для всего пакета, а только по одному символу. Поэтому, в функции прерывания вам надо в буфер вкидывать по одному байту, вычитывая ОДИН РАЗ регистр UDR.
То есть при приеме трех байт у вас должно происходить три прерывания. И соответственно, три раза вызываться функция обработчика этого прерывания.

PS: можете посмотреть как это делается в CodeVision AVR (у нее есть мастер по созданию проектов, формирующий куски кода). В нем вы можете получить пример, как записывать в буфер пакеты от UART.
1
Salah_ad_Din
0 / 0 / 0
Регистрация: 18.10.2015
Сообщений: 7
23.10.2015, 19:45  [ТС] 12
кстати нашол код
C++
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
//процедура приема строки по UART с использованием прерываний////////
/*при первом вызове функции создаем указатель на char выделяем память под 1 символ,
ждем пока он не придет, когда пришел записываем его в выделенную память, если
есть еще символы то выделяем еще байт и так до тех пор пока все символы не кончатся.
При последуюющих вызовах функции сначала нужно очистить память которую выделяли в прошлый раз
для этого указатель str объявляли как static.
 
выход из функции происходит только когда придет символ '\r' или '\0'
*/
char * u_receive_int (void) {
static char * str=NULL;        //объявляем указатель на строку статическим что бы при повторных вызовах можно было очистить память
static int i=0;            //создаем счетчик
char temp;                    //временная переменная
if (i==0) {                //если i==0 то либо функция еще не вызывалась либо в прошлый раз строка закончилась и надо освободить память
    free(str);            //то освобождаем память
    str=NULL;            //сбрасываем указаель    
}
temp=UDR0;                     //Считываем принятый байт в temp
if ((temp!='\0')&&(temp!='\r')) {    //Если приянтый байт не равен '\r' или '\0' то:
    str=(char*) realloc(str, i+1);        //выделяем память под символы
    *(str+i)=temp;                    //записываем принятый байт в конец массива
    i++;                    //инкрементируем счетчик
    //PORTB=1<<1;
    return NULL;            //так так это еще не конец строки то возвращаем нулевой указатель
}
else {
    //PORTB=1<<2;
    *(str+i)='\0';                    //записываем '\0' в конец массива
    i=0;                             //обнуляем счетчик
    return str;                        // возвращаем указатель на область памяти, по которому можно обратиться к принятым данным
};
 
}
0
Voland_
1694 / 1038 / 98
Регистрация: 04.01.2010
Сообщений: 3,517
23.10.2015, 21:52 13
Цитата Сообщение от Salah_ad_Din Посмотреть сообщение
кстати нашол код
кстати да, рекомендую не пользоваться таким кодом.
Трушный имбеддед не использует динамическое выделение памяти. Забудьте про функции free, alloc, malloc, realloc и т.д. Тем более в прерываниях...
1
pyzhman
796 / 488 / 68
Регистрация: 15.05.2012
Сообщений: 2,774
24.10.2015, 07:15 14
Посмотрите как работает код обработки UART, созданный визардом CodeVision. Там для вашей задачи есть лишние моменты, но суть та.
1
R0
17 / 17 / 13
Регистрация: 06.08.2015
Сообщений: 73
24.10.2015, 07:39 15
У ATtiny2313 128 байт ОЗУ.
128 Bytes Internal SRAM
. Тут не то что про malloc говорить не надо, лучше всего рекомендовать перейти на ассемблер. или следить за стеком, в функциях (наверное кроме main не стоит использовать другие функции) и в прерываниях.
1
pyzhman
796 / 488 / 68
Регистрация: 15.05.2012
Сообщений: 2,774
24.10.2015, 07:45 16
Лучше всего рекомендовать составить годный алгоритм.
1
R0
17 / 17 / 13
Регистрация: 06.08.2015
Сообщений: 73
24.10.2015, 10:01 17
C
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
int i, flag_isr=0;
char tmp[2]; 
//Подпрограмма обработки прерывания
ISR(USORT_RX_vect)
{  
     tmp[i] =UDR;   
     i++;
     if(i >2) {
         i = 0;
         flag_isr = 1;
     }
}
 
main 
...
 
while() {
 
   if(flag_isr == 1 ){
   flag_isr=0;
   if (tmp[0]=='a'&&tmp[1]=='c')//ca
    {
         PORTB^= (1<<1);
    } 
   }
Так будет получше, ждать когда придет три байта и в прерывании выставлять флаг, а в main его мониторить
1
Salah_ad_Din
0 / 0 / 0
Регистрация: 18.10.2015
Сообщений: 7
24.10.2015, 21:30  [ТС] 18
Спасибо))
0
ValeryS
Модератор
7481 / 5664 / 725
Регистрация: 14.02.2011
Сообщений: 19,364
Завершенные тесты: 1
24.10.2015, 22:52 19
Цитата Сообщение от R0 Посмотреть сообщение
Так будет получше, ждать когда придет три байта и в прерывании выставлять флаг, а в main его мониторить
Цитата Сообщение от R0 Посмотреть сообщение
char tmp[2];
маловат размерчик то
C++
1
char tmp[3];
0
Voland_
1694 / 1038 / 98
Регистрация: 04.01.2010
Сообщений: 3,517
25.10.2015, 01:02 20
R0, идея верная. только желательно бы еще добавить управление прерываниями. Иначе будут появляться непредсказуемые проблемы )). И также объявить переменные для прерываний с атрибутом volatile...
0
25.10.2015, 01:02
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
25.10.2015, 01:02

Использование таймера в ATTiny 2313
#include &lt;avr/io.h&gt; #include &lt;avr/interrupt.h&gt; unsigned char rab; ISR(TIMER1_COMPA_vect) { ...

Attiny 2313 замерзает внутренний тактовый
Объект: Attiny 2313 20SU. Имеются несколько одинаковых девайсов, заточенных на внутренний такт, 8...

Attiny 2313 простая задачка с индикацией
Задача состоит вот в чем: На основе микроконтроллера Atmel Atiny2313 необходимо разработать...


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

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

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