📄 demozrfdapp.c
字号:
starttime1=TickGet();
iii=TMR0L;
starttime1&=0x07FF; //add by zwcai
starttime1|=iii;
for(iii=0;iii<starttime1;iii++) CLRWDT();
SEND(ACK_QUER);
starttime1=TickGet();
ResetsubmacCurrentFrame();
}
}
else
if(TickGetDiff(TickGet(), starttime1) >=MAC_WAITFOR_QUERY_DURATION )
{thisnode.NODESTATE=GROUP_CAPTAIN;
thisnode.MEMBERNUM=0;
starttime1=TickGet();
ConsolePutROMString("Wait for captain query time out!This node is changed to be a captain!\r\n");
smApp=SM_APP_CAPTAINSLEEP;
}
}
}
break;
}
}
}
}
//判断新团长
void JudgeNewCaptain()
{if(submacCurrentFrame.data[0]>thisnode.MEMBERNUM)
{Newcaptain[0]= submacCurrentFrame.sub_source_addr.v[0];
Newcaptain[1]= submacCurrentFrame.sub_source_addr.v[1];}
else
{Newcaptain[0]= thisnode.NODEID[0];
Newcaptain[1]= thisnode.NODEID[1];}
}
BOOL GROUPUpdate()
{BYTE i;
BYTE k;
//如果新团长为自己,更新成员表及节点其他信息
if(Newcaptain[0]== thisnode.NODEID[0]&&Newcaptain[1]==thisnode.NODEID[1])
{k=thisnode.MEMBERNUM*2;
i=1;
while(i<=submacCurrentFrame.data[0]*2)
{thisnode.MEMBER_OR_CAPTAIN [k]=submacCurrentFrame.data[i];
thisnode.MEMBER_OR_CAPTAIN [k+1]=submacCurrentFrame.data[i+1];
k=k+2;
i=i+2;
}
thisnode.MEMBER_OR_CAPTAIN [k]=submacCurrentFrame.sub_source_addr.v[0];
thisnode.MEMBER_OR_CAPTAIN[k+1]=submacCurrentFrame.sub_source_addr.v[1];
thisnode.MEMBERNUM=thisnode.MEMBERNUM+submacCurrentFrame.data[0]+1;
return TRUE;
}
//如果新团长不是自己,将该节点置为团员态并广播新团长
else
{SEND(CAPTAIN_INF);
thisnode.NODESTATE=GROUP_MEMBER;
thisnode.MEMBERNUM=0;
thisnode.MEMBER_OR_CAPTAIN[0]=submacCurrentFrame.sub_source_addr.v[0];
thisnode.MEMBER_OR_CAPTAIN[1]=submacCurrentFrame.sub_source_addr.v[1];
ConsolePutROMString("this node's captain is:");
ConsolePutInitData(thisnode.MEMBER_OR_CAPTAIN[1],thisnode.MEMBER_OR_CAPTAIN[0]);
return FALSE;
}
}
void ResetsubmacCurrentFrame()
{submacCurrentFrame.sub_type.Val=0xff;
}
/*BOOL INTCOUNT(TICK START,TICK CURRENT,TICK DURATION)
{TICK c;
c=TickGetDiff(CURRENT,START);
if(c<DURATION)
return FALSE;
while(c>DURATION)
c=c-DURATION;
if(c==DURATION)
{START=CURRENT;
return TRUE;
}
else {START=CURRENT-c;
return FALSE;
}
}*/
static BOOL IsMACAddrAssigned(void)
{
// Read MAC long address from app-specific nonvolatile memory.
NVMRead(&macInfo.longAddr,
(ROM void*)&macLongAddr,
sizeof(macInfo.longAddr));
// An address is said to be invlaid if its OUI matches with our preset OUI
if ( macInfo.longAddr.v[7] != MAC_LONG_ADDR_BYTE7 ||
macInfo.longAddr.v[6] != MAC_LONG_ADDR_BYTE6 ||
macInfo.longAddr.v[5] != MAC_LONG_ADDR_BYTE5 )
return FALSE;
else
return TRUE;
}
// Callback to application to notify of a frame transmission.
void AppMACFrameTransmitted(void)
{
// Turn on LED to indicate activity. TMR0IF interrupt will turn it off.
// See interrupt handler.
// if ( !appFlags.bits.bInConfigMode )
// D2 = 1;
}
// Callback to application to notify of a frame reception
void AppMACFrameReceived(void)
{
// Turn on LED to indicate activity. TMR0IF interrupt will turn it off.
// See interrupt handler.
submacCurrentFrame.sub_type.Val=MACGet();
submacCurrentFrame.sub_dest_addr.v[0]=MACGet();
submacCurrentFrame.sub_dest_addr.v[1]=MACGet();
submacCurrentFrame.sub_source_addr.v[0]=MACGet();
submacCurrentFrame.sub_source_addr.v[1]=MACGet();
submacCurrentFrame.databytenum=MACGet();
MACGetArray(submacCurrentFrame.data, submacCurrentFrame.databytenum);
//ConsolePutROMString("receive!");
// if ( !appFlags.bits.bInConfigMode )
// D2 = 1;
}
// Callback to application to notify of an ack timeout
void AppMACFrameTimeOutOccurred(void)
{
}
// Callback to an end device.
// Called when a suitable coordinator is found as part of associate process.
// Return TRUE if okay to associate.
// May use PANDesc.for more information about this coordinator.
// See MAC.h for definition of PANDesc.
BOOL AppOkayToAssociate(void)
{
return TRUE;
}
BOOL AppOkayToUseChannel(BYTE channel)
{
// This demo uses all available channels
// You may check given channel against your allowable channels and return TRUE
// or FALSE as needed.
// For 2.4GHz, channel = 11 through 26.
DEBUG_OUT("Now operating in next channel.\r\n");
return TRUE;
}
static void InitializeBoard(void)
{
// This is a RS232 console - you may replace it with any console you like.
ConsoleInit();
// Switches S2 and S3 are on RB5 and RB4 respectively. We want interrupt-on-change
INTCON = 0x00;
// There is no external pull-up resistors on S2 and S3. We will use internal pull-ups.
// The CC2420 provides SFD (Start of Frame Detect) signal on RB2. We are using
// the falling edge of that signal to generate INT2
// Enable PORTB internal pullups, INT2 on falling edge
INTCON2 = 0x00;
// Enable INT2 interrupt - SFD from CC2420
INTCON3 = 0xD0;
// Make PORTB as input - this is the RESET default
TRISB = 0xff;
// Set PORTC control signal direction and initial states
// Start with CC2420 disabled and not selected
LATC = 0xfd;
// Set the SPI module for use by Stack
TRISC = 0xD0;
// Set the SPI module
SSPSTAT = 0xC0;
SSPCON1 = 0x20;
// D1 and D2 are on RA0 and RA1 respectively, and CS of TC77 is on RA2.
// Make PORTA as digital I/O.
// The TC77 temp sensor CS is on RA2.
ADCON1 = 0x0F;
// Deselect TC77 (RA2)
LATA = 0x04;
// Make RA0, RA1, RA2 and RA4 as outputs.
//TRISA = 0xE0;
TRISA = 0xC0;
// Enable global interrupts.
GIEL = 1;
GIEH = 1;
//test if error
if ( TO == 0 )
{
// Clear watchdog to set TO bit.
CLRWDT();
// Clear flags so that we can detect it next time.
STKPTR &= 0x3F;
RCON |= 0x1F;
// Display message on terminal.
ConsolePutROMString(resetMsg);
// Since core is going to sleep in coming lines, make sure that
// UART finishes its transmission.
while( !ConsoleIsPutReady() );
// Disable all interrupts
INTCON = 0;
// Prepare for alternating flashing LED sequence.
D1 = 0;
D2 = 1;
// On this error, blink LEDs.
while(1)
{
CLRWDT();
// This is to make sure that we don't waste battery.
// At least one LED is always ON so saving would not be
// that much - actual application may do something different.
SLEEP();
NOP();
D1 ^= 1;
D2 ^= 1;
}
}
}
// NOTE: Several PICs, including the PIC18F4620 revision A3 have a RETFIE FAST/MOVFF bug
// The interruptlow keyword is used to work around the bug when using C18
// To work around the bug on PICC-18, configure the compiler to Compile for ICD
#if defined(MCHP_C18)
#pragma interruptlow HighISR
void HighISR(void)
#elif defined(HITECH_C18)
void interrupt HighISR(void)
#else
void HighISR(void)
#endif
{
// This is a quick way to display MAC TX/RX status on RD1 LED.
// TMR0IF is also used by TickUpdate, so we will let it clear the flag.
if ( !appFlags.bits.bInConfigMode )
{
if ( TMR0IF )
D2 = 0;
}
// Must call this so that MAC module can determine if a transmission is progress or not.
MACISR();
// Must call this so that tick manager can update its tick count.
TickUpdate();
// Is this a interrupt-on-change interrupt?
if ( RBIF == 1 )
{
// Clear mismatch condition and flag
if ( S2 == 0 )
appFlags.bits.S2Toggled = TRUE;
if ( S3 == 0 )
appFlags.bits.S3Toggled = TRUE;
// Disable further RBIF until we process it
RBIE = 0;
// Clear mis-match condition
LATB = PORTB;
RBIF = 0;
}
}
#if defined(MCHP_C18)
#pragma code highVector=0x08
void HighVector (void)
{
_asm goto HighISR _endasm
}
#pragma code /* return to default code section */
#endif
#if defined(MCHP_C18)
#pragma code lowhVector=0x18
void LowVector (void)
{
_asm goto HighISR _endasm
}
#pragma code /* return to default code section */
#endif
static void ConfigTask(void)
{
MENU_CMD c;
ConsolePutROMString(menu);
// While in config mode, disable PORTB interrupt-on-change.
RBIE = 0;
// Turn D1 & D2 ON to indicate that we are in config mode.
D1 = 1;
D2 = 1;
// Wait for S3 to get released
while( S3 == 0 );
while( 1 )
{
// Check to see if there was any key press in terminal.
if ( ConsoleIsGetReady() )
{
// Get the key value.
c = ConsoleGet();
// If this is a valid command, execute it.
if ( ExecuteMenuChoice(c) )
// After completion of every menu command or invalid command
// redisplay the menu message.
ConsolePutROMString(menu);
else // Quit command is executed
{
// Display message and quit
ConsolePutROMString(exitMsg);
break;
}
}
}
// Turn OFF D1 & D2 to indicate that we are leaving config mode.
D1 = 0;
D2 = 0;
}
static BOOL ExecuteMenuChoice(MENU_CMD choice)
{
LONG_ADDR longAddr;
BYTE *p;
char idString[5];
WORD_VAL idValue;
switch(choice)
{
case MENU_CMD_SET_ID:
// Node id is combined with Microchip OUI to create 8-byte MAC address.
p = &longAddr.v[7];
// Preset the OUI and three other bytes.
*p-- = MAC_LONG_ADDR_BYTE7;
*p-- = MAC_LONG_ADDR_BYTE6;
*p-- = MAC_LONG_ADDR_BYTE5;
*p-- = 0x00;
*p-- = 0x00;
*p-- = 0x00;
// Prompt the user.
ConsolePutROMString(idEntryMsg);
if ( ConsoleGetString(idString, sizeof(idString)-1) )
{
// Convert string to 16-bit integer
idValue.Val = (WORD)atoi(idString);
// Make sure that it is a valid number.
if ( idValue.Val > 0xfffe )
{
ConsolePutROMString(invalidValueMsg);
// Wait for user to acknowledge the message.
while ( !ConsoleIsGetReady() );
}
else
{
// Save it locally
*p-- = idValue.v[1];
*p = idValue.v[0];
// Now that we have complete board id, save the info into nonvolatile memory.
SaveMACLongAddr(&longAddr);
// Update MAC address info
memcpy((void*)&macInfo.longAddr, (void*)&longAddr, (size_t)sizeof(macInfo.longAddr));
// Now ask MAC to set the address
MACUpdateAddressInfo();
}
}
else
{
ConsolePutROMString(invalidValueMsg);
}
break;
case MENU_CMD_QUIT:
return FALSE;
}
return TRUE;
}
void ConsolePutInitData(int highval,int lowval)
{
char i;
BYTE dig;
long divider;
int wordvalue;
wordvalue=highval*256+lowval;
divider=10000;
for(i=5; divider>wordvalue && i>1 ;i--)
{
divider/=10;
ConsolePut(' ');
}
for(;i>0;i--)
{
dig = (wordvalue/divider);
wordvalue = (wordvalue%divider);
ConsolePut(dig+0x30);
divider/=10;
}
ConsolePut('\r');
ConsolePut('\n');
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -