BT201 последовательность комманд

Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
Аватара пользователя
Forsio
Первый раз сказал Мяу!
Сообщения: 35
Зарегистрирован: Вс май 19, 2024 10:05:49
Откуда: Россия Кемерово
Контактная информация:

Re: BT201 последовательность комманд

Сообщение Forsio »

Я так сейчас подумал да наверное так никто и не согласится ничего написать тем более бесплатно. Поэтому всё придётся доделывать самому. Так что буду как то продолжать доделывать прошивку.
Сейчас ещё раз всё внимательно посмотрев я понял, то что в массив попадает какой то мусор, а это означает что не получается нормально принять данные от модуля. Однако от терминала первую посылку даже правильней сказать команду принимает и всё. Таким образом я проверял все команды на приём и всё работает, но похоже всё таки с модулем взаимодействовать не успевает. Не знаю даже что тут ещё попробовать? Может стоит заменить кварц у ATMEGA16 с 7.3728 MHz на 14.7456 MHz чтобы немного разогнать саму мегу.

Но однако ещё нужно понять почему всё таки даже в терминале не принимает весь пакет данных? Тут у меня есть какие то догадки что массив он же буфер данных принятых по UART не очищается и в итоге после вывода первой команды там получается каша. То есть после обработки данных массив нужно обязательно очистить. Ну я не знаю даже что ещё там может быть. Это всё очень не просто.
Реклама
jcxz
Мудрый кот
Сообщения: 1726
Зарегистрирован: Вт авг 15, 2017 10:51:13

Re: BT201 последовательность комманд

Сообщение jcxz »

[uquote="Forsio",url="/forum/viewtopic.php?p=4585752#p4585752"]Но однако ещё нужно понять почему всё таки даже в терминале не принимает весь пакет данных?[/uquote]Я выше уже ткнул носом в конкретное место. Неужто так до сих пор и не дошло??? :facepalm:
То что вы там понаписали - работать не может в принципе. Надо садиться и изучать, что такое "очереди" или "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); можно его обрабатывать
      //обработка символа.....
    }
    ...
  }
}
Всё примитивно. Ничего сложного. Классическое построение, используемое для взаимодействия с ISR-ами: "один писатель - один читатель".

PS: Для AVR никогда не писал, но думаю должно скомпилиться правильно.
PPS: В принципе - для ARM будет выглядеть примерно так же, только тип рабочих переменных (c, i) в функциях лучше сделать int.
Последний раз редактировалось jcxz Чт май 30, 2024 22:01:34, всего редактировалось 3 раза.
Реклама
Martian
Друг Кота
Сообщения: 12867
Зарегистрирован: Сб дек 18, 2021 19:25:32
Контактная информация:

Re: BT201 последовательность комманд

Сообщение Martian »

тут же массив, а массивы плохо работают :)))
jcxz
Мудрый кот
Сообщения: 1726
Зарегистрирован: Вт авг 15, 2017 10:51:13

Re: BT201 последовательность комманд

Сообщение jcxz »

[uquote="Martian",url="/forum/viewtopic.php?p=4585843#p4585843"]тут же массив, а массивы плохо работают :)))[/uquote]Ну да. Тогда наверное придётся менять кварц. :)))
Реклама
Эиком - электронные компоненты и радиодетали
Аватара пользователя
Forsio
Первый раз сказал Мяу!
Сообщения: 35
Зарегистрирован: Вс май 19, 2024 10:05:49
Откуда: Россия Кемерово
Контактная информация:

Re: BT201 последовательность комманд

Сообщение Forsio »

jcxz, чего то я не совсем понимаю как тут принимать данные в данном коде. Там же есть команда с данными которая приходит вот её и нужно отлавливать и обрабатывать, но как то в этом коде я пока не совсем прослеживаю вот момент где и как нужно отлавливать данные? Можешь подробнее прописать на примере какой ни будь скажем принятой команды с данными. А то как то не совсем понятно.
Реклама
Аватара пользователя
Forsio
Первый раз сказал Мяу!
Сообщения: 35
Зарегистрирован: Вс май 19, 2024 10:05:49
Откуда: Россия Кемерово
Контактная информация:

Re: BT201 последовательность комманд

Сообщение Forsio »

jcxz, вот к примеру к нам по UART приходит команда MT+00000C2E где 00000C2E это данные они могут быть абсолютно любыми. Это HEX число так как данные хранятся именно в hex формате. MT+ это и есть тег по которому мы определяем тип данных. И вот я в данном коде так и не пойму каким образом мы определяем к какому типу относятся данные и где хранятся принятые данные?
Реклама
Martian
Друг Кота
Сообщения: 12867
Зарегистрирован: Сб дек 18, 2021 19:25:32
Контактная информация:

Re: BT201 последовательность комманд

Сообщение Martian »

Так ведь русским языком комментарий написан. В буфере хранятся данные. в него записываютмся из него же и читаются. Наберите в гугле "буфер FIFO", чтобы понять, что это.
Что касается HEX: всё хранится в виде ноликов и единичек, а вот интерпретировать можете как хекс, как кекс, может даже свою систему придумать - совершенно пофиг.
Аватара пользователя
Forsio
Первый раз сказал Мяу!
Сообщения: 35
Зарегистрирован: Вс май 19, 2024 10:05:49
Откуда: Россия Кемерово
Контактная информация:

Re: BT201 последовательность комманд

Сообщение Forsio »

Martian, так в том то и дело как тут к буферу обратится? Неужели так сложно объяснить в каком массиве хранятся данные которые мы получаем?
Martian
Друг Кота
Сообщения: 12867
Зарегистрирован: Сб дек 18, 2021 19:25:32
Контактная информация:

Re: BT201 последовательность комманд

Сообщение Martian »

jcxz написал Вам 2х2=4. Да, мне сложно объяснить это.
но я попробую. следите за ходом моей мысли:

было написано

Код: Выделить всё

//здесь из FIFO извлечён очередной символ (в переменной c); можно его обрабатывать

Эта надпись отвечает сразу на два вопроса: где хранится и как обратиться. Потому что строчкой выше это показано:

Код: Выделить всё

c = fifo[i];
Что надо делать, Вам уже говорили. Повторю ещё раз: откладывайте в сторону всё это, берите книжки по программированию и читайте.
Аватара пользователя
Forsio
Первый раз сказал Мяу!
Сообщения: 35
Зарегистрирован: Вс май 19, 2024 10:05:49
Откуда: Россия Кемерово
Контактная информация:

Re: BT201 последовательность комманд

Сообщение Forsio »

Martian, так о чём это говорит если я правильно понял в массиве fifo хранятся данные, но для чего оно передаётся в переменную c? Вся команда я так понимаю остаётся в массиве в переменную как тут сказано попадает один символ, но что это даёт? Нам ведь нужно принимать обрабатывать всю команду. То есть по первым символам я определяю тип данных и затем уже в зависимости от типа данных по своему их обрабатываем. После типа данных далее идут сами данные. Так что тут только если брать данные напрямую с массива, по другому я даже не представляю как делать.

Добавлено after 2 hours 7 minutes 19 seconds:
Так может мне всё таки кто ни будь объяснить как обратиться к полученным данным в этом коде?
Никак вот этого не могу этого понять слишком здесь наворченый код с минимальным количеством комментариев и никаких пояснений о том как выводить информацию.
jcxz
Мудрый кот
Сообщения: 1726
Зарегистрирован: Вт авг 15, 2017 10:51:13

Re: BT201 последовательность комманд

Сообщение jcxz »

[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"]

Код: Выделить всё

...
      //здесь из FIFO извлечён очередной символ (в переменной c); можно его обрабатывать
      //обработка символа.....
...
[/uquote]
PS: Как всегда: "Чукча не читатель, чукча - писатель" :facepalm:
Аватара пользователя
Forsio
Первый раз сказал Мяу!
Сообщения: 35
Зарегистрирован: Вс май 19, 2024 10:05:49
Откуда: Россия Кемерово
Контактная информация:

Re: BT201 последовательность комманд

Сообщение Forsio »

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

Но всё же попробую пока так на скидку прикинуть алгоритм обработки. Приняли допустим команду MT+00000C2E в массиве fifo находится вся команда с данными. Далее первый символ передаётся в переменную с. Переменная с содержит в себе первый символ и теперь проверяем переменную с если она равна M то я так понимаю нужно переходить ко второму символу, то есть я так понимаю в переменную с загружаем уже второй символ и проверяем переменную с если равна T переходим к следующему символу если он равен +, то у нас совпала метка с типом данных и теперь переходим к следующему символу и начинаем принимать и обрабатывать данные. Вроде это я так логику как действовать понял.
jcxz
Мудрый кот
Сообщения: 1726
Зарегистрирован: Вт авг 15, 2017 10:51:13

Re: BT201 последовательность комманд

Сообщение jcxz »

[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'. Пользуйтесь:

Код: Выделить всё

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 последовательность комманд

Сообщение Forsio »

В общем так у меня от модуля приходит сразу несколько команд в том то и дело что нужно успеть их принять и обработать. Вот скрин из терминала.
Изображение
Тут можно чётко увидеть что с каждым треком присылается сразу несколько команд от плеера.
Любая принятая команда завершается символами \r\n

В буфере cmdBuf[] будет находится команда я так сейчас понял из последнего кода. И именно с этим массивом мне и нужно работать. То есть в нём обрабатывать принятые данные. Ведь верно мысль веду.
Novice user
Мудрый кот
Сообщения: 1704
Зарегистрирован: Вт янв 05, 2016 10:14:25
Откуда: поселок Мелеуз

Re: BT201 последовательность комманд

Сообщение Novice user »

Так у тебя есть отработка,только сделано через ж...у,и задержки офигенные,я тебе пишу-убери-тебе пофиг...
Отслеживать надо флаг приема,а потом его сбрасывать,а ты зачем то ждешь "М"...

Добавлено after 3 minutes 40 seconds:
Тебе пишут-

Код: Выделить всё

if (i != ixw) {  //в FIFO есть данные
у тебя-

Код: Выделить всё

if (rx_buf[i] == 'M')
Я тебе рабочий код дал,вставь его и не парь людям мозг,разберись с itoa-делов на пару минут,он есть в описании библиотеки,которую ты уже подключил
Аватара пользователя
Forsio
Первый раз сказал Мяу!
Сообщения: 35
Зарегистрирован: Вс май 19, 2024 10:05:49
Откуда: Россия Кемерово
Контактная информация:

Re: BT201 последовательность комманд

Сообщение Forsio »

Novice user, так я уже тебе сколько объяснял что в моём коде данные принимает и обрабатывает, но только из терминала и только первую команду. Поэтому я сейчас и решил полностью переписать UART на приём.
Всё у меня правильно было записано. Данный алгоритм тот что у меня был записан мне тоже подсказали, но по сути то так оно и есть нужно проверять символы чтоб принять команду и правильно её обработать.
Novice user
Мудрый кот
Сообщения: 1704
Зарегистрирован: Вт янв 05, 2016 10:14:25
Откуда: поселок Мелеуз

Re: BT201 последовательность комманд

Сообщение Novice user »

Так это понятно,я тебе указал на главную ошибку-надо отслеживать флаг приема,а не ждать когда придет буква "М",именно поэтому у тебя никогда не примет посылку после первой пока не сбросишь флаг
Если у тебя правильно записано почему тогда не работает?
Аватара пользователя
Forsio
Первый раз сказал Мяу!
Сообщения: 35
Зарегистрирован: Вс май 19, 2024 10:05:49
Откуда: Россия Кемерово
Контактная информация:

Re: BT201 последовательность комманд

Сообщение Forsio »

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;
			}
		}
    }
}
В чём моя ошибка в приёме данных? Я так и не могу понять что мне тут делать?
Martian
Друг Кота
Сообщения: 12867
Зарегистрирован: Сб дек 18, 2021 19:25:32
Контактная информация:

Re: BT201 последовательность комманд

Сообщение Martian »

что делает это?:

Код: Выделить всё

flags |= FLAG_END_RX;
Это устанавливает некие биты в flags
Теперь смотрим:

Код: Выделить всё

#define FLAG_END_RX (1<<3)
#define FLAG_ERR_RX (1<<4)
если выполнить

Код: Выделить всё

flags |= FLAG_ERR_RX;
а затем

Код: Выделить всё

flags |= FLAG_END_RX;
чему буде равна flags ? Она будет равна FLAG_END_RX | FLAG_ERR_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 последовательность комманд

Сообщение Forsio »

[uquote="Martian",url="/forum/viewtopic.php?p=4586288#p4586288"]что делает это?:

Код: Выделить всё

flags |= FLAG_END_RX;
Это устанавливает некие биты в flags
Теперь смотрим:

Код: Выделить всё

#define FLAG_END_RX (1<<3)
#define FLAG_ERR_RX (1<<4)
если выполнить

Код: Выделить всё

flags |= FLAG_ERR_RX;
а затем

Код: Выделить всё

flags |= FLAG_END_RX;
чему буде равна flags ? Она будет равна FLAG_END_RX | FLAG_ERR_RX, а если она равна этому, сработает ли после этого проверка

Код: Выделить всё

if (flags == FLAG_END_RX)
?

Если Вы используете состяния битов как флаги, то и проверяйте состояние битов, а не целиком всю переменную[/uquote]
Это как делается чего то я уже тут уже вообще не пойму? Один так советовал другой говорит что это не правильно. Так как же всё таки будет правильно уже?
Martian писал(а):я же оптимизировал ранее половину Вашего кода

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

Вернуться в «Разные вопросы по МК»