📄 wor.c
字号:
/*******************************************************************************************************
* *
* ********** *
* ************ *
* *** *** *
* *** +++ *** *
* *** + + *** This example shows how to use the Wake-on-Radio function of the CCxx00 *
* *** + in a simple burst mode Wake-on-Radio application. *
* *** + + *** *
* *** +++ *** Wor.c *
* *** *** *
* ************ *
* ********** *
* *
*******************************************************************************************************
* Compiler: Keil C51 V7.50 *
* Target platform: Chipcon CCxxx0 (Silabs F320) *
* Author: ESY *
*******************************************************************************************************
* Revision history: See end of file *
*******************************************************************************************************/
#include <Chipcon\srf04\regssrf04.h>
#include <Chipcon\srf04\halsrf04.h>
#include <Chipcon\srf04\ebsrf04.h>
#include <Wor.h>
//-------------------------------------------------------------------------------------------------------
// DESCRIPTION:
// This example is a simple implementation of a control system for a radio-controlled object.
// The system is modeled as a simplex system with a transmitter sending packets with control
// commands to a receiver. WOR is used to reduce power consumption at the receiver side.
// One evaluation board (EB) is set up as transmitter, and the other as a receiver (RX/WOR unit).
// If the joystick position is changed on the transmitter board, data containing info about
// the new position are transmitted to the receiver and the joystick position is displayed on
// the LCD of this EB. Please see App. Note 38 for more details.
//
// RX UNIT:
// * Move joystick right to choose RX
// * Push the S1 button to confirm your choice.
// After the unit has been configured, the yellow LED will be on.
//
// GLED: Toggles when a packet has been received successfully.
// RLED: Toggles when an invalid packet has been received.
// BLED: Toggles when a packet is received and an interrupt is given to the MCU.
//
// TX UNIT:
// * Move joystick left to choose TX
// * Push the S1 button to confirm your choice.
// After the unit has been configured, the yellow LED will turn on.
//
// BLED: Toggles when a packet has been sent.
//
// On the transmittter, you are now able to push the joystick button or move it up,
// down, left or right. This will start the packet burst. When all the packets (305) are transmitted
// "Done" will be displayed at the LCD. One should not move the joystick to a new position before
// the previous burst transmission has completed.
//
// The receiver will automatically enter the WOR mode, waiting for packets.
//
// The LCD will continuously display how many valid packets have been received together with
// the position of the joystick on the transmitter.
//
// The program can be terminated by pressing the S1 button after the setup has been done.
// This will turn off the yellow LED.
//
// Current config. specs
//
// Common Settings:
// Packet format = 4B preamble + 4B sync word + 1B payload + 2B CRC = 11 Bytes
//
// TX Unit Settings:
// Packet interval: 1.0 ms
// Packet send time: ~ 11 B * 8 bit/B / 250 kbps = 352 us
// Tx duty cycle: ~ 352 us / 1.0 ms = 35.2 %
//
// RX/WOR Unit Settings:
// Event0 timeout: 300 ms
// Event1 timeout: ~ 345 us (f_xosc = 26 MHz)
// Rx timeout: ~ 1.172 ms
// Rx duty cycle: ~ 1.172 ms / 300 ms = 0.391 %
//-------------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------------
// Global Variables
UINT8 xdata joystickPosition = JOYSTICK_CENTER;
UINT8 xdata prevJoystickPosition = JOYSTICK_CENTER;
UINT8 xdata mode = MODE_NOT_SET; // Variable used to hold the mode when setting up the unit in the menu
UINT32 xdata packetsSent = 0;
UINT32 xdata packetsReceived = 0;
// TX & RX FIFO buffer arrays
BYTE xdata txBuffer[1]; // Fixed packet length: 1B payload
BYTE xdata rxBuffer[1]; // Max received packet length = 1B (All packets longer then 1 byte
// will not be put in the RX FIFO due to packet length filtering
BYTE xdata asciiString[11]; // Byte array used by the intToAscii(UINT32 value) function
BYTE xdata asciiJoystickPosition[] = "Joystick: ";
BYTE xdata asciiPackets[] = "Pkts rcvd: ";
UINT8 xdata updateLcd = FALSE;
UINT16 xdata burstCount = 0; // Number of packets sent of current burst
BOOL burstDone = FALSE; // Flag set on the transmitter when all 305 packets are transmitted
//-------------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------------
// void main(void)
//
// DESCRIPTION:
// This function takes care of all the MCU initialization and the radio settings which is common
// for both the receiver and the transmitter.
//-------------------------------------------------------------------------------------------------------
void main (void) {
UINT8 xdata length = 0;
#ifdef STAND_ALONE
// Select the Internal Oscillator as Multiplier input source and disable the watchdog timer
// SYSCLK = 4X Clock Multiplier / 2
CLOCK_INIT();
#endif
// Set up the crossbar and I/O ports to communicate with the SmartRF04EB peripherals
IO_PORT_INIT();
// Initialize the LCD display. The SMBus uses timer 0 to generate SCL
ebLcdInit();
// Initialize the ADC converter
ebAdcInit(ADC_JOY);
SPI_INIT(SCLK_6_MHZ);
POWER_UP_RESET_CCxxx0();
halRfWriteRfSettings(&rfSettings);
halSpiWriteReg(CCxxx0_PATABLE, paTable);
// Starts menu for setting up EB unit to either "TX" or "RX/WOR" unit.
showMenu();
// Remote control
if (mode == TX) {
ebLcdUpdate("Tx unit...", "(Move joystick)");
runTransmitter();
// Remote-controlled object
} else {
ebLcdUpdate("Rx/WOR unit...", NULL);
runReceiver();
}
}// Main
//-------------------------------------------------------------------------------------------------------
// void runTransmitter(void)
//
// DESCRIPTION:
// This function is used to monitor the joystick position on the remote control. Every time the
// position changes, a packet burst is started (i.e. rapid repetition of a fixed number of
// identical packets containing information on the joystick position). These packets are used to
// wake up the WOR receiver. The packets are sent with a 1.0 ms interval, and 305 packets are
// transmitted in each burst.
//-------------------------------------------------------------------------------------------------------
void runTransmitter(void) {
// Initialize transmitter
initTransmitter();
SET_YLED(LED_ON); // Turn on yellow LED to indicate unit is running
// Loops forever. Press S1 for abortion.
while(!ebButtonPushed()) {
joystickPosition = ebGetJoystickPosition();
//If joystick is moved, start burst of packets
if (joystickPosition != prevJoystickPosition) {
prevJoystickPosition = joystickPosition;
// Disable interrupts while updating LCD + calibrating
INT_ENABLE(INUM_TIMER1, INT_OFF);
// Calibrate
halSpiStrobe(CCxxx0_SCAL);
// Setting correct payload into packet corresponding to joystick position
txBuffer[0] = joystickPosition;
// Starting burst of packets
burstCount = 0;
ebLcdUpdate("Bursting...", NULL);
INT_ENABLE(INUM_TIMER1, INT_ON); // Enable timer for packet burst interval
SET_BLED(LED_ON); // Set blue LED to indicate burst in progress
}
if (burstDone) {
ebLcdUpdate("Done", NULL);
burstDone = FALSE;
}
}
// Button S1 pressed for abortion
INT_ENABLE(INUM_TIMER1, INT_OFF); // Disable timer1 interrupts
SET_YLED(LED_OFF);
}// runTransmitter
//-------------------------------------------------------------------------------------------------------
// void initTransmitter(void)
//
// DESCRIPTION:
// This function is configuring some transmitter specific radio register settings and initializes
// interrupt timers for the transmitter unit.
// Timer1 is set up to overflow every 1000 us (Tx packet interval)
//
// 1/6000000 Hz * x = 1000 us => x = 6000
// 2^16 - 6000 = 59536 = 0xE890
// => TH1 = 0xE8
// => TL1 = 0x90
//-------------------------------------------------------------------------------------------------------
void initTransmitter(void) {
// Setup and initialize Timer1 to overflow every 1000 us (Tx packet interval)
TH1 = 0xE8; // Timer1 high byte
TL1 = 0x90; // Timer1 low byte
// Clock source: 6 MHz, Mode: 16-bits timer. Initialized with interrupts off.
halSetupTimer01(TIMER_1, SYSCLK_DIV_4, MODE_1, INT_OFF);
}// initTransmitter
//-------------------------------------------------------------------------------------------------------
// void runReceiver(void)
//
// DESCRIPTION:
// This function is used to put the radio in SLEEP mode using WOR. If the MCU detects that a packet
// is received, this function is used to update the LCD display in accordance with the packet
// data received.
//-------------------------------------------------------------------------------------------------------
void runReceiver(void) {
UINT8 i;
// Initialize receiver
initReceiver();
SET_YLED(LED_ON); // Turn on yellow LED to indicate unit is running
// Put the radio to SLEEP by starting Wake-on-Radio.
halSpiStrobe(CCxxx0_SWORRST); // Resets the real time clock
halSpiStrobe(CCxxx0_SWOR); // Starts Wake-on-Radio
// The MCU could here enter some power-down state to reduce power consumption while waiting for a
// WOR interrupt from the CCxx00 radio (this is not implemented here in this example
// - instead there is a while loop updating the LCD).
// Loops forever updating LCD with the received data. Button S1 for abortion.
while(!ebButtonPushed()) {
if (updateLcd) { // This flag is set in EXTERNAL1_ISR if the LCD needs to be updated
updateLcd = FALSE;
intToAscii(packetsReceived);
// Copying chars for better LCD presentation
for (i = 0; asciiString[i] >= '0' && asciiString[i] <= '9'; i++)
asciiPackets[11 + i] = asciiString[i];
asciiPackets[11 + i] = NULL;
ebLcdUpdate(asciiPackets, asciiJoystickPosition);
}
}
//Button S1 has been pressed for abortion
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -