Professional Documents
Culture Documents
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
AD
SD M8 I2C I2CBootLoader
SD BIN
PPM /
SD
SD PPM /3 /3
GPSZigBee
2 1.27
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
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;
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
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
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
#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()
#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.
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;
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()
{
TWI_msgSize=0;
}
*/
/*
static BOOTLOADER_SECTION void TWI_Prepare_Transceiver_With_Data( unsigned char *msg,
unsignedintmsgSize)
{
unsignedinttemp;
for(temp=TWI_msgSize;temp<TWI_msgSize+msgSize;temp++) //Copydatathat
maybetransmittediftheTWIMasterrequestsdata.
{
TWI_buf[temp]=msg[tempTWI_msgSize];
TWI_msgSize+=msgSize;
}*/
/*
staticBOOTLOADER_SECTIONvoidTWI_Start_TransceiverData()
{
TWI_statusReg.all=0;
TWI_state =TWI_NO_STATE;
TWCR=(1<<TWEN)| //TWIInterfaceenabled.
(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;
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.
}
}
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_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);
//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
#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
*/
static int
nDataIndex=0;
staticBOOL bDataFieldOK=FALSE;
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++;
}
3958.2399
39 58
2399 0.2399*60=0.2399*60=14.394
GoogleEarth 39 58 14.394 39 58'14.394''
GoogleEarth