本帖最后由 KING_阿飞 于 2022-8-2 15:40 编辑
【雅特力AT32WB415系列蓝牙BLE 5.0 MCU】移植MCU控制蓝牙,蓝牙固件烧录
很荣幸能获得雅特力AT32WB415系列蓝牙BLE 5.0 MCU的评测机会,为此按照我以前的评测的习惯,附上我的Github:,所有评测代码均开源分享。
如果因为网络问题无法进入Github可以在Gitee中下载,可能会存在没有及时更新。Gitee:My_AT32WB415_Demo: 雅特力科技AT32WB415系列学习,从各个外设入手,学习各个功能。 (gitee.com)
一、蓝牙固件代码烧录
雅特力AT32WB415是合体芯片,一个MCU加一个蓝牙,中间连接了一个串口,带2个UART, 其中UART21与MCU USART3连接。我们可以通过ArteryICPProgrammer这个软件烧入固件代码。这里我用到的版本是V3.0.03,第一次下载请给AT-Link固件升级一下,这个软件就可以升级。
页面中 第一个固件就是蓝牙的,另一个就是我们MCU的固件。
官方的蓝牙固件包在其页面下就可以找到雅特力科技 : 32位微控制器的创新领导者! (arterytek.com)
该工程是ARM9的工程,需要安装Legacy Support才能够编译, 用户可根据自己的环境在以下
路径进行下载: www2.keil.com/mdk5/legacy,这里我把我编译的bin文件放在仓库中,大家需要的可以自取。
在官方文件中的指南里面就讲的比较清楚,我在这里不过多赘述。讲几个需要注意的点:蓝牙的地址是0x000000的、在复位是应该有一个时序的问题,需要先复位MCU在复位蓝牙、我们手机的蓝牙必须使用类似LightBlue这类的软件才可以连接,直接是无法连接上,这部分我也没有涉及过,属于知识盲区了。希望有人可以在这方面研究一下。
二、MCU代码的移植
其实在,官方里面的文档也写了,我们没必要继续重复造轮子了(其实就是懒😁)
具体的移植步骤就不多说,也比较简单,有问题可以在评论区提出。这里讲一些我在移植过程中的问题,这样的效果更好。
FreeRTOS卡死:在Debug发现会一直等待,研究发现是官方的at32_button_press这个按键检测的函数里面的延时是delay_ms,这里我改成FreeRTOS里面的延时。
所有的代码我也不在这里放出来了,全部在Github上有,而且能够看到每次的变化,也知道我添加了哪些文件。
这里放一些必须要弄的:
#include "bsp_usart.h"
void usart3_init(uint32_t baudrate)
{
gpio_init_type gpio_init_struct;
crm_periph_clock_enable(CRM_USART3_PERIPH_CLOCK, TRUE);
crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK, TRUE);
crm_periph_clock_enable(CRM_IOMUX_PERIPH_CLOCK, TRUE);
gpio_pin_remap_config(USART3_GMUX_0010, TRUE);
gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
gpio_init_struct.gpio_pins = GPIO_PINS_7;
gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
gpio_init(GPIOA, &gpio_init_struct);
gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
gpio_init_struct.gpio_mode = GPIO_MODE_INPUT;
gpio_init_struct.gpio_pins = GPIO_PINS_6;
gpio_init_struct.gpio_pull = GPIO_PULL_UP;
gpio_init(GPIOA, &gpio_init_struct);
nvic_irq_enable(USART3_IRQn, 0, 0);
/* configure uart param */
usart_init(USART3, baudrate, USART_DATA_8BITS, USART_STOP_1_BIT);
usart_transmitter_enable(USART3, TRUE);
usart_receiver_enable(USART3, TRUE);
/* Enable the USARTx Interrupt */
usart_interrupt_enable(USART3, USART_RDBF_INT, TRUE);
usart_enable(USART3, TRUE);
}
#include "at_task.h"
#include "at32wb415_board.h"
#include "at_cmd.h"
#include "tp_mode.h"
#include "stdio.h"
#include "string.h"
#include "FreeRTOS.h"
#include "task.h"
//#define BT_FLASH_WR_TEST
#define SIZEOFMSG (sizeof(at_cmd_list)/sizeof(struct at_cmd_msg))
extern cmd_flash_read_status fr_flag;
extern cmd_rsp_status cmd_result;
extern flag_status recv_cmp_flag;
extern uint8_t bt_flash_data;
extern char recv_data[];
extern uartstruct tp_mode_rx_uart;
extern uartstruct tp_mode_tx_uart;
flag_status UART_TP_MODE = RESET;
flag_status switch_mode_flag = RESET;
void at_cmd_handler(void);
struct at_cmd_msg at_cmd_list[] =
{
{AT_CMD_IO_SET_LOW, AT_CMD_IOSET0},
{AT_CMD_IO_SET_HIGH, AT_CMD_IOSET1},
{AT_CMD_IO_GET, AT_CMD_IOGET},
};
button_type BUTTON;
void AT_Task(void *pvParameters)
{
printf("AT-Task Start!!\r\n");
while(1){
if(at32_button_press() == USER_BUTTON)
{
UART_TP_MODE = (flag_status)!UART_TP_MODE;
if(UART_TP_MODE)
{
switch_mode_flag = SET;
at_cmd_send(AT_CMD_TP_MODE_ON);
while(cmd_rsp_get(AT_TP_MODE_OK1) != RSP_OK);
switch_mode_flag = RESET;
at32_led_on(LED3);
printf("enter uart tp mode\r\n");
}
else
{
switch_mode_flag = SET;
at_cmd_send(AT_CMD_TP_MODE_OFF);
while(cmd_rsp_get(AT_TP_MODE_OK0) != RSP_OK);
switch_mode_flag = RESET;
at32_led_off(LED3);
printf("leave uart tp mode\r\n");
}
}
if(UART_TP_MODE)
{
tp_mode_rx_handler();
tp_mode_tx_handler();
}
else
{
at_cmd_handler();
}
vTaskDelay(100);
}
}
/**
* @brief handle input at command, it will response corresponding formats.
* @param none
* @retval none
*/
void at_cmd_handler(void)
{
uint8_t msg_id = SIZEOFMSG-1, i;
if(recv_cmp_flag == SET)
{
for(i = 0; i <= SIZEOFMSG; i++)
{
if(memcmp(recv_data, at_cmd_list.at_cmd_string, strlen(recv_data)) == 0)
{
printf("%s", recv_data);
msg_id = i;
break;
}
}
switch(at_cmd_list[msg_id].msg_id)
{
case AT_CMD_IOSET0:
{
at32_led_off(LED2);
at_cmd_send(AT_RESULT_OK0);
break;
}
case AT_CMD_IOSET1:
{
at32_led_on(LED2);
at_cmd_send(AT_RESULT_OK1);
break;
}
case AT_CMD_IOGET:
{
if(gpio_output_data_bit_read(GPIOB, GPIO_PINS_7))
{
at_cmd_send(AT_RESULT_OK1);
}
else
{
at_cmd_send(AT_RESULT_OK0);
}
break;
}
default:
{
at_cmd_send(AT_RSP_ERROR);
break;
}
}
recv_cmp_flag = RESET;
memset(recv_data, 0, strlen(recv_data));
}
}
三、效果演示
8月2日