查看: 3249|回复: 3

[主题月] 【7月主题】LPC845+HC05 蓝牙控制LED亮灭

[复制链接]
  • TA的每日心情

    2025-5-29 09:38
  • 签到天数: 632 天

    连续签到: 1 天

    [LV.9]以坛为家II

    94

    主题

    1639

    帖子

    2

    版主

    Rank: 7Rank: 7Rank: 7

    积分
    4470

    热心会员

    最后登录
    2025-6-10
    发表于 2021-7-28 15:24:05 | 显示全部楼层 |阅读模式
    本帖最后由 胤幻1988 于 2021-7-28 15:34 编辑

    最近刮台风啊,风挺大,很凉爽,然后老板夜里着凉,拉肚回家了。然后我就又有点小空了。这里我用LPC845自制版来驱动HC05蓝牙模块,来控制板上的2个小灯~
    主要硬件:
    MM2.jpg
    MM3.jpg

    //HC05_TXD-->          P1_16(U1_RXD)
    //HC05_RXD-->          P1_17(U1_TXD)
    //HC05_STA(LED)-->  P1_6
    //HC05_EN(KEY) -->   P1_2


    正好之前拿来驱动ESP8266的座子引脚几乎一直,只要稍微改造下就可以直接用了。
    软件,现用配置工具配置一些初始化代码:
    //GPIO
    AA1.jpg
    //时钟
    AA2.jpg
    //外设
    AA3.jpg
    AA4.jpg
    AA5.jpg
    这里启用USART0输出调试信息,USART1与HC05通讯,CT0作为USART1接收结束检测,SYSTEMCLOK上面未体现,直接写在代码里面,配制成
    延时函数的基准定时器。
    生成初始化代码后,我们要对外设的中断函数进行修改:
    主要是USART1与HC05通讯:
    USART1.H
    1. #ifndef __USART1_H_
    2. #define __USART1_H_

    3. #include "sys.h"
    4. #include "pin_mux.h"
    5. #include "peripherals.h"
    6. #include "fsl_gpio.h"
    7. #include "fsl_usart.h"
    8. #include "stdio.h"        

    9. #define USART1_MAX_RECV_LEN                600                                        //最大接收缓存字节数
    10. #define USART1_MAX_SEND_LEN                600                                        //最大发送缓存字节数
    11. #define USART1_RX_EN                         1                                        //0,不接收;1,接收.

    12. extern u8  USART1_RX_BUF[USART1_MAX_RECV_LEN];                 //接收缓冲,最大USART1_MAX_RECV_LEN字节
    13. extern u8  USART1_TX_BUF[USART1_MAX_SEND_LEN];                 //发送缓冲,最大USART1_MAX_SEND_LEN字节
    14. extern vu16 USART1_RX_STA;                                                   //接收数据状态

    15. void usart1_init(u32 bound);                                //串口1初始化
    16. void u1_printf(char* fmt,...);


    17. #endif
    复制代码

    USART1.C
    1. #include "usart1.h"
    2. #include "stdarg.h"                  
    3. #include "stdio.h"                  
    4. #include "string.h"        
    5. #include "math.h"
    6. #include "delay.h"
    7. #include "sctime.h"

    8. //串口接收缓存区         
    9. u8  USART1_RX_BUF[USART1_MAX_RECV_LEN];                                 //接收缓冲,最大USART1_MAX_RECV_LEN个字节.
    10. u8  USART1_TX_BUF[USART1_MAX_SEND_LEN];                         //发送缓冲,最大USART1_MAX_SEND_LEN字节

    11. //通过判断接收连续2个字符之间的时间差不大于10ms来决定是不是一次连续的数据.
    12. //如果2个字符接收间隔超过10ms,则认为不是1次连续数据.也就是超过10ms没有接收到
    13. //任何数据,则表示此次接收完毕.
    14. //接收到的数据状态
    15. //[15]:0,没有接收到数据;1,接收到了一批数据.
    16. //[14:0]:接收到的数据长度
    17. vu16 USART1_RX_STA=0;           


    18. void USART1_IRQHandler(void)
    19. {
    20.     /*  Place your code here */
    21.         u8 res;        
    22.     uint32_t status;
    23.     status = USART1->STAT;
    24.    
    25.         if((status & USART_STAT_RXRDY_MASK) != RESET)//接收到数据
    26.         {         
    27.                 res =USART_ReadByte(USART1);                 
    28.                 if((USART1_RX_STA&(1<<15))==0)//接收完的一批数据,还没有被处理,则不再接收其他数据
    29.                 {
    30.                         if(USART1_RX_STA<USART1_MAX_RECV_LEN)        //还可以接收数据
    31.                         {
    32.                 CTIMER0_PERIPHERAL->TC=0;;          //计数器清空
    33.                                 if(USART1_RX_STA==0)                                 //使能定时器7的中断
    34.                                 {
    35.                     CTIMER_StartTimer(CTIMER0_PERIPHERAL);//使能定时器
    36.                                 }
    37.                                 USART1_RX_BUF[USART1_RX_STA++]=res;        //记录接收到的值         
    38.                         }else
    39.                         {
    40.                                 USART1_RX_STA|=1<<15;                                //强制标记接收完成
    41.                         }
    42.                 }
    43.         }
    44.     USART_ClearStatusFlags(USART1,status);
    45.     /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F
    46.      Store immediate overlapping exception return operation might vector to incorrect interrupt. */
    47.     #if defined __CORTEX_M && (__CORTEX_M == 4U)
    48.     __DSB();
    49.     #endif   
    50. }   


    51. //初始化IO 串口1
    52. //pclk1:PCLK1时钟频率(Mhz)
    53. //bound:波特率         
    54. void usart1_init(u32 bound)
    55. {  
    56.      usart_config_t USART1_config = {
    57.       .baudRate_Bps = bound,
    58.       .syncMode = kUSART_SyncModeDisabled,
    59.       .parityMode = kUSART_ParityDisabled,
    60.       .stopBitCount = kUSART_OneStopBit,
    61.       .bitCountPerChar = kUSART_8BitsPerChar,
    62.       .loopback = false,
    63.       .enableRx = true,
    64.       .enableTx = true,
    65.       .clockPolarity = kUSART_RxSampleOnFallingEdge,
    66.       .enableContinuousSCLK = false
    67.     };


    68.     /* USART1 peripheral initialization */
    69.     USART_Init(USART1_PERIPHERAL, &USART1_config, USART1_CLOCK_SOURCE);
    70.     USART_EnableInterrupts(USART1_PERIPHERAL, kUSART_RxReadyInterruptEnable);
    71.     /* Enable interrupt USART1_IRQn request in the NVIC. */
    72.     EnableIRQ(USART1_USART_IRQN);
    73.         
    74.     //CTIME0_Init();
    75.     USART1_RX_STA=0;                //清零
    76.     CTIMER_StopTimer(CTIMER0_PERIPHERAL);//关闭CT0定时器

    77. }

    78. //串口1,printf 函数
    79. //确保一次发送数据不超过USART1_MAX_SEND_LEN字节
    80. void u1_printf(char* fmt,...)  
    81. {  
    82.         u16 i,j;
    83.         va_list ap;
    84.         va_start(ap,fmt);
    85.         vsprintf((char*)USART1_TX_BUF,fmt,ap);
    86.         va_end(ap);
    87.         i=strlen((const char*)USART1_TX_BUF);                //此次发送数据的长度
    88.         for(j=0;j<i;j++)                                                        //循环发送数据
    89.         {
    90.         while((USART1->STAT & USART_STAT_TXRDY_MASK)==RESET){};//循环发送,直到发送完毕   
    91.         USART1->TXDAT = (u8) USART1_TX_BUF[j];   
    92.         }
    93. }
    复制代码
    CTIME.H
    1. #ifndef __CTIME_H_
    2. #define __CTIME_H_

    3. #include "sys.h"
    4. #include "pin_mux.h"
    5. #include "peripherals.h"
    6. #include "fsl_gpio.h"

    7. void CTIME0_Init(u32 prescale,u16 matchValue);

    8. #endif
    复制代码

    CTIME.C
    1. #include "ctime.h"

    2. //prescale时钟分频
    3. //matchValue 累加事件触发数
    4. void CTIME0_Init(u32 prescale,u16 matchValue )
    5. {
    6.     ctimer_config_t CTIMER0_config = {
    7.     .mode = kCTIMER_TimerMode,
    8.     .input = kCTIMER_Capture_0,
    9.     .prescale = prescale-1
    10.     };
    11.     ctimer_match_config_t CTIMER0_Match_0_config = {
    12.     .matchValue = matchValue,
    13.     .enableCounterReset = true,
    14.     .enableCounterStop = false,
    15.     .outControl = kCTIMER_Output_NoAction,
    16.     .outPinInitState = false,
    17.     .enableInterrupt = true
    18.     };
    19.     /* Single callback functions definition */
    20.     ctimer_callback_t CTIMER0_callback[] = {CTIMER0_IRQn_Match0_callback};

    21.     CTIMER_StopTimer(CTIMER0_PERIPHERAL);
    22.     CTIMER_Deinit(CTIMER0_PERIPHERAL);
    23.     /* CTIMER0 peripheral initialization */
    24.     CTIMER_Init(CTIMER0_PERIPHERAL, &CTIMER0_config);
    25.     /* Interrupt vector CTIMER0_IRQn priority settings in the NVIC. */
    26.     NVIC_SetPriority(CTIMER0_TIMER_IRQN, CTIMER0_TIMER_IRQ_PRIORITY);
    27.     /* Match channel 0 of CTIMER0 peripheral initialization */
    28.     CTIMER_SetupMatch(CTIMER0_PERIPHERAL, CTIMER0_MATCH_0_CHANNEL, &CTIMER0_Match_0_config);
    29.     CTIMER_RegisterCallBack(CTIMER0_PERIPHERAL, CTIMER0_callback, kCTIMER_SingleCallback);
    30.     /* Start the timer */
    31.     CTIMER_StartTimer(CTIMER0_PERIPHERAL);

    32. }

    33. #include "led.h"
    34. #include "usart1.h"
    35. //#include "tmt.h"
    36. //设定为每100ms中断一次
    37. static u16 mscnt=0;
    38. void CTIMER0_IRQn_Match0_callback(uint32_t flags)
    39. {
    40.    
    41. //    mscnt++;
    42. //    if(mscnt==100)
    43. //    {
    44. //        LED_RED_T;
    45. //        mscnt=0;
    46. //    }
    47. //    u1_printf("ctimer\r\n");
    48.     USART1_RX_STA|=1<<15;        //标记接收完成
    49.     CTIMER_StopTimer(CTIMER0_PERIPHERAL);//关闭SCT0定时器
    50.    
    51. }
    复制代码
    HC05.H
    1. #ifndef __HC05_H_
    2. #define __HC05_H_

    3. #include "sys.h"
    4. #include "pin_mux.h"
    5. #include "peripherals.h"

    6. //HC05_TXD-->P1_16(U1_RXD)
    7. //HC05_RXD-->P1_17(U1_TXD)
    8. //HC05_STA-->P1_6
    9. //HC05_EN -->P1_2


    10. /*! @name PIO1_6 (number 38), hc05_led
    11.   @{ */

    12. /* Symbols to be used with GPIO driver */
    13. #define HC05_LED_GPIO               BOARD_INITPINS_hc05_led_GPIO            /*!<@brief GPIO peripheral base pointer */
    14. #define HC05_LED_GPIO_PIN_MASK      BOARD_INITPINS_hc05_led_GPIO_PIN_MASK  /*!<@brief GPIO pin mask */
    15. #define HC05_LED_PORT               BOARD_INITPINS_hc05_led_PORT                  /*!<@brief PORT device index: 1 */
    16. #define HC05_LED_PIN                BOARD_INITPINS_hc05_led_PIN                 /*!<@brief PORT pin number */
    17. #define HC05_LED_PIN_MASK           BOARD_INITPINS_hc05_led_PIN_MASK       /*!<@brief PORT pin mask */
    18.                                                          /* @} */

    19. /*! @name PIO1_2 (number 20), hc05_key
    20.   @{ */

    21. /* Symbols to be used with GPIO driver */
    22. #define HC05_KEY_GPIO               BOARD_INITPINS_hc05_key_GPIO              /*!<@brief GPIO peripheral base pointer */
    23. #define hc05_key_GPIO_PIN_MASK      BOARD_INITPINS_hc05_key_GPIO_PIN_MASK  /*!<@brief GPIO pin mask */
    24. #define HC05_KEY_PORT               BOARD_INITPINS_hc05_key_PORT                   /*!<@brief PORT device index: 1 */
    25. #define HC05_KEY_PIN                BOARD_INITPINS_hc05_key_PIN                    /*!<@brief PORT pin number */
    26. #define HC05_KEY_PIN_MASK           BOARD_INITPINS_hc05_key_PIN_MASK     /*!<@brief PORT pin mask */
    27.                                                          /* @} */

    28. #define HC05_KEY(x)                      GPIO_PinWrite(HC05_KEY_GPIO, HC05_KEY_PORT, HC05_KEY_PIN, x)                 //蓝牙控制KEY信号
    29. #define HC05_LED()                      GPIO_PinRead(HC05_LED_GPIO, HC05_LED_PORT,HC05_LED_PIN)    //蓝牙连接状态信号
    30.   
    31. u8 HC05_Init(void);
    32. void HC05_CFG_CMD(u8 *str);
    33. u8 HC05_Get_Role(void);
    34. u8 HC05_Set_Cmd(u8* atstr);         

    35. #endif
    复制代码

    HC05.C
    1. #include "hc05.h"
    2. #include "stdarg.h"                  
    3. #include "stdio.h"                  
    4. #include "string.h"        
    5. #include "math.h"
    6. #include "delay.h"
    7. #include "usart.h"
    8. #include "usart1.h"
    9. #include "ctime.h"

    10. /////////////////////HC05/////////////////////////////
    11. //初始化ATK-HC05模块
    12. //返回值:0,成功;1,失败.
    13. u8 HC05_Init(void)
    14. {
    15.         u8 retry=10,t;                           
    16.         u8 temp=1;
    17.         
    18.     //GPIO初始化在pin_mux
    19.         //usart1_init(9600);        //初始化串口2为:9600,波特率.
    20.         
    21.         while(retry--)
    22.         {
    23.                 HC05_KEY(1);                                        //KEY置高,进入AT模式
    24.                 delay_ms(10);
    25.                 u1_printf("AT\r\n");                //发送AT测试指令
    26.                 HC05_KEY(0);                                        //KEY拉低,退出AT模式
    27.                 for(t=0;t<10;t++)                         //最长等待50ms,来接收HC05模块的回应
    28.                 {
    29.                         if(USART1_RX_STA&0X8000)break;
    30.                         delay_ms(5);
    31.                 }               
    32.                 if(USART1_RX_STA&0X8000)        //接收到一次数据了
    33.                 {
    34.                         temp=USART1_RX_STA&0X7FFF;        //得到数据长度
    35.                         USART1_RX_STA=0;                        
    36.                         if(temp==4&&USART1_RX_BUF[0]=='O'&&USART1_RX_BUF[1]=='K')
    37.                         {
    38.                                 temp=0;//接收到OK响应
    39.                                 break;
    40.                         }
    41.                 }                                            
    42.         }                    
    43.         if(retry==0)temp=1;        //检测失败
    44.         return temp;         
    45. }         
    46. //获取ATK-HC05模块的角色
    47. //返回值:0,从机;1,主机;0XFF,获取失败.                                                         
    48. u8 HC05_Get_Role(void)
    49. {                             
    50.         u8 retry=0X0F;
    51.         u8 temp,t;
    52.         while(retry--)
    53.         {
    54.                 HC05_KEY(1);                                        //KEY置高,进入AT模式
    55.                 delay_ms(10);
    56.                 u1_printf("AT+ROLE?\r\n");        //查询角色
    57.                 for(t=0;t<20;t++)                         //最长等待200ms,来接收HC05模块的回应
    58.                 {
    59.                         delay_ms(10);
    60.                         if(USART1_RX_STA&0X8000)break;
    61.                 }               
    62.                 HC05_KEY(0);                                        //KEY拉低,退出AT模式
    63.                 if(USART1_RX_STA&0X8000)        //接收到一次数据了
    64.                 {
    65.                         temp=USART1_RX_STA&0X7FFF;        //得到数据长度
    66.                         USART1_RX_STA=0;                        
    67.                         if(temp==13&&USART1_RX_BUF[0]=='+')//接收到正确的应答了
    68.                         {
    69.                                 temp=USART1_RX_BUF[6]-'0';//得到主从模式值
    70.                                 break;
    71.                         }
    72.                 }               
    73.         }
    74.         if(retry==0)temp=0XFF;//查询失败.
    75.         return temp;
    76. }                                                            
    77. //ATK-HC05设置命令
    78. //此函数用于设置ATK-HC05,适用于仅返回OK应答的AT指令
    79. //atstr:AT指令串.比如:"AT+RESET"/"AT+UART=9600,0,0"/"AT+ROLE=0"等字符串
    80. //返回值:0,设置成功;其他,设置失败.                                                         
    81. u8 HC05_Set_Cmd(u8* atstr)
    82. {                             
    83.         u8 retry=0X0F;
    84.         u8 temp,t;
    85.         while(retry--)
    86.         {
    87.                 HC05_KEY(1);                                        //KEY置高,进入AT模式
    88.                 delay_ms(10);
    89.                 u1_printf("%s\r\n",atstr);        //发送AT字符串
    90.                 HC05_KEY(0);                                        //KEY拉低,退出AT模式
    91.                 for(t=0;t<20;t++)                         //最长等待100ms,来接收HC05模块的回应
    92.                 {
    93.                         if(USART1_RX_STA&0X8000)break;
    94.                         delay_ms(5);
    95.                 }               
    96.                 if(USART1_RX_STA&0X8000)        //接收到一次数据了
    97.                 {
    98.                         temp=USART1_RX_STA&0X7FFF;        //得到数据长度
    99.                         USART1_RX_STA=0;                        
    100.                         if(temp==4&&USART1_RX_BUF[0]=='O')//接收到正确的应答了
    101.                         {                        
    102.                                 temp=0;
    103.                                 break;                        
    104.                         }
    105.                 }               
    106.         }
    107.         if(retry==0)temp=0XFF;//设置失败.
    108.         return temp;
    109. }
    110. ///////////////////////////////////////////////////////////////////////////////////////////////////
    111. //通过该函数,可以利用USMART,调试接在串口3上的ATK-HC05模块
    112. //str:命令串.(这里注意不再需要再输入回车符)
    113. void HC05_CFG_CMD(u8 *str)
    114. {                                          
    115.         u8 temp;
    116.         u8 t;                  
    117.         HC05_KEY(1);                                                //KEY置高,进入AT模式
    118.         delay_ms(10);
    119.         u1_printf("%s\r\n",(char*)str); //发送指令
    120.         for(t=0;t<50;t++)                                 //最长等待500ms,来接收HC05模块的回应
    121.         {
    122.                 if(USART1_RX_STA&0X8000)break;
    123.                 delay_ms(10);
    124.         }                                                                           
    125.         HC05_KEY(0);                                                //KEY拉低,退出AT模式
    126.         if(USART1_RX_STA&0X8000)                //接收到一次数据了
    127.         {
    128.                 temp=USART1_RX_STA&0X7FFF;        //得到数据长度
    129.                 USART1_RX_STA=0;
    130.                 USART1_RX_BUF[temp]=0;                //加结束符                 
    131.                 printf("\r\n%s",USART1_RX_BUF);//发送回应数据到串口1
    132.         }                                 
    133. }
    复制代码
    HC05常见AT指令:
    WW1.jpg
    编译好下载到时板上,打开手机蓝牙调试工具 BTClient.rar (1.08 MB, 下载次数: 0)
    哎...今天够累的,签到来了~
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2025-7-11 08:53
  • 签到天数: 301 天

    连续签到: 2 天

    [LV.8]以坛为家I

    3939

    主题

    7560

    帖子

    0

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    40226
    最后登录
    2025-9-10
    发表于 2021-7-28 15:36:44 | 显示全部楼层
    老板拉肚子可还行,哈哈哈哈
    qiandao qiandao
    回复 支持 反对

    使用道具 举报

  • TA的每日心情

    2025-5-29 09:38
  • 签到天数: 632 天

    连续签到: 1 天

    [LV.9]以坛为家II

    94

    主题

    1639

    帖子

    2

    版主

    Rank: 7Rank: 7Rank: 7

    积分
    4470

    热心会员

    最后登录
    2025-6-10
     楼主| 发表于 2021-7-28 15:59:26 | 显示全部楼层
    NXP管管 发表于 2021-7-28 15:36
    老板拉肚子可还行,哈哈哈哈

    一个字:“爽”
    哎...今天够累的,签到来了~
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    擦汗
    2016-12-2 08:40
  • 签到天数: 3 天

    连续签到: 1 天

    [LV.2]偶尔看看I

    103

    主题

    869

    帖子

    7

    版主

    Rank: 7Rank: 7Rank: 7

    积分
    4353
    最后登录
    2025-8-21
    发表于 2021-7-28 16:06:20 | 显示全部楼层
    厉害了
    回复

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /3 下一条

    Archiver|手机版|小黑屋|恩智浦技术社区

    GMT+8, 2025-9-10 08:52 , Processed in 0.095272 second(s), 23 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.

    快速回复 返回顶部 返回列表