📄 rc24g.c
字号:
#include <avr/interrupt.h>
#include <avr/io.h>
#include <avr/wdt.h>
#include <avr/eeprom.h>
#include <avr/sleep.h>
#include <util/delay.h>
#include <util/crc16.h>
#include <inttypes.h>
#define SEL_HI() PORTB |= _BV(PB2)
#define SEL_LO() PORTB &= ~_BV(PB2)
#define MAX_CHANNELS 4
#define PACKAGE_LEN 6
#define SETTING 1 // 设置中
#define SAVESETTING 2 // 保存数据到E2PROM
#define SPI_WAIT() while (!(SPSR & (1<< SPIF)))
// CC2500 状态
#define CCxxx0_Ready() PINB & _BV(PB4)
#define CRC_OK 0x80
#define BYTES_IN_RXFIFO 0x7F
#define STATE_IDLE 0x01
// Definitions to support burst/single access:
#define WRITE_BURST 0x40
#define READ_SINGLE 0x80
#define READ_BURST 0xC0
// CC2500/CC1100 STROBE, CONTROL AND STATUS REGSITER
#define CCxxx0_IOCFG2 0x00 // GDO2 output pin configuration
#define CCxxx0_IOCFG1 0x01 // GDO1 output pin configuration
#define CCxxx0_IOCFG0 0x02 // GDO0 output pin configuration
#define CCxxx0_FIFOTHR 0x03 // RX FIFO and TX FIFO thresholds
#define CCxxx0_SYNC1 0x04 // Sync word, high byte
#define CCxxx0_SYNC0 0x05 // Sync word, low byte
#define CCxxx0_PKTLEN 0x06 // Packet length
#define CCxxx0_PKTCTRL1 0x07 // Packet automation control
#define CCxxx0_PKTCTRL0 0x08 // Packet automation control
#define CCxxx0_ADDR 0x09 // Device address
#define CCxxx0_CHANNR 0x0A // Channel number
#define CCxxx0_FSCTRL1 0x0B // Frequency synthesizer control
#define CCxxx0_FSCTRL0 0x0C // Frequency synthesizer control
#define CCxxx0_FREQ2 0x0D // Frequency control word, high byte
#define CCxxx0_FREQ1 0x0E // Frequency control word, middle byte
#define CCxxx0_FREQ0 0x0F // Frequency control word, low byte
#define CCxxx0_MDMCFG4 0x10 // Modem configuration
#define CCxxx0_MDMCFG3 0x11 // Modem configuration
#define CCxxx0_MDMCFG2 0x12 // Modem configuration
#define CCxxx0_MDMCFG1 0x13 // Modem configuration
#define CCxxx0_MDMCFG0 0x14 // Modem configuration
#define CCxxx0_DEVIATN 0x15 // Modem deviation setting
#define CCxxx0_MCSM2 0x16 // Main Radio Control State Machine configuration
#define CCxxx0_MCSM1 0x17 // Main Radio Control State Machine configuration
#define CCxxx0_MCSM0 0x18 // Main Radio Control State Machine configuration
#define CCxxx0_FOCCFG 0x19 // Frequency Offset Compensation configuration
#define CCxxx0_BSCFG 0x1A // Bit Synchronization configuration
#define CCxxx0_AGCCTRL2 0x1B // AGC control
#define CCxxx0_AGCCTRL1 0x1C // AGC control
#define CCxxx0_AGCCTRL0 0x1D // AGC control
#define CCxxx0_WOREVT1 0x1E // High byte Event 0 timeout
#define CCxxx0_WOREVT0 0x1F // Low byte Event 0 timeout
#define CCxxx0_WORCTRL 0x20 // Wake On Radio control
#define CCxxx0_FREND1 0x21 // Front end RX configuration
#define CCxxx0_FREND0 0x22 // Front end TX configuration
#define CCxxx0_FSCAL3 0x23 // Frequency synthesizer calibration
#define CCxxx0_FSCAL2 0x24 // Frequency synthesizer calibration
#define CCxxx0_FSCAL1 0x25 // Frequency synthesizer calibration
#define CCxxx0_FSCAL0 0x26 // Frequency synthesizer calibration
#define CCxxx0_RCCTRL1 0x27 // RC oscillator configuration
#define CCxxx0_RCCTRL0 0x28 // RC oscillator configuration
#define CCxxx0_FSTEST 0x29 // Frequency synthesizer calibration control
#define CCxxx0_PTEST 0x2A // Production test
#define CCxxx0_AGCTEST 0x2B // AGC test
#define CCxxx0_TEST2 0x2C // Various test settings
#define CCxxx0_TEST1 0x2D // Various test settings
#define CCxxx0_TEST0 0x2E // Various test settings
// Strobe commands
#define CCxxx0_SRES 0x30 // Reset chip.
#define CCxxx0_SFSTXON 0x31 // Enable and calibrate frequency synthesizer (if MCSM0.FS_AUTOCAL=1).
// If in RX/TX: Go to a wait state where only the synthesizer is
// running (for quick RX / TX turnaround).
#define CCxxx0_SXOFF 0x32 // Turn off crystal oscillator.
#define CCxxx0_SCAL 0x33 // Calibrate frequency synthesizer and turn it off
// (enables quick start).
#define CCxxx0_SRX 0x34 // Enable RX. Perform calibration first if coming from IDLE and
// MCSM0.FS_AUTOCAL=1.
#define CCxxx0_STX 0x35 // In IDLE state: Enable TX. Perform calibration first if
// MCSM0.FS_AUTOCAL=1. If in RX state and CCA is enabled:
// Only go to TX if channel is clear.
#define CCxxx0_SIDLE 0x36 // Exit RX / TX, turn off frequency synthesizer and exit
// Wake-On-Radio mode if applicable.
#define CCxxx0_SAFC 0x37 // Perform AFC adjustment of the frequency synthesizer
#define CCxxx0_SWOR 0x38 // Start automatic RX polling sequence (Wake-on-Radio)
#define CCxxx0_SPWD 0x39 // Enter power down mode when CSn goes high.
#define CCxxx0_SFRX 0x3A // Flush the RX FIFO buffer.
#define CCxxx0_SFTX 0x3B // Flush the TX FIFO buffer.
#define CCxxx0_SWORRST 0x3C // Reset real time clock.
#define CCxxx0_SNOP 0x3D // No operation. May be used to pad strobe commands to two
// bytes for simpler software.
#define CCxxx0_PARTNUM 0x30
#define CCxxx0_VERSION 0x31
#define CCxxx0_FREQEST 0x32
#define CCxxx0_LQI 0x33
#define CCxxx0_RSSI 0x34
#define CCxxx0_MARCSTATE 0x35
#define CCxxx0_WORTIME1 0x36
#define CCxxx0_WORTIME0 0x37
#define CCxxx0_PKTSTATUS 0x38
#define CCxxx0_VCO_VC_DAC 0x39
#define CCxxx0_TXBYTES 0x3A
#define CCxxx0_RXBYTES 0x3B
#define CCxxx0_RCCTRL1_STATUS 0x3C
#define CCxxx0_RCCTRL0_STATUS 0x3D
#define CCxxx0_PATABLE 0x3E
#define CCxxx0_TXFIFO 0x3F
#define CCxxx0_RXFIFO 0x3F
// 通道数据变量
uint16_t channelData[MAX_CHANNELS]; // 每个通道采用16位二进制数表示,单位uS (732-2268)
uint8_t package[PACKAGE_LEN]; // 数据包
volatile uint8_t newDataFound; // 新数据标志
volatile uint8_t isSetting; // 设置状态标志
volatile uint16_t Min[MAX_CHANNELS];
volatile uint16_t Max[MAX_CHANNELS];
// 8位CRC检验码
uint8_t crc8_ibutton(uint8_t *data, size_t n) {
uint8_t crc = 0x00;
while(n) {
crc = _crc_ibutton_update(crc, *data ++);
--n;
}
return crc;
}
void SPI_Master_Init() {
// 设置SS, MOSI和SCK为输出,其他为输入
DDRB = _BV(PB1) | _BV(PB2) | _BV(PB3) | _BV(PB5);
// MISO 设置为输入,并使能内部上拉电阻
PORTB |= _BV(PB4);
// SS默认拉高
SEL_HI();
// 使能SPI主机模式,设置时钟速率为 fck/2
SPCR = _BV(SPE) | _BV(MSTR) | _BV(SPI2X);
SPSR = 0x00;
}
void halSpiStrobe(uint8_t strobe) {
SEL_LO();
while(CCxxx0_Ready());
SPDR = strobe;
SPI_WAIT();
SEL_HI();
}
uint8_t halSpiReadReg(uint8_t addr) {
uint8_t x;
SEL_LO();
while(CCxxx0_Ready());
SPDR = (addr | READ_SINGLE);
SPI_WAIT();
SPDR = 0;
SPI_WAIT();
x = SPDR;
SEL_HI();
return (x);
}
void halSpiWriteReg(uint8_t addr, uint8_t value) {
SEL_LO();
while(CCxxx0_Ready());
SPDR = addr;
SPI_WAIT();
SPDR = value;
SPI_WAIT();
SEL_HI();
}
void halSpiWriteBurstReg(uint8_t addr, uint8_t *buffer, uint8_t count) {
uint8_t i;
SEL_LO();
while(CCxxx0_Ready());
SPDR = addr | WRITE_BURST;
SPI_WAIT();
for (i = 0; i < count; i++) {
SPDR = buffer[i];
SPI_WAIT();
}
SEL_HI();
}
void halSpiReadBurstReg(uint8_t addr, uint8_t *buffer, uint8_t count) {
uint8_t i;
SEL_LO();
while(CCxxx0_Ready());
SPDR = (addr | READ_BURST);
SPI_WAIT();
for (i = 0; i < count; i++) {
SPDR = 0;
SPI_WAIT();
buffer[i] = SPDR;
}
SEL_HI();
}
uint8_t halSpiReadStatus(uint8_t addr) {
uint8_t x;
SEL_LO();
while(CCxxx0_Ready());
SPDR = (addr | READ_BURST);
SPI_WAIT();
SPDR = 0;
SPI_WAIT();
x = SPDR;
SEL_HI();
return x;
}
void RESET_CCxxx0() {
SEL_LO();
while(CCxxx0_Ready());
SPDR = CCxxx0_SRES;
SPI_WAIT();
SEL_HI();
}
void POWER_UP_RESET_CCxxx0() {
SEL_HI();
_delay_ms(1);
SEL_LO();
_delay_ms(1);
SEL_HI();
_delay_ms(41);
RESET_CCxxx0();
}
void CC2500_Init() {
// CC2500上电重启
POWER_UP_RESET_CCxxx0();
// 设置寄存器值
halSpiWriteReg(CCxxx0_PATABLE, 0xFE);
halSpiWriteReg(CCxxx0_IOCFG1, 0x07);
halSpiWriteReg(CCxxx0_PKTLEN, PACKAGE_LEN);
halSpiWriteReg(CCxxx0_PKTCTRL1, 0x84);
halSpiWriteReg(CCxxx0_PKTCTRL0, 0x0C);
halSpiWriteReg(CCxxx0_FSCTRL1, 0x09);
halSpiWriteReg(CCxxx0_FREQ2, 0x5D);
halSpiWriteReg(CCxxx0_FREQ1, 0xB1);
halSpiWriteReg(CCxxx0_FREQ0, 0x38);
// 32Kbps
halSpiWriteReg(CCxxx0_MDMCFG4, 0x2A);
halSpiWriteReg(CCxxx0_MDMCFG3, 0x3B);
halSpiWriteReg(CCxxx0_MDMCFG2, 0x73);
halSpiWriteReg(CCxxx0_MDMCFG1, 0xD2);
halSpiWriteReg(CCxxx0_MDMCFG0, 0xF8);
halSpiWriteReg(CCxxx0_DEVIATN, 0x01);
halSpiWriteReg(CCxxx0_MCSM2, 0x07);
halSpiWriteReg(CCxxx0_MCSM1, 0x30);
halSpiWriteReg(CCxxx0_MCSM0, 0x18);
halSpiWriteReg(CCxxx0_FOCCFG, 0x1D);
halSpiWriteReg(CCxxx0_BSCFG, 0x1C);
halSpiWriteReg(CCxxx0_AGCCTRL2, 0xC7);
halSpiWriteReg(CCxxx0_AGCCTRL1, 0x00);
halSpiWriteReg(CCxxx0_AGCCTRL0, 0xB2);
halSpiWriteReg(CCxxx0_FREND1, 0xB6);
halSpiWriteReg(CCxxx0_FSCAL3, 0xCA);
halSpiWriteReg(CCxxx0_FSCAL0, 0x11);
// 清发送寄存器
halSpiStrobe(CCxxx0_SFTX);
// 校正
halSpiStrobe(CCxxx0_SCAL);
while(halSpiReadStatus(CCxxx0_FSCAL1) == 0x3F);
}
void halRfSendPacket(uint8_t *txBuffer, uint8_t size) {
halSpiWriteBurstReg(CCxxx0_TXFIFO, txBuffer, size);
halSpiStrobe(CCxxx0_STX);
// 等待结束
// ...
while(halSpiReadStatus(CCxxx0_MARCSTATE) != STATE_IDLE);
}
void IO_Init()
{
DDRD |= _BV(PD6);
PORTD &= ~_BV(PD6);
DDRC &= ~_BV(PC5);
PORTC &= ~_BV(PC5);
// 管脚电平中断使能PC5
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -