BT201 последовательность комманд
- Forsio
- Первый раз сказал Мяу!
- Сообщения: 35
- Зарегистрирован: Вс май 19, 2024 10:05:49
- Откуда: Россия Кемерово
- Контактная информация:
Re: BT201 последовательность комманд
Я так сейчас подумал да наверное так никто и не согласится ничего написать тем более бесплатно. Поэтому всё придётся доделывать самому. Так что буду как то продолжать доделывать прошивку.
Сейчас ещё раз всё внимательно посмотрев я понял, то что в массив попадает какой то мусор, а это означает что не получается нормально принять данные от модуля. Однако от терминала первую посылку даже правильней сказать команду принимает и всё. Таким образом я проверял все команды на приём и всё работает, но похоже всё таки с модулем взаимодействовать не успевает. Не знаю даже что тут ещё попробовать? Может стоит заменить кварц у ATMEGA16 с 7.3728 MHz на 14.7456 MHz чтобы немного разогнать саму мегу.
Но однако ещё нужно понять почему всё таки даже в терминале не принимает весь пакет данных? Тут у меня есть какие то догадки что массив он же буфер данных принятых по UART не очищается и в итоге после вывода первой команды там получается каша. То есть после обработки данных массив нужно обязательно очистить. Ну я не знаю даже что ещё там может быть. Это всё очень не просто.
Сейчас ещё раз всё внимательно посмотрев я понял, то что в массив попадает какой то мусор, а это означает что не получается нормально принять данные от модуля. Однако от терминала первую посылку даже правильней сказать команду принимает и всё. Таким образом я проверял все команды на приём и всё работает, но похоже всё таки с модулем взаимодействовать не успевает. Не знаю даже что тут ещё попробовать? Может стоит заменить кварц у ATMEGA16 с 7.3728 MHz на 14.7456 MHz чтобы немного разогнать саму мегу.
Но однако ещё нужно понять почему всё таки даже в терминале не принимает весь пакет данных? Тут у меня есть какие то догадки что массив он же буфер данных принятых по UART не очищается и в итоге после вывода первой команды там получается каша. То есть после обработки данных массив нужно обязательно очистить. Ну я не знаю даже что ещё там может быть. Это всё очень не просто.
- Реклама
Re: BT201 последовательность комманд
[uquote="Forsio",url="/forum/viewtopic.php?p=4585752#p4585752"]Но однако ещё нужно понять почему всё таки даже в терминале не принимает весь пакет данных?[/uquote]Я выше уже ткнул носом в конкретное место. Неужто так до сих пор и не дошло???
То что вы там понаписали - работать не может в принципе. Надо садиться и изучать, что такое "очереди" или "FIFO". И как следует строить обмен данными между ISR и фоновым процессом. А перед этим - освоить основы программирования.
Классический алгоритм передачи байтов из ISR UART в фоновый процесс строится обычно на FIFO (или очереди). FIFO - это массив из нескольких байт + указатель чтения + указатель записи. Размер FIFO определяется исходя из интерактивности фонового процесса (максимально возможной задержки чтения данных фоновым процессом). FIFO крайне прост в реализации.
Примерно так должна выглядеть передача потока принимаемых байтов из ISR в фоновую программу на 8-разрядном CPU:
Всё примитивно. Ничего сложного. Классическое построение, используемое для взаимодействия с ISR-ами: "один писатель - один читатель".
PS: Для AVR никогда не писал, но думаю должно скомпилиться правильно.
PPS: В принципе - для ARM будет выглядеть примерно так же, только тип рабочих переменных (c, i) в функциях лучше сделать int.
То что вы там понаписали - работать не может в принципе. Надо садиться и изучать, что такое "очереди" или "FIFO". И как следует строить обмен данными между ISR и фоновым процессом. А перед этим - освоить основы программирования.
Классический алгоритм передачи байтов из ISR UART в фоновый процесс строится обычно на FIFO (или очереди). FIFO - это массив из нескольких байт + указатель чтения + указатель записи. Размер FIFO определяется исходя из интерактивности фонового процесса (максимально возможной задержки чтения данных фоновым процессом). FIFO крайне прост в реализации.
Примерно так должна выглядеть передача потока принимаемых байтов из ISR в фоновую программу на 8-разрядном CPU:
Код: Выделить всё
enum {FIFO_N = 100}; //размер FIFO; поставить нужное значение
static char fifo[FIFO_N];
static char volatile ixr = 0, ixw = 0; //индексы чтения/записи
ISR(USART_RXC_vect)
{
char c = UDR;
char i = ixw;
if (--i < 0) i = FIFO_N - 1;
if (i == ixr) return; //FIFO полон, пропуск символа
fifo[i] = c;
ixw = i;
}
void main()
{
while (1) {
...
char c, i = ixr;
if (i != ixw) { //в FIFO есть данные
if (--i < 0) i = FIFO_N - 1;
c = fifo[i];
ixr = i;
//здесь из FIFO извлечён очередной символ (в переменной c); можно его обрабатывать
//обработка символа.....
}
...
}
}PS: Для AVR никогда не писал, но думаю должно скомпилиться правильно.
PPS: В принципе - для ARM будет выглядеть примерно так же, только тип рабочих переменных (c, i) в функциях лучше сделать int.
Последний раз редактировалось jcxz Чт май 30, 2024 22:01:34, всего редактировалось 3 раза.
Re: BT201 последовательность комманд
тут же массив, а массивы плохо работают 
Re: BT201 последовательность комманд
[uquote="Martian",url="/forum/viewtopic.php?p=4585843#p4585843"]тут же массив, а массивы плохо работают
[/uquote]Ну да. Тогда наверное придётся менять кварц. 
- Forsio
- Первый раз сказал Мяу!
- Сообщения: 35
- Зарегистрирован: Вс май 19, 2024 10:05:49
- Откуда: Россия Кемерово
- Контактная информация:
Re: BT201 последовательность комманд
jcxz, чего то я не совсем понимаю как тут принимать данные в данном коде. Там же есть команда с данными которая приходит вот её и нужно отлавливать и обрабатывать, но как то в этом коде я пока не совсем прослеживаю вот момент где и как нужно отлавливать данные? Можешь подробнее прописать на примере какой ни будь скажем принятой команды с данными. А то как то не совсем понятно.
- Реклама
- Forsio
- Первый раз сказал Мяу!
- Сообщения: 35
- Зарегистрирован: Вс май 19, 2024 10:05:49
- Откуда: Россия Кемерово
- Контактная информация:
Re: BT201 последовательность комманд
jcxz, вот к примеру к нам по UART приходит команда MT+00000C2E где 00000C2E это данные они могут быть абсолютно любыми. Это HEX число так как данные хранятся именно в hex формате. MT+ это и есть тег по которому мы определяем тип данных. И вот я в данном коде так и не пойму каким образом мы определяем к какому типу относятся данные и где хранятся принятые данные?
Re: BT201 последовательность комманд
Так ведь русским языком комментарий написан. В буфере хранятся данные. в него записываютмся из него же и читаются. Наберите в гугле "буфер FIFO", чтобы понять, что это.
Что касается HEX: всё хранится в виде ноликов и единичек, а вот интерпретировать можете как хекс, как кекс, может даже свою систему придумать - совершенно пофиг.
Что касается HEX: всё хранится в виде ноликов и единичек, а вот интерпретировать можете как хекс, как кекс, может даже свою систему придумать - совершенно пофиг.
- Forsio
- Первый раз сказал Мяу!
- Сообщения: 35
- Зарегистрирован: Вс май 19, 2024 10:05:49
- Откуда: Россия Кемерово
- Контактная информация:
Re: BT201 последовательность комманд
Martian, так в том то и дело как тут к буферу обратится? Неужели так сложно объяснить в каком массиве хранятся данные которые мы получаем?
Re: BT201 последовательность комманд
jcxz написал Вам 2х2=4. Да, мне сложно объяснить это.
но я попробую. следите за ходом моей мысли:
было написано
Эта надпись отвечает сразу на два вопроса: где хранится и как обратиться. Потому что строчкой выше это показано:
Что надо делать, Вам уже говорили. Повторю ещё раз: откладывайте в сторону всё это, берите книжки по программированию и читайте.
но я попробую. следите за ходом моей мысли:
было написано
Код: Выделить всё
//здесь из FIFO извлечён очередной символ (в переменной c); можно его обрабатыватьЭта надпись отвечает сразу на два вопроса: где хранится и как обратиться. Потому что строчкой выше это показано:
Код: Выделить всё
c = fifo[i];- Forsio
- Первый раз сказал Мяу!
- Сообщения: 35
- Зарегистрирован: Вс май 19, 2024 10:05:49
- Откуда: Россия Кемерово
- Контактная информация:
Re: BT201 последовательность комманд
Martian, так о чём это говорит если я правильно понял в массиве fifo хранятся данные, но для чего оно передаётся в переменную c? Вся команда я так понимаю остаётся в массиве в переменную как тут сказано попадает один символ, но что это даёт? Нам ведь нужно принимать обрабатывать всю команду. То есть по первым символам я определяю тип данных и затем уже в зависимости от типа данных по своему их обрабатываем. После типа данных далее идут сами данные. Так что тут только если брать данные напрямую с массива, по другому я даже не представляю как делать.
Добавлено after 2 hours 7 minutes 19 seconds:
Так может мне всё таки кто ни будь объяснить как обратиться к полученным данным в этом коде?
Никак вот этого не могу этого понять слишком здесь наворченый код с минимальным количеством комментариев и никаких пояснений о том как выводить информацию.
Добавлено after 2 hours 7 minutes 19 seconds:
Так может мне всё таки кто ни будь объяснить как обратиться к полученным данным в этом коде?
Никак вот этого не могу этого понять слишком здесь наворченый код с минимальным количеством комментариев и никаких пояснений о том как выводить информацию.
Re: BT201 последовательность комманд
[uquote="Forsio",url="/forum/viewtopic.php?p=4586003#p4586003"]Martian, так в том то и дело как тут к буферу обратится? Неужели так сложно объяснить в каком массиве хранятся данные которые мы получаем?[/uquote]В приведённом примере всё разжёвано максимально. Дальше некуда. Даже с комментами (которые и не нужны для такого примитивного кода; так как всё и так видно).
Если вы не можете понять даже такого простого кода, то объяснить вам ничего не возможно. Садитесь и начинайте учить программирование. С самых основ.
Добавлено after 1 minute 23 seconds:
[uquote="Martian",url="/forum/viewtopic.php?p=4586007#p4586007"]Что надо делать, Вам уже говорили. Повторю ещё раз: откладывайте в сторону всё это, берите книжки по программированию и читайте.[/uquote]+++
Добавлено after 3 minutes 31 second:
[uquote="Forsio",url="/forum/viewtopic.php?p=4586015#p4586015"]Так может мне всё таки кто ни будь объяснить как обратиться к полученным данным в этом коде?[/uquote][uquote="jcxz",url="/forum/viewtopic.php?p=4585842#p4585842"][/uquote]
PS: Как всегда: "Чукча не читатель, чукча - писатель"
Если вы не можете понять даже такого простого кода, то объяснить вам ничего не возможно. Садитесь и начинайте учить программирование. С самых основ.
Добавлено after 1 minute 23 seconds:
[uquote="Martian",url="/forum/viewtopic.php?p=4586007#p4586007"]Что надо делать, Вам уже говорили. Повторю ещё раз: откладывайте в сторону всё это, берите книжки по программированию и читайте.[/uquote]+++
Добавлено after 3 minutes 31 second:
[uquote="Forsio",url="/forum/viewtopic.php?p=4586015#p4586015"]Так может мне всё таки кто ни будь объяснить как обратиться к полученным данным в этом коде?[/uquote][uquote="jcxz",url="/forum/viewtopic.php?p=4585842#p4585842"]
Код: Выделить всё
...
//здесь из FIFO извлечён очередной символ (в переменной c); можно его обрабатывать
//обработка символа.....
...PS: Как всегда: "Чукча не читатель, чукча - писатель"
- Forsio
- Первый раз сказал Мяу!
- Сообщения: 35
- Зарегистрирован: Вс май 19, 2024 10:05:49
- Откуда: Россия Кемерово
- Контактная информация:
Re: BT201 последовательность комманд
Так в том то и дело что здесь данный код выдаёт по одному символу. Тут я уже не знаю даже каким образом вывести все данные и тем более отделять принятые команды между собой с данным кодом в голове такая каша получается.
Но всё же попробую пока так на скидку прикинуть алгоритм обработки. Приняли допустим команду MT+00000C2E в массиве fifo находится вся команда с данными. Далее первый символ передаётся в переменную с. Переменная с содержит в себе первый символ и теперь проверяем переменную с если она равна M то я так понимаю нужно переходить ко второму символу, то есть я так понимаю в переменную с загружаем уже второй символ и проверяем переменную с если равна T переходим к следующему символу если он равен +, то у нас совпала метка с типом данных и теперь переходим к следующему символу и начинаем принимать и обрабатывать данные. Вроде это я так логику как действовать понял.
Но всё же попробую пока так на скидку прикинуть алгоритм обработки. Приняли допустим команду MT+00000C2E в массиве fifo находится вся команда с данными. Далее первый символ передаётся в переменную с. Переменная с содержит в себе первый символ и теперь проверяем переменную с если она равна M то я так понимаю нужно переходить ко второму символу, то есть я так понимаю в переменную с загружаем уже второй символ и проверяем переменную с если равна T переходим к следующему символу если он равен +, то у нас совпала метка с типом данных и теперь переходим к следующему символу и начинаем принимать и обрабатывать данные. Вроде это я так логику как действовать понял.
Re: BT201 последовательность комманд
[uquote="Forsio",url="/forum/viewtopic.php?p=4586096#p4586096"]Так в том то и дело что здесь данный код выдаёт по одному символу. Тут я уже не знаю даже каким образом вывести все данные и тем более отделять принятые команды между собой с данным кодом в голове такая каша получается.[/uquote]Ну вот - в этой точке в переменной c получили поток символов.
Следующая задача - разбить поток символов на отдельные кадры. Что у вас является кадрами? Если кадрами являются текстовые строки, то нужно определиться - чем эти строки разграничиваются? Предположим - каждая строка завершается символом '\r' и/или '\n'. Значит нужно разбить принимаемый поток символов на строки, ограниченные символами конца строки и после этого - обработать их как команды.
[uquote="Forsio",url="/forum/viewtopic.php?p=4586096#p4586096"]Приняли допустим команду MT+00000C2E в массиве fifo находится вся команда с данными.[/uquote]В fifo[] не принимается никакая команда! FIFO - это очередь, необходимая для взаимодействия ISR с фоновым процессом. Для передачи потока символов из ISR в фоновый процесс. Т.е. - это элемент межпроцессной синхронизации.
Добавлено after 27 minutes 59 seconds:
Вот - добавил приём строки, завершающейся '\r' или '\n'. Пользуйтесь:
Следующая задача - разбить поток символов на отдельные кадры. Что у вас является кадрами? Если кадрами являются текстовые строки, то нужно определиться - чем эти строки разграничиваются? Предположим - каждая строка завершается символом '\r' и/или '\n'. Значит нужно разбить принимаемый поток символов на строки, ограниченные символами конца строки и после этого - обработать их как команды.
[uquote="Forsio",url="/forum/viewtopic.php?p=4586096#p4586096"]Приняли допустим команду MT+00000C2E в массиве fifo находится вся команда с данными.[/uquote]В fifo[] не принимается никакая команда! FIFO - это очередь, необходимая для взаимодействия ISR с фоновым процессом. Для передачи потока символов из ISR в фоновый процесс. Т.е. - это элемент межпроцессной синхронизации.
Добавлено after 27 minutes 59 seconds:
Вот - добавил приём строки, завершающейся '\r' или '\n'. Пользуйтесь:
Код: Выделить всё
typedef unsigned char u8;
enum {FIFO_N = 100}; //размер FIFO; поставить нужное значение
static char fifo[FIFO_N];
static char volatile ixr = 0, ixw = 0; //индексы чтения/записи
static u8 cmdLen = 0; //хранит длину принимаемой команды (или == sizeof(cmdBuf)+1 если произошло переполнение буфера и нужен пропуск до конца строки)
static char cmdBuf[20]; //длину буфера установить равной макс. возможной длине команды (не завершается 0!)
ISR(USART_RXC_vect)
{
char c = UDR;
char i = ixw;
if (--i < 0) i = FIFO_N - 1;
if (i == ixr) return; //FIFO полон, пропуск символа
fifo[i] = c;
ixw = i;
}
void main()
{
while (1) {
...
char c, i = ixr;
if (i != ixw) { //в FIFO есть данные
if (--i < 0) i = FIFO_N - 1;
c = fifo[i];
ixr = i;
//здесь из FIFO извлечён очередной символ; можно его обрабатывать
//обработка символа.....
u8 n = cmdLen;
if (c != '\n' && c != '\r') {
if (n < sizeof(cmdBuf)) cmdBuf[n++] = c;
else n = sizeof(cmdBuf) + 1;
} else {
if (n && n <= sizeof(cmdBuf)) {
//здесь в cmdBuf[] принята строка длиной == n (где: n == 1 ... sizeof(cmdBuf)); можно её обработать
//отсюда должна начинаться обработка текста команды, находящейся в cmdBuf[] (строка в cmdBuf[] не завершается 0!)
//...
//...
}
n = 0;
}
cmdLen = n;
}
...
}
}- Forsio
- Первый раз сказал Мяу!
- Сообщения: 35
- Зарегистрирован: Вс май 19, 2024 10:05:49
- Откуда: Россия Кемерово
- Контактная информация:
Re: BT201 последовательность комманд
В общем так у меня от модуля приходит сразу несколько команд в том то и дело что нужно успеть их принять и обработать. Вот скрин из терминала.

Тут можно чётко увидеть что с каждым треком присылается сразу несколько команд от плеера.
Любая принятая команда завершается символами \r\n
В буфере cmdBuf[] будет находится команда я так сейчас понял из последнего кода. И именно с этим массивом мне и нужно работать. То есть в нём обрабатывать принятые данные. Ведь верно мысль веду.
Тут можно чётко увидеть что с каждым треком присылается сразу несколько команд от плеера.
Любая принятая команда завершается символами \r\n
В буфере cmdBuf[] будет находится команда я так сейчас понял из последнего кода. И именно с этим массивом мне и нужно работать. То есть в нём обрабатывать принятые данные. Ведь верно мысль веду.
-
Novice user
- Мудрый кот
- Сообщения: 1704
- Зарегистрирован: Вт янв 05, 2016 10:14:25
- Откуда: поселок Мелеуз
Re: BT201 последовательность комманд
Так у тебя есть отработка,только сделано через ж...у,и задержки офигенные,я тебе пишу-убери-тебе пофиг...
Отслеживать надо флаг приема,а потом его сбрасывать,а ты зачем то ждешь "М"...
Добавлено after 3 minutes 40 seconds:
Тебе пишут-
у тебя-
Я тебе рабочий код дал,вставь его и не парь людям мозг,разберись с itoa-делов на пару минут,он есть в описании библиотеки,которую ты уже подключил
Отслеживать надо флаг приема,а потом его сбрасывать,а ты зачем то ждешь "М"...
Добавлено after 3 minutes 40 seconds:
Тебе пишут-
Код: Выделить всё
if (i != ixw) { //в FIFO есть данныеКод: Выделить всё
if (rx_buf[i] == 'M')- Forsio
- Первый раз сказал Мяу!
- Сообщения: 35
- Зарегистрирован: Вс май 19, 2024 10:05:49
- Откуда: Россия Кемерово
- Контактная информация:
Re: BT201 последовательность комманд
Novice user, так я уже тебе сколько объяснял что в моём коде данные принимает и обрабатывает, но только из терминала и только первую команду. Поэтому я сейчас и решил полностью переписать UART на приём.
Всё у меня правильно было записано. Данный алгоритм тот что у меня был записан мне тоже подсказали, но по сути то так оно и есть нужно проверять символы чтоб принять команду и правильно её обработать.
Всё у меня правильно было записано. Данный алгоритм тот что у меня был записан мне тоже подсказали, но по сути то так оно и есть нужно проверять символы чтоб принять команду и правильно её обработать.
-
Novice user
- Мудрый кот
- Сообщения: 1704
- Зарегистрирован: Вт янв 05, 2016 10:14:25
- Откуда: поселок Мелеуз
Re: BT201 последовательность комманд
Так это понятно,я тебе указал на главную ошибку-надо отслеживать флаг приема,а не ждать когда придет буква "М",именно поэтому у тебя никогда не примет посылку после первой пока не сбросишь флаг
Если у тебя правильно записано почему тогда не работает?
Если у тебя правильно записано почему тогда не работает?
- Forsio
- Первый раз сказал Мяу!
- Сообщения: 35
- Зарегистрирован: Вс май 19, 2024 10:05:49
- Откуда: Россия Кемерово
- Контактная информация:
Re: BT201 последовательность комманд
Novice user, ну и что попробовал записать как ты советовал. Только теперь вообще ничего не принимает.
Вот код.
В чём моя ошибка в приёме данных? Я так и не могу понять что мне тут делать?
Вот код.
Спойлер
Код: Выделить всё
#define F_CPU 7372800UL
#define BAUND 9600L
#define UBRRL_value (F_CPU/(BAUND*16))-1
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <stdlib.h>
#define MAIN_H_
#define LCD_H_
#define LCD_DDR DDRD
#define LCD_PORT PORTD
#define LCD_PIN PIND
#define LED_DDR DDRA
#define LED_PORT PORTA
#define LED_PIN PINA
#define BTN_DDR DDRC
#define BTN_PORT PORTC
#define BTN_PIN PINC
#define DATA 0b11110000
#define RS PD2
#define E PD3
#define E1 LCD_PORT|=(1<<E)
#define E0 LCD_PORT&=~(1<<E)
#define RS1 LCD_PORT|=(1<<RS)
#define RS0 LCD_PORT&=~(1<<RS)
#define LED1_R1 LED_PORT|=(1<<PA0)
#define LED1_R0 LED_PORT&=~(1<<PA0)
#define LED1_G1 LED_PORT|=(1<<PA1)
#define LED1_G0 LED_PORT&=~(1<<PA1)
#define LED1_B1 LED_PORT|=(1<<PA2)
#define LED1_B0 LED_PORT&=~(1<<PA2)
#define LED2_G1 LED_PORT|=(1<<PA3)
#define LED2_G0 LED_PORT&=~(1<<PA3)
#define LED2_R1 LED_PORT|=(1<<PA4)
#define LED2_R0 LED_PORT&=~(1<<PA4)
#define LED3_Y1 LED_PORT|=(1<<PA5)
#define LED3_Y0 LED_PORT&=~(1<<PA5)
#define LED4_B1 LED_PORT|=(1<<PA6)
#define LED4_B0 LED_PORT&=~(1<<PA6)
#define LED5_G1 LED_PORT|=(1<<PA7)
#define LED5_G0 LED_PORT&=~(1<<PA7)
#define BTN_PLAY_PAUSE (~PINC & (1<<PC0))
#define BTN_PREV (~PINC & (1<<PC1))
#define BTN_NEXT (~PINC & (1<<PC2))
#define BTN_VOL_MIN (~PINC & (1<<PC3))
#define BTN_VOL_PLS (~PINC & (1<<PC4))
#define BTN_RAND (~PINC & (1<<PC5))
#define BTN_REPEAT (~PINC & (1<<PC6))
#define BTN_MODE (~PINC & (1<<PC7))
#define FLAG_END_RX (1<<3)
#define FLAG_ERR_RX (1<<4)
#define BUF_SIZE 20
char rx_buf[BUF_SIZE];
char buf_index = 0;
char rxb;
volatile start=1, flags;
uint8_t n=0;
char ind7=0;
char ind6=0;
char ind5=0;
char ind4=0;
char ind3=0;
char ind2=0;
char ind1=0;
char ind0=0;
char chl=0;
char min=0;
char sec=0;
char vol=0;
char mode=0;
char repeat=0;
unsigned int dec=0;
unsigned int def=0;
unsigned int dek=0;
void lcd_ini(void);
void lcd_str(char* str);
void lcd_pos(uint8_t line, uint8_t pos);
void lcd_num(uint8_t num, uint8_t line, uint8_t pos);
void bt201_start(void);
void bt201_start (void)
{
_delay_ms(2000);
//Команда AT+CM02 зададаём модулю режим воспроизведения с USB
Send_Command("AT+CM02\r\n");
_delay_ms(100);
//Устанавливаем значение 2 в переменной mode
mode=2;
//Команда AT+CA15 задаём модулю уровень громкости на 15
Send_Command("AT+CA15\r\n");
_delay_ms(100);
//Конвертируем значение уровня звука в ASCII
vol = 15;
dek = vol%10;
def = vol/10;
ind0 = dek+48;
dek = def%10;
def = def/10;
ind1 = dek+48;
//Выводим на дисплей уровень звука
lcd_pos(1,11);
lcd_str("VOL");
lcd_pos(1,14);
send_byte(ind1,1);
lcd_pos(1,15);
send_byte(ind0,1);
//Команда AT+AA00 останавливаем воспроизведение
Send_Command("AT+AA00\r\n");
_delay_ms(100);
//Команда AT+AA01 задаём модулю команду PLAY
Send_Command("AT+AA01\r\n");
_delay_ms(1);
}
void write(uint8_t n)
{
n<<=4;
E1;
LCD_PORT&=~DATA;
LCD_PORT|=n;
_delay_us(1);
E0;
}
void send_byte(uint8_t byte, uint8_t tip)
{
if (tip) //если тип данные на линии RS 1
{
RS1;
}
else //иначе тип команда и на линии RS 0
{
RS0;
}
write(byte>>4); //передача старшего полубайта
_delay_us(250);
write(byte); //передача младшего полубайта
_delay_us(250);
}
void lcd_ini(void)
{
LCD_DDR|=DATA | (1<<RS) | (1<<E);
_delay_ms(20);
RS0;
write(3);
_delay_ms(5);
write(3);
_delay_us(150);
write(3);
_delay_us(50);
write(2);
_delay_us(50);
send_byte(40,0);
_delay_us(50);
send_byte(12,0);
_delay_us(50);
send_byte(1,0);
_delay_ms(2);
send_byte(6,0);
_delay_us(50);
}
void lcd_str(char* str)
{
uint8_t n=0;
while(str[n])
{
send_byte(str[n],1);
n++;
}
}
void lcd_pos(uint8_t line, uint8_t pos)
{
uint8_t adress=(line*0x40+pos)|0x80;
send_byte(adress,0);
_delay_us(50);
}
void init_UART()
{
UBRRL = UBRRL_value;
UBRRH = UBRRL_value>>8;
UCSRB|=(1<<TXEN);
UCSRB|=(1<<RXEN);
UCSRC|=((1<<URSEL)|(1<<UCSZ0)|(1<<UCSZ1));
UCSRB|=(1<<RXCIE);
sei();
flags = 0;
}
void send_UART(char value)
{
while(!(UCSRA&(1<<UDRE)));
UDR=value;
}
void Send_Command(char *str)
{
for(uint8_t i = 0; i < strlen(str); i++)
{
while(!(UCSRA&(1<<UDRE)));
UDR=str[i];
}
}
char CharToInt(char c)
{
char chl=0;
if ('0' <= c && c <= '9')
{
chl=c-48;
}
else if ('A' <= c && c <= 'F')
{
chl=c-55;
}
return chl;
}
char CharToDec(unsigned int s)
{
dek = s%10;
def = s/10;
ind0 = dek+48;
dek = def%10;
def = def/10;
ind1 = dek+48;
dek = def%10;
def = def/10;
ind2 = dek+48;
dek = def%10;
def = def/10;
ind3 = dek+48;
dek = def%10;
def = def/10;
ind4 = dek+48;
dek = def%10;
def = def/10;
ind5 = dek+48;
dek = def%10;
def = def/10;
ind6 = dek+48;
dek = def%10;
def = def/10;
ind7 = dek+48;
}
char Time(unsigned int s)
{
char min = s/60;
char sec = s%60;
dek = min%10;
def = min/10;
ind0 = dek+48;
dek = def%10;
def = def/10;
ind1 = dek+48;
dek = sec%10;
def = sec/10;
ind2 = dek+48;
dek = def%10;
def = def/10;
ind3 = dek+48;
}
ISR(USART_RXC_vect)
{
char rxb = UDR;
if(!(flags & FLAG_END_RX))
{
rx_buf[buf_index]=rxb;
if(rx_buf[buf_index] == 0x0D)
{
flags |= FLAG_END_RX;
return;
}
buf_index++;
if(buf_index >= BUF_SIZE)
{
buf_index = 0;
flags |= FLAG_ERR_RX;
}
}
}
int main(void)
{
BTN_PORT = 0b11111111;
init_UART();
lcd_ini();
flags = 0;
_delay_ms(5000);
bt201_start();
while(1)
{
if (flags == FLAG_END_RX)
{
char i = 0;
if (rx_buf[i] == 'M')//M
{
i++;
if (rx_buf[i] == '1')//1
{
dec=0;
def=0;
dek=0;
ind7=0;
ind6=0;
ind5=0;
ind4=0;
ind3=0;
ind2=0;
ind1=0;
ind0=0;
//M1 Номер текущего файла
long dec = CharToInt(rx_buf[3]);
dec = dec*16 + CharToInt(rx_buf[4]);
dec = dec*16 + CharToInt(rx_buf[5]);
dec = dec*16 + CharToInt(rx_buf[6]);
dec = dec*16 + CharToInt(rx_buf[7]);
dec = dec*16 + CharToInt(rx_buf[8]);
dec = dec*16 + CharToInt(rx_buf[9]);
dec = dec*16 + CharToInt(rx_buf[10]);
CharToDec(dec);
lcd_pos(1,0);
send_byte(ind3,1);
lcd_pos(1,1);
send_byte(ind2,1);
lcd_pos(1,2);
send_byte(ind1,1);
lcd_pos(1,3);
send_byte(ind0,1);
lcd_pos(1,4);
send_byte('/',1);
flags = 0;
buf_index = 0;
}
else if (rx_buf[i] == '2')//2
{
dec=0;
def=0;
dek=0;
ind7=0;
ind6=0;
ind5=0;
ind4=0;
ind3=0;
ind2=0;
ind1=0;
ind0=0;
//M2 Общее колличество звуковых файлов
long dec = CharToInt(rx_buf[3]);
dec = dec*16 + CharToInt(rx_buf[4]);
dec = dec*16 + CharToInt(rx_buf[5]);
dec = dec*16 + CharToInt(rx_buf[6]);
dec = dec*16 + CharToInt(rx_buf[7]);
dec = dec*16 + CharToInt(rx_buf[8]);
dec = dec*16 + CharToInt(rx_buf[9]);
dec = dec*16 + CharToInt(rx_buf[10]);
CharToDec(dec);
lcd_pos(1,5);
send_byte(ind3,1);
lcd_pos(1,6);
send_byte(ind2,1);
lcd_pos(1,7);
send_byte(ind1,1);
lcd_pos(1,8);
send_byte(ind0,1);
flags = 0;
buf_index = 0;
}
else if (rx_buf[i] == 'T')//T
{
dec=0;
def=0;
dek=0;
ind7=0;
ind6=0;
ind5=0;
ind4=0;
ind3=0;
ind2=0;
ind1=0;
ind0=0;
min=0;
sec=0;
//MT Общее время воспроизведения
long dec = CharToInt(rx_buf[3]);
dec = dec*16 + CharToInt(rx_buf[4]);
dec = dec*16 + CharToInt(rx_buf[5]);
dec = dec*16 + CharToInt(rx_buf[6]);
dec = dec*16 + CharToInt(rx_buf[7]);
dec = dec*16 + CharToInt(rx_buf[8]);
dec = dec*16 + CharToInt(rx_buf[9]);
dec = dec*16 + CharToInt(rx_buf[10]);
CharToDec(dec);
Time(dec);
lcd_pos(0,7);
send_byte(ind1,1);
lcd_pos(0,8);
send_byte(ind0,1);
lcd_pos(0,9);
send_byte(':',1);
lcd_pos(0,10);
send_byte(ind3,1);
lcd_pos(0,11);
send_byte(ind2,1);
flags = 0;
buf_index = 0;
}
else if (rx_buf[i] == 'F')//F
{
//MF Имя текущего файла
lcd_pos(0,0);
send_byte(rx_buf[4],1);
lcd_pos(0,1);
send_byte(rx_buf[5],1);
lcd_pos(0,2);
send_byte(rx_buf[6],1);
lcd_pos(0,3);
send_byte(rx_buf[7],1);
lcd_pos(0,4);
send_byte(rx_buf[8],1);
lcd_pos(0,5);
send_byte(rx_buf[9],1);
flags = 0;
buf_index = 0;
}
/*else if (rx_buf[i] == 'K')//K
{
//MK Время воспроизведения текущего файла
long dec = CharToInt(rx_buf[3]);
dec = dec*16 + CharToInt(rx_buf[4]);
dec = dec*16 + CharToInt(rx_buf[5]);
dec = dec*16 + CharToInt(rx_buf[6]);
dec = dec*16 + CharToInt(rx_buf[7]);
dec = dec*16 + CharToInt(rx_buf[8]);
dec = dec*16 + CharToInt(rx_buf[9]);
dec = dec*16 + CharToInt(rx_buf[10]);
CharToDec(dec);
Time(dec);
lcd_pos(0,7);
send_byte(ind1,1);
lcd_pos(0,8);
send_byte(ind0,1);
lcd_pos(0,9);
send_byte(':',1);
lcd_pos(0,10);
send_byte(ind3,1);
lcd_pos(0,11);
send_byte(ind2,1);
flags = 0;
buf_index = 0;
}*/
else if (rx_buf[i] == 'P')//P
{
//MP Текущее состояние плеера
if (rx_buf[4] == 0)
{
//Стоп
LED2_R1;
LED2_G0;
}
if (rx_buf[4] == 1)
{
//Воспроизведение
LED2_G1;
LED2_R0;
}
if (rx_buf[4] == 2)
{
//Пауза
LED2_R1;
LED2_G0;
}
}
flags = 0;
buf_index = 0;
}
if (rx_buf[i] == 'Q')//Q
{
i++;
if (rx_buf[i] == 'M')//M
{
//QM Режим работы плеера
if (rx_buf[4] == 1)
{
//Блютус
lcd_pos(0,13);
lcd_str("BLE");
LED1_R1;
LED1_G0;
LED1_B0;
}
if (rx_buf[4] == 2)
{
//USB Flash
lcd_pos(0,13);
lcd_str("USB");
LED1_R0;
LED1_G1;
LED1_B0;
}
if (rx_buf[4] == 3)
{
//SD Card
lcd_pos(0,13);
lcd_str(" SD");
LED1_R0;
LED1_G0;
LED1_B1;
}
}
flags = 0;
buf_index = 0;
}
}
if (BTN_PREV)
{
//Команда AT+CD задаём модулю воспроизведение предыдущего трека
Send_Command("AT+CD\r\n");
_delay_ms(500);
}
if (BTN_NEXT)
{
//Команда AT+CC задаём модулю воспроизведение следующего трека
Send_Command("AT+CC\r\n");
_delay_ms(500);
}
if (BTN_VOL_MIN)
{
//Команда AT+CF задаём модулю уменьшение громкости
Send_Command("AT+CF\r\n");
if (vol>0)
{
vol--;
}
_delay_ms(500);
//Конвертируем значение уровня звука в ASCII
dek = vol%10;
def = vol/10;
ind0 = dek+48;
dek = def%10;
def = def/10;
ind1 = dek+48;
//Выводим на дисплей уровень звука
lcd_pos(1,11);
lcd_str("VOL");
lcd_pos(1,14);
send_byte(ind1,1);
lcd_pos(1,15);
send_byte(ind0,1);
}
if (BTN_VOL_PLS)
{
//Команда AT+CE задаём модулю увеличение громкости
Send_Command("AT+CE\r\n");
if (vol<30)
{
vol++;
}
_delay_ms(500);
//Конвертируем значение уровня звука в ASCII
dek = vol%10;
def = vol/10;
ind0 = dek+48;
dek = def%10;
def = def/10;
ind1 = dek+48;
//Выводим на дисплей уровень звука
lcd_pos(1,11);
lcd_str("VOL");
lcd_pos(1,14);
send_byte(ind1,1);
lcd_pos(1,15);
send_byte(ind0,1);
}
if (BTN_MODE)
{
if (mode == 3)
{
//Команда AT+CM01 зададаём модулю режим воспроизведения с BLE
Send_Command("AT+CM01\r\n");
_delay_ms(500);
//Устанавливаем значение 1 в переменной mode
mode=1;
}
else if (mode == 2)
{
//Команда AT+CM03 зададаём модулю режим воспроизведения с SD CARD
Send_Command("AT+CM03\r\n");
_delay_ms(500);
//Устанавливаем значение 3 в переменной mode
mode=3;
}
else if (mode == 1)
{
//Команда AT+CM02 зададаём модулю режим воспроизведения с USB
Send_Command("AT+CM02\r\n");
_delay_ms(500);
//Устанавливаем значение 2 в переменной mode
mode=2;
}
}
if (BTN_PLAY_PAUSE)
{
//Команда AT+CB даём модулю команду PLAY/PAUSE
Send_Command("AT+CB\r\n");
_delay_ms(500);
}
if (BTN_REPEAT)
{
if (repeat == 2)
{
repeat=0;
//Команда AT+AC00 сбрасываем настройки воспроизведения по умолчанию
Send_Command("AT+AC00\r\n");
_delay_ms(500);
LED3_Y0;
LED4_B0;
}
else
{
repeat=2;
//Команда AT+AC02 воспроизведение в цикле
Send_Command("AT+AC02\r\n");
_delay_ms(500);
LED3_Y1;
LED4_B0;
}
}
if (BTN_RAND)
{
if (repeat == 3)
{
repeat=0;
//Команда AT+AC00 сбрасываем настройки воспроизведения по умолчанию
Send_Command("AT+AC00\r\n");
_delay_ms(500);
LED3_Y0;
LED4_B0;
}
else
{
repeat=3;
//Команда AT+AC03 воспроизведение в случайном порядке
Send_Command("AT+AC03\r\n");
_delay_ms(500);
LED3_Y0;
LED4_B1;
}
}
}
}Re: BT201 последовательность комманд
что делает это?:
Это устанавливает некие биты в flags
Теперь смотрим:
если выполнить
а затем
чему буде равна flags ? Она будет равна FLAG_END_RX | FLAG_ERR_RX, а если она равна этому, сработает ли после этого проверка
?
Если Вы используете состяния битов как флаги, то и проверяйте состояние битов, а не целиком всю переменную
Добавлено after 4 minutes 42 seconds:
я же оптимизировал ранее половину Вашего кода, показал как, так какого хрена здесь опять:
что, циклы тоже плохо?
Код: Выделить всё
flags |= FLAG_END_RX;Теперь смотрим:
Код: Выделить всё
#define FLAG_END_RX (1<<3)
#define FLAG_ERR_RX (1<<4)Код: Выделить всё
flags |= FLAG_ERR_RX;Код: Выделить всё
flags |= FLAG_END_RX;Код: Выделить всё
if (flags == FLAG_END_RX)Если Вы используете состяния битов как флаги, то и проверяйте состояние битов, а не целиком всю переменную
Добавлено after 4 minutes 42 seconds:
я же оптимизировал ранее половину Вашего кода, показал как, так какого хрена здесь опять:
Код: Выделить всё
dec = dec*16 + CharToInt(rx_buf[4]);
dec = dec*16 + CharToInt(rx_buf[5]);
dec = dec*16 + CharToInt(rx_buf[6]);
dec = dec*16 + CharToInt(rx_buf[7]);
dec = dec*16 + CharToInt(rx_buf[8]);
dec = dec*16 + CharToInt(rx_buf[9]);
dec = dec*16 + CharToInt(rx_buf[10]);
CharToDec(dec);
Time(dec);
lcd_pos(0,7);
send_byte(ind1,1);
lcd_pos(0,8);
send_byte(ind0,1);
lcd_pos(0,9);
send_byte(':',1);
lcd_pos(0,10);
send_byte(ind3,1);
lcd_pos(0,11);
send_byte(ind2,1);
flags = 0;
buf_index = 0;
}
else if (rx_buf[i] == 'F')//F
{
//MF Имя текущего файла
lcd_pos(0,0);
send_byte(rx_buf[4],1);
lcd_pos(0,1);
send_byte(rx_buf[5],1);
lcd_pos(0,2);
send_byte(rx_buf[6],1);
lcd_pos(0,3);
send_byte(rx_buf[7],1);
lcd_pos(0,4);
send_byte(rx_buf[8],1);
lcd_pos(0,5);
send_byte(rx_buf[9],1);- Forsio
- Первый раз сказал Мяу!
- Сообщения: 35
- Зарегистрирован: Вс май 19, 2024 10:05:49
- Откуда: Россия Кемерово
- Контактная информация:
Re: BT201 последовательность комманд
[uquote="Martian",url="/forum/viewtopic.php?p=4586288#p4586288"]что делает это?:
Это устанавливает некие биты в flags
Теперь смотрим:
если выполнить
а затем
чему буде равна flags ? Она будет равна FLAG_END_RX | FLAG_ERR_RX, а если она равна этому, сработает ли после этого проверка
?
Если Вы используете состяния битов как флаги, то и проверяйте состояние битов, а не целиком всю переменную[/uquote]
Это как делается чего то я уже тут уже вообще не пойму? Один так советовал другой говорит что это не правильно. Так как же всё таки будет правильно уже?
То что из твоей оптимизации заработало это только функция для отправки команд по UART её я и применил, а остальное извините не работает. Потому и не использую, а беру только рабочие варианты.
Код: Выделить всё
flags |= FLAG_END_RX;Теперь смотрим:
Код: Выделить всё
#define FLAG_END_RX (1<<3)
#define FLAG_ERR_RX (1<<4)Код: Выделить всё
flags |= FLAG_ERR_RX;Код: Выделить всё
flags |= FLAG_END_RX;Код: Выделить всё
if (flags == FLAG_END_RX)Если Вы используете состяния битов как флаги, то и проверяйте состояние битов, а не целиком всю переменную[/uquote]
Это как делается чего то я уже тут уже вообще не пойму? Один так советовал другой говорит что это не правильно. Так как же всё таки будет правильно уже?
Martian писал(а):я же оптимизировал ранее половину Вашего кода
То что из твоей оптимизации заработало это только функция для отправки команд по UART её я и применил, а остальное извините не работает. Потому и не использую, а беру только рабочие варианты.


