GD32F103-RFM69C遥控车

一、RFM69C

       RFM69C是一款收发模块,能够工作在较宽的频率范围内,包括315,433,868和915MHz免许可证ISM(工业科学和医疗)频段。全主流射频通信参数是可编程的,大部分参数都可以动态集RFM69C提供了独特的窄带和宽频带可编程的优点RFM69C是针对低同时提供高射频输出功率和信道化操作。符合ETSI和FCC规定。

        无线收发模块RFM69C基本特征:

       ● 最大+13dBm —发射发射功率

       ● 高灵敏度: -120 dBm @ 1.2 kbps

       ● 高灵敏度:16个FIR信道滤波器

       ● 抑制前端:IIP3 = -18 dBm,IIP2 = +35 dBm,80 dB阻断免疫,无镜像频率响应

       ● 低电流:接收状态时16 mA,寄存器保存状态下时100nA

       ● 可调功率范围:-18~+13dBm/1dB 步进

       ● 模块电压范围内射频性能稳定

       ● FSK速率高达300 kb/秒

       ● 高度集成的频率合成器,分辨率为61 Hz

       ● FSK, GFSK, MSK, GMSK及OOK解调

       ●  内置同位器,可实现Clock Recovery

       ● 同步字自动识别

       ● 115 dB+动态范围RSSI

       ● 超快AFC,自动射频侦测应

       ● 支持CRC,AES-128加密及66字节FIFO

       ● 内置温度传感器

       ● 模块尺寸:16*16mm

       ●模块采样SPI通信

二、TC1508S

        TC1508S是一款双通道直流马达驱动器,常用于玩具电机驱动。

       TC1508S基本特征:

       ● 双通道内置功率MOS全桥驱动

       ●驱动前进、后退、停止及刹车功能

       ● 超低的待机电流和工作电流

       ● 低导通电阻(1欧)

       ●最大连续输出电流可达1.8A/每通道,峰值2.5A

       ● 宽电压工作范围

       ● 采用SOP-16封装形式

三、程序

       RFM69C头文件

#ifndef _RFM69_H_
#define	_RFM69_H_

#include "gd32f10x.h"

#define		RFM69_GPIO_CS_RCC			RCU_GPIOD
#define		RFM69_GPIO_CS_PORT			GPIOD
#define		RFM69_GPIO_CS_PIN			GPIO_PIN_2

#define		RFM69_GPIO_RESET_RCC		RCU_GPIOB
#define		RFM69_GPIO_RESET_PORT		GPIOB
#define		RFM69_GPIO_RESET_PIN		GPIO_PIN_6

#define		RFM69_GPIO_DIO0_RCC			RCU_GPIOC
#define		RFM69_GPIO_DIO0_PORT		GPIOC
#define		RFM69_GPIO_DIO0_PIN			GPIO_PIN_12

#define	  	RFM69_CS_L					gpio_bit_reset(RFM69_GPIO_CS_PORT,RFM69_GPIO_CS_PIN)
#define		RFM69_CS_H					gpio_bit_set(RFM69_GPIO_CS_PORT,RFM69_GPIO_CS_PIN)

#define	  	RFM69_RESET_L				gpio_bit_reset(RFM69_GPIO_RESET_PORT,RFM69_GPIO_RESET_PIN)
#define		RFM69_RESET_H				gpio_bit_set(RFM69_GPIO_RESET_PORT,RFM69_GPIO_RESET_PIN)

#define	    RFM69_ReadDIO0Pin()			gpio_input_bit_get(RFM69_GPIO_DIO0_PORT,RFM69_GPIO_DIO0_PIN)


#define RFM69_FSTEP       61.03515625 // Step width of synthesizer [Hz]

enum {
  REG_FIFO          = 0x00,
  REG_OPMODE        = 0x01,
  REG_FRFMSB        = 0x07,
  REG_PALEVEL       = 0x11,
  REG_LNAVALUE      = 0x18,
  REG_AFCMSB        = 0x1F,
  REG_AFCLSB        = 0x20,
  REG_FEIMSB        = 0x21,
  REG_FEILSB        = 0x22,
  REG_RSSIVALUE     = 0x24,
  REG_IRQFLAGS1     = 0x27,
  REG_IRQFLAGS2     = 0x28,
  REG_SYNCVALUE1    = 0x2F,
  REG_SYNCVALUE2    = 0x30,
  REG_NODEADDR      = 0x39,
  REG_BCASTADDR     = 0x3A,
  REG_FIFOTHRESH    = 0x3C,
  REG_PKTCONFIG2    = 0x3D,
  REG_AESKEYMSB     = 0x3E,
  REG_FRFMID        = 0x08,
  REG_FRFLSB        = 0x09,
	
  MODE_SLEEP        = 0 << 2,
  MODE_STANDBY      = 1 << 2,
  MODE_TRANSMIT     = 3 << 2, 
  MODE_RECEIVE      = 4 << 2,

  IRQ1_MODEREADY    = 1 << 7,
  IRQ1_RXREADY      = 1 << 6,
  IRQ1_SYNADDRMATCH = 1 << 0,

  IRQ2_FIFONOTEMPTY = 1 << 6,
  IRQ2_PACKETSENT   = 1 << 3, 
  IRQ2_PAYLOADREADY = 1 << 2,
};

static const uint8_t configRegs [] = {
  0x02, 0x00, // 设置包模式,FSK
  0x03, 0x02, // 设置比特率高位, data rate = 49,261 bits/s
  0x04, 0x8A, // 设置比特率低位, divider = 32 MHz / 650
  0x04, 0x8A, // BitRateLsb, divider = 32 MHz / 650
  0x05, 0x02, // FdevMsb = 45 kHz
  0x06, 0xE1, // FdevLsb = 45 kHz
  0x0B, 0x20, // Low M
  0x11, 0x99, // OutputPower = +7 dBm - was default = max = +13 dBm
  0x19, 0x4A, // RxBw 100 kHz
  0x1A, 0x42, // AfcBw 125 kHz
  0x1E, 0x0C, // AfcAutoclearOn, AfcAutoOn
  //0x25, 0x40, //0x80, // DioMapping1 = SyncAddress (Rx)
  0x26, 0x07, // disable clkout
  0x29, 0xA0, // RssiThresh -80 dB
  0x2D, 0x05, // PreambleSize = 5
  0x2E, 0x88, // SyncConfig = sync on, sync size = 2
  0x2F, 0x2D, // SyncValue1 = 0x2D
  0x37, 0xD0, // PacketConfig1 = variable, white, no filtering
  0x38, 0x42, // PayloadLength = 0, unlimited
  0x3C, 0x8F, // FifoThresh, not empty, level 15
  0x3D, 0x12, // 0x10, // PacketConfig2, interpkt = 1, autorxrestart off
  0x6F, 0x20, // TestDagc ...
  0x71, 0x02, // RegTestAfc
  0
};

extern uint8_t rssi;

void RFM69_Init(uint8_t id, uint8_t group, int freq);
void RFM69_Encrypt(const char* key);
int8_t RFM69_Receive (void* ptr,uint8_t len);
void RFM69_Send(const void* ptr,int len);
uint32_t Get_Frequency(void);

#endif

RFM69C源文件(移植的时候只需要修改对应的引脚与SPI驱动)

#include "rfm69.h"
#include "stdio.h"
#include "systick.h"
#include "bsp_spi.h"

uint8_t mode;
uint8_t myId;
uint8_t parity;

uint8_t lna;	//增益系数
uint8_t afc;	//自动频率控制
uint8_t rssi;   //信号强度

static void RFM69_RST(void) 
{
 	RFM69_RESET_H;
	delay_ms(10);
	RFM69_RESET_L;
	delay_ms(10);
}

static void RFM69_GPIO_Config(void)
{
	rcu_periph_clock_enable(RFM69_GPIO_CS_RCC);
	rcu_periph_clock_enable(RFM69_GPIO_RESET_RCC);
	rcu_periph_clock_enable(RFM69_GPIO_DIO0_RCC);
	
	gpio_init(RFM69_GPIO_CS_PORT,    GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, RFM69_GPIO_CS_PIN);
	gpio_init(RFM69_GPIO_RESET_PORT, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, RFM69_GPIO_RESET_PIN);
	gpio_init(RFM69_GPIO_DIO0_PORT,  GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, RFM69_GPIO_DIO0_PIN);
	
	spi_config();
	RFM69_CS_H;
	RFM69_RST();
}

static void RFM69_Select() 
{
	RFM69_CS_L;
}

static void RFM69_Unselect() 
{
	RFM69_CS_H;
}


static uint8_t readReg(uint8_t reg)
{
	uint8_t regval;
	
	RFM69_Select();
	spi_read_write_byte(reg & 0x7F);
	regval = spi_read_write_byte(0);
	RFM69_Unselect();
	return regval;
}

static void writeReg(uint8_t reg,uint8_t value)
{
	RFM69_Select();
	spi_read_write_byte(reg | 0x80);
	spi_read_write_byte(value);
	RFM69_Unselect();
}

static void RFM69_SetMode(uint8_t newMode) 
{
	mode = newMode;
	writeReg(REG_OPMODE,(readReg(REG_OPMODE) & 0xE3) | newMode);
	while((readReg(REG_IRQFLAGS1) & IRQ1_MODEREADY) == 0);
}

//315MHz  433MHz  868MHz  915MHz
static void RFM69_Set_Frequency(uint32_t hz) 
{
	uint32_t frf;

	while(hz < 100000000)
	{
		hz *= 10;
	}

	frf = (hz << 2) / (32000000L >> 11);
	writeReg(REG_FRFMSB, frf >> 10);
	writeReg(REG_FRFMSB + 1, frf >> 2);
	writeReg(REG_FRFMSB + 2, frf << 6);
}

static void RFM69_Configure(const uint8_t* p) 
{
	uint8_t cmd;
	
	while(1) 
	{
		cmd = p[0];
		if (cmd == 0)
		{
			break;
		} 
		  
		writeReg(cmd, p[1]);
		p += 2;
	}
}

static void Set_Address(uint8_t addr)
{
    writeReg(REG_NODEADDR, addr);
}

static void Set_Network(uint8_t networkID)
{
    writeReg(REG_SYNCVALUE2, networkID);
}

static void RFM69_Tx_Power(uint8_t level) 
{
	writeReg(REG_PALEVEL,(readReg(REG_PALEVEL) & ~0x1F) | level);
}

static void RFM69_Sleep(void) 
{
	RFM69_SetMode(MODE_SLEEP);
}

uint32_t Get_Frequency(void) 
{
	return RFM69_FSTEP * (((uint32_t) readReg(REG_FRFMSB) << 16) 
		+ ((uint16_t) readReg(REG_FRFMID) << 8)+ readReg(REG_FRFLSB));
}

void RFM69_Init(uint8_t id, uint8_t group, int freq) 
{
	RFM69_GPIO_Config();
	
	myId = id;

	parity = group ^ (group << 4);
	parity = (parity ^ (parity << 2)) & 0xC0;

	do 
	{
		writeReg(REG_SYNCVALUE1, 0xAA);
	}while(readReg(REG_SYNCVALUE1) != 0xAA);
	
	do 
	{
		writeReg(REG_SYNCVALUE1, 0x55);
	} while(readReg(REG_SYNCVALUE1) != 0x55);
	
	RFM69_Configure(configRegs);
	RFM69_Configure(configRegs);
	RFM69_Set_Frequency(freq);
	
	RFM69_Tx_Power(31);
	Set_Address(id);
	writeReg(REG_SYNCVALUE2, group);
}

//加密
void RFM69_Encrypt(const char* key) 
{
	uint8_t i;
	uint8_t cfg;
	
	cfg = readReg(REG_PKTCONFIG2) & ~0x01;
	if(key)
	{
		for(i = 0;i < 16;i++) 
		{
			writeReg(REG_AESKEYMSB + i,*key);
			if(*key != 0)
			{
				key++;
			}
		}
		cfg |= 0x01;
	}
	writeReg(REG_PKTCONFIG2,cfg);
}


int8_t RFM69_Receive(void* ptr, uint8_t len) 
{
	uint8_t i;
	uint8_t value;
	uint8_t count;
	uint8_t dest;
	uint8_t destId;
	
	static uint8_t lastFlag;
	
	if(mode != MODE_RECEIVE) 
	{
		RFM69_SetMode(MODE_RECEIVE);
	} 
	else 
	{
		if((readReg(REG_IRQFLAGS1) & IRQ1_RXREADY) != lastFlag) 
		{
			lastFlag ^= IRQ1_RXREADY;
			if (lastFlag) 
			{ 
				lna = (readReg(REG_LNAVALUE) >> 3) & 0x7;
				afc = readReg(REG_AFCMSB) << 8;
				afc |= readReg(REG_AFCLSB);
			}
		}

		if(readReg(REG_IRQFLAGS2) & IRQ2_PAYLOADREADY) 
		{
			rssi = readReg(REG_RSSIVALUE);  
			count = readReg(REG_FIFO);
			for (i = 0;i < count;i++) 
			{
				value = readReg(REG_FIFO);
				if(i < len)
				{
					((uint8_t*) ptr)[i] = value;
				}  
			}

			dest = *(uint8_t*) ptr;
			if(dest == parity) 
			{
				destId = dest;
				if(destId == myId || destId == 0 || myId == 63)
				{
					return count;
				}
			}
		}
	}
	return -1;
}

void RFM69_Send(const void* ptr,int len) 
{
	uint8_t i;
	RFM69_SetMode(MODE_SLEEP);

	writeReg(REG_FIFO,len + 2);
	writeReg(REG_FIFO,parity); //网络ID
	writeReg(REG_FIFO,myId);
	for(i = 0;i < len;i++)
	{
		writeReg(REG_FIFO,((const uint8_t*) ptr)[i]);
	}
    
	RFM69_SetMode(MODE_TRANSMIT);
	while((readReg(REG_IRQFLAGS2) & IRQ2_PACKETSENT) == 0);
   
	RFM69_SetMode(MODE_STANDBY);
}

TC1508S头文件

#ifndef _DEVICE_H_
#define	_DEVICE_H_

#include  "gd32f10x.h"

#define		MODULE_EN_RCC			RCU_GPIOC
#define		MODULE_EN_PORT			GPIOC
#define		MODULE_EN_PIN			GPIO_PIN_5

#define		DC_MODE_nEN_RCC			RCU_GPIOC
#define		DC_MODE_nEN_PORT		GPIOC
#define		DC_MODE_nEN_PIN			GPIO_PIN_4

#define		DRIVER_EN_RCC			RCU_GPIOB
#define		DRIVER_EN_PORT			GPIOB
#define		DRIVER_EN_PIN			GPIO_PIN_1

//TC1508
#define		MOTOR_INA_RCC			RCU_GPIOA
#define		MOTOR_INA_PORT			GPIOA
#define		MOTOR_INA_PIN			GPIO_PIN_4

#define		MOTOR_INB_RCC			RCU_GPIOA
#define		MOTOR_INB_PORT			GPIOA
#define		MOTOR_INB_PIN			GPIO_PIN_5

#define		MOTOR_INC_RCC			RCU_GPIOA
#define		MOTOR_INC_PORT			GPIOA
#define		MOTOR_INC_PIN			GPIO_PIN_6

#define		MOTOR_IND_RCC			RCU_GPIOA
#define		MOTOR_IND_PORT			GPIOA
#define		MOTOR_IND_PIN			GPIO_PIN_7

#define		MODULE_EN_H				gpio_bit_set(MODULE_EN_PORT,MODULE_EN_PIN)
#define		MODULE_EN_L				gpio_bit_reset(MODULE_EN_PORT,MODULE_EN_PIN)

#define		DC_MODE_nEN_H			gpio_bit_set(DC_MODE_nEN_PORT,DC_MODE_nEN_PIN)
#define		DC_MODE_nEN_L			gpio_bit_reset(DC_MODE_nEN_PORT,DC_MODE_nEN_PIN)

#define		DRIVER_EN_H				gpio_bit_set(DRIVER_EN_PORT,DRIVER_EN_PIN)
#define		DRIVER_EN_L				gpio_bit_reset(DRIVER_EN_PORT,DRIVER_EN_PIN)

#define		MOTOR_INA_H				{gpio_bit_set(MOTOR_INA_PORT,MOTOR_INA_PIN);}
#define		MOTOR_INA_L				{gpio_bit_reset(MOTOR_INA_PORT,MOTOR_INA_PIN);}

#define		MOTOR_INB_H				{gpio_bit_set(MOTOR_INB_PORT,MOTOR_INB_PIN);}
#define		MOTOR_INB_L				{gpio_bit_reset(MOTOR_INB_PORT,MOTOR_INB_PIN);}

#define		MOTOR_INC_H				{gpio_bit_set(MOTOR_INC_PORT,MOTOR_INC_PIN);}
#define		MOTOR_INC_L				{gpio_bit_reset(MOTOR_INC_PORT,MOTOR_INC_PIN);}

#define		MOTOR_IND_H				{gpio_bit_set(MOTOR_IND_PORT,MOTOR_IND_PIN);}
#define		MOTOR_IND_L				{gpio_bit_reset(MOTOR_IND_PORT,MOTOR_IND_PIN);}


//刹车
#define		CAR_BRAKE      \
							MOTOR_INA_H\
							MOTOR_INB_H\
							MOTOR_INC_H\
							MOTOR_IND_H

//前进
#define 	CAR_ADVANCE		\
							MOTOR_INA_H\
							MOTOR_INB_L\
							MOTOR_INC_H\
							MOTOR_IND_H

//后退
#define		CAR_RETREAT		\
							MOTOR_INA_L\
							MOTOR_INB_H\
							MOTOR_INC_H\
							MOTOR_IND_H

//左转
#define 	CAR_LEFT_TURN	\
							MOTOR_INC_H\
							MOTOR_IND_L\
							MOTOR_INA_H\
							MOTOR_INB_H

//右转
#define     CAR_RIGHT_TURN	\
							MOTOR_INC_L\
							MOTOR_IND_H\
							MOTOR_INA_H\
							MOTOR_INB_H
							
//前进左转						
#define		CAR_ABVANCE_AND_LEFT_TURN	\
										MOTOR_INA_H\
										MOTOR_INB_L\
										MOTOR_INC_H\
										MOTOR_IND_L
//前进右转
#define		CAR_ABVANCE_AND_RIGHT_TURN	\
										MOTOR_INA_H\
										MOTOR_INB_L\
										MOTOR_INC_L\
										MOTOR_IND_H
//后退左转
#define		CAR_RETREAT_AND_LEFT_TURN	\
										MOTOR_INA_L\
										MOTOR_INB_H\
										MOTOR_INC_H\
										MOTOR_IND_L
//后退右转
#define		CAR_RETREAT_AND_RIGHT_TURN	\
										MOTOR_INA_L\
										MOTOR_INB_H\
										MOTOR_INC_L\
										MOTOR_IND_H

#define		STOP						0x00
#define 	ABVANCE     				0x01
#define		RETREAT	    				0x02
#define		LEFT_TURN  					0x04
#define		RIGHT_TURN					0x08
#define		ABVANCE_AND_LEFT_TURN		0X05
#define		ABVANCE_AND_RIGHT_TURN		0X09
#define		RETREAT_AND_LEFT_TURN		0X06
#define		RETREAT_AND_RIGHT_TURN		0x0A


void Device_Init(void);
void Set_Motor(uint8_t state);
#endif

TC1508S源文件

#include "device.h"
#include "bsp_led.h"


void Device_Init(void)
{
	rcu_periph_clock_enable(MODULE_EN_RCC | DC_MODE_nEN_RCC);	
	
	rcu_periph_clock_enable(DRIVER_EN_RCC);	
	
	rcu_periph_clock_enable(MOTOR_INA_RCC | MOTOR_INB_RCC 
							| MOTOR_INC_RCC | MOTOR_IND_RCC);	
	
	gpio_init(DC_MODE_nEN_PORT, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, DC_MODE_nEN_PIN);
	gpio_init(MODULE_EN_PORT, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, MODULE_EN_PIN);
	gpio_init(DRIVER_EN_PORT, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, DRIVER_EN_PIN);
	gpio_init(MOTOR_INA_PORT, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, MOTOR_INA_PIN);
	gpio_init(MOTOR_INB_PORT, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, MOTOR_INB_PIN);
	gpio_init(MOTOR_INC_PORT, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, MOTOR_INC_PIN);
	gpio_init(MOTOR_IND_PORT, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, MOTOR_IND_PIN);
	
	DC_MODE_nEN_L;
	MODULE_EN_H;
	DRIVER_EN_H;
	
	MOTOR_INA_L;
	MOTOR_INB_L;
	MOTOR_INC_L;
	MOTOR_IND_L;
}


void Set_Motor(uint8_t state)
{
	switch(state)
	{
		case ABVANCE:
		{
			CAR_ADVANCE;
		}break;
		
		case RETREAT:
		{
			CAR_RETREAT;
		}break;
		
		case LEFT_TURN:
		{
			CAR_LEFT_TURN;
		}break;
		
		case RIGHT_TURN:
		{
			CAR_RIGHT_TURN;
		}break;
		
		case ABVANCE_AND_LEFT_TURN:
		{
			CAR_ABVANCE_AND_LEFT_TURN;
		}break;
		
		case ABVANCE_AND_RIGHT_TURN:
		{
			CAR_ABVANCE_AND_RIGHT_TURN;
		}break;
		
		case RETREAT_AND_LEFT_TURN:
		{
			CAR_RETREAT_AND_LEFT_TURN;
		}break;
		
		case RETREAT_AND_RIGHT_TURN:
		{
			CAR_RETREAT_AND_RIGHT_TURN;
		}break;
		
		case STOP:
		default:
		{
			CAR_BRAKE;
			DEBUG_LED_OFF;
		}break;
	}
}

四、总结

       遥控距离有两百米左右,目前存在的问题是前进电机一工作就干扰到遥控信号的接收。

工程源码,提取码:tqa3https://pan.baidu.com/s/1dlI6vGBFRWRRc5OyH_lSCQ

评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值