感谢电子发烧友论坛和南京沁恒所提供的CH32V208 开发板的测试机会。
CH32V208 开发板的一个特色就是其提供了蓝牙协议栈,上次我们介绍蓝牙键盘,今天介绍一个更实用的例子:改进的蓝牙自拍杆。
1例程HID_Consumer
自拍杆给我们除外旅行拍照带来很大方便,现在已经非常普及了,它曾经进入过《时代》杂志2014年度25大最佳发明的榜单。我们知道手机在拍照模式下,按下音量调节键就可以实现拍照功能,而蓝牙自拍杆就是利用了这一特性,将自拍杆的遥控器以蓝牙HID设备的形式和手机配对,按下自拍杆的控制键时就发送音量调节键给手机,从而实现拍照功能。
在厂商提供的蓝牙例程中有一个HID_Consumer,这是个蓝牙自拍杆的雏形。它的工作过程和蓝牙键盘很类似,连接上手机后定时(1.6s)给手机发送音量调节键,从而实现拍照的功能。不过这一行为和蓝牙自拍杆不一样,我们希望将其改成按键触发,而不是定时拍照。
2开发板的硬件连接
开发板上提供了S2按键供用户使用,但是这个按键并没有直接连在IO管脚上,需要用杜邦线进行连接。我们将开发板上KEY管脚和PA1管脚进行连接,这样我们就可以用GPIO读取PA1管脚的状态,从而知道用户是否按下了S2键。
3程序相关修改
该例程的基本流程和蓝牙键盘相似,对其工作原理感兴趣的朋友可以看我上一篇文章。
3.1GPIO初始化
我们需要在hidconsumer.c中加入初始化GPIO的函数,把PA1设置为输入。
void GPIO_INIT(void)
{
GPIO_InitTypeDef GPIO_InitStructure = {0};
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
/*********************************************************************
* @fn main
*
* [url=home.php?mod=space&uid=2666770]@Brief[/url] Main function
*
* [url=home.php?mod=space&uid=1141835]@Return[/url] none
*/
int main(void)
{
Delay_Init();
#ifdef DEBUG
USART_Printf_Init( 115200 );
#endif
PRINT("start.%s\n",__TIME__);
PRINT("%s\n", VER_LIB);
WCHBLE_Init();
HAL_Init();
GPIO_INIT();
GAPRole_PeripheralInit();
HidDev_Init();
HidEmu_Init();
Main_Circulation();
}
3.2在任务函数中读取按键状态
函数HidEmu_ProcessEvent是整个程序的核心,它在处理START_REPORT_EVT消息时完成向手机发送音量调节键的功能。我们在这个函数中加入了读取PA1管脚状态的判断,如果用户按下按键,发送音量调节键,否则不发送。
if(events & START_REPORT_EVT)
{
if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_1) == 0)
{
hidEmuSendConsumerReport(0, 1);
hidEmuSendConsumerReport(0, 0);
}
tmos_start_task(hidEmuTaskId, START_REPORT_EVT, 1600);
return (events ^ START_REPORT_EVT);
}
4视频展示
最后录制了一段视频,展示手机上操作的全过程。