Кажется, нарыл исходники на Си для Атмеги16(32)!
Код:
/**************************************************************
***** Mouse-Implanted RFID Project *******
***** Base Station Code *******
***** *******
***** By Dan Golden *******
***** 09/11/2004 *******
**************************************************************/
/* This code is for the Atmel Mega32 Microcontroller */
/************************************
***** Port Description *******
************************************
Inputs:
D[2] Base Station Data Output
Outputs:
C[0:7] LEDs (for testing)
/************************************
***** Encoding Notes *******
************************************
Manchester encoding is used to communicate from the transponder to the base station.
Traditionally, in manchester encoding, the data ALWAYS contains an edge on the
clock's falling edge; a logic 1 is a rising edge, a logic 0 is a falling edge.
However, this base station INVERTS the received data; hence, a logic 1 is a falling
edge on the falling clock edge, and a logic 0 is a rising edge on the falling clock
edge.
Ex.
_ _ _ _ _ _ _ _
CLK |_| |_| |_| |_| |_| |_| |_| |_
_ _ _ ___ ___ _
DATA Sent |_| |___| |_| |___| |_| |_
_ ___ _ ___ _ _
DATA Rec'd _| |_| |_| |___| |___| |_|
| 0 | 0 | 1 | 1 | 0 | 1 | 0 | 0 |
Obviously, the received data is what is parsed.
Clock Periods of Note:
Width of one half clock period: 256 us = 64 CLK/64 cycles
Width of one full clock period: 513 us = 128 CLK/64 cycles
Width of four clock periods (1/2 byte): 2.05 ms = 512 CLK/64 cycles
*/
/************************************
***** Includes *******
************************************/
#include <Mega32.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/************************************
***** Definitions *******
************************************/
#define dataInput PIND.2
#define debugOut PORTA.0
#define LEDs PORTC
/************************************
***** Global Variables *******
************************************/
unsigned char count; // General indexing variable
unsigned char bitStream[3]; // Used to parse input data
unsigned char bitNumber, byteNumber;
unsigned char lastEdge, thisEdge, CLKedge, getData;
unsigned char data; /* The data byte received at the Base Station from the
transponder. */
unsigned char dataReady; // True when the data is ready
unsigned char junkByte; // True if the current byte is invalid
unsigned char junkCounter; // # of successive junk bytes since last sync
char sync; // Sync level
// 0: not syncing (receiving data)
// -1: not synced (waiting for sync pulse)
/************************************
***** Function Prototypes *******
************************************/
void initialize(void);
/************************************
***** Interrupts *******
************************************/
/* This interrupt is used only for FINDING the clock from the initial clock sync
byte. Parsing DATA is done separately. */
interrupt [EXT_INT0] void data_edge(void)
{
thisEdge = dataInput;
// If the detected period is too low (T < 200 us), then label
// this byte as junk.
if(TCNT1 < 50)
junkByte = 1; // Label the byte as junk.
// 200 us < T < 384 us. This period occurs after a clock edge or a same-bit
// boundary (e.g., 1-1 or 0-0).
else if (TCNT1 < 96)
{
// If we're at a clock edge...
if (CLKedge)
{
CLKedge = 0;
getData = 1;
}
else
CLKedge = 1;
}
// 384 us < T < 600 us.
// This period occurs after an opposing-bit boundary ONLY.
else if (TCNT1 < 150)
{
CLKedge = 0;
getData = 1;
}
// If the pulse period is too different from any legal values, the byte is junk.
else
{
junkByte = 1;
}
// Reset timer1
TCNT1 = 0;
// If we're on a rising clock edge, it's time to get the data
if (getData)
{
getData = 0;
// Shift bitstream down
bitStream[0] >>= 1;
bitStream[0] |= (bitStream[1] << 7);
bitStream[1] >>= 1;
bitStream[1] |= (bitStream[2] << 7);
bitStream[2] >>= 1;
// Insert the most recent bit into bitStream
bitStream[2] |= ((!dataInput) << 7);
bitNumber++;
}
// If we have sync, and we've just updated bitStream and bitStream has
// all 8 bits of data, then read the data. If the data has been
// marked as junk for any reason, then set it to 0xff.
if ((~CLKedge) && (sync != -1) && (bitNumber == 8))
{
// If the data is junk, make it 0xff.
if (junkByte)
{
data = 0xff;
junkCounter++;
}
else
{
data = bitStream[2];
junkCounter = 0;
}
byteNumber++;
// Force a sync every 100 data bytes, or if we get three junk
// bytes in a row.
if ((byteNumber == 100) || (junkCounter > 2))
{
sync = -1;
TCNT0 = 0;
TIMSK |= 0b00000010; // Send 0xff's while syncing
}
dataReady = 1;
bitNumber = 0;
junkByte = 0;
}
// If we're searching for the sync stream...
else if ((~CLKedge) && (sync == -1))
{
// If we've found the sync, stop searching and get ready for data.
if ((bitStream[0] == 0x00) && (bitStream[1] == 0xff) &&
(bitStream[2] == 0xff))
{
sync = 0;
TIMSK &= 0b11111101; // Stop sending 0xff's
bitNumber = 0;
byteNumber = 0;
}
}
}
interrupt [TIM0_COMP] void timer0_compare(void)
{
data = 0xff;
dataReady = 1;
}
/************************************
***** Main *******
************************************/
void main(void)
{
initialize();
while(1)
{
if (dataReady) // If we have received data...
{
LEDs = ~data;
dataReady = 0; // Prepare for new data
printf("%c", data); // send data to USART
}
if (TIFR & 0x04) // If timer 1 has overflowed (T = 0.26 sec)...
{
TIFR = TIFR | 0x04; // Clear TOV1.
sync = -1; // Start syncing.
TCNT0 = 0;
TIMSK |= 0b00000010; // Send 0xff's while syncing.
}
}
}
/************************************
***** Function Definitions *******
************************************/
/************************************
***** Initialization *******
************************************/
void initialize(void)
{
/**** Port initialization ****/
DDRD = 0x00; // D.2 is data input
DDRA = 0x01; // A.0 is debug output
DDRC = 0xff; // Port C is LED output
LEDs = 0xff; // All off initially
/**** Interrupt initialization ****/
MCUCR = 0b00000001; // Any edge on INT0 triggers interrupt
GICR = 0b01000000; // Enable INT0
/* Timer 1 is used for synchronizing with the transponder's data clock,
which should run at around (125e3/64) = 1.95 KHz, which means that
edges appear at 3.91 KHz (no opposing bit boundary) or 1.95KHz
(at opposing bit boundaries). */
TCCR1B = 0b00000011; // CLK/64 (250 KHz)
/* Timer 0 is used to output 0xff data points at the same frequency as
the usual data rate when the base is searching for the sync stream. */
TCCR0 = 0b00001101; // CTC on, CLK/1024 (15.6 KHz)
OCR0 = 65; // f = 240 Hz (almost 238.5 Hz, the data rate)
TIMSK = 0b00000010; // Enable OCIE0
/**** USART initialization ****/
UCSRB = 0b00011000 ; // TXC, RXC enabled
UBRRL = 16 ; // 57.6 kbaud @ 16MHz
/**** Variable initialization ****/
lastEdge = 0;
CLKedge = 0;
bitNumber = 0;
byteNumber = 0;
junkByte = 0;
for (count = 0; count < 3; count++)
bitStream[count] = 0;
data = 0;
dataReady = 0;
sync = -1; // Initially, we don't have sync
/**** Get this party started (enable interrupts) ****/
#asm("sei");
}
http://instruct1.cit.cornell.edu//courses/eceprojectsland/STUDENTPROJ/2004to2005/dig4/basestation.cТолько не понял пока - это только реализация манчестера?
Спать пора ...
Утро вечера мудренее.