📄 an_008.c
字号:
/****************************************************************************/
/* Application note AN008 */
/* Oversampling and data decision for the CC400/CC900 */
/* */
/* File: AN_008.c */
/* */
/* Microcontroller: */
/* Microchip PIC16F87x or compatible */
/* By changing hardware- and compiler-dependant code, */
/* this code can be used with any C compiler. */
/* Code was developed and tested using IAR's C Compiler for */
/* mid-range PIC MCUs and a PIC16F877 MCU. */
/* */
/* Author: Code written by Karl H. Torvmark based on an assembly */
/* language program by Kjell Tore Heien. */
/* */
/* Contact: Chipcon AS +47 22 95 85 44 */
/* support@chipcon.com */
/* */
/****************************************************************************/
/****************************************************************************/
/* DESCRIPTION */
/* */
/* General */
/* */
/* This code implements oversampling of the output signal from a CC400/ */
/* CC900 RF-transceiver. The output signal from the transceiver is coded in */
/* Manchester format. The MCU converts this signal to an NRZ signal by */
/* taking 8 samples per bit. Signal decision is by majority vote based on */
/* these samples, filtering out noise. */
/* */
/* The MCU is also used during transmission. The MCU then reads NRZ-coded */
/* data, and passes it on to the RF transceiver in Manchester format. */
/* */
/* A power down mode is also implemented. The MCU puts the CC400/CC900 into */
/* power down mode, then puts itself to sleep. It will awaken on a mode */
/* change. Mode changes are controlled by setting the RX_TX and PD pins. */
/* The MCU configures the CC400/CC900 for the appropriate mode by sending */
/* it configuration data on the PDATA/CLOCK/STROBE pins. */
/* */
/****************************************************************************/
/* This code must be adapted to fit the user application. Transmission */
/* rates and RF configuration data can be changed by changing the */
/* appropriate constants. The values for the configuration data should be */
/* calculated using SmartRF studio, and pasted into the source code. */
/* */
/* As written, the MCU merely functions as a protocol translator between */
/* an application circuit communicating using NRZ data, and the RF chip */
/* using Manchester coding. In a typical application, the MCU will have */
/* other functions, this must be added to the software. This software as */
/* written does not insert the required preamples in front of data */
/* messages, this is left to the application circuit or to additional */
/* software written by the user. */
/* */
/****************************************************************************/
/* Implementation */
/* */
/* An assembly language version of this program also exists. Chipcon */
/* recommends using the assembly version rather than this C program, as the */
/* assembly language program is faster and provides better timing. */
/* This 'C' version of the software was written to make it easier for the */
/* customer to understand the logic behind the algorithm. */
/* However, for low baud-rates (1200 bps or lower), the 'C' version is fast */
/* enough to be useable. */
/* */
/* This code was written and tested using the IAR C compiler for PIC16x MCUs*/
/* It was tested using a PIC16F877. The program should be easy to port */
/* to other PIC MCUs by changing the I/O port definitions. */
/* For maximum performance, it should be compiled using maximum speed */
/* optimisation in the compiler. */
/* */
/* Mode configuration: */
/* */
/* ********************************************************* */
/* * PIN * MODE * */
/* ************************* * */
/* * PD * RX_TX * * */
/* ********************************************************* */
/* * 0 * 0 * Transmit mode (TX) * */
/* * 0 * 1 * Receive mode (RX) * */
/* * 1 * X (Don't care) * Power-down mode (PD) * */
/* ********************************************************* */
/* */
/* Timing in TX mode: */
/* _ _ _ _ _ _ _ _ _ */
/* CLK_OUT _/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ */
/* */
/* DATA_IN pin (NRZ) | b1| b2| b3| b4| b5| b6| b7| b8| b9| */
/* DATA_IN pin read R R R R R R R R R R */
/* _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ */
/* DIO pin (Manchester) |_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_| */
/* */
/* Timing in RX mode: */
/* _______ _______ _______ _______ _____ */
/* DIO pin (Manchester) |_______|_______|_______|_______|_____ */
/* Sample S S S S S S S S S S S S S S S S S S S */
/* _______ _______ */
/* CLOCK_OUT pin ________/ \_______/ \_____ */
/* _______________ _______________ _____ */
/* DATA_OUT pin |_______________|_______________|_____ */
/* */
/* | Bit 1 | Bit 2 | Bit 3 ...*/
/****************************************************************************/
#include "io16f877.h" /* Includes I/O definitions for 16F877 */
#include "inpic.h" /* Includes PIC intrinsic functions */
/* Definitions for boolean expressions */
#define TRUE (1==1)
#define FALSE !TRUE
/****************************************************************************/
/* Overview of port usage: */
/* */
/* PORT: PORTB User interface */
/* pin 0 CLK_OUT Clock out */
/* pin 1 DATA_IN Data in (TX mode) */
/* pin 2 DATA_OUT Data out (RX mode) */
/* pin 3 unused */
/* pin 4 PD System configuration (1=Power down) */
/* pin 5 RX_TX System configuration (1=RX, 0=TX) */
/* pin 6 unused */
/* pin 7 unused */
/* */
/* PORT: PORTC Communication with CC700/CC900 */
/* pin 0 PDATA Configuration pin */
/* pin 1 CLOCK Configuration pin */
/* pin 2 STROBE Configuration pin */
/* pin 3 DIO Bi-directional data pin */
/* pin 4 SYNC Synchronisation status */
/* pin 5 unused */
/* pin 6 unused */
/* pin 7 unused */
/****************************************************************************/
/* Pin usage definitions */
#define PDATA RC0
#define CLOCK RC1
#define STROBE RC2
#define DIO RC3
#define SYNC RC4
#define CLK_OUT RB0
#define DATA_IN RB1
#define DATA_OUT RB2
#define PD RB4
#define RX_TX RB5
/* Data quality constants */
/****************************************************************************/
/* These values can be changed to optimise the program for different data */
/* and noise characteristics. */
/* A_LIMIT_VAL - Decision limit. If A is smaller than this value, */
/* the signal is a logical '0', else signal is '1' */
/* A_LIMIT_VAL2 - Decision limit during synchronisation. If A is */
/* smaller than this value signal is regarded as a */
/* '0', else it is a '1'. This value should be */
/* larger than A_LIMIT_VAL, and must be larger than */
/* 4. */
/* COUNT_LIMIT_VAL - Sets the synchronisation length. The value */
/* determines how many 1's (A>=A_LIMIT_VAL2) */
/* the MCU must receive before it is synchronised. */
/* Should be >=4. The preamble sent by the */
/* transmitter should be longer than this, as the */
/* RF transceiver also needs time to synchronise. */
/* A_SYNC_LIMIT_HI, */
/* A_SYNC_LIMIT_LO - Sets the limits for a proper Manchester-coded */
/* bit. If A is between these thresholds for a */
/* number of bits (set by BIT_ERROR_LIMIT, */
/* described below), the MCU goes out of */
/* synchronisation. This can be used to detect when */
/* valid data is no longer received. The MCU then */
/* waits for a new preamble. */
/* BIT_ERROR_LIMIT - Determines how many invalid bits must be */
/* received before the MCU loses synchronisation. */
/****************************************************************************/
#define A_LIMIT_VAL 0x04
#define A_LIMIT_VAL2 0x05
#define COUNT_LIMIT_VAL 0x0A
#define A_SYNC_LIMIT_HI 0x05
#define A_SYNC_LIMIT_LO 0x03
#define BIT_ERROR_LIMIT 0x02
/****************************************************************************/
/* These values must be changed for different combinations of bit-rate and */
/* MCU clock frequency. They determine the frequency of the intermal TMR0 */
/* interrupt, used both in RX and TX mode. See documentation for details. */
/****************************************************************************/
/****************************************************************************/
/* Fosc = 20 MHz */
/****************************************************************************/
/* Data rate * TIMING_RX * Rate_RX * Error * TIMING_TX * Rate_TX * Error */
/****************************************************************************/
/* 2.4 kbps * 0x9E * 0xD0 * 0.160% * 0x0B * 0xD1 * 0.160% */
/* 1.2 kbps * 0x1C * 0xD0 * 0.160% * 0x03 * 0xD2 * 0.032% */
/* 600 bps * 0x0C * 0xD1 * 0.160% * 0x80 * 0xD4 * 0.257% */
/* 300 bps * 0x04 * 0xD2 * 0.160% * 0x7F * 0xD5 * 0.208% */
/****************************************************************************/
/* */
/* For other combinations of MCU clock frequencies and data-rates, see */
/* application note for values and formulas. */
/* */
/****************************************************************************/
/* Default values */
/* 20 MHz MCU clock, 1.2 kbps data rate */
/****************************************************************************/
#define RATE_RX 0xD0
#define RATE_TX 0xD4
#define TIMING_RX 0x1C
#define TIMING_TX 0xC1
/* The location of the interrupt handler vector. Must be changed for */
/* different PIC MCUs */
#define INTERRUPT_VECTOR 0x04
/* The CC400/CC900 configuration parameters can be modified here */
/* Calculate new values using SmartRF Studio */
/****************************************************************************/
/* Default values: */
/* */
/* Chip used : CC400 */
/* */
/* X-tal frequency : 12.000000 MHz */
/* X-tal accuracy : 50 ppm */
/* RF frequency : 433.920000 */
/* IF Stage : 200 kHz */
/* Frequency sep. : 10 kHz */
/* Data rate : 1.2 kbit/s */
/* Power amp. class: Class B */
/* RF output power : 10 dBm */
/* Receiver mode : Optimum sensitivity */
/* LOCK indicator : Continous */
/* VCO current : 000 (Maximum) */
/****************************************************************************/
/* A, B, C, D, E, F, G, H */
const short RX_CONFIG[8] =
{0x002A, 0x230B, 0x4141, 0x6771, 0x8A00, 0xB803, 0xD24C, 0xE450 };
const short TX_CONFIG[8] =
{0x082A, 0x230B, 0x4141, 0x67A4, 0x8A14, 0xB803, 0xD24C, 0xE860 };
const short PD_CONFIG[8] =
{0x182A, 0x230B, 0x4151, 0x6771, 0x8A00, 0xB803, 0xD24C, 0xE860 };
/* global variables shared by main program and interrupt routine */
char ShiftReg; /* All samples are shifted into this register */
char An0; /* The current value of A */
char An1; /* The value of A one sample ago */
char An2; /* The value of A two samples ago */
char Sample; /* Number of sample within bit, between 0 and 7 */
char Sync; /* Set to 1 if SW is synchronised, 0 otherwise */
char Count; /* Counts consecutive 1's received during synchronisation*/
char ResyncEnable; /* Set to 1 if resynchronisation should be performed */
/* the next interrupt */
char ALimit; /* Decision limit. If A>ALimit, the bit received is a 1 */
char ALimit2; /* Decision limit during synchronisation */
char CountLimit; /* Number of consequtive 1's requried to synchronise */
char Number; /* Is 0 during the first baud in TX mode, 1 during */
/* the second */
char Read; /* Used to store value read from DATA_IN in TX mode */
char BitErrors; /* Counts number of consecutive bad bits received */
enum {TXMODE=0, RXMODE=1, PDMODE=2} Mode;
/* Keeps track of which mode software is in */
/****************************************************************************/
/* This routine initialises the MCU. Must be modified for different */
/* applications. */
/****************************************************************************/
void Initialise(void)
{
/* Clear I/O port latches */
PORTC=0x00;
PORTB=0x00;
/* PORTC : Set Pin 0, 1, 2 and 4 as output, Pin 3 as input */
TRISC=0x08;
/* PORT B : Set Pin 0 and 2 as output, pin 1, 4 and 5 as input */
TRISB=0x32;
}
/****************************************************************************/
/* This routine sends new configuration data to the CC400/CC900. */
/****************************************************************************/
void ConfigureCCX00(short const Configuration[8])
{
char BitCounter;
char WordCounter;
union { /* This union is used to easily access the most */
/* significant bit of the configuration data */
unsigned short Data;
struct
{
unsigned short :1;
unsigned short :1;
unsigned short :1;
unsigned short :1;
unsigned short :1;
unsigned short :1;
unsigned short :1;
unsigned short :1;
unsigned short :1;
unsigned short :1;
unsigned short :1;
unsigned short :1;
unsigned short :1;
unsigned short :1;
unsigned short :1;
unsigned short MSB :1;
};
};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -