• Объявления

    • admin

      Просьба всем принять участие!   24.11.2017

      На форуме разыгрывается спектроанализатор Arinst SSA-TG LC (цена 18500 руб). Просьба всем перейти по ссылке ниже и принять участие!
supercelt

Код На Си Для Генерации Манчестера В Rfid Эмуляторе

21 сообщение в этой теме

supercelt    2

Здрасьте!

Задание было такое. организовать генерацию манчестерского кода на atmega16 для стандарта RFID меток 125 кГц EM4100 (RF 64).

Исходные данные которые надо закодировать в манчестер это - 1110 и по кругу.

Я написал код, всё работает прекрасно скрин с протеуса прилагается

abc5587c666d.png

Манчестер код - красная диаграмма. Жёлтая - это несущая частота. Должна быть 125 кгц, но я уменьшил до 15 что бы чётче было в протеусе. Для тех кто мало ли не знает что такое RF64 - это значит что один бит данных метки передаётся за 64 такта несущей частоты.

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

//##################################################################################################################
//Так как Proteus 8 очень плохо моделирует при высоких частотах, то задана проверочная частота счётчика 15.625 kHz,
//вместо 125 kHz!
//Программа расчитана для стандарта EM4100A6CB2RC (Кодировка Manchester. Cycle/bit 64). Это значит что
//один бит данных занимает 64 периода сигнала на катушке.
//##################################################################################################################
#define F_CPU 8000000 //Частота камня
#include <avr/io.h>
#include <avr/interrupt.h>
volatile static char bit_rate_counter = 0; //переменная считает количество положительных тактов счётчика
unsigned char data[] = {1,1,1,0}; //массив с выходным двоичным кодом который надо передать
unsigned char i = 0; //переменная для выборки из массива data нужного элемента в нужном месте
volatile unsigned char pass = 0; //переменная нужна что бы программа в цикле лишний раз не заходила в условие if(bit_rate_counter == 8 && pass == 1)
ISR(TIMER0_COMP_vect){ //вектор прерывания по совпадению
if(PINB & (1 << 3)){ //если на пине 3 порта В устанолена 1
bit_rate_counter ++; //увеличиваем счётчик положительных тактов счётчика на 1
if(bit_rate_counter == 32){ //если число положительных тактов = 32
pass = 1; //то ставим флаг что бы разрежить программе зайти в условие if(bit_rate_counter == 32 && pass == 1)
}
}
}
int main(void)
{
DDRC |= (1 << 0); //0 пин порта С работает на выход
PORTC &= ~(1 << 0); //Ставил лог. 0 на 0 пин порта С
DDRB |= (1 << 3); //3 пин порта В работает на выход
PORTB &= ~(1 << 3); //ставим лог. 0 на 3 пин порта В
DDRA |= (1 << 0); //Порт А работает на выход
PORTA &= ~(1 << 0); //ставим лог. 0 на 0 пин порта А
OCR0 = 3; //Задаём частоту счётчика. При предделителе 1/64 и OCR = 3 Частота будет 15.625 kHz
TCCR0 |= (0 << WGM00)|(1 << WGM01); //Режим работы таймера-счётчика0 - сброс при совпадении (СТС)
TCCR0 |= (0 << CS02)|(1 << CS01)|(1 << CS00); //предделитель частоты 1\64
TCCR0 |= (0 << COM01)|(1 << COM00); //Смена сигнала на PB3 - Toggle
TIMSK |= (1 << OCIE0); //Разрешаем уходить в прерывание при совпадении TCNT0 и OCR
asm("sei"); //Разрешаем прерывания глобально
while(1) //Бесконечный цикл
{
 //asm("nop");
if(bit_rate_counter == 64){ //если число положительных тактов = 64
bit_rate_counter = 0; //Обнуляем счётчик положительных тактов
}
if(bit_rate_counter == 0){ //Если число положительных тактов = 0
if(data[i] == 1){ // Если в данных, в i бите единица
 PORTC |= (1 << 0); //подаем на порт С 0 пин - 1
 PORTA |= (1 << 0); //подаем на порт А 0 пин - 1
 } else { //если в данных в i бите не единица то есть ноль
 PORTC &= ~(1 << 0); //подаем на порт С 0 пин - 0
 PORTA &= ~(1 << 0); //подаем на порт С 0 пин - 0
}
}
if(bit_rate_counter == 32 && pass == 1){ //если число положительных тактов = 32 и сработало прерывание, которое установило флаг 1
if(data[i] == 1){ //Если в данных, в i бите единица
 PORTA &= ~(1 << 0); //подаем на порт А 0 пин - 0
} else { //если в данных в i бите не единица то есть ноль
 PORTA |= (1 << 0); //подаем на порт А 0 пин - 1
}
i++; //увеличиваем i на 1, для того что бы при следующем заходе брать следующий бит данных
if(i == 4){ //если биты данных закончились. А их всего 4, то
i = 0; //Обнуляем счётчик битов. При следующем заходе код будет передаваться заново.
}
pass = 0; //Обнуляем флаг, что бы программа сюда не заходила до следующего прерывания
}
}
}
//Все глобальные переменные, используемые в ISR, надо снабжать атрибутом "volatile".
//Прога выводит манчестер кода 1110

post-23236-0-77624500-1438615817_thumb.png

Поделиться сообщением


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

Быстрый заказ печатных плат

Полный цикл производства PCB по низким ценам!

  • x
    мм
Заказать Получить купон на $5.00
IMXO    1 099
Манчестер код - красная диаграмма. Жёлтая - это несущая частота. Должна быть 125 кгц, но я уменьшил до 15 что бы чётче было в протеусе.
мне кажется или получен инверсный код???

300px-Manchester-code.png

и почему несущая отдельно от кода???

и уменьшать частоту в протезе не нужно... вместо осциллографа пользуйтесь графом ЛОГИЧЕСКИЙ АНАЛИЗАТОР левой панели инструментов http://kazus.ru/forums/showthread.php?t=13198&page=3 с 22поста...

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
supercelt    2

Спасибо за ответ. Да, сорри код инверсный, поправлю. А не моги бы вы пояснить что значит несущая отельно от кода?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
supercelt    2

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

А в целом код норм? не громоздкий?

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
IMXO    1 099

ниче не понял.. какой приемник? если пины настроены на выход??? и куда вы подаете декретированный сигнал :umnik2:

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
supercelt    2

на второй мк который тут не указан. Второй мк должен просто прочитать манчестер и вывести исходный код. Поэтому мне и надо что бы приёмник давал просто манчестер без несущей частоты

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
IMXO    1 099

тогда в первый МК должна быть подключена несущая для синхронизации или нет?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
IMXO    1 099

а что мешает ее генерировать прямо в МК и выдавать код уже с несущей?

для этого достаточно включить ШИМ , настроить его на частоту 125кГц

в прерывании по постлелителю 1:32 переключать скважность ШИМа 0% или 35% тем самым формируя передачи полубитов для лог.1 или лог.0

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
supercelt    2

Чёт я не понял про шим. Если шим это значит TCCR0 (3 и 6 бит ставим в 1). В этом режиме вроде можно OCR регулировать скважность, а период будет постоянным. Если даже выбрать макс частоту камня 16мгц, то 16000000/256 тиков счётчика TCNT0 = 62.500 кгц. Не дотягивает до нужных 125

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
IMXO    1 099

так счетчик не обязательно должен считать до 256

не знаю как это реализовано в АВРх, в ПИКах изменением счетчика можно регулировать период ШИМа просто с повышением частоты уменьшаться разрядность ШИМа, думаю в АВРх тоже самое... почитайте доки

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
supercelt    2

Я это читал. Особо не помогло. Вычитал в какой-то статье что частотой шима можно управлять уменьшая верхний предел счётчика tcnt0. А вот как это сделать нигде не сказано

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
IMXO    1 099

да действительно несколько не то...

значит это только на ПИКх такая возможность

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Viktor26    300

Настраивание таймер на сброс при совпадении, в регистр сравнения пишите число меньше чем 255. Настраиваете ножку чтоб меняла свое значение на противоположное при совпадении счетного регистра с регистром сравнения. Теперь давайте посчитаем какая частота у вас будет при 8 МГц и если в регистр сравнения будет записано число например 20, правильно уже 400кГц.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
IMXO    1 099

это не совсем то что нужно... как я понял в АВР нет возможности установить разрядность ШИМа меньше 8

и при этом получить прерывание от таймера через 16 периодов ШИМа ....

отсюда невозможно получить

Для тех кто мало ли не знает что такое RF64 - это значит что один бит данных метки передаётся за 64 такта несущей частоты.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Viktor26    300

Тут нужны гуру. Так далеко я еще не копал

Знаю точно Геннадий копает в данный момент rfid у него можно спросить как это дело прикручивается.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Viktor26    300

Зайдите в ветку AVR или мк для начинающих. Он там в темах частенько фигурирует. Ща попробую с телефона ссылку на него вставить

http://forum.cxem.net/index.php?showuser=16151

Вот он

Поделиться сообщением


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

Создайте аккаунт или войдите в него для комментирования

Вы должны быть пользователем, чтобы оставить комментарий

Создать аккаунт

Зарегистрируйтесь для получения аккаунта. Это просто!

Зарегистрировать аккаунт

Войти

Уже зарегистрированы? Войдите здесь.

Войти сейчас