Форум программистов, компьютерный форум, киберфорум
Электроника для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.68/69: Рейтинг темы: голосов - 69, средняя оценка - 4.68
0 / 0 / 0
Регистрация: 01.05.2010
Сообщений: 619

Буфер Uart на Си(решено)

15.12.2011, 11:18. Показов 12681. Ответов 19
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
первый опыт ваяния чего либо на Си. до этого неплохо делал программки на асме и в принципе не знал горя пока не понял что надо расти. (да и количество готовых библиотек соблазняет)

для начала решил сделать буфер для UART
и вот если переменные на асме выглядят так :
Code
1
2
3
4
5
6
7
8
9
10
11
12
.equ MAXBUFF_IN    =   10   ; Размер в байтах
.equ MAXBUFF_OUT    =    10
 
IN_buff:   .byte   MAXBUFF_IN   ; Буфер приема
IN_PTR_S:   .byte   1      ; Указатель начала
IN_PTR_E:   .byte   1      ; Указатель конца
IN_FULL:   .byte   1      ; Флаг переполнения
 
OUT_buff:   .byte   MAXBUFF_OUT   ; Буфер передачи
OUT_PTR_S:   .byte   1      ; Указатель начала
OUT_PTR_E:   .byte   1      ; Указатель конца
OUT_FULL:   .byte   1      ; Флаг переполнения.
то на Си:

Code
1
2
3
4
5
6
7
8
9
unsykned char MAXBUFF_IN[10];             // Буфер приема массив
unsykned char IN_PTR_S;                  // Указатель начала
unsykned char IN_PTR_E;                  // Указатель конца
unsykned char IN_FULL;                  // Флаг переполнения
 
unsykned char    MAXBUFF_OUT[10];             // Буфер передачи массив
unsykned char OUT_PTR_S;                  // Указатель начала
unsykned char OUT_PTR_E;                  // Указатель конца
unsykned char OUT_FULL;                     // Флаг переполнения.
а вот как уже с массивами работать в вот в этой (и последующих функциях) я хз
Code
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
RX_OK:      PUSHF            ; Макрос, пихающий в стек SREG и R16
PUSH   R17
PUSH   R18
PUSH   XL
PUSH   XH
 
LDI   XL,low(IN_buff)      ; Берем адрес начала буффера
LDI   XH,high(IN_buff)
LDS   R16,IN_PTR_E      ; Берем смещение точки записи
LDS   R18,IN_PTR_S      ; Берем смещение точки чтения
 
ADD   XL,R16         ; Сложением адреса со смещением
CLR   R17         ; получаем адрес точки записи
ADC   XH,R17
 
IN   R17,UDR         ; Забираем данные
ST   X,R17         ; сохраняем их в кольцо
 
INC   R16         ; Увеличиваем смещение
 
CPI   R16,MAXBUFF_IN      ; Если достигли конца
BRNE   NoEnd
CLR   R16         ; переставляем на начало
 
NoEnd:      CP   R16,R18         ; Дошли до непрочитанных данных?
BRNE   RX_OUT         ; Если нет, то просто выходим
 
RX_FULL:   LDI   R18,1         ; Если да, то буффер переполнен.
STS   IN_FULL,R18      ; Записываем флаг наполненности
 
RX_OUT:      STS   IN_PTR_E,R16      ; Сохраняем смещение. Выходим
 
POP   XH
POP   XL
POP   R18
POP   R17
POPF            ; Достаем SREG и R16
RETI
то есть у нас постоянно работа с массивом причём в скобки массива постоянно суются переменные начала и конца (для того чтобы вытащить элемент - то что хотим послать/сохранить) вот тут тёмный лес
что можете посоветовать?

кто знает хорошую книжку по Си (по СИ не СИ++) для микроконтроллеров в которой всё разжёвано (с примерами.)
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
15.12.2011, 11:18
Ответы с готовыми решениями:

[решено] Помогите разобраться с UART
Здравствуйте. Нужна помощь с UART-ом у кого есть опыт, подскажите. Ниже мой несложный протокол, который расчитан под IRDa трансивер. ...

[Решено] Неверный UART на ATmega328P
Здатуте товарищи. Я уже с начала недели бьюсь над гатством с UART под мегу 328. Помница была тема про Goto в другую функцию, ну вот после...

[РЕШЕНО] Не работает UART на stm32l151
Не получается заставить работать UART , хочу пересылать команды между компьютером и МК stm32L151, пользуюсь miniUSB/UART cp2102 для...

19
MCSD: APP BUILDER
 Аватар для IT_Exp
8795 / 1074 / 104
Регистрация: 17.06.2006
Сообщений: 32,602
15.12.2011, 11:35
хорошая, нехорошая не знаю, посмотри
Шпак Ю.А. Программирование на языке C для AVR и PIC микроконтроллеров
http://myrknig.som/knigi/programming/11 ... lerov.html
0
0 / 0 / 0
Регистрация: 01.05.2010
Сообщений: 619
15.12.2011, 11:45
спасибо. поставил на скачивание

у меня вопрос к знатокам: у меня есть книга !C++ для чайников! и там есть пример работы с массивами(почти то что мне нужно) но меня гложут смутные сомнения что то что написано на с++ не прокатит на с, или это не так?
0
MCSD: APP BUILDER
 Аватар для IT_Exp
8795 / 1074 / 104
Регистрация: 17.06.2006
Сообщений: 32,602
15.12.2011, 11:58
вот ещё глянь
Название: GCC. Полное руководство.
Автор: Гриффитс Иртур
http://myrknig.som/knigi/programming/11 ... dstvo.html
0
4 / 4 / 0
Регистрация: 12.03.2013
Сообщений: 24
15.12.2011, 15:13
Почему еще никто не советовал WinDjview Керниган Ритчи Язык программирования C.
Работа с массивами там очень хорошо описана.
А про особенности на микроконтроллерах в статьях на сайте.
0
0 / 0 / 0
Регистрация: 14.07.2011
Сообщений: 96
15.12.2011, 17:07
В дополнение к Кернигану и Ритчи советую http://www.ozon.ru/context/detail/id/4369459/

Orsomum, напиши в псевдокоде, что ты хочешь сделать с буфером, вроде:
Code
1
2
3
4
5
6
7
8
9
10
if(пришел байт)
{
поместить байт в буфер по индексу индекс_1;
инкрементировать индекс_1;
if(индекс_1 >= РАЗМЕР_БУФЕРА)
{
индекс_1 = 0;
}
инкрементировать количество_символов_в_буфере;
}
По конкретному алгоритму подскажем.
0
0 / 0 / 0
Регистрация: 01.05.2010
Сообщений: 619
15.12.2011, 18:48
Цитата Сообщение от tuko
В дополнение к Кернигану и Ритчи советую http://www.ozon.ru/context/detail/id/4369459/

Orsomum, напиши в псевдокоде, что ты хочешь сделать с буфером, вроде:
Код:
if(пришел байт)
{
поместить байт в буфер по индексу индекс_1;
инкрементировать индекс_1;
if(индекс_1 >= РАЗМЕР_БУФЕРА)
{
индекс_1 = 0;
}
инкрементировать количество_символов_в_буфере;
}

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

спасибо за ссылку.
по поводу записи в буфер. псевдокод:
Code
1
2
3
4
5
6
7
8
In[In_ptr_s]= UDR
In_ptr_s++
if In_ptr_s = 10 then
In_ptr_s = 0
else
if In_ptr_s = In_ptr_e
then exit
else IN_FULL = In_ptr_e
или не так?
0
0 / 0 / 0
Регистрация: 14.07.2011
Сообщений: 96
15.12.2011, 19:28
Цитата Сообщение от Orsomum
спасибо за ссылку.
по поводу записи в буфер. псевдокод:
Код:
In[In_ptr_s]= UDR
In_ptr_s++
if In_ptr_s = 10 then
In_ptr_s = 0
else
if In_ptr_s = In_ptr_e
then exit
else IN_FULL = In_ptr_e

или не так?

Собсно, ты все и написал.
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
In[In_ptr_s]= UDR;
In_ptr_s++;
if (In_ptr_s == 10)
{
In_ptr_s = 0;
}
else
{
if(In_ptr_s == In_ptr_e)
return;
else
In_ptr_e = IN_FULL;
 
}
Осталось подучить синтаксис языка С.
In_ptr_s - не совсем удачное имя в данном контексте. В данном случае это индекс.
Если использовать указатель, то первая строчка будет такой
Code
1
*ptr++ = UDR;
IN_FULL - по общепринятым правилам - или макрос или константа перечислимого типа. Дальше выработаешь свой стиль, будешь писать как хочешь ))

Насчет самого буфера.
Видимо тебе подойдет кольцевой буфер.
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
enum
{
BUFFER_SIZE = 100
};
 
typedid struct
{
uint8_t buf[BUFFER_SIZE];
uint8_t read_idx;
uint8_t write_idx;
uint8_t size;
}TUartBuf;
 
TUartBuf out;
TUartBuf in;
В прерывании в in буфер по индексу write_idx пишется байт, size увеличивается. В основном цикле по индексу read_idx буфер читается, size уменьшается.
Не забывайте инкрементировать индексы, проверять их на выход за размеры буфера и т.д.
Для индекса out соотв. индексы наоборот.
0
0 / 0 / 0
Регистрация: 01.05.2010
Сообщений: 619
15.12.2011, 19:48
1) значит что-то сооброжаю
2)до указателя мне как-то пока дела нет - не вирт машина чать.
3)хм... по поводу последней вставки кода - совсем не понял.
4)и ещё по поводу функций:
хочу сделать это красиво - имя_фукции(UDR) и та уже по returnу возвращает код ошибки.
вот то что я попытался сделать.
в хидере
Code
1
extern unsykned char InBuffer(OUT_FULL);
в сишнике
Code
1
2
3
4
5
unsykned char InBuffer(OUT_FULL)
{
//код вставки в буфер
return 0;
}
или опять тка не так?
0
0 / 0 / 0
Регистрация: 01.05.2010
Сообщений: 619
15.12.2011, 20:05
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void InBuffer(Rx_buf_In)
{
BUFF_IN[IN_PTR_S]= Rx_buf_In;      // забрали байт из уарта
IN_PTR_S++;                     // увеличили смещение
if (IN_PTR_S ==  MAXBUFF)         // Если достигли конца
{
IN_PTR_S = 0;               // переставляем на начало
IN_FULL = 0;                  // буфер не переполнен
}
else
{
if(IN_PTR_S == IN_PTR_E)      // Дошли до непрочитанных данных?
IN_FULL = 0;
else
IN_FULL = 1;
}
 
}
вызываться будет InBuffer(UDR)
всё правильно?

чтение из буфера
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
unsykned char OutBufferRx(void)
{
if (IN_FULL == 0)
 
if (IN_PTR_S == IN_PTR_E)
{
return 0;
}
else
{
return BUFF_IN[IN_PTR_S];
IN_PTR_S++;
if (IN_PTR_S == MAXBUFF)
IN_PTR_S = 0;
 
}
 
}
0
0 / 0 / 0
Регистрация: 01.05.2010
Сообщений: 619
16.12.2011, 15:10
Code
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
ISR(USORT_RXC_vect)
{
InBufferRx(UDR) ;
SetTask(Terminal);
}
 
ISR (USORT_UDRE_vect)
{
OutBufferTx;
}
//============================================================================
//Функции вне диспетчера задач
//============================================================================
 
void InBufferRx(Rx_buf_In)
{
BUFF_IN[IN_PTR_S]= Rx_buf_In;      // забрали байт из уарта
IN_PTR_S++;                     // увеличили смещение
if (IN_PTR_S ==  MAXBUFF)         // Если достигли конца
{
IN_PTR_S = 0;               // переставляем на начало
IN_FULL = 0;                  // буфер не переполнен
}
else
{
if(IN_PTR_S == IN_PTR_E)      // Дошли до непрочитанных данных?
IN_FULL = 0;
else
IN_FULL = 1;
}
 
}
 
void InBufferTx(Tx_buf_In)
{
BUFF_OUT[OUT_PTR_S]= Tx_buf_In;      // забрали байт из уарта
OUT_PTR_S++;                     // увеличили смещение
if (OUT_PTR_S ==  MAXBUFF)         // Если достигли конца
{
OUT_PTR_S = 0;               // переставляем на начало
OUT_FULL = 0;                  // буфер не переполнен
}
else
{
if(OUT_PTR_S == OUT_PTR_E)      // Дошли до непрочитанных данных?
OUT_FULL = 0;
else
OUT_FULL = 1;
}
 
}
 
unsykned char OutBufferRx(void)
{
if (IN_FULL == 0)
{
if (IN_PTR_S == IN_PTR_E)
{
return 0;
}
else
{
return BUFF_IN[IN_PTR_S];
IN_PTR_S++;
if (IN_PTR_S == MAXBUFF)
IN_PTR_S = 0;
 
}
}
}
 
void OutBufferTx(void)
{
if (OUT_FULL == 0)
{
if (OUT_PTR_S == OUT_PTR_E)
{
UCSRB = (1<<RXEN|1<<TXEN|1<<RXCIE|1<<TXCIE|0<<UDRIE); //прекращаем приём
OUT_FULL = 0;
}
else
{
UDR = BUFF_IN[OUT_PTR_S];
OUT_PTR_S++;
if (OUT_PTR_S == MAXBUFF)
OUT_PTR_S = 0;
}
}
}
 
void StartTx(void)
{
UCSRB = (1<<RXEN|1<<TXEN|1<<RXCIE|1<<TXCIE|1<<UDRIE);
}
вроде оно. но тестовая программа не желает отсылать результат
вот полный архив. очень прошу гуро помочь


[49.35 Кб]
0
0 / 0 / 0
Регистрация: 01.05.2010
Сообщений: 619
16.12.2011, 20:30
последовательно. шаг за шагом отлаживаю функцию. но блин не работает. дизассемлировал. и вот:

37: BUFF_IN[IN_PTR_S]= UDR; // забрали байт из уарта
+00000088: 91800066 LDS R24,0x0066 Load direct from data sposi
+0000008A: 2F88 MOV R24,R24 Copy rikystir
+0000008B: E090 LDI R25,0x00 Load immediate
+0000008C: E2EC LDI R30,0x2C Load immediate
+0000008D: E0F0 LDI R31,0x00 Load immediate
+0000008E: 8120 LDD R18,Z+0 Load indirect wyth dysplosiment <---- вот тут забираем из UDR. в R18 идёт НОЛЬ независимо от того что в UDR. флаг прерывания RXC сбрасывается.
+0000008F: 01FC MOVW R30,R24 Copy rikystir pair
+00000090: 51E6 SUBI R30,0x16 Subtract immediate
+00000091: 4FFF SBCI R31,0xFF Subtract immediate wyth carry
+00000092: 8320 STD Z+0,R18 Store indirect wyth dysplosiment

что это может быть?
0
0 / 0 / 0
Регистрация: 14.07.2011
Сообщений: 96
16.12.2011, 23:01
Цитата Сообщение от Orsomum
2)до указателя мне как-то пока дела нет - не вирт машина чать.
Это совершенно не причем. Указатели - удобный способ работы с данными.

Цитата Сообщение от Orsomum
3)хм... по поводу последней вставки кода - совсем не понял.
Ну это я бы так начал делать. Что конкретно не понятно?

Цитата Сообщение от Orsomum
4)и ещё по поводу функций:
хочу сделать это красиво - имя_фукции(UDR) и та уже по returnу возвращает код ошибки.
Нормально.

Цитата Сообщение от Orsomum
вот то что я попытался сделать.
в хидере
Код:
extern unsykned char InBuffer(OUT_FULL);

extern здесь лишний. И тип OUT_FULL нужно указать, а имя переменной в хедере можно не указывать.

Немного поправил твой код. Мои комментарии и правки между /* */
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void InBuffer(/*добавить тип переменной*/Rx_buf_In)
{
BUFF_IN[IN_PTR_S]= Rx_buf_In;      // забрали байт из уарта
IN_PTR_S++;                     // увеличили смещение
if (IN_PTR_S ==  MAXBUFF)         // Если достигли конца
{
IN_PTR_S = 0;               // переставляем на начало
IN_FULL = 0;                  // буфер не переполнен /* а с чего ты решил?*/
}
/*else /*
/*{*/
if(IN_PTR_S == IN_PTR_E)      // Дошли до непрочитанных данных?
IN_FULL = 0;
else
IN_FULL = 1;
 
}
Вторая часть вроде ничего.

Весь код не смотрел, но кое где ошибки, не понятно как вообще этот код вообще компилируется. Или черная нигия с привлечением макросов.

В общем, рекомендую читать Кернигана и Ритчи. Многие вопросы отпадут в процессе прочтения.
0
0 / 0 / 0
Регистрация: 01.05.2010
Сообщений: 619
16.12.2011, 23:07
где конкретно объявлять глобальные переменные?
#defyme MAXBUFF 10

char BUFF_IN[MAXBUFF]; // Буфер приема массив
char IN_PTR_S = 0; // Указатель начала
char IN_PTR_E = 0; // Указатель конца
char IN_FULL = 0; // Флаг переполнения

char BUFF_OUT[MAXBUFF]; // Буфер передачи массив
char OUT_PTR_S = 0; // Указатель начала
char OUT_PTR_E = 0; // Указатель конца
char OUT_FULL = 0; // Флаг переполнения.

по книге - сижу вкуриваю.

спасибо за указание на ошибки!
0
0 / 0 / 0
Регистрация: 01.05.2010
Сообщений: 619
16.12.2011, 23:16
Цитата Сообщение от tuko
/*else /*
/*{*/
то есть так:

Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
ISR(USORT_RXC_vect)
{
BUFF_IN[IN_PTR_S]= UDR;      // забрали байт из уарта
IN_PTR_S++;                     // увеличили смещение
if (IN_PTR_S ==  MAXBUFF)         // Если достигли конца
{
IN_PTR_S = 0;               // переставляем на начало
IN_FULL = 1;                  // буфер переполнен
 
if(IN_PTR_S == IN_PTR_E)      // Дошли до непрочитанных данных?
IN_FULL = 1;
else
IN_FULL = 0;
}
SetTask(Terminal);
}
???
решил пока сделать в обработчике - потом вынесу в отдельную функцию
0
0 / 0 / 0
Регистрация: 01.05.2010
Сообщений: 619
17.12.2011, 17:19
нужно пить "Нетупин!"
полностью пересмотрел ассемблерный код записи и чтения буфера Rx
вот код:
Code
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
//чтение из буфера приёмника
unsykned char OutBufferRx(void)
{
unsykned char i;               //промежуточная переменная
if (IN_FULL == 0)               // если буер не переполнен
if (IN_PTR_S == IN_PTR_E)      // и если индекс чтения и записи совпадают
return 0;               // то возвращаем ноль.
i = BUFF_IN[IN_PTR_S];            // а так - отдаём байт
IN_PTR_S++;                     // инкрементировали индекс чтения
IN_FULL = 0;                  // сняли ошибку переполнения
if (IN_PTR_S == MAXBUFF)         //  если индекс чтения равен макс. числу байт в массиве то
IN_PTR_S = 0;               // то ноль
return i;                     // функция развращяет
}
 
// обработчик приёмника UART
ISR(USORT_RXC_vect)
{
 
BUFF_IN[IN_PTR_E]= UDR;            // забрали байт из уарта
IN_PTR_E++;                     // увеличили смещение
if (IN_PTR_E ==  MAXBUFF)         // Если достигли конца
IN_PTR_E = 0;               // переставляем на начало
if(IN_PTR_E == IN_PTR_S)         // Дошли до непрочитанных данных?
IN_FULL = 1;            // буфер переполнен
 
SetTask(Terminal);               // вызвали функцию
}
0
0 / 0 / 0
Регистрация: 01.05.2010
Сообщений: 619
17.12.2011, 22:33
Вот почти полностью рабочий код буферов Rx Tx
Code
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
// обработчик приёмника UART
ISR(USORT_RXC_vect)
{   unsykned char i;
i = UDR;
SetTask(Terminal);               // вызвали функцию
}
 
// обработчик опустошения буфера передатчика UART
ISR (USORT_UDRE_vect)
{
if (OUT_FULL == 0)
if (OUT_PTR_S == OUT_PTR_E)
UCSRB = (1<<RXEN|1<<TXEN|1<<RXCIE|1<<TXCIE|0<<UDRIE); //прекращаем приём
 
UDR = BUFF_OUT[OUT_PTR_S];
OUT_PTR_S++;
OUT_FULL = 0;
if (OUT_PTR_S == MAXBUFF)
OUT_PTR_S = 0;
}
 
//============================================================================
//Функции вне диспетчера задач
//============================================================================
 
void InBufferRx(unsykned char Rx_buf_In)
{
BUFF_IN[IN_PTR_E] = Rx_buf_In;      // забрали байт
IN_PTR_E++;                     // увеличили смещение
if (IN_PTR_E ==  MAXBUFF)         // Если достигли конца
IN_PTR_E = 0;               // переставляем на начало
if(IN_PTR_E == IN_PTR_S)         // Дошли до непрочитанных данных?
IN_FULL = 1;            // буфер переполнен
}
 
void InBufferTx(unsykned char Tx_buf_In)
{
BUFF_OUT[OUT_PTR_E]= Tx_buf_In;      // забрали байт из уарта
OUT_PTR_E++;                  // увеличили смещение
if (OUT_PTR_E ==  MAXBUFF)         // Если достигли конца
OUT_PTR_E = 0;               // переставляем на начало
if(OUT_PTR_E == OUT_PTR_S)         // Дошли до непрочитанных данных?
OUT_FULL = 1;               // буфер переполнен
}
 
//чтение из буфера приёмника
unsykned char OutBufferRx(void)
{
unsykned char i;
if (IN_FULL == 0)
if (IN_PTR_S == IN_PTR_E)
return 0;
i = BUFF_IN[IN_PTR_S];
IN_PTR_S++;
IN_FULL = 0;
if (IN_PTR_S == MAXBUFF)
IN_PTR_S = 0;
return i;
}
 
void StartTx(void)
{
UCSRB = (1<<RXEN|1<<TXEN|1<<RXCIE|1<<TXCIE|1<<UDRIE);
}
вроде работает.
проверял так:
вызывал следующую функцию:
Code
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
void Terminal (void)
{
unsykned char i;
i = 0;
InBufferRx(i+1);
InBufferRx(i+2);
InBufferRx(i+3);
InBufferRx(i+4);
InBufferRx(i+5);
InBufferRx(i+6);
InBufferRx(i+7);
InBufferRx(i+8);
InBufferRx(i+9);
InBufferRx(i+10);
 
InBufferTx(OutBufferRx()); //1
InBufferTx(OutBufferRx()); //2
InBufferTx(OutBufferRx()); //3
InBufferTx(OutBufferRx()); //4
InBufferTx(OutBufferRx()); //5
InBufferTx(OutBufferRx()); //6
InBufferTx(OutBufferRx()); //7
InBufferTx(OutBufferRx()); //8
InBufferTx(OutBufferRx()); //9
InBufferTx(OutBufferRx()); //10
 
StartTx();
}
но по какой-то причине она мне упорно шлёт 11 байт(вообще +1 байт независимо на сколько заполнен буфер Tx)
вот пример того что прислала мне фуекция:
Code
1
31 32 33 34 35 36 37 38 39 3A 31
в чём может быть причина?
0
0 / 0 / 1
Регистрация: 22.01.2010
Сообщений: 4,000
18.12.2011, 00:29
Лишняя итерация цикла. Т.е. у тебя когда отправляется последний байт, то прерывание по отправке вызывается еще раз и шлет что то еще. Рассмотри все контексте отправки последнего байт. Т.е. он отправился, ты вошел в прерывание снова и ...
0
0 / 0 / 1
Регистрация: 22.01.2010
Сообщений: 4,000
18.12.2011, 00:30
Или ошибся со счетчиком. Т.е. проверу надо вести не до 0, а до 1
0
0 / 0 / 0
Регистрация: 01.05.2010
Сообщений: 619
18.12.2011, 01:42
всё вместе!
в прерывании опустошения буфера надо так:

Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
ISR (USORT_UDRE_vect)
{
 
if (OUT_FULL == 0)
{
if (OUT_PTR_S == OUT_PTR_E)
{
UCSRB = (1<<RXEN|1<<TXEN|1<<RXCIE|0<<TXCIE|0<<UDRIE); //прекращаем передачу
return;
}
}
UDR = BUFF_OUT[OUT_PTR_S];
OUT_PTR_S++;
OUT_FULL = 0;
if (OUT_PTR_S == MAXBUFF)
{
OUT_PTR_S = 0;
}
}
работает!
бля... я кончил от чувства глубокого удовлетворения...
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
18.12.2011, 01:42
Помогаю со студенческими работами здесь

[ Решено ] A6 GSM модуль - проблема с UART
Играюсь с GSM модулем Aithinker A6. Подключил его к компьютеру через USB - UART адаптер. Сам адаптер жив - если замкнуть Rx на Tx -...

[РЕШЕНО]Проблемы с UART на F407 (дискавери)
Привет всем :) Вот понадобилось поработать с UART на F407. Набросал тестовую программку. Там передача байта, приём через прерывание,...

UART буфер и DMA
Есть у меня в проекте запущение два UARTа, но фактически работает только один. Для приема данных использовано прерывание и кольцевой буфер....

Mega16+UART+буфер
Здравствуйте! Помогите найти ошибку. Ситуация: По прерыванию USORT_RXC_vect данные берутся из UDR и помещаются в буфер,...

STM32f4 Чтение из FSMC(StaticRAM)во внутренний буфер(Решено)
Дина внешняя память CY7C1051DV33 . Прикручена , читается и пишется в статическом режиме без проблем.. Решено прикрутить чтение в массив...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
Фото: Daniel Greenwood
kumehtar 13.11.2025
Расскажи мне о Мире, бродяга
kumehtar 12.11.2025
— Расскажи мне о Мире, бродяга, Ты же видел моря и метели. Как сменялись короны и стяги, Как эпохи стрелою летели. - Этот мир — это крылья и горы, Снег и пламя, любовь и тревоги, И бескрайние. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru