Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
串口
RT-Thread 实现蓝牙串口通信功能
发布于 2020-03-31 11:06:00 浏览:2641
订阅该版
[tocm] ## 作业题目8 实现蓝牙串口通信功能 - 当手机端蓝牙调试助手发送:`LED1 Toggle` 时,反转LED1灯状态; - 当手机端蓝牙调试助手发送: `LED2 BrightnessN` (其中最后一个字母N表示亮度等级,可取为1,2,3,4,5,数字越大,越亮)时,调节LED2的亮度等级 - LED1、LED2自由选择GPIO口 大家提交作业时,直接在本贴下方跟贴即可
查看更多
22
个回答
默认排序
按发布时间排序
yoowiwi
2020-04-06
这家伙很懒,什么也没写!
## 小作业:实现蓝牙串口通信功能 * 宏定义及相关变量 ``` #define LED2_Brightness0 0x01 #define LED2_Brightness1 0x02 #define LED2_Brightness2 0x04 #define LED2_Brightness3 0x08 #define LED2_Brightness4 0x10 #define LED2_Brightness5 0x20 #define LED1_TOGGLE 0x40 ``` * 蓝牙串口\DMA初始化 ```C static void NVIC_Configuration(void) { NVIC_InitTypeDef NVIC_InitStructure; NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); NVIC_InitStructure.NVIC_IRQChannel = DEBUG_USART3_IRQ; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); } void USARTx_DMA_Config(void) { DMA_InitTypeDef dma; RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); dma.DMA_PeripheralBaseAddr = (u32)&(USART3->DR); dma.DMA_MemoryBaseAddr = (u32)buff3; dma.DMA_DIR = DMA_DIR_PeripheralSRC; dma.DMA_BufferSize = BUFF_REC_SIZE; dma.DMA_PeripheralInc = DMA_PeripheralInc_Disable; dma.DMA_MemoryInc = DMA_MemoryInc_Enable; dma.DMA_PeripheralDataSize= DMA_PeripheralDataSize_Byte; dma.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; dma.DMA_Mode = DMA_Mode_Normal; dma.DMA_Priority = DMA_Priority_Medium; dma.DMA_M2M = DMA_M2M_Disable; DMA_Init(DMA1_Channel3, &dma); DMA_Cmd (DMA1_Channel3,ENABLE); } int USART3_Config(void) { GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; DEBUG_USART3_GPIO_APBxClkCmd(DEBUG_USART3_GPIO_CLK, ENABLE); DEBUG_USART3_APBxClkCmd(DEBUG_USART3_CLK, ENABLE); GPIO_InitStructure.GPIO_Pin = DEBUG_USART3_TX_GPIO_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(DEBUG_USART3_TX_GPIO_PORT, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = DEBUG_USART3_RX_GPIO_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(DEBUG_USART3_RX_GPIO_PORT, &GPIO_InitStructure); USART_InitStructure.USART_BaudRate = DEBUG_USART3_BAUDRATE; USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_Parity = USART_Parity_No ; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; USART_Init(DEBUG_USART3, &USART_InitStructure); NVIC_Configuration(); USARTx_DMA_Config(); USART_DMACmd(USART3,USART_DMAReq_Rx,ENABLE); DMA_ClearFlag(DMA1_FLAG_TC3); DMA_ITConfig(DMA1_Channel3, DMA_IT_TE, ENABLE); // USART_ITConfig(DEBUG_USART3, USART_IT_RXNE, ENABLE); USART_ITConfig(DEBUG_USART3, USART_IT_IDLE, ENABLE); USART_Cmd(DEBUG_USART3, ENABLE); return 0; } INIT_BOARD_EXPORT(USART3_Config); ``` * 通用定时器初始化,并将TIM1CCR1对应的引脚与LEDR灯相接 ```C static void GENERAL_TIM_GPIO_Config(void) { GPIO_InitTypeDef GPIO_InitStructure; // 输出比较通道1 GPIO 初始化 RCC_APB2PeriphClockCmd(GENERAL_TIM_CH1_GPIO_CLK, ENABLE); GPIO_InitStructure.GPIO_Pin = GENERAL_TIM_CH1_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GENERAL_TIM_CH1_PORT, &GPIO_InitStructure); } static void GENERAL_TIM_Mode_Config(void) { GENERAL_TIM_APBxClock_FUN(GENERAL_TIM_CLK,ENABLE); TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_TimeBaseStructure.TIM_Period=GENERAL_TIM_Period; TIM_TimeBaseStructure.TIM_Prescaler= GENERAL_TIM_Prescaler; TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1; TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; TIM_TimeBaseStructure.TIM_RepetitionCounter=0; TIM_TimeBaseInit(GENERAL_TIM, &TIM_TimeBaseStructure); TIM_OCInitTypeDef TIM_OCInitStructure; TIM_OCInitStructure.TIM_Pulse = 0; TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OC1Init(GENERAL_TIM, &TIM_OCInitStructure); TIM_OC1PreloadConfig(GENERAL_TIM, TIM_OCPreload_Enable); TIM_Cmd(GENERAL_TIM, ENABLE); } int GENERAL_TIM_Init(void) { GENERAL_TIM_GPIO_Config(); GENERAL_TIM_Mode_Config(); // LED灯控制线程初始化 rt_thread_init(&tled,"tled",LED_Control_Thread,RT_NULL, \ tled_stack,sizeof(tled_stack),2,10); rt_thread_startup(&tled); // LED事件初始化 rt_event_init(&event_led,"event_led",RT_IPC_FLAG_FIFO); return 0; } INIT_APP_EXPORT(GENERAL_TIM_Init); ``` * LED灯事件处理线程 ```C void LED_Control_Thread(void *paramter) { rt_uint32_t ctrl; while(1) { // 0X7F为所有事件集 rt_event_recv(&event_led, 0x7F , \ RT_EVENT_FLAG_OR|RT_EVENT_FLAG_CLEAR, \ RT_WAITING_FOREVER,&ctrl); switch(ctrl) { case LED1_TOGGLE: GPIOB->ODR ^= GPIO_Pin_1; // LED1翻转 break; case LED2_Brightness0: GENERAL_TIM->CCR1 = 0; // 亮度设置为0/5 break; case LED2_Brightness1: GENERAL_TIM->CCR1 = 1; // 亮度设置为1/5 break; case LED2_Brightness2: GENERAL_TIM->CCR1 = 2; // 亮度设置为2/5 break; case LED2_Brightness3: GENERAL_TIM->CCR1 = 3; // 亮度设置为3/5 break; case LED2_Brightness4: GENERAL_TIM->CCR1 = 4; // 亮度设置为4/5 break; case LED2_Brightness5: GENERAL_TIM->CCR1 = 5; // 亮度设置为5/5 break; } rt_thread_mdelay(50); } } ``` * 蓝牙串口接收中断 ```C void DEBUG_USART3_IRQHandler() { uint8_t len = 0; if(USART_GetFlagStatus(USART3, USART_FLAG_IDLE) != RESET) { USART3->SR;USART3->DR; // 清除中断标志位 DMA_Cmd(DMA1_Channel3, DISABLE); len = BUFF_REC_SIZE - DMA_GetCurrDataCounter(DMA1_Channel3); if(buff3[3] == '1') { rt_event_send(&event_led,LED1_TOGGLE); // 发送事件 } else if(buff3[3] == '2') { switch(buff3[15]) { case '0': rt_event_send(&event_led,LED2_Brightness0); break; case '1': rt_event_send(&event_led,LED2_Brightness1); break; case '2': rt_event_send(&event_led,LED2_Brightness2); break; case '3': rt_event_send(&event_led,LED2_Brightness3); break; case '4': rt_event_send(&event_led,LED2_Brightness4); break; case '5': rt_event_send(&event_led,LED2_Brightness5); break; } } DMA1_Channel3->CNDTR = BUFF_REC_SIZE; DMA_Cmd(DMA1_Channel3, ENABLE); } } ``` ## 效果截图: LED2亮度调节:为了亮度区分比较明显,此处仅用亮度1和亮度5及亮度0作对比 [attach]14719[/attach] [attach]14720[/attach] [attach]14721[/attach] LED1翻转 [attach]14722[/attach] [attach]14723[/attach]
赵撵猪
2020-04-07
这家伙很懒,什么也没写!
蓝牙实现led控制还是比较简单的,主要有以下几个步骤 - 调试led驱动 - 调试串口(蓝牙)驱动 - 解析数据 - 调试led驱动 需要两个led,所以一个直接用HAL_GPIO_TogglePin进行反转电平,另一个涉及到亮度控制,所以选用定时器定时,比如设定的时间100us,分五分,1分为20us,高电平20us后反转,如此循环。 因为要进行控制,使用事件触发,一个是电平翻转事件,另一个是亮度控制事件,并且亮度用一个变量传递参数。 ```c #include "led.h" #include "tim.h" #include "stdlib.h" #include "string.h" #include "rtthread.h" #include
LED_DutyTypeDef LED_Duty; static TIM_HandleTypeDef* led_tim; /* 注册led使用的timer */ void LED_timer_register(TIM_HandleTypeDef *htim) { led_tim = htim; } /* * duty 占空比 10ms 高电平持续时间 */ void LED_RUN(uint8_t duty) { LED_Duty.duty = duty; HAL_TIM_Base_Start_IT(led_tim); } void LED_Keep(GPIO_PinState PinState) { HAL_TIM_Base_Stop(led_tim); HAL_GPIO_WritePin(LD1_GPIO_Port,LD1_Pin,PinState); } extern rt_base_t level ; void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { level = rt_hw_interrupt_disable(); /* Prevent unused argument(s) compilation warning */ if (htim->Instance == led_tim->Instance) { HAL_TIM_Base_Stop(led_tim); HAL_TIM_Base_DeInit(led_tim); LED_Duty.duty%=101; switch (LED_Duty.duty) { case 0: HAL_GPIO_WritePin(LD1_GPIO_Port,LD1_Pin,GPIO_PIN_RESET); led_tim->Instance = led_tim->Instance; led_tim->Init.Prescaler = 5999; led_tim->Init.CounterMode = TIM_COUNTERMODE_UP; led_tim->Init.Period = 100-1; led_tim->Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; led_tim->Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; if (HAL_TIM_Base_Init(led_tim) != HAL_OK) { Error_Handler(); } break; case 100: HAL_GPIO_WritePin(LD1_GPIO_Port,LD1_Pin,GPIO_PIN_SET); led_tim->Instance = led_tim->Instance; led_tim->Init.Prescaler = 5999; led_tim->Init.CounterMode = TIM_COUNTERMODE_UP; led_tim->Init.Period = 100 -1; led_tim->Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; led_tim->Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; if (HAL_TIM_Base_Init(led_tim) != HAL_OK) { Error_Handler(); } break; default: if (LED_Duty.mode == 1) { HAL_GPIO_WritePin(LD1_GPIO_Port,LD1_Pin,GPIO_PIN_SET); LED_Duty.mode = 2; led_tim->Instance = led_tim->Instance; led_tim->Init.Prescaler = 599; led_tim->Init.CounterMode = TIM_COUNTERMODE_UP; led_tim->Init.Period = (LED_Duty.duty%100)*10 - 1; led_tim->Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; led_tim->Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; if (HAL_TIM_Base_Init(led_tim) != HAL_OK) { Error_Handler(); } } else { HAL_GPIO_WritePin(LD1_GPIO_Port,LD1_Pin,GPIO_PIN_RESET); LED_Duty.mode = 1; led_tim->Instance = led_tim->Instance; led_tim->Init.Prescaler = 599; led_tim->Init.CounterMode = TIM_COUNTERMODE_UP; led_tim->Init.Period = (100 - (LED_Duty.duty%100))*10 - 1; led_tim->Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; led_tim->Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; if (HAL_TIM_Base_Init(led_tim) != HAL_OK) { Error_Handler(); } } break; } __HAL_TIM_CLEAR_FLAG(led_tim, TIM_SR_UIF); HAL_TIM_Base_Start_IT(led_tim); } rt_hw_interrupt_enable(level); } ``` - 调试串口(蓝牙)驱动 蓝牙就是透传,几乎不需要任何指令,先设置下波特率,名字,手机连接就可以使用了。 非常简单。串口使用消息队列,接收数据存储在消息队列中,需要时将数据取出。 ```c static uint8_t uart_rx_byte; //tem buf byte rt_mq_t uart4_mq; //uart mq id rt_base_t level ; void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { level = rt_hw_interrupt_disable(); if (huart->Instance == UART4) { // printf("%c",uart_rx_byte); HAL_UART_Receive_IT(&huart4, &uart_rx_byte, 1); rt_mq_send (uart4_mq, &uart_rx_byte, 1); } rt_hw_interrupt_enable(level); } /* * read data from at uart * buf data ptr * size_max is buf size max */ int uart_read(uint8_t* buf,uint16_t size_max,uint32_t timeout) { uint16_t len = 0; memset(buf,0,size_max); while (1) { if (rt_mq_recv (uart4_mq, buf+len,1, timeout) != RT_EOK) { if(len == 0) { return -1; } return len; } if ((++len) == size_max) return len; } } int uart4_rt_create(void) { uart4_mq = rt_mq_create("uart4_mq", 1,1024, RT_IPC_FLAG_FIFO); HAL_UART_Receive_IT(&huart4, &uart_rx_byte, 1); return 0; } INIT_PREV_EXPORT(uart4_rt_create); ``` - 解析数据 只需要用rt_strncmp进行比对我们需要的数据,正确时释放事件就可以了,周期的进行解析。 如果想响应快一点把读取周期改小一点即可。 [attach]14760[/attach] [attach]14759[/attach]
瑞尧
2020-04-07
这家伙很懒,什么也没写!
需求:实现蓝牙串口通信 需要用到的工具:串口,PWM PWM配置,使用定时器产生PWM输出至LED引脚,以达到调节LED亮度的效果,代码如下: ``` void TIM11_PWM_Init(void) { //此部分需手动修改IO口设置 GPIO_InitTypeDef GPIO_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM11,ENABLE); //TIM1时钟使能 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE); //使能PORTF时钟 GPIO_PinAFConfig(GPIOF,GPIO_PinSource7,GPIO_AF_TIM11); //GPIOF7复用为定时器11 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7; //GPIOF7 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; //复用功能 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//速度100MHz GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽复用输出 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉 GPIO_Init(GPIOF,&GPIO_InitStructure); //初始化PF7 TIM_TimeBaseStructure.TIM_Prescaler=499; //定时器分频 TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上计数模式 TIM_TimeBaseStructure.TIM_Period=83; //自动重装载值 TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1; TIM_TimeBaseInit(TIM11,&TIM_TimeBaseStructure);//初始化定时器11 //初始化TIM14 Channel1 PWM模式 TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //选择定时器模式:TIM脉冲宽度调制模式1 TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能 TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //输出极性:TIM输出比较极性低 TIM_OC1Init(TIM11, &TIM_OCInitStructure); //根据T指定的参数初始化外设TIM11OC1 TIM_OC1PreloadConfig(TIM11, TIM_OCPreload_Enable); //使能TIM11在CCR1上的预装载寄存器 TIM_ARRPreloadConfig(TIM11,ENABLE);//ARPE使能 TIM_Cmd(TIM11, DISABLE); //使能TIM11 } ``` 在使用pwm调光是,只需要使用函数TIM_SetCompare1改变PWM占空比即可。 蓝牙串口通信,这个没什么好说的,直接使用第二次作业的例程即可,只需要对指令的解析修改即可,代码如下: ``` static rt_thread_t led_thread = RT_NULL; void led_thread_entry(void *parameter) { char level; rt_thread_delay(500); TIM_Cmd(TIM11, ENABLE); while(1) { rt_thread_mdelay(50); if (UART4_RX_STA&0x8000) { UART4_RX_STA = 0; rt_kprintf("Receive message from UART4:"); rt_kprintf("%s\n",UART4_RX_BUF); if(strstr((char*)UART4_RX_BUF, "LED1 Toggle")) { LED1 = !LED1; rt_kprintf("LED1:%d\n",LED1); } else if(strstr((char*)UART4_RX_BUF, "LED2 Brightness")) { level = UART4_RX_BUF[15] -'0'; if(level<=5) { rt_kprintf("set LED2 level:%d\n",level); TIM_SetCompare1(TIM11,(level*84/5)); } } else if(strstr((char *)UART4_RX_BUF,"quit")) { rt_kprintf("quie led thread\n"); break; } } } } rt_err_t blutooth_sample(void) { rt_err_t result; TIM11_PWM_Init(); /* 创建线程 */ led_thread = rt_thread_create("led", led_thread_entry, \ RT_NULL, 512, 10, 10); if(led_thread != RT_NULL) { /* 启动线程 */ rt_thread_startup(led_thread); rt_kprintf("led thread start!\n"); } } INIT_APP_EXPORT(blutooth_sample); ``` 实现效果如下: [attach]14769[/attach]
yichao
2020-04-07
这家伙很懒,什么也没写!
[md]1. pwm输出LED2 ``` //TIM14 PWM 部分初始化 //PWM 输出初始化 //arr:自动重装值 psc:时钟预分频数 void TIM14_PWM_Init(u32 arr,u32 psc) { GPIO_InitTypeDef GPIO_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM14,ENABLE);//TIM14 时钟使能 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE); //使能 PORTF 时钟 GPIO_PinAFConfig(GPIOF,GPIO_PinSource9,GPIO_AF_TIM14); //GF9 复用为 TIM14 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //GPIOF9 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; //复用功能 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; //速度 50MHz GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽复用输出 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉 GPIO_Init(GPIOF,&GPIO_InitStructure); //初始化 PF9 TIM_TimeBaseStructure.TIM_Prescaler=psc; //定时器分频 TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上计数模式 TIM_TimeBaseStructure.TIM_Period=arr; //自动重装载值 TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1; TIM_TimeBaseInit(TIM14,&TIM_TimeBaseStructure);//初始化定时器 14 //初始化 TIM14 Channel1 PWM 模式 TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //PWM 调制模式 1 TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能 TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //输出极性低 TIM_OC1Init(TIM14, &TIM_OCInitStructure); //初始化外设 TIM1 4OC1 TIM_OC1PreloadConfig(TIM14, TIM_OCPreload_Enable); //使能预装载寄存器 TIM_ARRPreloadConfig(TIM14,ENABLE);//ARPE 使能 TIM_Cmd(TIM14, ENABLE); //使能 TIM14 } 初始化调用 TIM14_PWM_Init(500-1,84-1); //定时器时钟为 84M,分频系数为 84,所以计数频率 //为 84M/84=1Mhz,重装载值 500,所以 PWM 频率为 1M/500=2Khz. ``` 2. 利用信号量获取串口2蓝牙数据 通过发来的LED1 Toggle LED2指令做响应动作。 ``` void usart2_recv_thread_entry(void *parameter) { rt_err_t uwRet= RT_EOK; rt_uint8_t number = 0; //uint8_t r_queue; while(1) { /* uwRet = rt_mq_recv(msg_usart2_mq, &r_queue, sizeof(r_queue), RT_WAITING_FOREVER); if(RT_EOK == uwRet && r_queue==MSG_USART2) { number++; rt_kprintf("usart2_recv_thread: number = %d Usart2 Receive Data:%s \n",number,g_USART2_RxBuf); memset(g_USART2_RxBuf,0,USART2_RX_BUF_SIZE); g_USART2_RecPos = 0; } */ uwRet = rt_sem_take(usart2_recv_sem, RT_WAITING_FOREVER); if(RT_EOK == uwRet) { number++; rt_kprintf("usart2_recv_thread: number = %d Usart2 Receive Data:%s \n",number,g_USART2_RxBuf); if(strstr((char*)g_USART2_RxBuf,"BeepOn")!=NULL) { BeepOn(); } if(strstr((char*)g_USART2_RxBuf,"BeepOff")!=NULL) { BeepOff(); } if(strstr((char*)g_USART2_RxBuf,"LED1 Toggle")!=NULL) { LedToggle(GPIOA,GPIO_Pin_0); } int nlever =-1; sscanf((char*)g_USART2_RxBuf,"LED2 Brightness%d",&nlever); if(nlever>0 && nlever <6) { TIM_SetCompare1(TIM14,nlever*60); //修改比较值,修改占空比,从而改变led2明暗 } memset(g_USART2_RxBuf,0,USART2_RX_BUF_SIZE); g_USART2_RecPos = 0; } } } ```[/md]
summer_me
2020-04-08
这家伙很懒,什么也没写!
翻转LED1:PC13 亮度控制LED2:PB5(定时器3通道2,重映射到PB5引脚)
风雨潇潇
2020-04-09
这家伙很懒,什么也没写!
使用CC2541模块,我的模块指令是TTM开头的,跟常用的AT指令开头不太一样,有点坑了……使用USART3连接蓝牙模块,使用stm32cubeMX配置TIM2的通道1产生PWM信号,根据硬件选择具体配置,我的通道1连接到一个LED2上 ``` void MX_TIM2_Init(void) { TIM_ClockConfigTypeDef sClockSourceConfig = {0}; TIM_MasterConfigTypeDef sMasterConfig = {0}; TIM_OC_InitTypeDef sConfigOC = {0}; htim2.Instance = TIM2; htim2.Init.Prescaler = 79; htim2.Init.CounterMode = TIM_COUNTERMODE_UP; htim2.Init.Period = 5000-1; htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; if (HAL_TIM_Base_Init(&htim2) != HAL_OK) { Error_Handler(); } sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL; if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK) { Error_Handler(); } if (HAL_TIM_PWM_Init(&htim2) != HAL_OK) { Error_Handler(); } sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK) { Error_Handler(); } sConfigOC.OCMode = TIM_OCMODE_PWM1; sConfigOC.Pulse = 0; sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH; sConfigOC.OCFastMode = TIM_OCFAST_DISABLE; if (HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_1) != HAL_OK) { Error_Handler(); } HAL_TIM_MspPostInit(&htim2); } ``` 创建一个蓝牙接收数据的处理线程和一个信号量,还有PWM的设置函数 ``` /* 指向信号量的指针 */ rt_sem_t dynamic_sem = RT_NULL; rt_uint8_t BT[50] = {0}; rt_uint8_t BTpos = 0; void user_pwm_setvalue(uint16_t value) { TIM_OC_InitTypeDef sConfigOC; sConfigOC.OCMode = TIM_OCMODE_PWM1; sConfigOC.Pulse = value; sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH; sConfigOC.OCFastMode = TIM_OCFAST_DISABLE; HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_1); HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1); } void bluetooth_Task_Init(void) { /* 创建一个动态信号量,初始值是 0 */ dynamic_sem = rt_sem_create("dsem", 0, RT_IPC_FLAG_FIFO); if (dynamic_sem == RT_NULL) { rt_kprintf("create dynamic semaphore failed.\n"); return; } else { rt_kprintf("create done. dynamic semaphore value = 0.\n"); } bluetooth_thread = rt_thread_create("BlueToothThread", /* 线程名字 */ bluetooth_thread_entry, /* 线程入口函数 */ RT_NULL, /* 线程入口函数参数 */ 512, /* 线程栈大小 */ 4, /* 线程的优先级 */ 10 /* 线程时间片 */ ); if(bluetooth_thread != RT_NULL) { rt_thread_startup(bluetooth_thread); } } void bluetooth_thread_entry(void *parameter) { while(1) { if (rt_sem_take(dynamic_sem, RT_WAITING_FOREVER) == RT_EOK) { printf("%s\r\n",BT); if(!rt_strcmp(BT,"LED1 Toggle")) { HAL_GPIO_WritePin(GPIOB, LED_Pin, !HAL_GPIO_ReadPin(GPIOB, LED_Pin)); printf("Toggle\r\n"); } else if(!rt_strncmp(BT,"LED2 Brightness",15)) { if(BT[15] == '1') { user_pwm_setvalue(5000); } else if(BT[15] == '2') { user_pwm_setvalue(4000); } else if(BT[15] == '3') { user_pwm_setvalue(3000); } else if(BT[15] == '4') { user_pwm_setvalue(2000); } else if(BT[15] == '5') { user_pwm_setvalue(1000); } else { user_pwm_setvalue(0); } } rt_memset(BT, 0, 50); } } } ``` 当串口中断接收数据完成时释放一个信号量,在蓝牙线程里等待信号量, 判断接收到的数据信息,进行相应的处理 ``` void USART3_IRQHandler(void) { /* USER CODE BEGIN USART3_IRQn 0 */ uint8_t recByte; if(__HAL_UART_GET_FLAG(&huart3,UART_FLAG_RXNE) && __HAL_UART_GET_IT_SOURCE(&huart3,UART_IT_RXNE)) //接收中断 { if(HAL_UART_Receive(&huart3,&recByte,1,10) == HAL_OK) { BT[BTpos++] = recByte; } } else if(__HAL_UART_GET_FLAG(&huart3,UART_FLAG_IDLE)) //空闲中断 { BTpos = 0; rt_sem_release(dynamic_sem); __HAL_UART_CLEAR_IDLEFLAG(&huart3); } /* USER CODE END USART3_IRQn 0 */ HAL_UART_IRQHandler(&huart3); /* USER CODE BEGIN USART3_IRQn 1 */ __HAL_UART_ENABLE_IT(&huart3, UART_IT_RXNE); /* USER CODE END USART3_IRQn 1 */ } ``` [attach]14814[/attach]
gzyy2005
2020-04-10
这家伙很懒,什么也没写!
好东西 我要学习
。。。
2020-04-11
这家伙很懒,什么也没写!
本次使用信号量方式实现串口2与蓝牙模块的通讯,LED1和LED2共阳,其连接的引脚分别为PB.0和PB.1。我在config.h的头文件中定义一个串口2接收信号量控制指针,如下: ``` EXT rt_sem_t usart2_recv_sem;//定义串口2接收信号量控制块指针 ``` 我创建一个线程用来串口2 接收数据处理,代码如下: ``` static rt_thread_t usart2_recv_thread = RT_NULL; void usart2_recv_thread_entry(void *parameter) { rt_err_t uwRet = RT_EOK; while(1) { uwRet =rt_sem_take(usart2_recv_sem, RT_WAITING_FOREVER);//获取串口2接收帧完成信号量 if(RT_EOK == uwRet ) { #if USART2_EN == 1 if(strstr((char*)g_USART2_RxBuf,"LED1 Toggle")!=NULL) { /*LED1灯进行状态反转*/ LedToggle(GPIOB, GPIO_Pin_0); rt_kprintf("LED1 Toggle\n"); } if(strstr((char*)g_USART2_RxBuf,"LED2 Brightness")!=NULL) { /*调节LED2的亮度等级*/ switch( g_USART2_RxBuf[g_USART2_RecPos-1]) { case '5': TIM_SetCompare4(TIM3,0); rt_kprintf("Brightness level of LED2 at present:%c\n",g_USART2_RxBuf[g_USART2_RecPos-1]);break; case '4': TIM_SetCompare4(TIM3,25*Multiple); rt_kprintf("Brightness level of LED2 at present:%c\n",g_USART2_RxBuf[g_USART2_RecPos-1]);break; case '3': TIM_SetCompare4(TIM3,50*Multiple); rt_kprintf("Brightness level of LED2 at present:%c\n",g_USART2_RxBuf[g_USART2_RecPos-1]);break; case '2': TIM_SetCompare4(TIM3,75*Multiple); rt_kprintf("Brightness level of LED2 at present:%c\n",g_USART2_RxBuf[g_USART2_RecPos-1]);break; case '1': TIM_SetCompare4(TIM3,100*Multiple); rt_kprintf("Brightness level of LED2 at present:%c\n",g_USART2_RxBuf[g_USART2_RecPos-1]);break; default:break; } } memset(g_USART2_RxBuf,0,USART2_RX_BUF_SIZE);//清零 g_USART2_RecPos = 0; #endif } } } void TaskInit(void) { usart2_recv_sem = rt_sem_create("usart2_recv_sem", //信号量名字 0, //信号量初始值 RT_IPC_FLAG_FIFO //信号量模式 FIFO(0x00) ); if(usart2_recv_sem != RT_NULL) rt_kprintf("Semaphore usart2_recv_sem created successfully\r\n"); usart2_recv_thread = rt_thread_create("usart2_recv_thread", /* 线程名字 */ usart2_recv_thread_entry, /* 线程入口函数 */ RT_NULL, /* 线程入口函数参数 */ 512, /* 线程栈大小 */ 2, /* 线程的优先级 */ 10 /* 线程时间片 */ ); if(usart2_recv_thread != RT_NULL) { rt_thread_startup(usart2_recv_thread); } } ``` 串口2的波特率要设为9600。 串口2的中断函数,代码如下: ``` uint8 g_USART2_RxBuf[USART2_RX_BUF_SIZE];//串口接收缓冲区 uint16 g_USART2_RecPos = 0;//存放当前串口接收数据存放的位置 //USART2_IRQHandler,串口2中断回调函数 void USART2_IRQHandler(void) { #if USART2_EN == 1 //用户代码 uint8 RecCh; #endif if( USART_GetFlagStatus(USART2,USART_FLAG_RXNE)!=RESET ) // 串口接收数据 { #if USART2_EN == 1 //用户代码 RecCh = (uint8)USART_ReceiveData(USART2); g_USART2_RxBuf[g_USART2_RecPos++] = RecCh; USART_SendData(USART2, RecCh); #endif USART_ClearFlag(USART2, USART_FLAG_RXNE); } if( USART_GetFlagStatus(USART2,USART_FLAG_ORE)==SET ) // 串口溢出错误 { USART_ClearFlag(USART2, USART_FLAG_ORE); } if( USART_GetFlagStatus(USART2,USART_FLAG_IDLE)==SET ) // 串口溢出错误 { #if USART2_EN == 1 //用户代码 g_USART2_RxBuf[g_USART2_RecPos] = '\0'; rt_sem_release(usart2_recv_sem);//释放一个信号量,表示数据已接收;给出二值信号量 ,发送接收到新数据帧标志,供前台线程查询 USART_SendData(USART2, '\n'); #endif USART_ReceiveData(USART2);//使用该语句清除空闲中断标志位,请不要使用USART_ClearITPendingBit(USART2, USART_IT_IDLE);该语句无法达到效果 } } ``` 控制LED灯反转的函数,代码如下: ``` void LedToggle(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) { GPIOx->ODR ^= GPIO_Pin; } ``` 调节LED2亮度的方式,采用PWM控制。 PWM的头文件中: ``` // TIM3 输出比较通道4 #define GENERAL_TIM_CH4_GPIO_CLK RCC_APB2Periph_GPIOB #define GENERAL_TIM_CH4_PORT GPIOB #define GENERAL_TIM_CH4_PIN GPIO_Pin_1 ``` PWM设置的代码如下: ``` static void GENERAL_TIM_GPIO_Config(void) { GPIO_InitTypeDef GPIO_InitStructure; // 输出比较通道4 GPIO 初始化 RCC_APB2PeriphClockCmd(GENERAL_TIM_CH4_GPIO_CLK, ENABLE); GPIO_InitStructure.GPIO_Pin = GENERAL_TIM_CH4_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GENERAL_TIM_CH4_PORT, &GPIO_InitStructure); } static void GENERAL_TIM_Mode_Config(void) { /*--------------------输出比较结构体初始化-------------------*/ TIM_OCInitTypeDef TIM_OCInitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; // 开启定时器时钟,即内部时钟CK_INT=72M GENERAL_TIM_APBxClock_FUN(GENERAL_TIM_CLK,ENABLE); /*--------------------时基结构体初始化-------------------------*/ // 配置周期,这里配置为1K // 自动重装载寄存器的值,累计TIM_Period+1个频率后产生一个更新或者中断 TIM_TimeBaseStructure.TIM_Period=GENERAL_TIM_Period; // 驱动CNT计数器的时钟 = Fck_int/(psc+1) TIM_TimeBaseStructure.TIM_Prescaler= GENERAL_TIM_Prescaler; // 时钟分频因子 ,配置死区时间时需要用到 TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1; // 计数器计数模式,设置为向上计数 TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; // 重复计数器的值,没用到不用管 TIM_TimeBaseStructure.TIM_RepetitionCounter=0; // 初始化定时器 TIM_TimeBaseInit(GENERAL_TIM, &TIM_TimeBaseStructure); // 配置为PWM模式1 TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; // 输出使能 TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; // 输出通道电平极性配置 TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; // 输出比较通道 4 TIM_OCInitStructure.TIM_Pulse = 0; TIM_OC4Init(GENERAL_TIM, &TIM_OCInitStructure); TIM_OC4PreloadConfig(GENERAL_TIM, TIM_OCPreload_Enable); // 使能计数器 TIM_Cmd(GENERAL_TIM, ENABLE); } void GENERAL_TIM_Init(void) { GENERAL_TIM_GPIO_Config(); GENERAL_TIM_Mode_Config(); } ``` 硬件调试结果: 信号量创建成功: [attach]14861[/attach] LED1的功能已实现,能进行反转,调试结果如图: [attach]14857[/attach] [attach]14858[/attach] [attach]14859[/attach] [attach]14860[/attach] LED2的功能已实现,能控制其亮度等级,等级越大,就越亮,调试结果如下: [attach]14862[/attach] [attach]14864[/attach] [attach]14865[/attach] [attach]14866[/attach] [attach]14867[/attach] [attach]14868[/attach] [attach]14863[/attach]
奔跑的蜗牛大大
2020-04-11
这家伙很懒,什么也没写!
f(RT_EOK == uwRet ) { rt_kprintf("Usart2 Receive Data:%s\n",g_USART2_RxBuf); if(strstr((char*)g_USART2_RxBuf,"LED1 Toggle")!=NULL) { LedToggle(GPIOE,GPIO_Pin_5); } if(strstr((char*)g_USART2_RxBuf,"LED2 Brightness")!=NULL) { right(tmp,(char*)g_USART2_RxBuf,1); rt_kprintf("%s\r\n",tmp); cnt=atol(tmp); switch(cnt) { case 1: led_setPwm(50); break; case 2: led_setPwm(100); break; case 3: led_setPwm(200); break; case 4: led_setPwm(250); break; case 5: led_setPwm(300); break; default: led_setPwm(0); break; }
guangying
2020-04-11
这家伙很懒,什么也没写!
# 实现蓝牙串口通信功能 **标准库函数(STD)版** ## 硬件平台介绍 正点原子 NanoSTM32F103RBT6 ,本程序中 Finsh 组件使用 USART1 ;USART3(PB10、PB11) 连接 ESP32 的串口。 ## 设计思路 - 使用蓝牙串口模块,接收数据 - 判断接收数据控制类型 - 使用 PWM 实现调光 ## 实现过程 - 使用 ESP32 的蓝牙功能 - USART3 接收蓝牙的串口数据 - PWM 调光 ### 使用 ESP32 的蓝牙功能 这里就不再赘述了,使用非常简单,教程 https://www.sohu.com/a/322152652_100299098 ### USART3 接收蓝牙的串口数据 这里 USART3 接收蓝牙模块的数据,通过一个信号量提示处理线程接收完毕,进行数据处理。 USART3 使用到了 PB10 和 PB11 ,串口的初始化就不再赘述了, 介绍一下串口中断处理函数和数据处理线程 ``` c //中断处理函数 void USART3_IRQHandler(void) { uint8_t RecCh; if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET) //接收中断 { RecCh = (uint8_t)USART_ReceiveData(USART3); //读取数据 USART3_RX_BUF[g_USART3_RecPos] = RecCh; //存入缓存区 //本次接收到的是 0x0a 并且 上次接收到了 0x0d 也就是说接收到回车换行认为接收完成 if(RecCh == 0x0a && USART3_RX_BUF[g_USART3_RecPos - 1] == 0x0d) { USART3_RX_BUF[g_USART3_RecPos - 1]='\0'; rt_sem_release(usart3_recv_sem); //释放信号量 } else g_USART3_RecPos++; USART_ClearITPendingBit(USART3,USART_IT_RXNE); } } //数据处理线程 static void usart3_Recv_entry(void *parameter) { rt_err_t uwRet=RT_EOK; while(1) { //等待获得信号量 uwRet = rt_sem_take(usart3_recv_sem,RT_WAITING_FOREVER); if(uwRet == RT_EOK) { rt_kprintf("USART3 Receive:%s\n",USART3_RX_BUF); //输出接收到的信息 } if(rt_strstr((char *)USART3_RX_BUF,"LED1 Toggle") != NULL) //接收到反转指令 { if(GPIO_ReadOutputDataBit(GPIOC,GPIO_Pin_7)) GPIO_ResetBits(GPIOC,GPIO_Pin_7); else GPIO_SetBits(GPIOC,GPIO_Pin_7); } if(rt_strstr((char *)USART3_RX_BUF,"LED2 Brightness1") != NULL) //亮度为1 { TIM_SetCompare1(TIM3,5); } if(rt_strstr((char *)USART3_RX_BUF,"LED2 Brightness2") != NULL) //亮度为2 { TIM_SetCompare1(TIM3,20); } if(rt_strstr((char *)USART3_RX_BUF,"LED2 Brightness3") != NULL) //亮度为3 { TIM_SetCompare1(TIM3,80); } if(rt_strstr((char *)USART3_RX_BUF,"LED2 Brightness4") != NULL) //亮度为4 { TIM_SetCompare1(TIM3,150); } if(rt_strstr((char *)USART3_RX_BUF,"LED2 Brightness5") != NULL) //亮度为5 { TIM_SetCompare1(TIM3,400); } rt_memset(USART3_RX_BUF,0,USART3_REC_LEN); //清空接收数组 g_USART3_RecPos = 0; } } ``` ### PWM 调光 调光使用到了 TIM3 CH1 进行 PWM 调光,由 rt-thread 自动初始化。 因为板载 LED 在 PC6 所以将 TIM3 完全重映射到了 PC6 ```c //通用定时器中断初始化 //这里时钟选择为APB1的2倍,而APB1为36M //arr:自动重装值。 //psc:时钟预分频数 //这里使用的是定时器3 void TIM3_CH1_Init(u16 arr,u16 psc) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; GPIO_InitTypeDef GPIO_InitStructure; TIM_OCInitTypeDef TIM_OCInitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); // 时钟使能 // GPIO 和 AFIO 使能 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_AFIO,ENABLE); GPIO_AFIODeInit(); // 重置复用功能 GPIO_PinRemapConfig(GPIO_FullRemap_TIM3,ENABLE); // TIM3 完全重映射 // GPIO 初始化 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOC,&GPIO_InitStructure); // 初始化定时器 TIM3 //设置在下一个更新事件装入活动的自动重装载寄存器周期的值 计数到5000为500ms TIM_TimeBaseStructure.TIM_Period = arr; //设置用来作为TIMx时钟频率除数的预分频值 10Khz的计数频率 TIM_TimeBaseStructure.TIM_Prescaler =psc; TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式 TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //初始化TIM3 // 初始化通道 TIM3_CH1 TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //脉宽调制模式 2 TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能 TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性高 TIM_OC1Init(TIM3, &TIM_OCInitStructure); //初始化外设 TIM3 TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable); ///CH1 预装载使能 TIM_Cmd(TIM3, ENABLE); //使能TIMx外设 } int TIM3_PWM_CH1(void) { TIM3_CH1_Init(899,0); return 0; } INIT_APP_EXPORT(TIM3_PWM_CH1); //由 rt-thread 调用初始化 ``` ## 下载验证 ### 用手机连接 ESP32 的蓝牙 ![screenshot_Gb07JU.png](https://oss-club.rt-thread.org/uploads/20240909/687e082a8f8e6fa97675736fee86f11d.png.webp) ### 反转 LED1 ![Gb0bz4.png](https://oss-club.rt-thread.org/uploads/20240909/fa24918db8da14cd6412cc13626b7cc6.png.webp) ### 调节 LED2 的亮度 ![Gb0HWF.png](https://oss-club.rt-thread.org/uploads/20240909/c6c8c0fbbb18a08eae625690a449ae13.png.webp) [attach]14897[/attach] [attach]14896[/attach]
撰写答案
登录
注册新账号
关注者
0
被浏览
2.6k
关于作者
RT-Thread小喇叭
这家伙很懒,什么也没写!
提问
29
回答
54
被采纳
1
关注TA
发私信
相关问题
1
串口DMA发送数据时,数据被覆盖
2
关于串口DMA模式下rt_device_close问题
3
利用stm32f427实现usb转串口,电脑端什么也没有识别到
4
finsh 控制台 适配 RS 485请大神指点????
5
uart_sample.c 中,读串口设备时偏移量pos要设置为-1而不是0?
6
【结贴】at_device软件包中对串口接收数据缺少判断导致数据接收异常
7
串口无法接受数据,但可以发送
8
串口如何有效的清除掉接收缓冲,而不必一个一个的去读取
9
串口接收使用方式问题
10
雅特力FINSH问题
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
最新文章
1
【RT-Thread】【ci】【scons】将ci.attachconfig.yml和scons结合使用
2
Rt-thread中OTA下载后,bootloader不搬程序
3
ulog 日志 LOG_HEX 输出时间改为本地日期时间
4
在RT-Thread Studio中构建前执行python命令
5
研究一了一段时间RTT,直接标准版上手太难,想用nano,但又舍不得组件
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
USB
DMA
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
I2C_IIC
ESP8266
UART
WIZnet_W5500
ota在线升级
cubemx
PWM
flash
freemodbus
BSP
packages_软件包
潘多拉开发板_Pandora
定时器
ADC
flashDB
GD32
socket
编译报错
中断
Debug
rt_mq_消息队列_msg_queue
SFUD
msh
keil_MDK
ulog
C++_cpp
MicroPython
本月问答贡献
xusiwei1236
8
个答案
2
次被采纳
踩姑娘的小蘑菇
1
个答案
2
次被采纳
用户名由3_15位
9
个答案
1
次被采纳
bernard
4
个答案
1
次被采纳
RTT_逍遥
3
个答案
1
次被采纳
本月文章贡献
聚散无由
2
篇文章
15
次点赞
catcatbing
2
篇文章
5
次点赞
Wade
2
篇文章
4
次点赞
Ghost_Girls
1
篇文章
7
次点赞
xiaorui
1
篇文章
2
次点赞
回到
顶部
发布
问题
分享
好友
手机
浏览
扫码手机浏览
投诉
建议
回到
底部