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

CAN снифер


Smith2007

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

Имеется контроллер STM32F103RET6.

На CAN интерфейс подключен трансивер TJA1040

USART подключаю к компьютеру на котором запускаю CAN Hacker.

Создал проект (Keil) с использованием библиотек cmsis. 

Включаю режим CAN_Mode_LoopBack. Отправляю пакет в цикле из CAN Hacker и получаю его же обратно.

Прием пакетов по прерыванию в кольцевой буфер. 

Осцилографом становлюсь на выход трансивера (CANH, CANL)

photo_2019-03-07_21-51-54.jpg.239abf13f7471c4e3d921057f2b2fae8.jpg

Количество отправленных пакетов = количеству принятых. При разных установленных скоростях шины - длительность сигналов так же меняется.

Подключаюсь к CAN Шине авто.

Ни одного пакета принять не могу. Подозреваю, что я не верно выставляю тайминги.

DSC_1437.thumb.JPG.7fa5626d0e06b6e07f2933fd13d90e6a.JPG

 

Как правильно определить параметры таймингов по форме сигнала? (цена деления 2 мкс)

 

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

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

ну надо почитать спецификацию на CAN, там все подробненько изложено. Лупбэк будет работать полюбому, так как отправка и прием идет на одной скорости. А для того чтобы "нюхать" чужой поток надо как минимум знать его частоту. Иначе нишиша асинхронный CAN не примет

Нужно делать то, что нужно. А то, что не нужно, делать не нужно. (С) Винни Пух

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

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

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

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

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

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

Какая частота синхронизации? и какие значения в этих регистрах CAN_SJW, CAN_BS1, CAN_BS2, CAN_Prescaler ? и какое авто?

Изменено пользователем optima

Сергей.

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

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

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

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

48 минут назад, optima сказал:

Какая частота синхронизации? и какие значения в этих регистрах CAN_SJW, CAN_BS1, CAN_BS2, CAN_Prescaler ? и какое авто?

Автомобиль УАЗ Патриот 2016 года. 

На разъеме OBD имеются пины 6 и 14.

Судя по описанию распиновки разъема (найдено в инете) это и есть CANH, CANL

В этот разъем подключаю ELM327 -, загружаю torque pro.

5c8531f0da3bb_2019-03-0222-15-37.thumb.PNG.480af47bfa179feb5540b726a2681ac7.PNG

 

Если я правильно понимаю, то ELM327 цепляется через этот разъем к скоростной шине 500 кбит. Доступные датчики.

Screenshot_2019-03-10-20-43-49.thumb.png.43dd414058ac53e65ff449dba72d6ebd.png

Частота тактирования CAN шины 36 МГц

2019-03-10_20-54-43.png.0382d442f543b597301ad2d41025b674.png

 

2019-03-10_20-59-02.png.bf1f58d772edb5de179e5c3f43ca1d1a.png

 

Prescaler=  6,  Seg1 = 6, Seg2 = 5

36/6/(1+6+5) = 500 кбит.

SJW ставил 1, 2, 3 - не помогло.

Осцилограмма сигнала

2019-03-10_21-03-07.png.d79997c7398d4d87a50d1412916548c3.png

 

Процедура инициализации CAN

//*****************************************************************
//
//  Модуль CAN шины
//
//
//
//*****************************************************************
#include "can.h"

void init_CAN(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;

	/* CAN GPIOs configuration */
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); 		// включаем тактирование AFIO
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); 				// включаем тактирование порта

	RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);		// включаем тактирование CAN-шины
	
	// Настраиваем CAN RX pin GPIOA Pin11
	GPIO_InitStructure.GPIO_Pin   = CAN1_RX_SOURCE;
	GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_IPU;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(CAN1_GPIO_PORT, &GPIO_InitStructure);

	// Настраиваем CAN TX pin GPIOA Pin12
	GPIO_InitStructure.GPIO_Pin   = CAN1_TX_SOURCE;
	GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_PP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(CAN1_GPIO_PORT, &GPIO_InitStructure);

  	// Включаем трансивер GPIOB Pin1
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
	GPIO_InitStructure.GPIO_Pin   = CAN1_STB_PIN;
	GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
	GPIO_Init(CAN1_STB_PORT, &GPIO_InitStructure);
	GPIO_WriteBit(CAN1_STB_PORT, CAN1_STB_PIN, Bit_SET );
	
	#ifdef CAN1_ReMap
		GPIO_PinRemapConfig(GPIO_Remap1_CAN1, ENABLE);			// Переносим Can1 на PB8, PB9
	#endif

	// Инициализация режима CAN шины по умолчанию
	CAN_InitStructure.CAN_TTCM = DISABLE;
	CAN_InitStructure.CAN_ABOM = DISABLE;	// DISABLE
	CAN_InitStructure.CAN_AWUM = ENABLE;
	CAN_InitStructure.CAN_NART = ENABLE;	// DISABLE
	CAN_InitStructure.CAN_RFLM = DISABLE;
	CAN_InitStructure.CAN_TXFP = DISABLE;
	CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;			// Обычный режим работы устройства
	//CAN_InitStructure.CAN_Mode = CAN_Mode_LoopBack;	// Для тестирования без подключенных устройств шины
	CAN_InitStructure.CAN_BS1 = CAN_BS1_13tq;
	CAN_InitStructure.CAN_BS2 = CAN_BS2_2tq;
	CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
	CAN_InitStructure.CAN_Prescaler = CAN1_SPEED_500KB;	// Выбираем нужную скорость
	
	CAN_Init(CAN1, &CAN_InitStructure);

	// CAN filter init
	CAN_Filter.CAN_FilterNumber = 0;
	CAN_Filter.CAN_FilterMode = CAN_FilterMode_IdMask;
	CAN_Filter.CAN_FilterScale = CAN_FilterScale_32bit;
	CAN_Filter.CAN_FilterIdHigh = 0x0000;
	CAN_Filter.CAN_FilterIdLow = 0x0000;
	CAN_Filter.CAN_FilterMaskIdHigh = 0x0000;
	CAN_Filter.CAN_FilterMaskIdLow = 0x0000;
	CAN_Filter.CAN_FilterFIFOAssignment = CAN_FIFO0;
	CAN_Filter.CAN_FilterActivation = ENABLE;
	CAN_FilterInit(&CAN_Filter);

	// CAN FIFO0 message pending interrupt enable
	CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE);

	// NVIC Configuration
	// Enable CAN1 RX0 interrupt IRQ channel
	NVIC_InitTypeDef NVIC_InitStructure;
	NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);
	
}

#ifdef __cplusplus
 extern "C" {
#endif
  

//**********************************************
// Устанавливаем параметры шины
//
//**********************************************
void CAN_Setup(CAN_InitTypeDef CAN_InitStructure){

	CAN_Init(CAN1, &CAN_InitStructure);
}

//**********************************************
// Устанавливает скорость CAN
//
//**********************************************
void CAN_Speed(uint16_t prescaler, uint8_t bs1, uint8_t bs2, uint8_t sjw) {
	CAN_InitStructure.CAN_BS1 = bs1;
	CAN_InitStructure.CAN_BS2 = bs2;
	CAN_InitStructure.CAN_SJW = sjw;
	CAN_InitStructure.CAN_Prescaler = prescaler;	// Выбираем нужную скорость
	CAN_Setup(CAN_InitStructure);
}

В данном случае скорость шины выставляется настройками CANHacker.

 

 

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

Вопрос еще закрался....

Если после инициализации контроллера я создаю новые настройки (собираю структуру с новыми параметрами) и выполняю 

CAN_Init(CAN1, &CAN_InitStructure);

Это правильно?

Или нужно сначала сделать DeInit?

 

 

upd.

Подключился к шине в режиме отладки.

Изменения наблюдаю только в одном регистре MSR

2019-03-10_15-35-29.png.ba874575ee125ad0f00427772566457e.png2019-03-10_15-35-49.png.df767c697f444c6bd1d59a4516b07510.png

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

Да все верно шина там работает на 500к. По расчетам скорости тоже все верно. Так что с таймингами думаю порядок.  Возможно еще что то упустили в настройках!

1 минуту назад, Smith2007 сказал:

Это правильно?

Да вообще не вопрос, сколько надо столько и перестраивай.

я перестраивал и без  DeInit проблем не возникало, но правильно думаю с DeInit

Сергей.

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

Создайте в CubeMx проект
"из короьбки" там все работает

могли не проинициализировать DMA

могли не включить прерывание

могли неверно задать фильтр

и т.д. и т.п.

 

А все ваши посты - гадание на кофейно гуще

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

22 минуты назад, Smith2007 сказал:

Может это СФТ

Вряд ли. Почему в настройках у тебя значения  CAN_BS1_13tq; CAN_BS2_2tq;  CAN_SJW_1tq; не такие как были указаны ранее?

Сергей.

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

Прерывание, фильтры и т.д. - все работает. Я же проверяю работу в режиме loopback. Все принимается и отправляется. Параллельно слежу осцилографом за сигналом. Вижу изменения и уже различаю 0 и 1. 

 

2 минуты назад, optima сказал:

CAN_BS1_13tq; CAN_BS2_2tq;  CAN_SJW_1tq; не такие как были указаны ранее?

Скорость задается при подключении CAN Hacker. Происходит переинициализация структуры настроек.

2019-03-10_22-11-16.png.930f278761ff4afc938c477f524289a5.png

 

2019-03-10_22-10-41.png.bc9d06490a0ff5a589f4cdc31971c2ea.png

 

2019-03-10_22-11-32.png.cee4bea32b0a912889ec2e555c1dd578.png

 

 

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

А выше что за

1 час назад, Smith2007 сказал:

Процедура инициализации CAN

Судя по ней если preskaler остается равным 6 то 500к уже не получается!  36/6/(13+2+1)

Сергей.

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

Сам себе отвечу.

Написал небольшую тестовую программку, которая сканирует прием перебирая все возможные скорости.

//**********************************************************************/
//         Тестирование скорости приема с CAN
//
//**********************************************************************/
void app_CANScaner (void *argument) {
	USARTSend("CAN Scaner\n\r");
	CanRxMsg msg;
	uint32_t speed;
	uint32_t ratio;

	uint8_t rec;
	uint8_t lec;

  while(1) {
		USARTSend("Prescaler\tBS1\tBS2\tSpeed\tRatio \n\r");
		for (uint16_t prescaler = 1; prescaler < 15; prescaler++) {
			for (uint8_t bs1 = CAN_BS1_1tq; bs1 <= CAN_BS1_16tq; bs1++) {
				for (uint8_t bs2 = CAN_BS2_1tq; bs2 <= CAN_BS2_8tq; bs2++) {
					//while (CAN_RxFrameCount() == 0);
					CAN_InitStructure.CAN_Prescaler = prescaler;
					CAN_InitStructure.CAN_BS1 = bs1;
					CAN_InitStructure.CAN_BS2 = bs2;
					CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
					//CAN_InitStructure.CAN_Mode = CAN_Mode_LoopBack;	// Для тестирования без подключенных устройств шины
					Reinit_CAN();
					osDelay(200);
					lec = CAN_GetLastErrorCode(CAN1);  // err == CAN_ErrorCode_NoErr
					rec = CAN_GetReceiveErrorCounter(CAN1);
					if (rec == 0 and lec == 0) {
						speed = 36000000/CAN_InitStructure.CAN_Prescaler/(1+ CAN_InitStructure.CAN_BS1 + 1 + CAN_InitStructure.CAN_BS2 + 1);
						ratio = CAN_InitStructure.CAN_BS1 * 1000 / (1+ CAN_InitStructure.CAN_BS1 + 1 + CAN_InitStructure.CAN_BS2 + 1);
						USARTSend("\t"); USARTSend(CAN_InitStructure.CAN_Prescaler, 'd'); 
						USARTSend(" \t"); USARTSend(CAN_InitStructure.CAN_BS1 + 1, 'd');
						USARTSend(" \t"); USARTSend(CAN_InitStructure.CAN_BS2 + 1, 'd');
						//USARTSend("\t"); USARTSend(CAN_InitStructure.CAN_SJW + 1, 'd');
						USARTSend(" \t"); USARTSend(speed, 'd');
						USARTSend(" \t"); USARTSend(ratio, 'd');
						USARTSend("     ");
						USARTSend("\n\r");
					}
					else {
						USARTSend("\t"); USARTSend(CAN_InitStructure.CAN_Prescaler, 'd'); 
						USARTSend(" \t"); USARTSend(CAN_InitStructure.CAN_BS1 + 1, 'd');
						USARTSend(" \t"); USARTSend(CAN_InitStructure.CAN_BS2 + 1, 'd');
						USARTSend("     ");
						USARTSend("\r");
					}
					//osDelay(50);
				}
			}
		}		
	}
}

Загрузил в контроллер, подключил к шине авто и запустил.

Через некоторое время получил результат.

2019-03-15_21-49-29.thumb.png.28932cfcf44b78e124c9e6ce5e2f511a.png

Затем сравнил полученные показатели настроек с тем, что я делал и сразу обнаружил ошибку.

Ранее при настройке BS1, BS2 я указывал просто числа 1, 2, 3 ..и т.д. Однако если взглянуть на дефайны

/** @defgroup CAN_time_quantum_in_bit_segment_1 
  * @{
  */

#define CAN_BS1_1tq                 ((uint8_t)0x00)  /*!< 1 time quantum */
#define CAN_BS1_2tq                 ((uint8_t)0x01)  /*!< 2 time quantum */
#define CAN_BS1_3tq                 ((uint8_t)0x02)  /*!< 3 time quantum */
#define CAN_BS1_4tq                 ((uint8_t)0x03)  /*!< 4 time quantum */
#define CAN_BS1_5tq                 ((uint8_t)0x04)  /*!< 5 time quantum */
#define CAN_BS1_6tq                 ((uint8_t)0x05)  /*!< 6 time quantum */
#define CAN_BS1_7tq                 ((uint8_t)0x06)  /*!< 7 time quantum */
#define CAN_BS1_8tq                 ((uint8_t)0x07)  /*!< 8 time quantum */
#define CAN_BS1_9tq                 ((uint8_t)0x08)  /*!< 9 time quantum */
#define CAN_BS1_10tq                ((uint8_t)0x09)  /*!< 10 time quantum */
#define CAN_BS1_11tq                ((uint8_t)0x0A)  /*!< 11 time quantum */
#define CAN_BS1_12tq                ((uint8_t)0x0B)  /*!< 12 time quantum */
#define CAN_BS1_13tq                ((uint8_t)0x0C)  /*!< 13 time quantum */
#define CAN_BS1_14tq                ((uint8_t)0x0D)  /*!< 14 time quantum */
#define CAN_BS1_15tq                ((uint8_t)0x0E)  /*!< 15 time quantum */
#define CAN_BS1_16tq                ((uint8_t)0x0F)  /*!< 16 time quantum */

1 тайм квант (1tq) указывается как 0, а не 1.

Указал верные значения и вуаля!

2019-03-16_00-17-50.png.a5dd532d36597915eaafad455e8550a0.png

CANHacker подцепился с ходу.

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

  • 2 года спустя...
17.03.2019 в 01:40, Smith2007 сказал:

CANHacker подцепился с ходу.

А исходниками не поделитесь? Или прошивкой для STM32. Тоже хочу CAN в машине пощупать.

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

  • 2 недели спустя...
В 12.11.2021 в 08:36, mr_smit сказал:

А исходниками не поделитесь? Или прошивкой для STM32. Тоже хочу CAN в машине пощупать.

Здравствуйте. Писал для STM используя SPI, что б пощупать связь CAN промышленного контроллера, используя скорость 1Мб. В принципе можно сконфигурировать, настройки описаны там же и исходник есть. Я думаю считать можно, только что б расшифровать нужна спецификация. Там же исходники. Пробуйте. https://www.ap-impulse.com/can-stm32-standard-peripherals-library-can-hacker-chast-2-shag-98/  

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

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

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

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

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

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

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

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

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

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

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

    • Автору. Никаких тут 250...200 ватт у этой китайской бздюшки нет в помине. Тем паче на таком подобии радиатора Катушки даже на выходе нет-плохо  
    • Повторюсь - НЕТ, так как у вас там крутилки, что приведет к искажениям при работе в мостовой схеме. Если бы вы "могли" то вам нужно было разорвать выход с темброблока и вход усилителей и впаять (можно навесом) вот такую схему:
    • Все верно, вы почти все что нужно сделали.  Только не нужно было добавлять это b=UDR; Сразу после старта сбросить флаг flags = 0; А в основном цикле ждать установки флага FLAG_END_RX. И если он установлен, проверять на совпадение строки в буфере (rx_buf) с вашей строкой (AT+QM \ r \ n .....   .....  AT+MP \ r \ n) При совпадении вызывать выполнение нужного алгоритма.
    • У меня до саба ещё дело не дошло, только сейчас думаю купить амп на полкиловатта, но так можно, при условии, что на входе будет моно, и будет срез частот
    • Про флаг Т: если он не используется в основной программе, а у меня он постоянно в деле. для меня меня отложенная обработка прерывания обычное дело, нужно лишь правильно расставить приоритеты частей программы. И обычное дело: выставляешь частоту задающего генератора побольше, делишь его до получения частоты 1000 Гц каким либо таймером, загоняешь в прерывание с флагом. затем закольцовываешь основную программу с проверкой флага прерывания от таймера 1000Гц. загоняешь программу в Sleep. Получаешь кольцо обработки с образцовым интервалом в 1 мс. После любого прерывания проверяешь флаг от таймера, если он, то сбрасываешь флаг и начинаешь перебирать подпрограммы обработки индикаторов, клавиатуры, и тд. и тп, подпрограммы обработки флагов и др. После окончания обработки всех подпрограмм возвращаешься к Sleep. И так по кольцу. Если происходит прерывание не от таймера, программа выходит из Sleep, проверяется флаг от таймера, если не он (а это не он) обратно к Sleep. В большенстве программ использую этот алгоритм.   GPIOR1 и GPIOR2 в 88 условно можно использовать как флаги, но их адреса больше 0х1Е, на них не распространяются команды cbi, sbi, sbic, sbis, и их сначала нужно загрузить в общий регистр, промодифицировать, и заново сохранить. Эта последовательность длинная, и модифицирует SREG, что сводит на нет работу по сравнению с  классическим GPIOR.
    • @korsaj Сегодня попробовал сделать как ты посоветовал. Получился следующий код. #define F_CPU 7372800UL #define BAUND 9600L #define UBRRL_value (F_CPU/(BAUND*16))-1 #include <avr/io.h> #include <util/delay.h> #include <avr/interrupt.h> #include <stdlib.h> void init_pin(void); #define C_PC0 (~PINC&(1<<PC0)) #define C_PC1 (~PINC&(1<<PC1)) #define LED_1_ON() PORTD|=(1<<PD2) #define LED_1_OFF() PORTD&=~(1<<PD2) #define LED_2_ON() PORTD|=(1<<PD3) #define LED_2_OFF() PORTD&=~(1<<PD3) #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; volatile start=1, flags; char b; ISR(USART_RXC_vect) { b=UDR; if(!(flags & FLAG_END_RX)) { rx_buf[buf_index]=UDR; 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; } } } 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; } int main(void) { init_pin(); init_UART(); while(1) { if (start==1) { _delay_ms(500); send_UART('O'); send_UART('K'); send_UART('!'); send_UART(0x0D); send_UART(0x0A); _delay_ms(10); start=0; } if (b == '0') { LED_1_ON(); LED_2_OFF(); send_UART('N'); send_UART('+'); send_UART('0'); send_UART('0'); send_UART(0x0D); send_UART(0x0A); _delay_ms(10); b=4; } if (b == '1') { LED_1_OFF(); LED_2_ON(); send_UART('N'); send_UART('+'); send_UART('0'); send_UART('1'); send_UART(0x0D); send_UART(0x0A); _delay_ms(10); b=4; } if (b == '2') { LED_1_ON(); LED_2_ON(); send_UART('N'); send_UART('+'); send_UART('0'); send_UART('2'); send_UART(0x0D); send_UART(0x0A); _delay_ms(10); b=4; } if (b == '3') { LED_1_OFF(); LED_2_OFF(); send_UART('N'); send_UART('+'); send_UART('0'); send_UART('3'); send_UART(0x0D); send_UART(0x0A); _delay_ms(10); b=4; } if (C_PC0) { send_UART('P'); send_UART('C'); send_UART('0'); send_UART(0x0D); send_UART(0x0A); _delay_ms(250); } if (C_PC1) { send_UART('P'); send_UART('C'); send_UART('1'); send_UART(0x0D); send_UART(0x0A); _delay_ms(250); } } } void init_pin(void) { DDRC = 0b00000000; PORTC = 0b11111111; DDRD |= ((1<<2)|(1<<3)); PORTD &=~ ((1<<2)|(1<<3)); } Ну как сказать всё работает, но вот меня очень интересует приём команд на саму ATMEGA16. Он так и работает только с цифрами. Более ничего корректно принять не получается даже используя таблицу ascii. А мне нужно будет принимать команды и посложней чем просто буквенно - цифровые. Потому как возвращаясь к командам самого плеера там в этих командах хранятся различные данные. Вот примерно так это всё выглядит. AT+QM \ r \ n Запрос режима работы [0: Bluetooth], [1: MP3] AT+M1 \ r \ n Номер текущего файла AT+M2 \ r \ n Общее количество звуковых файлов AT+MD \ r \ n Источник музыки USB или SD Card AT+MT \ r \ n Общее время воспроизведения текущего файла AT+MK \ r \ n Время воспроизведения текущего файла AT+MP \ r \ n Текущее состояние плеера [0]Стоп, [1]Воспроизведение, [2]Пауза К примеру при отправке команды AT+M1 \ r \ n в ответ мы получим M1 + 000002 \ r \ n при этом здесь может быть любое число в hex формате. Мне же нужно каким то образом принять эти данные и обработать их соответствующим образом. Но при этом и нужно учитывать так же что плеер может сам отправить эти данные по началу воспроизведения трека. Вот в этом сейчас и стоит основная задача. Чего я и пытаюсь получить в итоге.
×
×
  • Создать...