单片机---HLK-W801蓝牙遥控点灯

总目录

《单片机—HLK-W801开发环境搭建》
《单片机—HLK-W801蓝牙BLE功能测试》

昨天吧demo运行明白了,今天那就来看一下手机通过蓝牙远程遥控点亮开发板的LED吧,虽然这并不是低功耗蓝牙的典型用法,但是通过这种手段,能够快速学习一下W801这套恶心的SDK代码,也算是一种福报。嚯,正好这个芯片是阿里生产的,这不是正应了马老的一句话么。
单片机---HLK-W801蓝牙遥控点灯_第1张图片

调试工具

这里用的手机蓝牙调试工具叫nRF connect。应用商店也可以搜索BLE,就能搜索到很多蓝牙开发的工具,不过都会各种申请手机权限,定位啊,相册啊,不允许就没法用,简直就是流氓行为,这国家早就说过了这种问题,无奈就是没办法啊。
单片机---HLK-W801蓝牙遥控点灯_第2张图片
不过这款软件倒是挺好的,没有申请什么权限
直接就可以使用。让人感动。

自动启动server

原有的demo中,我们知道了需要让开发板自动运行成为BLE的server,需要两部分

  • 开启蓝牙
  • 以server运行

核心的代码就这两个函数

	demo_bt_enable();
	demo_ble_server_on();

不过你想要干净的将这两个函数的实现复制到你的主函数文件中,那还是想多了,里面用了一些的全局变量,例如打印等级,或者adapter状态。
单片机---HLK-W801蓝牙遥控点灯_第3张图片
所以,你干脆,人家给你造了一套代码,你干嘛还想自己写,就直接用它的demo代码,直接在包含好所有的头文件,然后调用这两个函数,就完事了。
所以主要代码就这样写

	demo_bt_enable();
	while(bt_adapter_state == WM_BT_STATE_OFF)
	{
		tls_os_time_delay(5000 /HZ);
	}
	tls_os_time_delay(5000 /HZ);
	demo_ble_server_on();

就能够让开发板以server身份运行起来了。简单吧

接收命令

这里就需要找到BLE server接收命令的地方,就在这个函数当中

static int gatt_svr_chr_demo_access_func(uint16_t conn_handle, uint16_t attr_handle,         struct ble_gatt_access_ctxt *ctxt, void *arg)
{
	int i = 0;
	struct os_mbuf *om = ctxt->om;

	switch (ctxt->op) 
	{
		case BLE_GATT_ACCESS_OP_WRITE_CHR:
		while(om) 
		{
			if(g_ble_uart_output_fptr)
			{
				g_ble_uart_output_fptr((uint8_t *)om->om_data, om->om_len);
			}
			else
			{
				print_bytes(om->om_data, om->om_len); 
			}
			om = SLIST_NEXT(om, om_next);
		}
	return 0;
	default:
	assert(0);
	return BLE_ATT_ERR_UNLIKELY;
	}
}

其中它指明了一个逻辑,就是如果没有输出函数指针g_ble_uart_output_fptr,那么就自动打印出来,找到了接收消息的地方就办了。我们就已经可以将数据或者命令通过蓝牙,从手机发送到开发板了。
单片机---HLK-W801蓝牙遥控点灯_第4张图片

消息传输

这里为了将我们的代码稍微独立出来一点,用了一个消息队列queue,将蓝牙收到的命令,通过queue发送到我的主任务当中,这部分放在主函数文件中,那么以后就直接在这里修改需求,不必再关心消息传递过程了。

主函数中创建队列,并启动监控接收任务

	if(tls_os_queue_create(&MyBLE_QUEUE, 32)!=TLS_OS_SUCCESS)
	{
		printf("create queue fail\n");
		return;
	}
	tls_os_task_create(NULL, NULL,
                       my_ble_msg_task,
                       NULL,
                       (void *)MyBLETaskStk,          /* task's stack start address */
                       MyBLE_TASK_SIZE * sizeof(u32), /* task's stack size, unit:byte */
                       MyBLE_TASK_PRIO,
                       0);

消息接收任务

void my_ble_msg_task(void *sdata)
{
	void *msg;

	for(;;)
	{
		tls_os_queue_receive(MyBLE_QUEUE, (void **)&msg, 0, 0);
		printf("myble revice %ld \n",(u32)msg);
	}
}

将前面的输出打印,替换为发送消息,我们目前只取第一个字节,足够传递信息了。

//print_bytes(om->om_data, om->om_len); 
if(om->om_len>0)
{
	tls_os_queue_send(MyBLE_QUEUE, (void *)(om->om_data[0]), 0);
}

这样,启动之后,消息自动就会发送到我这个任务中来,我们就只专心处理这个消息即可。
单片机---HLK-W801蓝牙遥控点灯_第5张图片

消息处理

这里将消息转化为控制LED的亮灭,达到了测试效果
单片机---HLK-W801蓝牙遥控点灯_第6张图片
这里只要控制GPIO输出低电平,就可以点亮LED,输出高电平就熄灭。
点亮过程。

tls_gpio_cfg(MyLED1_IO, WM_GPIO_DIR_OUTPUT, WM_GPIO_ATTR_FLOATING);
tls_gpio_write(MyLED1_IO,0);	

整体测试

首先运行开发板,等待server状态启动。
单片机---HLK-W801蓝牙遥控点灯_第7张图片
然后手机打开测试工具,扫描到开发板,连接上
单片机---HLK-W801蓝牙遥控点灯_第8张图片
然后点击上箭头,进行数据发送

单片机---HLK-W801蓝牙遥控点灯_第9张图片
发送0,可以控制led点亮
单片机---HLK-W801蓝牙遥控点灯_第10张图片
开发板被点亮了
单片机---HLK-W801蓝牙遥控点灯_第11张图片
发送1过去,开发板熄灭。

完事。单片机---HLK-W801蓝牙遥控点灯_第12张图片

补充说明

这套SDK,把FreeRTOS原有的内容,加以了封装,例如

//消息队列
 tls_os_status_t tls_os_queue_create(tls_os_queue_t **queue, u32 queue_size)
 //任务创建
 tls_os_status_t tls_os_task_create(tls_os_task_t *task,
      const char* name,
      void (*entry)(void* param),
      void* param,
      u8 *stk_start,
      u32 stk_size,
      u32 prio,
      u32 flag)
//延迟
 void tls_os_time_delay(u32 ticks)

这套明明,也是没看出来有啥好的,搞得总和tls加密联系起来,其实没有半毛钱关系
单片机---HLK-W801蓝牙遥控点灯_第13张图片

可以用它封装好的代码,例如我上面用到的消息队列。这样可以使代码显得干净,也可以用freeRTOS原有的功能,没有本质的区别,就看你喜好了。关于FreeRTOS的用法,可以参考我的几篇文章
FreeRTOS学习—“任务”篇
FreeRTOS学习—“消息队列”篇
FreeRTOS学习—“信号量”篇
FreeRTOS学习—“事件组”篇
FreeRTOS学习—“定时器”篇

结束语

花费了三个小时做了个demo,写了一篇文章,只是提供一种解决问题的思路,有时候,不太需要你理解功能多透彻,只要是会切入,找到实现的关键点,很快就能做出点东西。
不过当然不是说深入理解不好,一旦出现一些稳定性的bug,可能就需要深入理解代码了。
时间就是金钱,效率就是生命,不过有时候,拼命去赶时间,也不是好事,今早高峰,看见一辆车
单片机---HLK-W801蓝牙遥控点灯_第14张图片
气囊也出来了,玻璃也碎了。哎,希望救护车帮你再抢点时间出来吧。但愿人没事。

你可能感兴趣的:(单片机,C语言典型代码,HLKW801,蓝牙,BLE,遥控)