15块钱的遥控器(T-65 X-WING)的改造利用

本文的主角:
15块钱的遥控器(T-65 X-WING)的改造利用_第1张图片
15块钱的遥控器(T-65 X-WING)的改造利用_第2张图片

内部主板布局

硬件资源:

    两个自动回中摇杆、数个微动开关、一个震动马达、一个喇叭、一块锂电(带保护板)、两个蓝牙模块和一个2.4G无线模块,其中两个蓝牙模块的型号分别为BK3431SMA-V2和BK2451,2.4G无线模块型号为BK2425 (封装TSSOP-16),没找到任何资料,问了淘宝上仅有的卖这块芯片三个卖家都说没有资料,有大神找到资料的话希望分享分享。有资料的话可以不改硬件改造成自己的航模遥控器。

线路:

    主控是GD32F130C6T6,据说和STM32是pin to pin兼容。粗略测出引脚连接情况如下:15块钱的遥控器(T-65 X-WING)的改造利用_第3张图片
15块钱的遥控器(T-65 X-WING)的改造利用_第4张图片
    主要用的是摇杆的四个引脚和SPI通讯的引脚,有些引脚不止控制一个元件,需要使用的话要自己测量外部电路,纯数字的标号连接的是CON9的,最左边的1是GND,左往右第10是3.3V。板载3.3V稳压,长得和1117一个样,引脚定义也一样,就当是1117了,按照1117的标准来说BAT+的输入电压要大于3.3+1.5=4.8V,测试过5v可以开机。开机的话可以用原机自带下方的板长按开机,也可以短接CON9的12、13脚开机。

程序烧录

    我用ST-LINK V2烧录调试,可以用GD32官方的GDLINK也可以用Jlink。这里以stlink为例,注意SWDAT就是SWDIO。

3.3V————VDD
GND————BAT-
SWCLK————SWCLK
SWDIO————SWDAT


    用Keil编程时需要到GD32的官网下载芯片包,建议同时下载数据手册,用库开发的话下载固件库,目前固件库最新的版本是3.1.0。初次烧录程序需要stm32 st-link utility工具解除ReadOutProtection,先点击Connect to the target然后再选择Target->Option Bytes,Read Out Protection选择Level0,Read Out Protection解除,之后可以直接用keil烧录程序了。

摇杆ADC采集

    摇杆四个电位器的连接情况:

CH1————PB1
CH2————PA0
CH3————PA5
CH4————PA4

15块钱的遥控器(T-65 X-WING)的改造利用_第5张图片
    查询数据手册得到对应的ADC通道,要注意的是数据手册的版本要和使用的库的版本要一致,不同版本的内容会有差异。具体代码如下:

void ADC_init(void)
{
	GPIO_InitPara GPIO_InitStructure;
	ADC_InitPara ADC_InitStructure;
    DMA_InitPara DMA_InitStructure;
    
    GPIO_InitStructure.GPIO_Pin = GPIO_PIN_1  ;
    GPIO_InitStructure.GPIO_Speed = GPIO_SPEED_50MHZ;
    GPIO_InitStructure.GPIO_Mode = GPIO_MODE_AN;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PUPD_NOPULL;
    GPIO_Init(GPIOB, &GPIO_InitStructure);
			
    GPIO_InitStructure.GPIO_Pin = (GPIO_PIN_0|GPIO_PIN_4|GPIO_PIN_5);
    GPIO_Init(GPIOA, &GPIO_InitStructure);
   
	RCC_AHBPeriphClock_Enable(RCC_AHBPERIPH_DMA1,ENABLE);
    RCC_APB2PeriphClock_Enable(RCC_APB2PERIPH_ADC1,ENABLE);
	RCC_ADCCLKConfig(RCC_ADCCLK_APB2_DIV6);
	
    DMA_DeInit(DMA1_CHANNEL1); 
    DMA_InitStructure.DMA_PeripheralBaseAddr = ADC_RDTR_Address; 
    DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)ADC_ConvertedValue; 
    DMA_InitStructure.DMA_DIR = DMA_DIR_PERIPHERALSRC;  
    DMA_InitStructure.DMA_BufferSize = 4;    
    DMA_InitStructure.DMA_PeripheralInc = DMA_PERIPHERALINC_DISABLE;    
    DMA_InitStructure.DMA_MemoryInc = DMA_MEMORYINC_ENABLE; 
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PERIPHERALDATASIZE_HALFWORD; 
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MEMORYDATASIZE_HALFWORD; 
    DMA_InitStructure.DMA_Mode = DMA_MODE_CIRCULAR; 
    DMA_InitStructure.DMA_Priority = DMA_PRIORITY_HIGH;
    DMA_InitStructure.DMA_MTOM = DMA_MEMTOMEM_DISABLE; 
    DMA_Init(DMA1_CHANNEL1, &DMA_InitStructure);     
    
    /* Enable DMA1 channel1 */
    DMA_Enable(DMA1_CHANNEL1, ENABLE);  
    
    ADC_DeInit(&ADC_InitStructure);
    ADC_InitStructure.ADC_Mode_Scan = ENABLE;        
    ADC_InitStructure.ADC_Mode_Continuous = DISABLE;  
    ADC_InitStructure.ADC_Trig_External = ADC_EXTERNAL_TRIGGER_MODE_NONE;  
    ADC_InitStructure.ADC_Data_Align = ADC_DATAALIGN_RIGHT;
    ADC_InitStructure.ADC_Channel_Number = 4;  
    ADC_Init(&ADC_InitStructure);  
    
    /* ADC regular channels configuration */ 
    ADC_RegularChannel_Config(ADC_CHANNEL_4, 1, ADC_SAMPLETIME_239POINT5);
    ADC_RegularChannel_Config(ADC_CHANNEL_5, 2, ADC_SAMPLETIME_239POINT5);
    ADC_RegularChannel_Config(ADC_CHANNEL_0, 3, ADC_SAMPLETIME_239POINT5);
    ADC_RegularChannel_Config(ADC_CHANNEL_9, 4, ADC_SAMPLETIME_239POINT5);
    
    /* Enable ADC DMA */
    ADC_DMA_Enable(ENABLE); 
    
    /* Enable ADC */
    ADC_Enable(ENABLE); 
    ADC_Calibration();

    /* Start ADC Software Conversion */ 
    ADC_SoftwareStartConv_Enable(ENABLE);  
		
}

串口

    板子上有两个串口的四个测试点,分别为UART1和UART3,其中UART3连接到了板载的蓝牙模块,UART1可以用于调试。具体代码如下:

void Usart_Init(void)
{

    RCC_AHBPeriphClock_Enable( RCC_AHBPERIPH_GPIOA , ENABLE ); 
    /* Enable USART1 APB clock */
    RCC_APB2PeriphClock_Enable( RCC_APB2PERIPH_USART1 , ENABLE );
    /* USART1 Pins configuration **************************************************/
    GPIO_DeInit( GPIOA );
    {
        /* Configure the GPIO ports */
        GPIO_InitPara GPIO_InitStructure;
        /* Connect pin to Periph */
        GPIO_PinAFConfig( GPIOA , GPIO_PINSOURCE9, GPIO_AF_1 );    
        GPIO_PinAFConfig( GPIOA , GPIO_PINSOURCE10, GPIO_AF_1 ); 
        
        /* Configure pins as AF pushpull */
        GPIO_InitStructure.GPIO_Pin     = GPIO_PIN_9 | GPIO_PIN_10;
        GPIO_InitStructure.GPIO_Mode    = GPIO_MODE_AF;
        GPIO_InitStructure.GPIO_Speed   = GPIO_SPEED_50MHZ;
        GPIO_InitStructure.GPIO_OType   = GPIO_OTYPE_PP;
        GPIO_InitStructure.GPIO_PuPd    = GPIO_PUPD_NOPULL;
        GPIO_Init( GPIOA , &GPIO_InitStructure); 
    }
    { 
        USART_InitPara USART_InitStructure;       
        USART_DeInit( USART1 );       
        USART_InitStructure.USART_BRR           = 115200;
        USART_InitStructure.USART_WL            = USART_WL_8B;
        USART_InitStructure.USART_STBits            = USART_STBITS_1;
        USART_InitStructure.USART_Parity                = USART_PARITY_RESET;
        USART_InitStructure.USART_HardwareFlowControl = USART_HARDWAREFLOWCONTROL_NONE;
        USART_InitStructure.USART_RxorTx                = USART_RXORTX_RX | USART_RXORTX_TX;
        USART_Init(USART1, &USART_InitStructure);
    }
    /* USART enable */
    USART_Enable(USART1, ENABLE);
}
void Usart_SendByte(USART_TypeDef * pUSARTx,uint8_t data)
{
	
	USART_DataSend(pUSARTx,data);
	while(USART_GetBitState(pUSARTx,USART_FLAG_TBE)==RESET);
	
}

void Usart_SendString(USART_TypeDef * pUSART,char *str)
{
	unsigned int k=0;
	do
	{
		Usart_SendByte(USART1, *(str+k));
		k++;
	}while(*(str+k)!='\0');
	while(USART_GetBitState(pUSART,USART_FLAG_TC)==RESET);
}
	
int fputc(int ch,FILE *f)  //重定向之后可以直接用printf函数打印
{
	USART_DataSend(USART1,(uint8_t) ch);
	while(USART_GetBitState(USART1,USART_FLAG_TBE)==RESET);
	return(ch);
}

无线传输SPI

15块钱的遥控器(T-65 X-WING)的改造利用_第6张图片
    板子上集成了一块BK2425,连接到了MCU的一个硬件SPI上淘宝上说和NRF24L01兼容,不过没有资料,利用不了,如果用的是硬件SPI的话可以推测出三个脚的定义。为了连接NRF24L01,我用了CON9的部分针脚连接,这样不用焊接,较为方便。
15块钱的遥控器(T-65 X-WING)的改造利用_第7张图片
    用PB13、PB14、PB15对应的硬件SPI,初始化代码如下。

void SPI1_Init(void)
{
    /* Initialization GPIO and SPI */
    GPIO_InitPara GPIO_InitStructure;
    SPI_InitPara  SPI_InitStructure;
    
    /* Enable Peripheral clock */
    RCC_AHBPeriphClock_Enable( RCC_AHBPERIPH_GPIOA | RCC_AHBPERIPH_GPIOB | RCC_AHBPERIPH_GPIOC , ENABLE);
    RCC_APB1PeriphClock_Enable(RCC_APB1PERIPH_SPI2 ,ENABLE);

    /* Configure SPI2 pins: */
    GPIO_PinAFConfig( GPIOB , GPIO_PINSOURCE13, GPIO_AF_0 );
    GPIO_PinAFConfig( GPIOB, GPIO_PINSOURCE14, GPIO_AF_0 );
    GPIO_PinAFConfig( GPIOB, GPIO_PINSOURCE15, GPIO_AF_0 );
    GPIO_InitStructure.GPIO_Pin = GPIO_PIN_13| GPIO_PIN_14 | GPIO_PIN_15  ;
    GPIO_InitStructure.GPIO_Speed = GPIO_SPEED_10MHZ;
    GPIO_InitStructure.GPIO_Mode = GPIO_MODE_AF;
    GPIO_InitStructure.GPIO_OType = GPIO_OTYPE_PP;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PUPD_PULLUP ;
    GPIO_Init(GPIOB, &GPIO_InitStructure);

	NRF_CSN_HIGH(); 
	
	  /*配置SPI_NRF_SPI的CE引脚,和SPI_NRF_SPI的 CSN 引脚*/
    GPIO_InitStructure.GPIO_Pin = NRF_CSN_PIN;
    GPIO_InitStructure.GPIO_Speed = GPIO_SPEED_10MHZ;
    GPIO_InitStructure.GPIO_OType = GPIO_OTYPE_PP;
    GPIO_InitStructure.GPIO_Mode = GPIO_MODE_OUT;
	GPIO_InitStructure.GPIO_PuPd = GPIO_PUPD_PULLUP ;
    GPIO_Init(NRF_CSN_GPIO_PORT, &GPIO_InitStructure);
  
    GPIO_InitStructure.GPIO_Pin = NRF_CE_PIN;
    GPIO_InitStructure.GPIO_Speed = GPIO_SPEED_10MHZ;
	GPIO_InitStructure.GPIO_OType = GPIO_OTYPE_PP;
    GPIO_InitStructure.GPIO_Mode = GPIO_MODE_OUT;
	GPIO_InitStructure.GPIO_PuPd = GPIO_PUPD_PULLUP ;
    GPIO_Init(NRF_CE_GPIO_PORT, &GPIO_InitStructure);
	
    /* SPI2 configuration */
    SPI_InitStructure.SPI_TransType  = SPI_TRANSTYPE_FULLDUPLEX;
    SPI_InitStructure.SPI_Mode = SPI_MODE_MASTER;;
    SPI_InitStructure.SPI_FrameFormat  = SPI_FRAMEFORMAT_8BIT;;
    SPI_InitStructure.SPI_SCKPL	= SPI_SCKPL_LOW ;
    SPI_InitStructure.SPI_SCKPH = SPI_SCKPH_1EDGE ;
    SPI_InitStructure.SPI_SWNSSEN= SPI_SWNSS_SOFT;
    SPI_InitStructure.SPI_PSC = SPI_PSC_8 ;
    SPI_InitStructure.SPI_FirstBit = SPI_FIRSTBIT_MSB;;
    SPI_InitStructure.SPI_CRCPOL  = 7;
    SPI_Init(SPI2, &SPI_InitStructure);
	SPI_Enable(SPI2,ENABLE);
}

OLED显示屏

    可以利用引出的串口两个引脚复用为硬件IIC连接OLED。具体代码可以看整个工程的源码。
https://download.csdn.net/download/W770603600/12485110

存在的问题

    到这里ADC和SPI已经能正常使用了,一个四通道的遥控器已经完事了。可以用上顶上的四个微动开关增加通道。存在的问题是MCU一直在复位,我试过将NRST直接接到3.3V,确实不会再复位,但是swd复位不了了,一开始以为是复位电路的问题,折腾了好久断开了复位电路问题依旧。网上查资料说用STLINK烧录都会有这个问题,解决了再更。 解决方法如下:
https://blog.csdn.net/W770603600/article/details/106183853

你可能感兴趣的:(笔记)