Форум
 

Вернуться   Форум "Фрикер Клуб" - кодграббер своими руками > Основной раздел > Микроконтроллеры

Важная информация

Ответ
 
Опции темы Опции просмотра
Старый 25.04.2018, 10:00   #1
EPA Меню Пользователя
Супер Модератор
 
Аватар для EPA
 
Регистрация: 01.11.2016
Сообщений: 1,182
По умолчанию от простого к сложному общая Структура (или Формат) Пакета

От простого к сложному: общая структура пакетов.

// ниже, это типа RFSwitch -библиотеки

чтоб передать в радиоэфир определенный сигнал, надо как-то понимать чё за фигня такая

2.0 Формат Пакета состоит В ОБЩЕМ СЛУЧАЕ из такой структуры

2.0.1
- преамбула
- хедер
- стартбит
- собственно данных
- гуардтаим ( время между посылками )
- стопбит


2.0.2
А так же, надо понимать есть еще
- количество повторения посылок
- базовая еденица длительности TE
- модуляция АМ ФМ ЧМ и их производные

2.0.3
данные также имеют различную сруктуру, в общем случае
- количество бит
- вид и длительность логического 0 или 1

2.1.
рассмотрим различные виды форматов пакетов, но для начало надо создать некий код в программе, чтоб в этих всех понятиях пп 2.0. разобраться и с лёгкостью этими данными оперировать.
Самое лучшее средство, это конечно же структура struct ( кстати, через struct - прогеры пишут различные net-протоколы, а мы чё лысые чтоли?... тоже этим воспользуемя )
Так как наш МК 8-битный, будем и делать структуру кратную 8 бит

Код:
uint8_t const SIZE_DATA=11;  // количество байт данных, по идее их может быть и больше или меньше.

typedef struct { 
	// пока уберём uint8_t command; // ЭТО НАМ ПОТОМ ПРИГОДИТЬСЯ
	uint8_t TE; // базововая длительность полупериода TE*mult
	uint8_t mult;  
	uint8_t pre_count; // кол-во импульсов преамбул
	uint8_t pre_t; // длительность импульса преамбулы
	uint8_t hdr_count; // кол-во периодов хедера
	uint8_t hdr_t0; // первая половина периода хедера ( полупериод )
	uint8_t hdr_t1; // вторая половина периода
	uint8_t stb_t0; // старт-бит
	uint8_t stb_t1; //
	uint8_t bit_count; // количество бит данных
	uint8_t log0_t0; // длительность первой половины полупериода лог0
	uint8_t log0_t1; // -"- второй половины полупериода лог0
	uint8_t log1_t0; // -"- лог1
	uint8_t log1_t1; // -"- лог1
	uint8_t guardTime_t; // время между посылками
	uint8_t repeat_pack; // кол-во повторений посылок
	uint8_t dicsription; // приложение...
	uint8_t data[SIZE_DATA]; // собственно данные
	} packetStructure;

volatile packetStructure packStruct; // таким образом создали структуру
volatile uint8_t *tx_ptr; // указатель на нашу стуктуру, чтоб оперативно обращаться к полям стуктуры
2.1.1. Старлаин

выглядеть будет в коде так:
uint8_t PROTOCOL_STARLINE64_OOK_433={250, 1 (умножение TE), 6, 4, 0, 0, 0, 0, 0, 64, 1,1, 2,2, 0, 10, 1 };

А так понимает человек
PROTOCOL_STARLINE64_OOK_433 - формат пакета Starline 64 бита, OOK_433 - модуляция 433 МГц

struct {
// пока уберём uint8_t command; // ЭТО НАМ ПОТОМ ПРИГОДИТЬСЯ
uint8_t TE=250; // базововая длительность полупериода TE*mult
uint8_t mult=1; // 250*1=250микросек
uint8_t pre_count=6; // кол-во импульсов преамбул
uint8_t pre_t=4; // длительность импульса преамбулы, т.е. если TE=250мкс,то длительность преамбулы 250*4=1000
uint8_t hdr_count=0; // ГЫ, у стара нет хедера
uint8_t hdr_t0=0; //
uint8_t hdr_t1=0; //
uint8_t stb_t0; // ГЫ, у стара нет стартбита
uint8_t stb_t1; //
uint8_t bit_count=64; // количество бит данных
uint8_t log0_t0=1; // длительность первой половины полупериода лог0, т.е. TE*log0_t0=250*1=250 мкс
uint8_t log0_t1=1; // -"-
uint8_t log1_t0=2; // -"- лог1, т.е. TE*log1_t0=250*2=500мкс
uint8_t log1_t1=2; // -"- лог1
uint8_t guardTime_t=0 ; // ГЫ, у стара нет время между посылками
uint8_t repeat_pack=10; // кол-во повторений посылок
uint8_t dicsription=1; // приложение..., условимся, что если 1, то импульс Высокий-Низкий
uint8_t data[SIZE_DATA]; // собственно данные
} PROTOCOL_STARLINE64_OOK_433;

Последний раз редактировалось EPA; 25.04.2018 в 09:59.
EPA вне форума   Ответить с цитированием
Старый 25.04.2018, 10:01   #2
EPA Меню Пользователя
Супер Модератор
 
Аватар для EPA
 
Регистрация: 01.11.2016
Сообщений: 1,182
По умолчанию Re: от простого к сложному общая Структура (или Формат) Пакета

2.1.2. Keeloq
...
2.1.3
таких структур мона куеву тучу нарисовать, например вот мой ребус

uint8_t PROTOCOL_CAME12_OOK_433_92= {160, 2, 0, 0, 1, 36, 0, 0, 1, 12, 1,2, 2,1, 0, 4, 2 };
uint8_t PROTOCOL_NICE12_OOK_433_92= {175, 4, 0, 0, 1, 36, 0, 0, 1, 12, 1,2, 2,1, 0, 4, 2 };
uint8_t PROTOCOL_Manchester_OOK_433_92={200, 4,16, 1, 1, 0, 3, 1, 1, 68, 1,1, 1,1, 8, 6, 3 };

как пример PROTOCOL_Manchester_OOK_433_92 - есть и преамбула, и хедер, и стартбит, ... даже есть стопбит ( тока мы его в данные запихнули)

2.1.4. Забегу в перед: весь прикол в том, что универсальная функция передачи пакета у меня весит 500байт,
а если писать код функции на один Формат Пакета, то смысл в стуктурах и универсальности теряется, ибо простая функция будет весить не более 100 байт сделанная на delay(). И к тому же у меня прога на тиньку2313 ( по Тахионовскому проекту) которая умеет принимать сигнал ( но не анализировать, анализирует планшет) , передовать на комп, а так же умеет передовать пакеты , обрабатывать команды от компа и т.д. и т.п.
ВЕСИТ

Task "RunOutputFileVerifyTask"
Program Memory Usage : 1286 bytes
Data Memory Usage : 74 bytes
ИТОГО: 1360 байт

Вечером скину код, перекур закончен

Последний раз редактировалось EPA; 25.04.2018 в 10:07.
EPA вне форума   Ответить с цитированием
Старый 25.04.2018, 19:41   #3
DIVER_SANT Меню Пользователя
Модератор
 
Аватар для DIVER_SANT
 
Регистрация: 27.03.2011
Сообщений: 2,219
По умолчанию Re: от простого к сложному общая Структура (или Формат) Пакета

Да ,реально описание похоже на описание протоколов в rcswitch
__________________
Правильно поставленный вопрос-на половину полученный ответ;)
++++++++++++++++++++++++++++++++++++++
[url]http://www.youtube.com/watch?v=ktnn-s3ebzw[/url]
DIVER_SANT вне форума   Ответить с цитированием
Старый 25.04.2018, 21:28   #4
EPA Меню Пользователя
Супер Модератор
 
Аватар для EPA
 
Регистрация: 01.11.2016
Сообщений: 1,182
По умолчанию Re: от простого к сложному общая Структура (или Формат) Пакета

Вот код, схема на протезе таже как и в глушилке
Пример достаточно туповат, НО на то он и пример.
Допустим, нам надо радиопередать через формат keeloq
прошивка весит 746 bytes, в том числе универсальная функция sendPerProtocol() - 430 байт : передаёт практически любые форматы, которые описаны у нас на форумском букваре.
Код HTML:



#include <avr/io.h>
#include <avr/interrupt.h>  // эта чытоби прерывания работали
#include <stdint.h> // чтоб компилятор понимал допустим uint8 uint16 ....


#define F_CPU 8000000L //Clock Config
//------------------------
#define ADC_OFF  ACSR=1<<ACD; // отключаем компаратор, чтоб не жрал энергию
//------------------------
// наш будущий предатчик PC4
#define TX0_PIN 4 
// обзавём порт по своему
#define TX_DDR DDRC
#define TX_PORT PORTC
#define TX_PIN_PORT PINC
#define TX_LOW    TX_PORT&(~(1<<TX0_PIN))
#define TX_HIGHT  TX_PORT|(1<<TX0_PIN)
//------------------------
// обнуляем счетчик
#define TIMER1_START	TCNT1=0  
	
//------------------------
uint8_t const SIZE_DATA=11;  // количество байт данных, по идее их может быть и больше или меньше.

typedef struct {
	// пока уберём uint8_t command; // ЭТО НАМ ПОТОМ ПРИГОДИТЬСЯ
	uint8_t TE; // базововая длительность полупериода TE*mult
	uint8_t mult;
	uint8_t pre_count; // кол-во импульсов преамбул
	uint8_t pre_t; // длительность импульса преамбулы
	uint8_t hdr_count; // кол-во периодов хедера
	uint8_t hdr_t0; // первая половина периода хедера ( полупериод )
	uint8_t hdr_t1; // вторая половина периода
	uint8_t stb_t0; // старт-бит
	uint8_t stb_t1; //
	uint8_t bit_count; // количество бит данных
	uint8_t log0_t0; // длительность первой половины полупериода лог0
	uint8_t log0_t1; // -"- второй половины полупериода лог0
	uint8_t log1_t0; // -"- лог1
	uint8_t log1_t1; // -"- лог1
	uint8_t guardTime_t; // время между посылками
	uint8_t repeat_pack; // кол-во повторений посылок
	uint8_t dicsription; // приложение...
	uint8_t data[SIZE_DATA]; // собственно данные
} packetStructure;

packetStructure packKeeloq; // таким образом создали структуру для формата Keeloq
//uint8_t *tx_ptr; // указатель на нашу стуктуру, чтоб оперативно обращаться к полям стуктуры	


// функция инициализация портов
inline void portsInit (void)
{
	// в данном случае ногу PC4 (TX0_PIN) настраиваем на выход записав 1 в регистр DDRC(TX_DDR)
	// это типа ардуиновская функция digitalWrite(PC4, HIGT)
	TX_DDR=(1<<TX0_PIN); //порт на выход
}

/* \ инициализация таймера
* так как CPU=8000000, а прескалер 8, то тикать он будет 8000000/8=1000000MГц, т.е.  каждую 1 микросекунду
*/
void timerInitTimer1_Prescaler1_8(int adjustment)
{	
	adjustment=adjustment-1; // в нашем случае 1500-1=1499, почему 1499, а потому что отсчет идёт с нуля, т.е. 0,1,2,3 ...1499 насчитаем ровно 1500
	TCCR1B|=(1<<WGM12);//CTC mode - режим сравнения 
	TIMSK1|=(1<<OCIE1A); //разрешаем прерывание
	OCR1AH=adjustment>>8;// счетчик 16-битный, здесь половинку числа в записываем в старший байт
	OCR1AL=adjustment; // другую половинку числа в записываем в младший байт, НАПРИМЕР число 1499  в двоичном коде  OCR1AH =0b00010100,  OCR1AL=0b10011001
	TCCR1B|=(1<<CS11);// прескалер, делит CPU на 8
}

volatile uint8_t tick_PROT=0; // для подсчета длительности импульсов


// это типа задержка delay()
void my_delay_PROT(uint8_t t)
{
	while(t>tick_PROT)	{ }
	tick_PROT=0; 
}


void sendPerProtocol() //
{
	
	uint8_t mask; // маска для обработки байта данных побитово.
	uint8_t i_bit_count; // кол-во бит в пакете
	uint8_t i; // итератор циклов
	//uint8_t tempPort=TX_PORT;//|(0<<TX0_PIN)|(0<<TX1_PIN); // запомним последнее состояние порта
	uint8_t half_cycle_0;
	uint8_t half_cycle_1;

	//tempPort&=(0<<TX0_PIN)|(0<<TX1_PIN); // запомним последнее состояние порта, но на всяк случай отключим TX
	
	// опишем поведение сигнала: 1 или 3 период высокий-низкий , 2 период низкий-высокий
	if (packKeeloq.dicsription==2)
	{
		half_cycle_0= TX_LOW;// TX_PORT&(~(1<<TX0_PIN));
		half_cycle_1= TX_HIGHT;// TX_PORT|(1<<TX0_PIN);
	}
	else
	{
		half_cycle_0= TX_HIGHT;//TX_PORT|(1<<TX0_PIN);
		half_cycle_1= TX_LOW;// TX_PORT&(~(1<<TX0_PIN));
	}
	
	TIMER1_START; // обнуляем таймер начинаем считать 
	
	for (uint8_t i_repeat_pack=0; i_repeat_pack<packKeeloq.repeat_pack; i_repeat_pack++)
	{
		i=packKeeloq.pre_count; // pre_count
		// preambula
		while (i--)
		{
			TX_PORT=half_cycle_0;
			my_delay_PROT(packKeeloq.pre_t);
			
			TX_PORT=half_cycle_1;
			my_delay_PROT(packKeeloq.pre_t);
		}
		
		// hdr
		i=packKeeloq.hdr_count;
		while (i--)
		{
			if (packKeeloq.hdr_t0)
			{
				TX_PORT=half_cycle_0;
				my_delay_PROT(packKeeloq.hdr_t0);
			}
			if (packKeeloq.hdr_t1)
			{
				TX_PORT=half_cycle_1;
				my_delay_PROT(packKeeloq.hdr_t1);
			}
			
		}
		// startbit
		if (packKeeloq.stb_t0)
		{
			TX_PORT=half_cycle_0;
			my_delay_PROT(packKeeloq.stb_t0);
		}
		if (packKeeloq.stb_t1)
		{
			TX_PORT=half_cycle_1;
			my_delay_PROT(packKeeloq.stb_t1);
		}
		
		// кол-во битданных
		i_bit_count=packKeeloq.bit_count; //-1;  // минус 1
		
		// данные
		for (i=0; i<SIZE_DATA;i++)
		{
			
			mask=1;
			while (mask)
			{
				
				if (packKeeloq.dicsription!=3)  // 3 - manchester
				{
					//if (data[i]&mask)
					if (packKeeloq.data[i]&mask)
					{
						TX_PORT=half_cycle_0;
						my_delay_PROT(packKeeloq.log1_t0);
						TX_PORT=half_cycle_1;
						my_delay_PROT(packKeeloq.log1_t1);
					}
					else
					{
						TX_PORT=half_cycle_0;
						my_delay_PROT(packKeeloq.log0_t0);
						TX_PORT=half_cycle_1;
						my_delay_PROT(packKeeloq.log0_t1);
					}
				}
				else
				{  // это манчечтерское кодирование
					
					if (packKeeloq.data[i]&mask)
					{
						TX_PORT=half_cycle_0;
						my_delay_PROT(packKeeloq.log1_t0);
						TX_PORT=half_cycle_1;
						my_delay_PROT(packKeeloq.log1_t1);
					}
					else
					{
						TX_PORT=half_cycle_1;
						my_delay_PROT(packKeeloq.log0_t0);
						TX_PORT=half_cycle_0;
						my_delay_PROT(packKeeloq.log0_t1);
					}
				}
				
				mask=mask<<1;
				if (i_bit_count--<=1)  //выход при выдаче всех БИТОВ ПОЧЕМУ НЕ ==1, А ИМЕННО <=1, ЭТО ЧТОБЫ НЕ ЗАВИСЛА ПРОГА
				{
					mask=0;
					i=SIZE_DATA; // максимальное число в цикле
					break;
				}
				
			}
			
		}
		//guardTime_t
		if (packKeeloq.guardTime_t) my_delay_PROT(packKeeloq.guardTime_t);
	}
	
// 	TX_PORT=tempPort; // значение порта перед обработкой функции
// 	CLEAR_BIT(TX_PORT,TX_SWITCH);// выключаем передатчик
// 	
// 	timerInitTimer1_Prescaler1_8(k_adjustment);
// 	title_status=TITLE_SCAN;// после передачи, сканировать эфир;
	
}




int main(void)
{
   ADC_OFF;
   portsInit();
   
   // вот так будет выглядеть пакет под формат keeloq
   // следует заметить два первых элемента 200*2=400 , т.е. длительность TE будет равна 400Us
 
   packKeeloq = {200, 2, 12,1,1,0,9,0,0,66,2,1,1,2,38,6,1, {0,1,2,3,4,5,6,7,8,2,0} };// 
   
   timerInitTimer1_Prescaler1_8(packKeeloq.TE*packKeeloq.mult); // таймер будет тикать 400Us
   sei(); // глобальное разрешение прерываний
   
   
   sendPerProtocol(); // 

    while (1) 
    {
    }
}


// прерывание по сравнению A  
ISR(TIMER1_COMPA_vect)
{
		tick_PROT++; // тикает по протоколу
}

В следующем мануале затронем передачу команд через юсарт.

Последний раз редактировалось EPA; 25.04.2018 в 21:32.
EPA вне форума   Ответить с цитированием
Старый 26.04.2018, 10:09   #5
DIVER_SANT Меню Пользователя
Модератор
 
Аватар для DIVER_SANT
 
Регистрация: 27.03.2011
Сообщений: 2,219
По умолчанию Re: от простого к сложному общая Структура (или Формат) Пакета

Цитата:
Сообщение от EPA
Вот код, схема на протезе таже как и в глушилке
Пример достаточно туповат, НО на то он и пример.
Допустим, нам надо радиопередать через формат keeloq
прошивка весит 746 bytes, в том числе универсальная функция sendPerProtocol() - 430 байт : передаёт практически любые форматы, которые описаны у нас на форумском букваре.

По идее можно портировать под CVAVR.Удобно перефирию настраивать в нем.

Добавлено через 7 минут
По идее все настройки пакетов в один файл типа Protocol.h ,потом инклюдим его к проекту граба?
__________________
Правильно поставленный вопрос-на половину полученный ответ;)
++++++++++++++++++++++++++++++++++++++
[url]http://www.youtube.com/watch?v=ktnn-s3ebzw[/url]
DIVER_SANT вне форума   Ответить с цитированием
Старый 26.04.2018, 11:44   #6
EPA Меню Пользователя
Супер Модератор
 
Аватар для EPA
 
Регистрация: 01.11.2016
Сообщений: 1,182
По умолчанию Re: от простого к сложному общая Структура (или Формат) Пакета

Да, где будут лежать протоколы зависит от фантазии прогера, а так же от объема оперативки камня. Здесь просматривается три варианта:
-либо отдельной либой protokol.h, но тогда нужно место в памяти оперативки камня. Зато это будет самый быстрый способ доступа к данным. Но допустим если камень слабый то Чё? Или допустим вдруг мы хотим добавить новый протокол и опять репу чесать...как прошивку обновить.
-держать данные в еепроме, оперативка будет свободна, но тогда как с новым добавлением протокола?
-держать все протоколы например в компе, как сделано у меня. Тогда проблем с добавлением протоколов не будет, ибо у тебя все протоколы лежат в текстовом файле. Вот чем и отличается этот метод от либы rcswicth. )))

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

Последний раз редактировалось EPA; 26.04.2018 в 11:04.
EPA вне форума   Ответить с цитированием
Старый 26.04.2018, 22:43   #7
EPA Меню Пользователя
Супер Модератор
 
Аватар для EPA
 
Регистрация: 01.11.2016
Сообщений: 1,182
По умолчанию Re: от простого к сложному общая Структура (или Формат) Пакета

3. Приём данных с радиоприёмника и передача данных через USART

3.1. Алгорит простой и без всяких наворотов
Смысл такой: принцип работы обычного логического анализатора
1) каждые 32 микросекунды происходит снятие уровня с пина RX.
2) каждый бит RX укладывается в байт и отравляется на комп через USART. И всё!

Вот так выглядет кодинг , которая находятся в той же функции прерывания таймера
PHP код:

ISR
(TIMER1_COMPA_vect
{

...

TCNT1=0// обнуляем счетчик, для следующего раза
            
            
            
static uint8_t maskPin=0b00000001// маска
            
static uint8_t rxByte=0// этот байт и отправим через ЮСАРТ
            
static uint8_t iShiftLeft=0;// Номер бита,   уровень бита RX будем укладывать в байт
                    
            
rxByte|=(RX_PIN_PORT maskPin)<<iShiftLeft// укладываем
            
if (iShiftLeft++==7// если байт заполнили, то отправляем в USART
            
{
                
                
iShiftLeft=0;
                
tx_buffer[tx_wr_index++]=rxByte;  // буффер
                
tx_wr_index &= TX_BUFFER_MASK//
                
UCSR0B|=(1<<UDRIE0);    // Разрешаем прерывание UDRE, т.е. мона работать с передачей через USART
                
rxByte=0
                ...
                
            }
...


Здесь надо заметить две вещи:
1) это кольцевой буффер: прежде чем передать байт через USART, этот байт с начало записывается в кольцевой буфер, так данные целее будут.

Код:
const uint8_t TX_BUFFER_SIZE=32; // размер буфера, !!!!!! обязательно кратный степени двойки
const uint8_t TX_BUFFER_MASK=(TX_BUFFER_SIZE-1); // маска буфера
volatile uint8_t tx_buffer[TX_BUFFER_SIZE]; // сюда будем записывать данные, т.е. в кольцевой буфер
volatile uint8_t tx_wr_index; // индекс записи из кольцового бувера
volatile uint8_t tx_rd_index; // индек чтения из кольцевого буфера
2) данные передаются USART'ом через прерывание
PHP код:

// прерывание, если есть что отправить, то оправит
ISR (USART_UDRE_vect)
{
    
    if(
tx_wr_index!=tx_rd_index)      // Вывели весь буффер?
    
{
        
UDR0 =tx_buffer[tx_rd_index++];    // Берем данные из буффера.
        
tx_rd_index &=TX_BUFFER_MASK;
    }
    else
    {
        
UCSR0B &=~(1<<UDRIE0);    // Запрещаем прерывание по опустошению - передача закончена
    
}


Завтра скину кодинг приёма команд UASRT, и всё, мона весь код собирать как конструктор Лего. перейдём на объяснялку проги на компе.
EPA вне форума   Ответить с цитированием
Старый 27.04.2018, 20:47   #8
EPA Меню Пользователя
Супер Модератор
 
Аватар для EPA
 
Регистрация: 01.11.2016
Сообщений: 1,182
По умолчанию Re: от простого к сложному общая Структура (или Формат) Пакета

4. Инициализация USART.
4.1. USART я разогнал до максимальной скорости BAUD=500000, т.е.
-F_CPU 8000000 Гц
-в асинхронном режиме и при двойной скорости USE2X=1
-8-n-1.
При этом отклонение - 0%

Если перевести BAUD=500000 в секунды ~1/(5000000/10)=2мксек отравляется один байт

4.2. Есть стандартная библиотека #include <util/setbaud.h> , чтобы мозг свой не напрягать
вычислениями UBRR

4.3. Функция инициализации uart_init(void)

Код HTML:
...
#include <util/setbaud.h>
...

#define F_CPU 8000000UL //Clock Config
#define BAUD 500000  // это получается при F_CPU=8МГц и двойной скорости USE2X=1, один длительность передачи одного байта через ЮСАРТ примерно 20Us !!!!! 
#define USE2X 1    // двойная скорость USE2X

...
...

inline void uart_init(void)
{
	
	//UBRR0H = (unsigned char)(ubrr>>8);
	//UBRR0L = (unsigned char)ubrr;
	
	UBRR0H = UBRRH_VALUE;
	UBRR0L = UBRRL_VALUE;
	
	#if USE_2X
	UCSR0A |= (1 << U2X0);
	#else
	UCSR0A &= ~(1 << U2X0);
	#endif
	
	// RX и TX на мази  и прерывание при приёме така я же фигня
	UCSR0B = (1 << RXEN0) | (1 << TXEN0) | (1 << RXCIE0);

	// 8-bit, 1 stop bit, no parity, asynchronous UART
	UCSR0C = (1 << UCSZ01) | (1 << UCSZ00) | (0 << USBS0) |
	(0 << UPM01) | (0 << UPM00) | (0 << UMSEL01) |
	(0 << UMSEL00);


}
С приёмом, чуть по сложнее, так как нам необходимо будет принять кучу не простых байт

Добавлено через 19 минут
6. Система команд в передаче по USART

6.1. Взял основные для простоты

Код:
uint8_t const TITLE_SCAN = 'T'; // сканирование эфира
uint8_t const TITLE_PacketSend = 'P'; // передача данных по Формату Пакета
uint8_t const TITLE_GROM = 'G'; // глушилка
//uint8_t const TITLE_SPEC = 'B'; // спектроанализатор
uint8_t const TITLE_RESET ='A'; // reset
6.2. Смысл такой: Комп отправляет массив байт на камень по такой структуре
> StartByte > Comanda > Data > CRS ( контрольная сумма )
Камень приняв этот массив, проверив посылку с помощью контрольной суммы, начинает исполнять приказ компа.
Если данные придут и не сойдётся контрольная сумма, то комп повторно отправит байты.

PHP код:

// прерывание при получении данных с юсарта
ISR (USART_RX_vect)
{

    static 
uint8_t rx_counter=0;    // счётчик байтов
    
static uint8_t faza=0;    //  фаза сотояния
    
static uint8_t controlSum=0;   // контрольная сумма
    
static uint8_t calculator_controlSum=0// итог контрольной суммы
    
static uint8_t size_packet=0// кол-во байт в пакете
    
    
uint8_t rx_data=UDR0;
    
    if ((
UCSR0A & (FRAMING_ERROR DATA_OVERRUN))==0)
    {
        
timers_STOP(); //TIMERs_STOP; //тупо останавливаем таймер
        //////////////////////////////////////////////////////////////////////////
        
switch(faza)
        {
            case 
0:  // стартовый бит
                    
if (rx_data =='S')  //ловим стартовый байт
                    
{
                        
faza=1;// break;
                        
controlSum=0// подготавливаем переменную для подсчета контрольной суммы
                        
tx_ptr=&packStruct.command// устанавливаем указатель на первый элемент структуры
                        
size_packet=sizeof(packStruct)+1;//  пакет будет из 30 байт: размер packStruct + байт контрольной ссумы
                        
TX_ENABLE// включаем передатчик, если будет TITLE_SCAN, то выключим передатчик потом                            
                    
}
            break;
            case 
1// принимаем данные                    
                
                    
if ((!rx_counter) & (rx_data=='A'))          // RESET камня        
                    
{
                           
wdt_enable(WDTO_30MS);  // прогораммнеый сброс через 30милисек
                            
while(1){}    
                    }
                    
                    
                    *
tx_ptr++=rx_data;      // заполняем данными структуру rx_struct    //заполняем кольцевой буфер rx_buffer[rx_wr_index++]=rx_data; rx_wr_index &= RX_BUFFER_MASK; // записываем в буфер    //                        
                    
controlSum^=rx_data// сразу же подсчитываем контрольную сумму            
                    
rx_counter++; 
            
                    if(
rx_counter == (size_packet-1))     calculator_controlSum=controlSum// предпоследний байт будет контрольной суммой - подсчет контрольной суммы
            
                    //завершение, подготовка для обработки полученных данных
                    
if(rx_counter == size_packet)  // конец передачи, с одновременной проверкой вычисленной контрольной с принятой контрольной суммой
                    
{
                                            
                        
uart_TX_DISABLE();//USART_TX_DISABLE;    // Запрещаем прерывание по опустошению в USART, чтоб не мешала функции обработки                
                        
USART_Transmit_8_NoBuffer(calculator_controlSum); // если она не сойдется, то отправитель это увидит                
                        
if (calculator_controlSum==rx_data)  // если всё хорошо, то начинаем обработку принятых данных
                        
{    
                            if (
packStruct.command==TITLE_PacketSendprotocolOption();  // передача пакета
                            
else 
                            if (
packStruct.command== TITLE_GROMgromOption(); // глушилка
                            
else scanOption(); // сканирование эфира
                            
timerInitTimer1_Prescaler1_8(packStruct.TE *packStruct.mult); // по идее лучше воспользоваться операцией сдвига чем умножением
                        
}
                        
                        
size_packet=0;                
                        
rx_counter=0// сброс счетчика
                        
faza 0;    // сброс сотояния  //    rx_wr_index=rx_rd_index; //!!!!!!!!
                    
                    
}
            
            break;
            
        }
        
    }
    

...
Код:

inline void scanOption()
{	
сканируем эфир
}

inline void gromOption()
{
 включаем глушилку	
}

inline void protocolOption()
{
	
отправляем пакет в эфир	

}
Добавлено через 5 минут
Ща причешу исходники и вместе с протезом скину для симуляции. Вдруг ты чёнить, есшо захочешь прикрутить. И перейдем прогу на компе разбирать, там ваще легко! Высокоуровневые языки рулят, а прогер мозг себе не трахает мелочами, т.е. весь интерфейс и визуализацию на себя берёт IDE, а прогеру остаётся тока логику программировать
EPA вне форума   Ответить с цитированием
Старый 28.04.2018, 20:10   #9
EPA Меню Пользователя
Супер Модератор
 
Аватар для EPA
 
Регистрация: 01.11.2016
Сообщений: 1,182
По умолчанию Re: от простого к сложному общая Структура (или Формат) Пакета

Исходники под мегу328 и тиню2313( под Тахину схему) & Протез. Завтра будет время, презентабельнее сделаю винприложение ( Запорожец уберу) скину

Последний раз редактировалось EPA; 09.10.2018 в 08:47.
EPA вне форума   Ответить с цитированием
Старый 29.04.2018, 06:07   #10
DIVER_SANT Меню Пользователя
Модератор
 
Аватар для DIVER_SANT
 
Регистрация: 27.03.2011
Сообщений: 2,219
По умолчанию Re: от простого к сложному общая Структура (или Формат) Пакета

Процесс идет
__________________
Правильно поставленный вопрос-на половину полученный ответ;)
++++++++++++++++++++++++++++++++++++++
[url]http://www.youtube.com/watch?v=ktnn-s3ebzw[/url]
DIVER_SANT вне форума   Ответить с цитированием
Ответ

Опции темы
Опции просмотра

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.



Текущее время: 21:54. Часовой пояс GMT +3.


vBulletin 4.1.0 Перевод: zCarot
(C) www.phreakerclub.com
Яндекс.Метрика