[PIC/AVR MCU]为了遥控的更远,我用PIC18F16Q41驱动CC1101收发数据

之前我做了蓝牙遥控的小车,这里为了拓展遥控的距离,我准备采用CC1101模块进行拓展距离。
我之所以选择PIC或AVR是出于MCC的快捷可视化配置,让我不用去了解单片机的寄存器即可轻松快速实现设计目标。

端口的配置上我使用MCC进行配置,这样就不需要在移植代码中实现一堆的初始化了,非常方便。
PIC和AVR都具备内部上拉电阻,在需要配置为输入的端口,使用上拉稳定电平是非常容易的。
另外MCC的端口可定制新名字功能,非常有助于我们移植代码,防止多了就容易乱。


在这个表里,非常容易初始化代码,可以设置是否上拉,另外可以指定初始化后是否默认高电平。


利用MCC生成的代码我们直接就可以用于移植了。比如下面的串口收发

 利用MCC生成的代码我们直接就可以用于移植了。比如下面的串口收发

/**

  * [url=home.php?mod=space&uid=247401]@brief[/url] :串口发送数据

  * @param :

  *                        @TxBuffer:发送数据首地址

  *                        @Length:数据长度

  * [url=home.php?mod=space&uid=536309]@NOTE[/url]  :无

  * @retval:无

  */

void drv_uart_tx_bytes( uint8_t* TxBuffer, uint8_t Length )

{

        while( Length-- )

        {

                UART1_Write(*TxBuffer);

                TxBuffer++;

        }

}



/**

  * [url=home.php?mod=space&uid=247401]@brief[/url] :串口接收数据

  * @param :

  *                        @RxBuffer:发送数据首地址

  * [url=home.php?mod=space&uid=536309]@NOTE[/url]  :无

  * @retval:接收到的字节个数

  */

uint8_t drv_uart_rx_bytes( uint8_t* RxBuffer )

{

        uint8_t l_RxLength = 0;

        uint16_t l_UartRxTimOut = 0x7FFF;

        

        while( l_UartRxTimOut-- )                        //等待查询串口数据

        {



                if( UART1_is_rx_ready())

                {

            *RxBuffer = UART1_Read();

            RxBuffer++;

            l_RxLength++;

                        l_UartRxTimOut = 0x7FFF;        //接收到一个字符,回复等待时间

                }

                if( 100 == l_RxLength )

                {

                        break;                        //不能超过100个字节

                }

        }

        

        return l_RxLength;                                        //等待超时,数据接收完成

}

以及SPI的端口操作映射,只需要在对应的头文件修改成MCC生成的代码即可

#define __USE_SOFT_SPI_INTERFACE__





#define spi_set_nss_high( )                        NSS_SetHigh()                                         //片选置高

#define spi_set_nss_low( )                        NSS_SetLow()        //片选置低





#ifdef __USE_SOFT_SPI_INTERFACE__                        /** 只有使用软件SPI才需要的封装 */                





#define spi_set_clk_high( )                        SCL_SetHigh()                                        //时钟置高

#define spi_set_clk_low( )                        SCL_SetLow()         //时钟置低



#define spi_set_mosi_hight( )                MOSI_SetHigh()                                        //发送脚置高

#define spi_set_mosi_low( )                        MOSI_SetLow()        //发送脚置低



#define spi_get_miso( )                                MISO_GetValue() // 若相应输入位为低则得到0,相应输入位为高则得到1

因为开发板只有一个可配置的LED,所以这里我就只使用了红色的

void drv_led_on( LedPortType LedPort )

{

        if( LED_RED == LedPort )        //LED_RED

        {

                RED_LED_SetLow();        //红色LED引脚置低,红色LED亮

        }

        else                                                //LED_BLUE

        {

                ;//绿色LED引脚置低,蓝色LED亮

        }

        

}



/**

  * @brief :LED灭

  * @param :

  *                        @LedPort:LED选择,红色或绿色

  * @note  :无

  * @retval:无

  */

void drv_led_off( LedPortType LedPort )

{

        if( LED_RED == LedPort )        //LED_RED

        {

                RED_LED_SetHigh();                //红色LED引脚置高,红色LED灭

        }

        else                                                //LED_BLUE

        {

                ;        //绿色LED引脚置高,蓝色LED灭

        }

        

}



/**

  * @brief :LED闪烁

  * @param :

  *                        @LedPort:LED选择,红色或绿色

  * @note  :无

  * @retval:无

  */

void drv_led_flashing( LedPortType LedPort )

{

        //引脚翻转,LED闪烁

        if( LED_RED == LedPort )

        {

                RED_LED_Toggle();        

        }

        else

        {

                ;

        }

}

按钮的使用,也是非常容易,直接使用MCC生成的函数

/**

  * @brief :按键查询

  * @param :无

  * @note  :无

  * @retval:

  *                        0:按键没有按下

  *                        1:检测到按键动作

  */

uint8_t drv_button_check( void )

{

        if( 0x00 == (BUTTON_GetValue() & 0x01 ))                //检测按键输入状态

        {

                drv_delay_ms( 40 );                        //消抖

                if( 0x00 == (BUTTON_GetValue()& 0x01 ))

                {

                        return 1;                                //按键按下,返回按键状态

                }

        }

        

        return 0;

}

cc1101库函数里的相关操作也是使用MCC的生成函数替换

#define CC1101_SET_CSN_HIGH( )                        spi_set_nss_high( )

#define CC1101_SET_CSN_LOW( )                        spi_set_nss_low( )



#define CC1101_GET_GDO0_STATUS( )                (( GDO0_GetValue()) == 0x00 ) ? 0 : 1        //GDO0状态

#define CC1101_GET_GDO2_STATUS( )                (( GDO2_GetValue()) == 0x00 ) ? 0 : 1        //GDO2状态

至此,我们基本上没去了解关于寄存器的任何知识,就完成了移植。


最后奉上main.c的完整内容


#include "mcc_generated_files/mcc.h"

#include"drv_periph/inc/drv_CC1101.h"

#include"drv_mcu/inc/drv_button.h"

#include"drv_mcu/inc/drv_delay.h"

#include"drv_mcu/inc/drv_spi.h"

#include"drv_mcu/inc/drv_uart.h"

#include"drv_mcu/inc/drv_led.h"

#include"string.h"



#define        __CC1101_TX_TEST__        

/*

                         Main application

 */

const char *g_Text = "Hello I'm PIC18F16Q41";

uint8_t g_TxMode = 0, g_UartRxFlag = 0;

uint8_t g_UartRxBuffer[ 100 ] = { 0 };

uint8_t g_RF24L01RxBuffer[ 32 ] = { 0 }; 

/** 发送模式定义 */

enum

{

        TX_MODE_1 = 0,                //发送模式1,发送固定的字符串

        TX_MODE_2                        //发送模式2,发送串口接收到的数据

};



void main(void)

{

    uint8_t i = 0;

    // Initialize the device

    SYSTEM_Initialize();



    // If using interrupts in PIC18 High/Low Priority Mode you need to enable the Global High and Low Interrupts

    // If using interrupts in PIC Mid-Range Compatibility Mode you need to enable the Global Interrupts

    // Use the following macros to:



    // Enable the Global Interrupts

    //INTERRUPT_GlobalInterruptEnable();



    // Disable the Global Interrupts

    //INTERRUPT_GlobalInterruptDisable();

    printf("Hello\n");

            //CC1101初始化

        CC1101_Init( );

        for( i = 0; i < 6; i++ )

        {

                led_red_flashing( );

                led_green_flashing( );

                drv_delay_ms( 500 );

        }

    

#ifdef        __CC1101_TX_TEST__        

        

        //按键初始化

        drv_button_init( );



        while( 1 )        

        {

                //模式切换

                //Demo程序默认为发送模式1,即发送固定字符串“Hello I'm PIC18F16Q41"”,可以通过按键切换到发送模式2,即通过串口发送数据,按键的作用就是切换发送模式1 2

                //如果在程序移植过程中不需要两种发送模式,删除下面 if 语句程序块和按键初始化程序即可

                if( BUTOTN_PRESS_DOWN == drv_button_check( ))

                {

                        g_TxMode = 1 - g_TxMode;                //模式会在 TX_MODE_1( 0 ),TX_MODE_2( 1 )之间切换

                        

                        //状态显示清零

                        led_green_off( );

                        led_red_off( );

                        

                        if( TX_MODE_1 == g_TxMode )

                        {

                                for( i = 0; i < 6; i++ )                

                                {

                                        led_red_flashing( );        //固定发送模式,红灯闪烁3次

                                        drv_delay_ms( 500 );                

                                }

                        }

                        else

                        {

                                for( i = 0; i < 2; i++ )

                                {

                                        led_red_flashing( );        //串口发送模式,绿灯闪烁3次

                                        drv_delay_ms( 500 );

                                }

                        }

                }



                //如果在程序移植过程中不需要两种发送模式,删除上面 if 语句程序块和按键初始化程序即可

                //模式切换



                

                //发送

                if( TX_MODE_1 == g_TxMode )

                {

                        CC1101_Tx_Packet( (uint8_t *)g_Text, strlen(g_Text) , ADDRESS_CHECK );                //模式1发送固定字符,1S一包

                        drv_delay_ms( 1000 );        

                        led_red_flashing( );                        

                }

                else

                {        

                        //查询串口数据

                        i = drv_uart_rx_bytes( g_UartRxBuffer );

                        

                        if( 0 != i )

                        {

                                CC1101_Tx_Packet( g_UartRxBuffer, i , ADDRESS_CHECK );

                                led_red_flashing( );

                        }

                }

        }    

 #else

/*

 接收 

 */

    while (1)

    {

//        DELAY_milliseconds(1000);

//        printf("Hello World \n");



        CC1101_Clear_RxBuffer( );

                CC1101_Set_Mode( RX_MODE );



                i = CC1101_Rx_Packet( g_RF24L01RxBuffer );                //接收字节

                if( 0 != i )

                {

                        led_red_flashing( );

                        drv_uart_tx_bytes( g_RF24L01RxBuffer, i );        //输出接收到的字节

            printf("\n");

                }

    }

#endif    

}

/**

 End of File

*/

---------------------
作者:gaoyang9992006
链接:https://bbs.21ic.com/icview-3179858-1-1.html
来源:21ic.com
此文章已获得原创/原创奖标签,著作权归21ic所有,任何人未经允许禁止转载。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值