Code:
#include <mega8.h>
// Standard Input/Output functions
#include <stdio.h>
#include <string.h>
#include <delay.h>
#asm
.equ portb=0x18
.equ portd=0x12
.equ sdi=0 ;PortB,0
.equ sck=1 ;PortB,1
.equ nsel=2 ;PortB,2
.equ sdo=3 ;PortB,3
.equ nirq=2 ;PortD,2
#endasm
// Declare your global variables here
bit newstring=0; /* Ein neuer gültiger Datenstring wurde empfangen */
flash unsigned int ui_frequ[32]={1240,1270,1300,1330,1360,1390,1420,1450,1480,1510,1540,1570,1600,1630,1660,1690,1720,1750,1780,1810,1840,1870,1900,1900,1900,1900,1900,1900,1900,1900,1900,1900};
volatile unsigned char uc_receivebuffer[127];/* Empfangspuffer */
volatile unsigned char uc_receivebyte=0;/* Zeiger aktuelles Sendebyte */
volatile unsigned char uc_timeout=0;
volatile unsigned char uc_kanal; /* gewählter Kanal */
// Sende ein Byte zum RFM 01
void sendbyte(volatile unsigned char uc_byte)
{
#asm
push r26 ;Register retten
in r26,sreg
push r26
push r27
ldi r26,8 ;Schleifenzähler mit 8 laden
ld r27,y ;uc_Byte vom Ram holen
sendloop:
tst r26 ;Schleifenzähler eins runterzählen
breq endsend
dec r26
clc
rol r27 ;High Byte ins Carry schieben
brcs send1 ;Bei 1 -> High ausgeben
cbi portb,sdi ;Bei 0 -> Low ausgeben
rcall clockpulse
rjmp sendloop
send1:
sbi portb,sdi
rcall clockpulse
rjmp sendloop
clockpulse:
nop
nop
nop
sbi portb,sck ;Clock Port auf 1 setzen
nop
nop
nop
nop
nop
nop
cbi portb,sck ;Clock Port auf 0 setzen
nop
nop
nop
ret ;Zurück zur aufrufenden Routine
endsend:
cbi portb,sdi ;SDI Port auf 0 setzen zwecks kosmetik
pop r27
pop r26
out sreg,r26
pop r26
#endasm
}
// XOR Verknüpfung Code Vision kann kein EXOR
#pragma warn- // this will prevent warnings
unsigned char funk_xor (unsigned char uc_wert1,unsigned char uc_wert2)
{
#asm
push r26
in r26,sreg
push r26
ld r26,y ;uc_wert2 holen
ldd r30,y+1 ;uc_wert1 holen
eor r30,r26 ;Rückgabewert im Register r30
pop r26
out sreg,r26
pop r26
#endasm
}
#pragma warn+ // enable warnings
// Checksumme berechnen
unsigned char checksum (void)
{
volatile unsigned char uc_check[2]={0,0}; /* (Checksummenpuffer)*/
volatile unsigned char uc_i=0;
uc_check[0]=uc_receivebuffer[uc_receivebyte-4]; /* High nibble einlesen */
uc_check[1]=uc_receivebuffer[uc_receivebyte-3]; /* Low nibble einlesen */
if (uc_check[0]>0x39)
{
uc_check[0]=uc_check[0]-0x37; /*ASCII Code A...F */
}
else
{
uc_check[0]=uc_check[0]-0x30; /*ASCII Code 0...9 */
}
if (uc_check[1]>0x39)
{
uc_check[1]=uc_check[1]-0x37;
}
else
{
uc_check[1]=uc_check[1]-0x30;
}
uc_check[0]=uc_check[0]<<4; /* Checksummen zusammenführen */
uc_check[0]=uc_check[0]|uc_check[1];
for (uc_i=0;uc_i<(uc_receivebyte-4);uc_i++)
{
uc_check[0]=funk_xor(uc_check[0],uc_receivebuffer[uc_i]); /* XOR Verknüpfung */
}
return uc_check[0]; /* Rückgabe der Checksumme, sollte wenn richtig 0 sein */
}
//FIFO Puffer initialisieren bei Fehlern und Datensatzende
void reset_fifo (void)
{
/* FIFO Command: Enable FIFO, IT level=8, Sync. Patt + VDI, stop FIFO */
#asm ("cbi portb,nsel");
sendbyte(0b11001110);
sendbyte(0b10001001);
#asm ("sbi portb,nsel");
#asm ("nop");
/* FIFO Command: Enable FIFO, IT level=8, Sync. Patt + VDI, start FIFO */
#asm ("cbi portb,nsel");
sendbyte(0b11001110);
sendbyte(0b10001011);
#asm ("sbi portb,nsel");
#asm ("nop");
uc_receivebyte=0;
}
// Einen Taktimpuls erzeugen
void clockpulse(void)
{
#asm
nop
nop
nop
sbi portb,sck ;Clock Port auf 1 setzen
nop
nop
nop
nop
nop
nop
cbi portb,sck ;Clock Port auf 0 setzen
nop
nop
nop
#endasm
}
// Empfange Daten vom RFM 01
interrupt [EXT_INT0] void ext_int0_isr(void)
{
unsigned char uc_i=0;
unsigned char uc_buffer=0;
unsigned char uc_check=0;
uc_timeout=0; /* Timeout Zähler zurücksetzen */
/* Die ersten 16 Bit des Statuswortes übergehen */
#asm ("cbi portb,nsel");
sendbyte(0b00000000);
sendbyte(0b00000000);
for(uc_i=0;uc_i<8;uc_i++)/* 8 Bits auslesen */
{
if ((PINB&(1<<3))!=0) /* SDO abfragen = PortB,3 */
{
uc_buffer=(uc_buffer<<1)| 0x01;
}
else
{
uc_buffer=(uc_buffer<<1);
}
clockpulse();
}
#asm ("sbi portb,nsel"); /* nSel Leitung abschalten */
#asm ("nop");
uc_receivebuffer[uc_receivebyte]=uc_buffer;
uc_receivebyte++;
if (uc_buffer==10) /* Line Feed wurde empfangen*/
{
uc_receivebuffer[uc_receivebyte]=0;
reset_fifo();
uc_check=checksum();
uc_receivebyte=0;
if (uc_check==0);
{
newstring=1;
}
}
}
#define RXB8 1
#define TXB8 0
#define UPE 2
#define OVR 3
#define FE 4
#define UDRE 5
#define RXC 7
#define FRAMING_ERROR (1<<FE)
#define PARITY_ERROR (1<<UPE)
#define DATA_OVERRUN (1<<OVR)
#define DATA_REGISTER_EMPTY (1<<UDRE)
#define RX_COMPLETE (1<<RXC)
// USART Transmitter buffer
#define TX_BUFFER_SIZE 127
char tx_buffer[TX_BUFFER_SIZE];
#if TX_BUFFER_SIZE<256
unsigned char tx_wr_index,tx_rd_index,tx_counter;
#else
unsigned int tx_wr_index,tx_rd_index,tx_counter;
#endif
// USART Transmitter interrupt service routine
interrupt [USART_TXC] void usart_tx_isr(void)
{
if (tx_counter)
{
--tx_counter;
UDR=tx_buffer[tx_rd_index];
if (++tx_rd_index == TX_BUFFER_SIZE) tx_rd_index=0;
};
}
#ifndef _DEBUG_TERMINAL_IO_
// Write a character to the USART Transmitter buffer
#define _ALTERNATE_PUTCHAR_
#pragma used+
void putchar(char c)
{
while (tx_counter == TX_BUFFER_SIZE);
#asm("cli")
if (tx_counter || ((UCSRA & DATA_REGISTER_EMPTY)==0))
{
tx_buffer[tx_wr_index]=c;
if (++tx_wr_index == TX_BUFFER_SIZE) tx_wr_index=0;
++tx_counter;
}
else
UDR=c;
#asm("sei")
}
#pragma used-
#endif
//RFM01 initialisieren
void init_rfm01(void)
{
volatile unsigned char uc_frequ[2]; /* Frequenz tuningword */
/* Frequenzwortermittlung aus der Kanalangabe */
uc_frequ[1]=ui_frequ[uc_kanal]/256;
uc_frequ[1]|=0b10100000;
uc_frequ[0]=ui_frequ[uc_kanal]%256;
/* Configuration Setting: 433MHz, CLK on, 11,5pf Kapaz., 67kHz */
#asm ("cbi portb,nsel");
sendbyte(0b10001001);
sendbyte(0b01101100);
#asm ("sbi portb,nsel");
#asm ("nop");
/* Low Batt Clock Divider Command: clock 5MHz */
#asm ("cbi portb,nsel");
sendbyte(0b11000010);
sendbyte(0b11000000);
#asm ("sbi portb,nsel");
#asm ("nop");
/* Frequency Setting: 434MHz (je nach Kanal) */
#asm ("cbi portb,nsel");
sendbyte(uc_frequ[1]);
sendbyte(uc_frequ[0]);
#asm ("sbi portb,nsel");
#asm ("nop");
/* Receiver Setting Command: VDI= Digital RSSI Out, -103dB, receiver disabled */
#asm ("cbi portb,nsel");
sendbyte(0b11000000);
sendbyte(0b10000000);
#asm ("sbi portb,nsel");
#asm ("nop");
/* Receiver Setting Command: VDI= Digital RSSI Out, -103dB receiver enabled */
#asm ("cbi portb,nsel");
sendbyte(0b11000000);
sendbyte(0b10000001);
#asm ("sbi portb,nsel");
#asm ("nop");
/* FIFO Command: Enable FIFO, IT level=8, Sync. Patt + VDI, stop FIFO */
#asm ("cbi portb,nsel");
sendbyte(0b11001110);
sendbyte(0b10001001);
#asm ("sbi portb,nsel");
#asm ("nop");
/* FIFO Command: Enable FIFO, IT level=8, Sync. Patt + VDI, start FIFO */
#asm ("cbi portb,nsel");
sendbyte(0b11001110);
sendbyte(0b10001011);
#asm ("sbi portb,nsel");
#asm ("nop");
/* Data Filter Command: */
#asm ("cbi portb,nsel");
sendbyte(0b11000100);
sendbyte(0b10101100);
#asm ("sbi portb,nsel");
#asm ("nop");
/* Data Rate Command: 2400 bit/s */
#asm ("cbi portb,nsel");
sendbyte(0b11001000);
sendbyte(0b10010001);
#asm ("sbi portb,nsel");
#asm ("nop");
/* AFC Command: Enable AFC, +3/-4, offset at VDI high */
#asm ("cbi portb,nsel");
sendbyte(0b11000110);
sendbyte(0b10111111);
#asm ("sbi portb,nsel");
#asm ("nop");
}
// Timer 1 output compare A interrupt service routine
interrupt [TIM1_COMPA] void timer1_compa_isr(void)
{
/* 1 Sekunde */
uc_timeout++;
if (uc_timeout>3)/* Wenn 3 Sekunden kein Bit mehr Empfangen wurde wird der FiFo resetet */
{
init_rfm01();
reset_fifo();
uc_timeout=0;
}
}
// Declare your global variables here
void main(void)
{
// Declare your local variables here
unsigned char uc_i=0;
// Input/Output Ports initialization
// Port B initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=Out Func1=Out Func0=Out
// State7=T State6=T State5=T State4=T State3=T State2=0 State1=0 State0=0
PORTB=0x00;
DDRB=0x07;
// Port C initialization
// Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State6=T State5=P State4=P State3=P State2=P State1=P State0=P
PORTC=0x3F;
DDRC=0x00;
// Port D initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTD=0x00;
DDRD=0x00;
// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
TCCR0=0x00;
TCNT0=0x00;
// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 31,250 kHz
// Mode: Normal top=FFFFh
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer 1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: On
// Compare B Match Interrupt: Off
// CTC Mode : On
TCCR1A=0x00;
TCCR1B=0x0C;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x7A; /* Comparematch Register mit 31250 laden = 1 Sekunde */
OCR1AL=0x11;
OCR1BH=0x00;
OCR1BL=0x00;
// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer 2 Stopped
// Mode: Normal top=FFh
// OC2 output: Disconnected
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;
// External Interrupt(s) initialization
// INT0: On
// INT0 Mode: Falling Edge
// INT1: Off
GICR|=0x40;
MCUCR=0x02;
GIFR=0x40;
// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x10;
// USART initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART Receiver: Off
// USART Transmitter: On
// USART Mode: Asynchronous
// USART Baud Rate: 38400
UCSRA=0x00;
UCSRB=0x48;
UCSRC=0x86;
UBRRH=0x00;
UBRRL=0x0C;
// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;
// Kanalauswahl
uc_kanal=(PINC&0b00111111);
// RFM 01 initialisieren
delay_ms(200);
init_rfm01();
reset_fifo();
// Testroutinen
/*strcpyf (uc_receivebuffer,"$123456789ABCDEF#31");
uc_receivebyte=strlen(uc_receivebuffer);
uc_receivebuffer[uc_receivebyte]=13;
uc_receivebuffer[uc_receivebyte+1]=10;
uc_receivebuffer[uc_receivebyte+2]=0;
uc_receivebyte=strlen(uc_receivebuffer);
checksum();*/
// Ende der Testroutinen
// Global enable interrupts
#asm("sei")
while (1)
{
/*newstring=1;*/ /* zu Testzwecken */
if (newstring==1)
{
for (uc_i=0;uc_i<strlen(uc_receivebuffer);uc_i++)
{
putchar (uc_receivebuffer[uc_i]);
}
newstring=0;
}
};
}
Lesezeichen