在线时间376 小时
UID3135871
注册时间2016-10-9
NXP金币97

TA的每日心情 | 怒 2025-5-29 09:38 |
---|
签到天数: 632 天 连续签到: 1 天 [LV.9]以坛为家II
版主
  
- 积分
- 4470

- 最后登录
- 2025-6-10
|
本帖最后由 胤幻1988 于 2021-7-28 15:34 编辑
最近刮台风啊,风挺大,很凉爽,然后老板夜里着凉,拉肚回家了。然后我就又有点小空了。这里我用LPC845自制版来驱动HC05蓝牙模块,来控制板上的2个小灯~
主要硬件:
//HC05_TXD--> P1_16(U1_RXD)
//HC05_RXD--> P1_17(U1_TXD)
//HC05_STA(LED)--> P1_6
//HC05_EN(KEY) --> P1_2
正好之前拿来驱动ESP8266的座子引脚几乎一直,只要稍微改造下就可以直接用了。
软件,现用配置工具配置一些初始化代码:
//GPIO
//时钟
//外设
这里启用USART0输出调试信息,USART1与HC05通讯,CT0作为USART1接收结束检测,SYSTEMCLOK上面未体现,直接写在代码里面,配制成
延时函数的基准定时器。
生成初始化代码后,我们要对外设的中断函数进行修改:
主要是USART1与HC05通讯:
USART1.H
- #ifndef __USART1_H_
- #define __USART1_H_
- #include "sys.h"
- #include "pin_mux.h"
- #include "peripherals.h"
- #include "fsl_gpio.h"
- #include "fsl_usart.h"
- #include "stdio.h"
- #define USART1_MAX_RECV_LEN 600 //最大接收缓存字节数
- #define USART1_MAX_SEND_LEN 600 //最大发送缓存字节数
- #define USART1_RX_EN 1 //0,不接收;1,接收.
- extern u8 USART1_RX_BUF[USART1_MAX_RECV_LEN]; //接收缓冲,最大USART1_MAX_RECV_LEN字节
- extern u8 USART1_TX_BUF[USART1_MAX_SEND_LEN]; //发送缓冲,最大USART1_MAX_SEND_LEN字节
- extern vu16 USART1_RX_STA; //接收数据状态
- void usart1_init(u32 bound); //串口1初始化
- void u1_printf(char* fmt,...);
- #endif
复制代码
USART1.C
- #include "usart1.h"
- #include "stdarg.h"
- #include "stdio.h"
- #include "string.h"
- #include "math.h"
- #include "delay.h"
- #include "sctime.h"
- //串口接收缓存区
- u8 USART1_RX_BUF[USART1_MAX_RECV_LEN]; //接收缓冲,最大USART1_MAX_RECV_LEN个字节.
- u8 USART1_TX_BUF[USART1_MAX_SEND_LEN]; //发送缓冲,最大USART1_MAX_SEND_LEN字节
- //通过判断接收连续2个字符之间的时间差不大于10ms来决定是不是一次连续的数据.
- //如果2个字符接收间隔超过10ms,则认为不是1次连续数据.也就是超过10ms没有接收到
- //任何数据,则表示此次接收完毕.
- //接收到的数据状态
- //[15]:0,没有接收到数据;1,接收到了一批数据.
- //[14:0]:接收到的数据长度
- vu16 USART1_RX_STA=0;
- void USART1_IRQHandler(void)
- {
- /* Place your code here */
- u8 res;
- uint32_t status;
- status = USART1->STAT;
-
- if((status & USART_STAT_RXRDY_MASK) != RESET)//接收到数据
- {
- res =USART_ReadByte(USART1);
- if((USART1_RX_STA&(1<<15))==0)//接收完的一批数据,还没有被处理,则不再接收其他数据
- {
- if(USART1_RX_STA<USART1_MAX_RECV_LEN) //还可以接收数据
- {
- CTIMER0_PERIPHERAL->TC=0;; //计数器清空
- if(USART1_RX_STA==0) //使能定时器7的中断
- {
- CTIMER_StartTimer(CTIMER0_PERIPHERAL);//使能定时器
- }
- USART1_RX_BUF[USART1_RX_STA++]=res; //记录接收到的值
- }else
- {
- USART1_RX_STA|=1<<15; //强制标记接收完成
- }
- }
- }
- USART_ClearStatusFlags(USART1,status);
- /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F
- Store immediate overlapping exception return operation might vector to incorrect interrupt. */
- #if defined __CORTEX_M && (__CORTEX_M == 4U)
- __DSB();
- #endif
- }
- //初始化IO 串口1
- //pclk1:PCLK1时钟频率(Mhz)
- //bound:波特率
- void usart1_init(u32 bound)
- {
- usart_config_t USART1_config = {
- .baudRate_Bps = bound,
- .syncMode = kUSART_SyncModeDisabled,
- .parityMode = kUSART_ParityDisabled,
- .stopBitCount = kUSART_OneStopBit,
- .bitCountPerChar = kUSART_8BitsPerChar,
- .loopback = false,
- .enableRx = true,
- .enableTx = true,
- .clockPolarity = kUSART_RxSampleOnFallingEdge,
- .enableContinuousSCLK = false
- };
- /* USART1 peripheral initialization */
- USART_Init(USART1_PERIPHERAL, &USART1_config, USART1_CLOCK_SOURCE);
- USART_EnableInterrupts(USART1_PERIPHERAL, kUSART_RxReadyInterruptEnable);
- /* Enable interrupt USART1_IRQn request in the NVIC. */
- EnableIRQ(USART1_USART_IRQN);
-
- //CTIME0_Init();
- USART1_RX_STA=0; //清零
- CTIMER_StopTimer(CTIMER0_PERIPHERAL);//关闭CT0定时器
- }
- //串口1,printf 函数
- //确保一次发送数据不超过USART1_MAX_SEND_LEN字节
- void u1_printf(char* fmt,...)
- {
- u16 i,j;
- va_list ap;
- va_start(ap,fmt);
- vsprintf((char*)USART1_TX_BUF,fmt,ap);
- va_end(ap);
- i=strlen((const char*)USART1_TX_BUF); //此次发送数据的长度
- for(j=0;j<i;j++) //循环发送数据
- {
- while((USART1->STAT & USART_STAT_TXRDY_MASK)==RESET){};//循环发送,直到发送完毕
- USART1->TXDAT = (u8) USART1_TX_BUF[j];
- }
- }
复制代码 CTIME.H
- #ifndef __CTIME_H_
- #define __CTIME_H_
- #include "sys.h"
- #include "pin_mux.h"
- #include "peripherals.h"
- #include "fsl_gpio.h"
- void CTIME0_Init(u32 prescale,u16 matchValue);
- #endif
复制代码
CTIME.C
- #include "ctime.h"
- //prescale时钟分频
- //matchValue 累加事件触发数
- void CTIME0_Init(u32 prescale,u16 matchValue )
- {
- ctimer_config_t CTIMER0_config = {
- .mode = kCTIMER_TimerMode,
- .input = kCTIMER_Capture_0,
- .prescale = prescale-1
- };
- ctimer_match_config_t CTIMER0_Match_0_config = {
- .matchValue = matchValue,
- .enableCounterReset = true,
- .enableCounterStop = false,
- .outControl = kCTIMER_Output_NoAction,
- .outPinInitState = false,
- .enableInterrupt = true
- };
- /* Single callback functions definition */
- ctimer_callback_t CTIMER0_callback[] = {CTIMER0_IRQn_Match0_callback};
- CTIMER_StopTimer(CTIMER0_PERIPHERAL);
- CTIMER_Deinit(CTIMER0_PERIPHERAL);
- /* CTIMER0 peripheral initialization */
- CTIMER_Init(CTIMER0_PERIPHERAL, &CTIMER0_config);
- /* Interrupt vector CTIMER0_IRQn priority settings in the NVIC. */
- NVIC_SetPriority(CTIMER0_TIMER_IRQN, CTIMER0_TIMER_IRQ_PRIORITY);
- /* Match channel 0 of CTIMER0 peripheral initialization */
- CTIMER_SetupMatch(CTIMER0_PERIPHERAL, CTIMER0_MATCH_0_CHANNEL, &CTIMER0_Match_0_config);
- CTIMER_RegisterCallBack(CTIMER0_PERIPHERAL, CTIMER0_callback, kCTIMER_SingleCallback);
- /* Start the timer */
- CTIMER_StartTimer(CTIMER0_PERIPHERAL);
- }
- #include "led.h"
- #include "usart1.h"
- //#include "tmt.h"
- //设定为每100ms中断一次
- static u16 mscnt=0;
- void CTIMER0_IRQn_Match0_callback(uint32_t flags)
- {
-
- // mscnt++;
- // if(mscnt==100)
- // {
- // LED_RED_T;
- // mscnt=0;
- // }
- // u1_printf("ctimer\r\n");
- USART1_RX_STA|=1<<15; //标记接收完成
- CTIMER_StopTimer(CTIMER0_PERIPHERAL);//关闭SCT0定时器
-
- }
复制代码 HC05.H
- #ifndef __HC05_H_
- #define __HC05_H_
- #include "sys.h"
- #include "pin_mux.h"
- #include "peripherals.h"
- //HC05_TXD-->P1_16(U1_RXD)
- //HC05_RXD-->P1_17(U1_TXD)
- //HC05_STA-->P1_6
- //HC05_EN -->P1_2
- /*! @name PIO1_6 (number 38), hc05_led
- @{ */
- /* Symbols to be used with GPIO driver */
- #define HC05_LED_GPIO BOARD_INITPINS_hc05_led_GPIO /*!<@brief GPIO peripheral base pointer */
- #define HC05_LED_GPIO_PIN_MASK BOARD_INITPINS_hc05_led_GPIO_PIN_MASK /*!<@brief GPIO pin mask */
- #define HC05_LED_PORT BOARD_INITPINS_hc05_led_PORT /*!<@brief PORT device index: 1 */
- #define HC05_LED_PIN BOARD_INITPINS_hc05_led_PIN /*!<@brief PORT pin number */
- #define HC05_LED_PIN_MASK BOARD_INITPINS_hc05_led_PIN_MASK /*!<@brief PORT pin mask */
- /* @} */
- /*! @name PIO1_2 (number 20), hc05_key
- @{ */
- /* Symbols to be used with GPIO driver */
- #define HC05_KEY_GPIO BOARD_INITPINS_hc05_key_GPIO /*!<@brief GPIO peripheral base pointer */
- #define hc05_key_GPIO_PIN_MASK BOARD_INITPINS_hc05_key_GPIO_PIN_MASK /*!<@brief GPIO pin mask */
- #define HC05_KEY_PORT BOARD_INITPINS_hc05_key_PORT /*!<@brief PORT device index: 1 */
- #define HC05_KEY_PIN BOARD_INITPINS_hc05_key_PIN /*!<@brief PORT pin number */
- #define HC05_KEY_PIN_MASK BOARD_INITPINS_hc05_key_PIN_MASK /*!<@brief PORT pin mask */
- /* @} */
- #define HC05_KEY(x) GPIO_PinWrite(HC05_KEY_GPIO, HC05_KEY_PORT, HC05_KEY_PIN, x) //蓝牙控制KEY信号
- #define HC05_LED() GPIO_PinRead(HC05_LED_GPIO, HC05_LED_PORT,HC05_LED_PIN) //蓝牙连接状态信号
-
- u8 HC05_Init(void);
- void HC05_CFG_CMD(u8 *str);
- u8 HC05_Get_Role(void);
- u8 HC05_Set_Cmd(u8* atstr);
- #endif
复制代码
HC05.C
- #include "hc05.h"
- #include "stdarg.h"
- #include "stdio.h"
- #include "string.h"
- #include "math.h"
- #include "delay.h"
- #include "usart.h"
- #include "usart1.h"
- #include "ctime.h"
- /////////////////////HC05/////////////////////////////
- //初始化ATK-HC05模块
- //返回值:0,成功;1,失败.
- u8 HC05_Init(void)
- {
- u8 retry=10,t;
- u8 temp=1;
-
- //GPIO初始化在pin_mux
- //usart1_init(9600); //初始化串口2为:9600,波特率.
-
- while(retry--)
- {
- HC05_KEY(1); //KEY置高,进入AT模式
- delay_ms(10);
- u1_printf("AT\r\n"); //发送AT测试指令
- HC05_KEY(0); //KEY拉低,退出AT模式
- for(t=0;t<10;t++) //最长等待50ms,来接收HC05模块的回应
- {
- if(USART1_RX_STA&0X8000)break;
- delay_ms(5);
- }
- if(USART1_RX_STA&0X8000) //接收到一次数据了
- {
- temp=USART1_RX_STA&0X7FFF; //得到数据长度
- USART1_RX_STA=0;
- if(temp==4&&USART1_RX_BUF[0]=='O'&&USART1_RX_BUF[1]=='K')
- {
- temp=0;//接收到OK响应
- break;
- }
- }
- }
- if(retry==0)temp=1; //检测失败
- return temp;
- }
- //获取ATK-HC05模块的角色
- //返回值:0,从机;1,主机;0XFF,获取失败.
- u8 HC05_Get_Role(void)
- {
- u8 retry=0X0F;
- u8 temp,t;
- while(retry--)
- {
- HC05_KEY(1); //KEY置高,进入AT模式
- delay_ms(10);
- u1_printf("AT+ROLE?\r\n"); //查询角色
- for(t=0;t<20;t++) //最长等待200ms,来接收HC05模块的回应
- {
- delay_ms(10);
- if(USART1_RX_STA&0X8000)break;
- }
- HC05_KEY(0); //KEY拉低,退出AT模式
- if(USART1_RX_STA&0X8000) //接收到一次数据了
- {
- temp=USART1_RX_STA&0X7FFF; //得到数据长度
- USART1_RX_STA=0;
- if(temp==13&&USART1_RX_BUF[0]=='+')//接收到正确的应答了
- {
- temp=USART1_RX_BUF[6]-'0';//得到主从模式值
- break;
- }
- }
- }
- if(retry==0)temp=0XFF;//查询失败.
- return temp;
- }
- //ATK-HC05设置命令
- //此函数用于设置ATK-HC05,适用于仅返回OK应答的AT指令
- //atstr:AT指令串.比如:"AT+RESET"/"AT+UART=9600,0,0"/"AT+ROLE=0"等字符串
- //返回值:0,设置成功;其他,设置失败.
- u8 HC05_Set_Cmd(u8* atstr)
- {
- u8 retry=0X0F;
- u8 temp,t;
- while(retry--)
- {
- HC05_KEY(1); //KEY置高,进入AT模式
- delay_ms(10);
- u1_printf("%s\r\n",atstr); //发送AT字符串
- HC05_KEY(0); //KEY拉低,退出AT模式
- for(t=0;t<20;t++) //最长等待100ms,来接收HC05模块的回应
- {
- if(USART1_RX_STA&0X8000)break;
- delay_ms(5);
- }
- if(USART1_RX_STA&0X8000) //接收到一次数据了
- {
- temp=USART1_RX_STA&0X7FFF; //得到数据长度
- USART1_RX_STA=0;
- if(temp==4&&USART1_RX_BUF[0]=='O')//接收到正确的应答了
- {
- temp=0;
- break;
- }
- }
- }
- if(retry==0)temp=0XFF;//设置失败.
- return temp;
- }
- ///////////////////////////////////////////////////////////////////////////////////////////////////
- //通过该函数,可以利用USMART,调试接在串口3上的ATK-HC05模块
- //str:命令串.(这里注意不再需要再输入回车符)
- void HC05_CFG_CMD(u8 *str)
- {
- u8 temp;
- u8 t;
- HC05_KEY(1); //KEY置高,进入AT模式
- delay_ms(10);
- u1_printf("%s\r\n",(char*)str); //发送指令
- for(t=0;t<50;t++) //最长等待500ms,来接收HC05模块的回应
- {
- if(USART1_RX_STA&0X8000)break;
- delay_ms(10);
- }
- HC05_KEY(0); //KEY拉低,退出AT模式
- if(USART1_RX_STA&0X8000) //接收到一次数据了
- {
- temp=USART1_RX_STA&0X7FFF; //得到数据长度
- USART1_RX_STA=0;
- USART1_RX_BUF[temp]=0; //加结束符
- printf("\r\n%s",USART1_RX_BUF);//发送回应数据到串口1
- }
- }
复制代码 HC05常见AT指令:
编译好下载到时板上,打开手机蓝牙调试工具
BTClient.rar
(1.08 MB, 下载次数: 0)
|
|