You are on page 1of 46

DIY

cnmusic@163.net

6 2

feng_matrix

MOS

22121000KV
30A

GWS 10
9
10 10

10 9

I2C
I2C
2

PID

PID
0.2

I2C F22

PI I2C I I
I2C

450 450

KeepOutLayer

450

450

1.2


2 2 8


900
450 150


Mega8 M8 IO
8 8 ARM7 AT91SAM7S256

55Mhz 64KB 256KB Flash


2 I2C
CRC16

AD

MicroSD AT91SAM7S256 SPI


EFSL
EFSL
SD
SD

SD M8 I2C I2CBootLoader
SD BIN

PPM /
SD

SD PPM /3 /3
GPSZigBee
2 1.27

PPM / M8 16 ICP PPM

1.5ms
8
200Hz

I2C
ICP 8 1.5ms * 8 = 12ms
(1.5+2)ms * 8 = 28ms 63Hz M8

PPM I2C
M8

PI 2

AD
10
300Hz 10
33ms

AD
2

PI

90
90 0

0
ENC03

=94
= 696 100Hz 6 3.3V
22
5

1 1 1
100% 12 AD
P

PI

P I

PID P
P I =0
80% P

I I P=0 I
P

I
I I
I

2
I P P 50
50
50 50 P

40 I

10

50

15
10
100Hz 300Hz Excel

1PPM
http://bbs.5imx.com/bbs/viewthread.php?tid=219838&page=26#pid3319190

AVRMega8
PPM
P

2ms
M8 8M

12M

M8
M

ISP

ISP

M8
RESSET

8M
1M

....

M8

main

main

TIME0

//
//
//PP
PM /
//Veersion1.0
//cn
nmusic@163.net
//
AVRMegga8,
8M
//
//
#include<avr/io.h>
#include<avr/intterrupt.h>
#include<util/deelay.h>
#include<stdlib.h
h>

#defineFEED_DOG asm("wdr");
#defineNOP asm("nop");
#defineINT_ON sei();
#defineINT_OFF cli();

typedefunsignedchar BOOL;
typedefunsignedchar BYTE;
typedefunsignedchar CHAR;

#defineTRUE 1
#defineFALSE 0

#defineCHANNELCOUNT 1

#define TICK_COUNT_LEAD 70 // 0.5ms 0


64 0.5ms
//

typedefstructtagChannelData
{
BYTE nChannelOutValue; //
BYTE nChannelOutStep; //
}CHANNELDATA;

volatileCHANNELDATA g_ChannelData[CHANNELCOUNT]={{0}};
volatileBOOL g_bOutAllComplete=TRUE;
volatileBYTE g_nOutIndex=0;

//TIME0
// 3
// 0.5ms 2ms
// TIME0
ISR(TIMER0_OVF_vect)
{
if(g_ChannelData[g_nOutIndex].nChannelOutStep==0)
{
PORTD|=(1<<PD7);
TCNT0=0xFFTICK_COUNT_LEAD;
g_ChannelData[g_nOutIndex].nChannelOutStep=1;
}
elseif(g_ChannelData[g_nOutIndex].nChannelOutStep==1)
{
TCNT0=0xFFg_ChannelData[g_nOutIndex].nChannelOutValue;

g_ChannelData[g_nOutIndex].nChannelOutStep=2;
}
else
{
PORTD&=~(1<<PD7);
g_nOutIndex++;

if(g_nOutIndex>=CHANNELCOUNT)
{
g_bOutAllComplete=TRUE;
TCCR0=0;
}
else
{
TCNT0=0xFF1;
}
}
}

intmain()
{
BYTE nChannelValueFinal=0;

DDRD=(1<<DDD2)|(1<<DDD3)|(1<<DDD7); //PD2PD3 PD7

PORTD&=~((1<<PD6)|(1<<PD7));
PORTD|=(1<<PD3); //

INT_ON; //

// 0
TIMSK|=(1<<TOIE0); //

while(1)
{
//
// PD6

asm("nop");

//TIME2

TCCR2=(1<<CS22); //64

//
while(!(PIND&(1<<PIND6)))
{
//asm("nop"); //
while
}

//
TCNT2=0;

// 0.5ms
while(PIND&(1<<PIND6))
{
if (TCNT2 == TICK_COUNT_LEAD) // 0.5ms

{
TCNT2=0;
break;
}
}

//
while(PIND&(1<<PIND6))
{
//asm("nop");
}

//
TCCR2=0;
nChannelValueFinal=TCNT22; //
16uS

if ((abs((int)g_ChannelData[0].nChannelOutValue (int)nChannelValueFinal)) >


1)
{
g_ChannelData[0].nChannelOutValue=nChannelValueFinal; //

g_ChannelData[0].nChannelOutStep=0; //

// 0
g_nOutIndex = 0; // 0

TCNT0=0xFF1; // 1

TCCR0=(1<<CS00)|(1<<CS01); //64

// 0
g_bOutAllComplete=FALSE;

while(!g_bOutAllComplete);
}
}

IO

2.5ms
17.5ms

/ ESKY /OK

5g9g
ESKY05000508
ELEES03

2M8 I2CBootLoader
http://bbs.5imx.com/bbs/viewthread.php?tid=219838&page=34#pid3638185

Atmel AVRM8 I2C/TWIBootLoader

BootLoader M8 BootLoader BootLoader


I2C BootLoader

BootLoader BootLoader
BOOTLOADER_SECTION<avr/boot.h>
bootloader .map

static

bootloader

Bootloader

4
3 2

BootLoader I2C

BootLoader C main

BootLoader

vectors.S

#include<avr/io.h>

#if__AVR_MEGA__
#defineXJMPjmp
#defineXCALLcall
#else
#defineXJMPrjmp
#defineXCALLrcall
#endif

.section.boot_vectors,"ax",@progbits
XJMP start

.word 0 //pad(vector7)
.word 0 //pad(vector8)


//
//
//
//vector__vector_9 //OverFlow0
.word 0
//vector__vector_10
.word 0
//vector__vector_11 //OverFlow0
.word 0
//vector__vector_12
.word 0
//vector__vector_13
.word 0
//vector__vector_14
.word 0
//vector__vector_15
.word 0
//vector__vector_16 //OverFlow0
.word 0
//vector__vector_17 //TWI
.word 0
//vector__vector_18
.word 0
//vector__vector_19 //TWI
.word 0
//vector__vector_20
.word 0
//vector__vector_21
.word 0
//vector__vector_22
.word 0
//vector__vector_23
.word 0
//vector__vector_24 //TWI
.word 0
//vector__vector_25
.word 0
//vector__vector_26
.word 0
//vector__vector_27
.word 0
//vector__vector_28
.word 0

//vector__vector_29
.word 0
//vector__vector_30
.word 0
//vector__vector_31
.word 0
//vector__vector_32
.word 0
//vector__vector_33 //TWI
.word 0

//Wedon'tneedanyvectorshigherthan33,sodon'twastetheflash

#define__zero_reg__ r1

// __stack
.global__stack
.set __stack,RAMEND

start:
//
// C
clr __zero_reg__
out _SFR_IO_ADDR(SREG),__zero_reg__
ldi r28,lo8(__stack)
ldi r29,hi8(__stack)
out _SFR_IO_ADDR(SPH),r29
out _SFR_IO_ADDR(SPL),r28

ldi r24,lo8(0)
ldi r25,hi8(0)

XJMP main

M8

section.1 2
section
.bootloader0xc25 C 0x25

.boot_vectors0xc00
ProjectOptions MemorySettings

3 TWIBootLoader.c

C Atmel TWI BootLoader


CRC16
//
//TWIBootLoader.c
//

#include<avr/io.h>
#include<avr/interrupt.h>
#include<avr/boot.h>
#include<util/delay.h>
#include<string.h>
#include<stdio.h>
#include<stdlib.h>

//
// IO BL_LIGHT1 BL_LIGHT2
//
#ifdefGPSBOARD

#defineTWI_ADDR

30

#defineBL_PORT_INIT()

DDRB=(1<<DDB0)|(1<<PB1)|(1<<PB2);

#defineBL_LIGHT1()

PORTB=(1<<PB0)|(1<<PB1);

#defineBL_LIGHT2()

PORTB=(1<<PB2)|(1<<PB1);
#elifDRIVERBOARD

#defineTWI_ADDR

20

#defineBL_PORT_INIT()

DDRC=(1<<DDC0)|(1<<DDC1);

#defineBL_LIGHT1()

PORTC=(1<<PC0);

#defineBL_LIGHT2()

PORTC=(1<<PC1);
#else

#defineTWI_ADDR

31

#defineBL_PORT_INIT()

DDRB = (1<<DDB3) | (1<<DDB1) | (1<< DDB0) |


(1<<DDB2);

#defineBL_LIGHT1()

PORTB=(1<<PB1)|(1<<PB0)|(1<<PB2)|(1<<PB3);

#defineBL_LIGHT2()

PORTB=0;
#endif


#defineBL_ADDR

0x1800
//BootLoader
//
//TWI_Slave.h
//

/****************************************************************************
TWIStatus/Controlregisterdefinitions
****************************************************************************/

#defineTWI_BUFFER_SIZE
(SPM_PAGESIZE+2) // Reserves memory for the drivers
transceiverbuffer.
// Set this to the largest message size that will be sent
includingaddressbyte.

/****************************************************************************
Globaldefinitions
****************************************************************************/

unionTWI_statusReg //Statusbyteholdingflags.
{
unsignedcharall;
struct
{
unsignedcharlastTransOK:1;
unsignedcharRxDataInBuf:1;
unsigned char genAddressCall:1; // TRUE = General call,
FALSE=TWIAddress;
unsignedcharunusedBits:5;
};
};

//externunionTWI_statusRegTWI_statusReg;

/****************************************************************************
Functiondefinitions
****************************************************************************/
staticvoidTWI_Slave_Initialise(unsignedchar);
staticunsignedcharTWI_Transceiver_Busy(void);
//staticunsignedcharTWI_Get_State_Info(void);
staticvoidTWI_Start_Transceiver_With_Data(unsignedchar*,unsignedint);
staticvoidTWI_Start_Transceiver(void);
//staticunsignedcharTWI_Get_Data_From_Transceiver(unsignedchar*,unsignedchar);

staticunsignedchar*TWI_Get_Data_Pointer_From_Transceiver(void);
staticvoidTWI_Get_Data_Pointer_From_Transceiver_Release(void);

//staticvoidTWI_Prepare_Transceiver_CleanDataSize(void);
//staticvoidTWI_Prepare_Transceiver_With_Data(unsignedchar*msg,unsignedintmsgSize);
//staticvoidTWI_Start_TransceiverData(void);
staticvoidTWI_ISR(void);
staticvoidTWIProcess(void);

//
typedefunsignedint UINT;
typedefunsignedchar BYTE;

typedefstructtagInfo
{

BYTE
szSign[2];

BYTE
nSize;

BYTE
PageSize;

BYTE
nBLVersion;

BYTE
CurrentAddr;
}INFO;

UINT g_BL_FlashAddr=0;
INFO
g_BL_CurrentInfo;

//
#definePROG_START 0x0000

#defineBOOTLOADER_ADDR_START_USER_APP
1

//
#defineBOOTLOADER_ADDR_GET_INFO

//
#defineBOOTLOADER_ADDR_UPLOAD

//
#defineBOOTLOADER_ADDR_RESET

//

/****************************************************************************
Bitandbytedefinitions
****************************************************************************/
#defineTWI_READ_BIT 0 //BitpositionforR/Wbitin"addressbyte".
#defineTWI_ADR_BITS 1 //BitpositionforLSBoftheslaveaddressbitsintheinitbyte.
#defineTWI_GEN_BIT 0 //BitpositionforLSBofthegeneralcallbitintheinitbyte.

#defineTRUE 1

#defineFALSE 0

/****************************************************************************
TWIStatecodes
****************************************************************************/
//GeneralTWIMasterstauscodes
#defineTWI_START 0x08 //STARThasbeentransmitted
#defineTWI_REP_START 0x10 //RepeatedSTARThasbeentransmitted
#defineTWI_ARB_LOST 0x38 //Arbitrationlost

//TWIMasterTransmitterstauscodes
#define TWI_MTX_ADR_ACK 0x18 // SLA+W has been tramsmitted and ACK
received
#define TWI_MTX_ADR_NACK 0x20 // SLA+W has been tramsmitted and NACK
received
#define TWI_MTX_DATA_ACK 0x28 // Data byte has been tramsmitted and ACK
received
#defineTWI_MTX_DATA_NACK 0x30 //DatabytehasbeentramsmittedandNACK
received

//TWIMasterReceiverstauscodes
#define TWI_MRX_ADR_ACK 0x40 // SLA+R has been tramsmitted and ACK
received
#define TWI_MRX_ADR_NACK 0x48 // SLA+R has been tramsmitted and NACK
received
#define TWI_MRX_DATA_ACK 0x50 // Data byte has been received and ACK
tramsmitted
#define TWI_MRX_DATA_NACK 0x58 // Data byte has been received and NACK
tramsmitted

//TWISlaveTransmitterstauscodes
#defineTWI_STX_ADR_ACK 0xA8 //OwnSLA+Rhasbeenreceived;ACKhasbeen
returned
#defineTWI_STX_ADR_ACK_M_ARB_LOST0xB0 //ArbitrationlostinSLA+R/WasMaster;own
SLA+Rhasbeenreceived;ACKhasbeenreturned
#define TWI_STX_DATA_ACK 0xB8 // Data byte in TWDR has been transmitted;
ACKhasbeenreceived
#define TWI_STX_DATA_NACK 0xC0 // Data byte in TWDR has been transmitted;
NOTACKhasbeenreceived
#defineTWI_STX_DATA_ACK_LAST_BYTE0xC8 //LastdatabyteinTWDRhasbeentransmitted
(TWEA=??;ACKhasbeenreceived

//TWISlaveReceiverstauscodes
#defineTWI_SRX_ADR_ACK 0x60 //OwnSLA+WhasbeenreceivedACKhasbeen

returned
#defineTWI_SRX_ADR_ACK_M_ARB_LOST0x68 //ArbitrationlostinSLA+R/WasMaster;own
SLA+Whasbeenreceived;ACKhasbeenreturned
#defineTWI_SRX_GEN_ACK 0x70 //Generalcalladdresshasbeenreceived;ACK
hasbeenreturned
#define TWI_SRX_GEN_ACK_M_ARB_LOST 0x78 // Arbitration lost in SLA+R/W as Master;
Generalcalladdresshasbeenreceived;ACKhasbeenreturned
#defineTWI_SRX_ADR_DATA_ACK 0x80 //PreviouslyaddressedwithownSLA+W;data
hasbeenreceived;ACKhasbeenreturned
#defineTWI_SRX_ADR_DATA_NACK 0x88 //PreviouslyaddressedwithownSLA+W;data
hasbeenreceived;NOTACKhasbeenreturned
#defineTWI_SRX_GEN_DATA_ACK 0x90 //Previouslyaddressedwithgeneralcall;data
hasbeenreceived;ACKhasbeenreturned
#defineTWI_SRX_GEN_DATA_NACK 0x98 //Previouslyaddressedwithgeneralcall;data
hasbeenreceived;NOTACKhasbeenreturned
#define TWI_SRX_STOP_RESTART 0xA0 // A STOP condition or repeated START
conditionhasbeenreceivedwhilestilladdressedasSlave

//TWIMiscellaneousstatuscodes
#define TWI_NO_STATE 0xF8 // No relevant state information available;
TWINT=??
#define TWI_BUS_ERROR 0x00 // Bus error due to an illegal START or STOP
condition

//
//TWI_Slave.c
//
static unsigned char TWI_buf[TWI_BUFFER_SIZE]; // Transceiver buffer. Set the size in the
headerfile
staticunsignedint TWI_msgSize =0; //Numberofbytestobetransmitted.
static unsigned char TWI_state = TWI_NO_STATE; // State byte. Default set to
TWI_NO_STATE.

union TWI_statusReg TWI_statusReg = {0}; // TWI_statusReg is defined in


TWI_Slave.h

BOOTLOADER_SECTIONintmain(void)
{

int nCount=0;

cli();

BL_PORT_INIT();
memset(TWI_buf,0,TWI_BUFFER_SIZE);
g_BL_FlashAddr=0;
g_BL_CurrentInfo.szSign[0]='B';
g_BL_CurrentInfo.szSign[1]='L';
g_BL_CurrentInfo.nSize=sizeof(g_BL_CurrentInfo);
g_BL_CurrentInfo.nBLVersion=1;
g_BL_CurrentInfo.CurrentAddr=g_BL_FlashAddr;
g_BL_CurrentInfo.PageSize=SPM_PAGESIZE;
TWI_Slave_Initialise((TWI_ADDR<<TWI_ADR_BITS)|(0<<TWI_GEN_BIT));
TWI_Start_Transceiver();
while(1)
{

//while(TWI_Transceiver_Busy())

if(TWCR&(1<<TWIE))

if(TWCR&(1<<TWINT))

TWI_ISR();

TWIProcess();

nCount++;

if((nCount>=10000)&&(nCount<20000))

BL_LIGHT1();

elseif(nCount>=20000)

BL_LIGHT2();

nCount=0;

}
}
return0;

/****************************************************************************
CallthisfunctiontosetuptheTWIslavetoitsinitialstandbystate.
RemembertoenableinterruptsfromthemainapplicationafterinitializingtheTWI.
Passboththeslaveaddressandtherequrementsfortriggeringonageneralcallinthe
samebyte.Usee.g.thisnotationwhencallingthisfunction:
TWI_Slave_Initialise((TWI_slaveAddress<<TWI_ADR_BITS)|(TRUE<<TWI_GEN_BIT));
TheTWImoduleisconfiguredtoNACKonanyrequests.UseaTWI_Start_Transceiverfunctionto
starttheTWI.
****************************************************************************/
staticBOOTLOADER_SECTIONvoidTWI_Slave_Initialise(unsignedcharTWI_ownAddress)
{
TWAR = TWI_ownAddress; // Set own TWI slave address.
AcceptTWIGeneralCalls.
TWDR=0xFF; //Defaultcontent=SDAreleased.
TWCR = (1<<TWEN)| // Enable TWIinterface and
releaseTWIpins.
(0<<TWIE)|(0<<TWINT)| //DisableTWIInterupt.
(0<<TWEA)|(0<<TWSTA)|(0<<TWSTO)| // Do not ACK on any requests,
yet.
(0<<TWWC); //
}

/****************************************************************************
CallthisfunctiontotestiftheTWI_ISRisbusytransmitting.
****************************************************************************/
staticBOOTLOADER_SECTIONunsignedcharTWI_Transceiver_Busy(void)
{
return ( TWCR & (1<<TWIE) ); // IF TWI interrupt is enabled then the
Transceiverisbusy
}

/****************************************************************************
Callthisfunctiontofetchthestateinformationofthepreviousoperation.Thefunctionwillhold
execution(loop)
until the TWI_ISR has completed with the previous operation. If there was an error, then the
function
willreturntheTWIStatecode.
****************************************************************************/
/*
staticBOOTLOADER_SECTIONunsignedcharTWI_Get_State_Info(void)
{
while ( TWI_Transceiver_Busy() ); // Wait until TWI has completed the

transmission.
return(TWI_state); //Returnerrorstate.
}
*/
/****************************************************************************
Callthisfunctiontosendapreparedmessage,orstarttheTransceiverforreception.Include
apointertothedatatobesentifaSLA+Wisreceived.ThedatawillbecopiedtotheTWIbuffer.
Alsoincludehowmanybytesthatshouldbesent.NotethatunlikethesimilarMasterfunction,
the
Addressbyteisnotincludedinthemessagebuffers.
The function will hold execution (loop) until the TWI_ISR has completed with the previous
operation,
theninitializethenextoperationandreturn.
****************************************************************************/
static BOOTLOADER_SECTION void TWI_Start_Transceiver_With_Data( unsigned char *msg,
unsignedintmsgSize)
{
unsignedinttemp;

while ( TWI_Transceiver_Busy() ); // Wait until TWI is ready for next


transmission.

TWI_msgSize=msgSize; //Numberofdatatotransmit.
for(temp=0;temp<msgSize;temp++) //Copydatathatmaybetransmittedifthe
TWIMasterrequestsdata.
TWI_buf[temp]=msg[temp];
TWI_statusReg.all=0;
TWI_state =TWI_NO_STATE;
TWCR=(1<<TWEN)| //TWIInterfaceenabled.
(1<<TWIE)|(1<<TWINT)| // Enable TWI Interupt and clear the
flag.
(1<<TWEA)|(0<<TWSTA)|(0<<TWSTO)| //PreparetoACKnexttimetheSlave
isaddressed.
(0<<TWWC); //
}

/*
staticBOOTLOADER_SECTIONvoidTWI_Prepare_Transceiver_CleanDataSize()
{

while ( TWI_Transceiver_Busy() ); // Wait until TWI is ready for next


transmission.

TWI_msgSize=0;
}

*/

/*
static BOOTLOADER_SECTION void TWI_Prepare_Transceiver_With_Data( unsigned char *msg,
unsignedintmsgSize)
{

unsignedinttemp;

while ( TWI_Transceiver_Busy() ); // Wait until TWI is ready for next


transmission.

for(temp=TWI_msgSize;temp<TWI_msgSize+msgSize;temp++) //Copydatathat
maybetransmittediftheTWIMasterrequestsdata.
{

TWI_buf[temp]=msg[tempTWI_msgSize];

TWI_msgSize+=msgSize;
}*/

/*
staticBOOTLOADER_SECTIONvoidTWI_Start_TransceiverData()
{

while ( TWI_Transceiver_Busy() ); // Wait until TWI is ready for next


transmission.

TWI_statusReg.all=0;

TWI_state =TWI_NO_STATE;

TWCR=(1<<TWEN)| //TWIInterfaceenabled.

(1<<TWIE)|(1<<TWINT)| // Enable TWI Interupt and clear the


flag.

(1<<TWEA)|(0<<TWSTA)|(0<<TWSTO)| //PreparetoACKnexttimetheSlave
isaddressed.

(0<<TWWC); //
}*/

/****************************************************************************
Call this function to start the Transceiver without specifing new transmission data. Usefull for
restarting
a transmission, or just starting the transceiver for reception. The driver will reuse the data
previouslyput
in the transceiver buffers. The function will hold execution (loop) until the TWI_ISR has
completedwiththe
previousoperation,theninitializethenextoperationandreturn.
****************************************************************************/

staticBOOTLOADER_SECTIONvoidTWI_Start_Transceiver(void)
{
while ( TWI_Transceiver_Busy() ); // Wait until TWI is ready for next
transmission.
TWI_statusReg.all=0;
TWI_state =TWI_NO_STATE;
TWCR=(1<<TWEN)| //TWIInterfaceenabled.
(1<<TWIE)|(1<<TWINT)| // Enable TWI Interupt and clear the
flag.
(1<<TWEA)|(0<<TWSTA)|(0<<TWSTO)| //PreparetoACKnexttimetheSlave
isaddressed.
(0<<TWWC); //
}
/****************************************************************************
CallthisfunctiontoreadoutthereceiveddatafromtheTWItransceiverbuffer.I.e.firstcall
TWI_Start_TransceivertogettheTWITransceivertofetchdata.ThenRunthisfunctiontocollect
the
data when they have arrived. Include a pointer to where to place the data and the number of
bytes
to fetch in the function call. The function will hold execution (loop) until the TWI_ISR has
completed
withthepreviousoperation,beforereadingoutthedataandreturning.
IftherewasanerrorintheprevioustransmissionthefunctionwillreturntheTWIStatecode.
****************************************************************************/
/*
static BOOTLOADER_SECTION unsigned char TWI_Get_Data_From_Transceiver( unsigned char
*msg,unsignedcharmsgSize)
{
unsignedinti;

while ( TWI_Transceiver_Busy() ); // Wait until TWI is ready for next


transmission.

if(TWI_statusReg.lastTransOK) //Lasttransmissioncompetedsuccessfully.
{
for(i=0;i<msgSize;i++) //CopydatafromTransceiverbuffer.
{
msg[i]=TWI_buf[i];
}
TWI_statusReg.RxDataInBuf = FALSE; // Slave Receive data has been read from
buffer.
}
return(TWI_statusReg.lastTransOK);
}

*/

staticBOOTLOADER_SECTIONunsignedchar*TWI_Get_Data_Pointer_From_Transceiver()
{
//while ( TWI_Transceiver_Busy() ); // Wait until TWI is ready for next
transmission.

if( TWI_statusReg.lastTransOK ) // Last transmission competed


successfully.
{

returnTWI_buf;
}
else
{

return0;

}
}

staticBOOTLOADER_SECTIONvoidTWI_Get_Data_Pointer_From_Transceiver_Release()
{
TWI_statusReg.RxDataInBuf = FALSE; // Slave Receive data has been read from
buffer.
}

//**********InterruptHandlers**********//
/****************************************************************************
This function is the Interrupt Service Routine (ISR), and called when the TWI interrupt is
triggered;
thatiswheneveraTWIeventhasoccurred.Thisfunctionshouldnotbecalleddirectlyfromthe
main
application.
****************************************************************************/
//BOOTLOADER_SECTIONISR(TWI_vect)
staticBOOTLOADER_SECTIONvoidTWI_ISR(void)
{
staticunsignedintTWI_bufPtr;
switch(TWSR)
{
case TWI_STX_ADR_ACK: // Own SLA+R has been received; ACK has been
returned
// case TWI_STX_ADR_ACK_M_ARB_LOST: // Arbitration lost in SLA+R/W as Master; own
SLA+Rhasbeenreceived;ACKhasbeenreturned
TWI_bufPtr = 0; // Set buffer pointer to first
datalocation

caseTWI_STX_DATA_ACK: //DatabyteinTWDRhasbeentransmitted;ACKhas
beenreceived
TWDR=TWI_buf[TWI_bufPtr++];
TWCR=(1<<TWEN)| //TWIInterfaceenabled
(1<<TWIE)|(1<<TWINT)| // Enable TWI Interupt and
cleartheflagtosendbyte
(1<<TWEA)|(0<<TWSTA)|(0<<TWSTO)| //
(0<<TWWC); //
break;
case TWI_STX_DATA_NACK: // Data byte in TWDR has been transmitted; NACK
hasbeenreceived.
//I.e.thiscouldbetheendofthetransmission.
if(TWI_bufPtr==TWI_msgSize)//Havewetransceivedallexpecteddata?
{
TWI_statusReg.lastTransOK = TRUE; // Set status bits to completed
successfully.
}else // Master has sent a NACK before all data where
sent.
{
TWI_state = TWSR; // Store TWI State as
errormessage.
}
// Put TWI Transceiver in
passivemode.
TWCR=(1<<TWEN)| //EnableTWIinterfaceand
releaseTWIpins
(0<<TWIE)|(0<<TWINT)| //DisableInterupt
(0<<TWEA)|(0<<TWSTA)|(0<<TWSTO)| // Do not acknowledge on
anynewrequests.
(0<<TWWC); //
break;
caseTWI_SRX_GEN_ACK: //Generalcalladdresshasbeenreceived;ACKhas
beenreturned
// caseTWI_SRX_GEN_ACK_M_ARB_LOST://ArbitrationlostinSLA+R/WasMaster;General
calladdresshasbeenreceived;ACKhasbeenreturned
TWI_statusReg.genAddressCall=TRUE;
case TWI_SRX_ADR_ACK: // Own SLA+W has been received ACK has been
returned
// case TWI_SRX_ADR_ACK_M_ARB_LOST: // Arbitration lost in SLA+R/W as Master; own
SLA+Whasbeenreceived;ACKhasbeenreturned
// Dont need to clear
TWI_S_statusRegister.generalAddressCallduetothatitisthedefaultstate.
TWI_statusReg.RxDataInBuf=TRUE;
TWI_bufPtr = 0; // Set buffer pointer to first

datalocation
//ResettheTWIInteruptto
waitforanewevent.
TWCR=(1<<TWEN)| //TWIInterfaceenabled
(1<<TWIE)|(1<<TWINT)| // Enable TWI Interupt and
cleartheflagtosendbyte
(1<<TWEA)|(0<<TWSTA)|(0<<TWSTO)| // Expect ACK on this
transmission
(0<<TWWC); //
break;
caseTWI_SRX_ADR_DATA_ACK: //PreviouslyaddressedwithownSLA+W;datahas
beenreceived;ACKhasbeenreturned
case TWI_SRX_GEN_DATA_ACK: // Previously addressed with general call; data has
beenreceived;ACKhasbeenreturned
TWI_buf[TWI_bufPtr++] =TWDR;
TWI_statusReg.lastTransOK = TRUE; // Set flag transmission
successfull.
//ResettheTWIInteruptto
waitforanewevent.
TWCR=(1<<TWEN)| //TWIInterfaceenabled
(1<<TWIE)|(1<<TWINT)| // Enable TWI Interupt and
cleartheflagtosendbyte
(1<<TWEA)|(0<<TWSTA)|(0<<TWSTO)| // Send ACK after next
reception
(0<<TWWC); //
break;
caseTWI_SRX_STOP_RESTART: //ASTOPconditionorrepeatedSTARTconditionhas
beenreceivedwhilestilladdressedasSlave
// Put TWI Transceiver in
passivemode.
TWCR=(1<<TWEN)| //EnableTWIinterfaceand
releaseTWIpins
(0<<TWIE)|(0<<TWINT)| //DisableInterupt
(0<<TWEA)|(0<<TWSTA)|(0<<TWSTO)| // Do not acknowledge on
anynewrequests.
(0<<TWWC); //
break;
caseTWI_SRX_ADR_DATA_NACK: //PreviouslyaddressedwithownSLA+W;datahas
beenreceived;NOTACKhasbeenreturned
caseTWI_SRX_GEN_DATA_NACK: //Previouslyaddressedwithgeneralcall;datahas
beenreceived;NOTACKhasbeenreturned
case TWI_STX_DATA_ACK_LAST_BYTE: // Last data byte in TWDR has been transmitted
(TWEA=??;ACKhasbeenreceived
// case TWI_NO_STATE // No relevant state information available; TWINT

=??
caseTWI_BUS_ERROR: //BuserrorduetoanillegalSTARTorSTOPcondition
default:
TWI_state = TWSR; // Store TWI State as
errormessage,operationalsoclearstheSuccessbit.
TWCR=(1<<TWEN)| //EnableTWIinterfaceand
releaseTWIpins
(0<<TWIE)|(0<<TWINT)| //DisableInterupt
(0<<TWEA)|(0<<TWSTA)|(1<<TWSTO)| // Do not acknowledge on
anynewrequests.
(0<<TWWC); //
}
}

//
// BootLoader main bootloader
// Bootloader BootLoader
//

// Flash
staticBOOTLOADER_SECTIONvoidBootLoader_WriteOnePage(BYTE*pBuffer)
{

UINT

PagePointer;

if(g_BL_FlashAddr<BL_ADDR)

boot_page_erase(g_BL_FlashAddr); // Flash

boot_spm_busy_wait();

for(PagePointer=0;PagePointer<SPM_PAGESIZE;PagePointer+=2)

boot_page_fill(g_BL_FlashAddr + PagePointer, pBuffer[PagePointer] |


((pBuffer[PagePointer+1]<<8)));// WORD2 BYTE

boot_page_write(g_BL_FlashAddr); //
Flash

boot_spm_busy_wait();
//

g_BL_FlashAddr+=SPM_PAGESIZE;

g_BL_CurrentInfo.CurrentAddr=g_BL_FlashAddr/SPM_PAGESIZE;

}
}

//CRC16
staticBOOTLOADER_SECTIONvoidCRC16(BYTE*buf,intnSize,BYTE*pHighByte,BYTE*pLowByte)
{

unsignedintj;

unsignedchari;

unsignedintt;

unsignedintcrc;

crc=0;

for(j=nSize;j>0;j)

// CRC

crc=(crc^(((unsignedint)*buf)<<8));

for(i=8;i>0;i)

t=crc<<1;

if(crc&0x8000)

t=t^0x1021;

crc=t;

buf++;

*pHighByte=crc/256;

*pLowByte=crc%256;
}

//
staticBOOTLOADER_SECTIONvoidquit()
{

boot_rww_enable(); //
TWCR = (0<<TWEN)| // Disable TWIinterface and
releaseTWIpins
(0<<TWIE)|(1<<TWINT)| //DisableInterupt
(0<<TWEA)|(0<<TWSTA)|(1<<TWSTO)| // Do not acknowledge on any
newrequests.
(0<<TWWC); //

(*((void(*)(void))PROG_START))(); //'jmp0'
}

staticBOOTLOADER_SECTIONvoidTWIProcess()
{
BYTE
*pMessageBuf=0;

BYTE
CRCHigh=0;

BYTE
CRCLow=0;

BYTE
nInternalAddr=0;

//TWI
if(!TWI_Transceiver_Busy())
{

//

if(TWI_statusReg.lastTransOK)

//

if(TWI_statusReg.RxDataInBuf)

pMessageBuf=TWI_Get_Data_Pointer_From_Transceiver();

nInternalAddr=pMessageBuf[0];

pMessageBuf=&pMessageBuf[1];

//TWI_Get_Data_From_Transceiver(messageBuf,2);

// 0

if(TWI_statusReg.genAddressCall)

//0

else

//

/*

if(PINB&(1<<PB2))

PORTB&=~(1<<PB2);

else

PORTB|=(1<<PB2);

*/

//

//

//

if(nInternalAddr==BOOTLOADER_ADDR_START_USER_APP)

//

quit();

while(1);

elseif(nInternalAddr==BOOTLOADER_ADDR_RESET)

g_BL_FlashAddr=0;

g_BL_CurrentInfo.CurrentAddr=0;

elseif(nInternalAddr==BOOTLOADER_ADDR_UPLOAD)

//

// SPM_PAGESIZE 2 CRC16

CRC16(pMessageBuf,SPM_PAGESIZE,&CRCHigh,&CRCLow);

if ((CRCHigh == pMessageBuf[SPM_PAGESIZE]) && (CRCLow ==


pMessageBuf[SPM_PAGESIZE+1]))

//CRC

//

BootLoader_WriteOnePage(pMessageBuf);

TWI_Get_Data_Pointer_From_Transceiver_Release();

//

//

elseif(nInternalAddr==BOOTLOADER_ADDR_GET_INFO)

TWI_Start_Transceiver_With_Data((BYTE*)&g_BL_CurrentInfo,sizeof(g_BL_CurrentInfo));

TWI_Get_Data_Pointer_From_Transceiver_Release();

//CheckiftheTWITransceiverhasalreadybeenstarted.

//Ifnotthenrestartittoprepareitfornewreceptions.

if(!TWI_Transceiver_Busy())

TWI_Start_Transceiver();

else

//

//TWI_Act_On_Failure_In_Last_Transmission(TWI_Get_State_Info());

TWI_Start_Transceiver();

}
}
}

/*
intmain(void)
{

while(1);

main1();

DDRB=(1<<DDB2)|(1<<DDB1)|(1<<DDB0);

while(1)

PORTB=(1<<PB2);

_delay_ms(200);

PORTB=0;

_delay_ms(200);

}
*/

4GPSNMEA M8

/*

AVRGPS

GPS NMEMA I2C


*/

#include<stdio.h>
#include<avr/io.h>
#include<avr/interrupt.h>
#include<util/delay.h>
#include<string.h>

#defineINT_ON

sei();
#defineINT_OFF

cli();

typedefstructtagGPSPosition
{

//float
fLon;

// Longitude

USHORT
nLonHigh;

USHORT
nLonLow;

BYTE
WE;

BYTE
Reserved1;

// AVR 8
1

// ARM PC 32

//float
fLat;

// Latitude

USHORT
nLatHigh;

USHORT
nLatLow;

BYTE
NS;

BYTE
Reserved2;
}GPSPOSITION;

#defineNOP

asm("nop");
#defineTX_BUFFER_SIZE20
#defineUDR_EMPTY(1<<UDRE)

BOOL

g_bState=FALSE;

//GPS
GPSPOSITION

g_Position={0};

BYTEtx_buffer[TX_BUFFER_SIZE]={0};
BYTEtx_wr_index=0;
BYTEtx_rd_index=0;
BYTEtx_counter=0;

voidGPS_Decode(BYTEnData)
{

/*

$GPRMC,121252.000,A,3958.3032,N,11629.6046,E,15.15,359.95,070306,,,A*54

$GPRMC,<1>,<2>,<3>,<4>,<5>,<6>,<7>,<8>,<9>,<10>,<11>,<12>*hh<CR><LF>

<1>UTC hhmmss

<2> A=V=

<3> ddmm.mmmm 0

<4> N S

<5> dddmm.mmmm 0

<6> E W

<7> 000.0~999.9 0

<8> 000.0~359.9 0

<9>UTC ddmmyy

<10> 000.0~180.0 0

<11> E W

<12> NMEA01833.00 A=D=E=N=


*/

static int
nDataIndex=0;

staticBOOL bDataFieldOK=FALSE;

static int nItemIndex=0;

static charszBuffer[15]={0};

static char*pBufferIndex=0;

BYTEi=0;

USHORT nData1=0;

USHORT nData2=0;

if(nData=='$')

//

nDataIndex=0;

nItemIndex=0;

pBufferIndex=&szBuffer[0];

bDataFieldOK=FALSE;

else

nDataIndex++;

if((nDataIndex==5)&&(nData=='C'))
// 6 C GPS
$GPRMC

if(!g_bState)

PORTB|=(1<<PB0);

//

bDataFieldOK=TRUE;

elseif((nDataIndex==5)&&(nData!='C')) // $GPRMC

//

if((bDataFieldOK)&&(nDataIndex>6))

//

if((nData==',')||(nData=='*'))

PORTB&=~(1<<PB0);

*pBufferIndex=0;
//

//

switch(nItemIndex)

case0:

//UTC hhmmss

//TRACE("UTCTime:%s",szBuffer);

break;

case1:

// A=V=

//TRACE(":%s",szBuffer);

if(strcmp(szBuffer,"A")==0)

PORTB|=(1<<PB2);

g_bState=TRUE;

else

PORTB&=~(1<<PB2);

g_bState=FALSE;

break;

case2:

// ddmm.mmmm 0

// AVR Intel32

//g_Position.fLat=atof(szBuffer);

for(i=0;i<sizeof(szBuffer);i++)

if(szBuffer[i]=='.')

szBuffer[i]=0;

nData1=atoi(szBuffer);

nData2=atoi(&szBuffer[i+1]);

g_Position.nLatHigh=nData1;

g_Position.nLatLow=nData2;

break;

break;

case3:

// N S

g_Position.NS=szBuffer[0];

break;

case4:

// dddmm.mmmm 0

//g_Position.fLon=atof(szBuffer);

// AVR Intel32

for(i=0;i<sizeof(szBuffer);i++)

if(szBuffer[i]=='.')

szBuffer[i]=0;

nData1=atoi(szBuffer);

nData2=atoi(&szBuffer[i+1]);

g_Position.nLonHigh=nData1;

g_Position.nLonLow=nData2;

break;

break;

case5:

// E W

g_Position.WE=szBuffer[0];

break;

case6:

// 000.0~999.9 0

break;

case7:

// 000.0~359.9 0

break;

case8:

//UTC ddmmyy

break;

case9:

// 000.0~180.0 0

break;

case10:

// E W

break;

case11:

// NMEA01833.00 A=D=
E=N=

// $GPRMC

// 1s

//

g_bAllowGetTemperature=FALSE;

break;

default:

break;

//

nItemIndex++;

//

pBufferIndex=&szBuffer[0];
}
else
{

//

*pBufferIndex=nData;

pBufferIndex++;
}

5GPS NMEA ddmm.mmmm GoogleEarth

GPS ddmm.mmmm 3958.2399 39 dd


58 2 GoogleEarth
2399 GoogleEarch *60

3958.2399
39 58
2399 0.2399*60=0.2399*60=14.394
GoogleEarth 39 58 14.394 39 58'14.394''
GoogleEarth

You might also like