你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【福利三:逢7发帖赢大礼】使用arc弧形拉条控件控制PWM舵机及使用SPI3接口操作NRF24L01模块进行无线通信

[复制链接]
donatello1996 发布时间:2026-7-25 02:25
       LVGL的虚拟输入控件有button(按钮)、checkbox(复选框)、radiobox(单选框)、bar(直线拉条)和arc(弧形拉条)等,都可以通过这些输入控件的回调函数给MCU发送指令进而控制GPIO外设,而事件也有按下,抬起,按下+抬起,数值改变,状态改变等,这帖我就用arc+状态改变回调函数,实现弧形拉条控制PWM舵机的功能。


初始化TIM3为PWM输出功能,输出引脚为PC8,PC8接舵机PWM引脚:


TIM_HandleTypeDef g_timx_pwm_chy_handle;


void TIM3_PWM_Init(uint16_t arr, uint16_t psc)
{
        GPIO_InitTypeDef gpio_init_struct;
        TIM_OC_InitTypeDef timx_oc_pwm_chy = {0};


        __HAL_RCC_GPIOC_CLK_ENABLE();
        __HAL_RCC_TIM3_CLK_ENABLE();


        gpio_init_struct.Mode = GPIO_MODE_AF_PP;
        gpio_init_struct.Pull = GPIO_PULLUP;
        gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;
        gpio_init_struct.Alternate = GPIO_AF2_TIM3;
        
        gpio_init_struct.Pin = GPIO_PIN_8;
        HAL_GPIO_Init(GPIOC , &gpio_init_struct);
        
        g_timx_pwm_chy_handle.Instance = TIM3;
        g_timx_pwm_chy_handle.Init.Prescaler = psc;
        g_timx_pwm_chy_handle.Init.CounterMode = TIM_COUNTERMODE_UP;
        g_timx_pwm_chy_handle.Init.Period = arr;
        HAL_TIM_PWM_Init(&g_timx_pwm_chy_handle);


        timx_oc_pwm_chy.OCMode = TIM_OCMODE_PWM1;
        timx_oc_pwm_chy.Pulse = arr / 2;


        timx_oc_pwm_chy.OCPolarity = TIM_OCPOLARITY_LOW;
        HAL_TIM_PWM_ConfigChannel(&g_timx_pwm_chy_handle, &timx_oc_pwm_chy, TIM_CHANNEL_3);
        
        HAL_TIM_PWM_Start(&g_timx_pwm_chy_handle, TIM_CHANNEL_3);
}


设置弧形拉条的参数和回调函数,弧形拉条位于tile_2界面即滑屏从左到右数起第二个界面的偏下方(LV_ALIGN_CENTER, 0 , 90),回调函数触发事件为拉条值改变(LV_EVENT_VALUE_CHANGED):
void lv_example_tileview(void)
{
。。。
        arc_left = lv_arc_create(tile_2);
        lv_obj_set_size(arc_left , 200 , 200);
        lv_obj_align(arc_left , LV_ALIGN_CENTER, 0 , 90);
        lv_arc_set_value(arc_left , 66);
        lv_obj_set_style_arc_width(arc_left , 40 , LV_PART_MAIN);
        lv_obj_set_style_arc_width(arc_left , 40 , LV_PART_INDICATOR);
        lv_obj_add_event_cb(arc_left , arc_event_cb , LV_EVENT_VALUE_CHANGED, NULL);
}


弧形拉条回调函数:
static void arc_event_cb(lv_event_t *e)
{
        int32_t val;
        lv_obj_t * target = (lv_obj_t *)lv_event_get_target(e);
        lv_event_code_t code = lv_event_get_code(e);


        if(code == LV_EVENT_VALUE_CHANGED)
        {
                val = lv_arc_get_value(target);
                printf("%d.\n" , val);
               
                TIM3->CCR3 = 10000 + 400 * val;
        }
}


演示效果:



然后是使用SPI3接口控制一个NRF24L01模块进行发送,代码如下:
SPI_HandleTypeDef g_spi3_handler;


uint8_t SPI3_PC10_PC11_PC12_Read_Write_Byte(uint8_t txdata)
{
    uint8_t rxdata;
    HAL_SPI_TransmitReceive(&g_spi3_handler , &txdata , &rxdata , 1 , 1000);
    return rxdata;
}


void SPI3_PC10_PC11_PC12_Init(void)
{
        GPIO_InitTypeDef  GPIO_InitStruct;
        RCC_PeriphCLKInitTypeDef rcc_periph_clk_init;


        __HAL_RCC_GPIOC_CLK_ENABLE();
        __HAL_RCC_SPI3_CLK_ENABLE();


        GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
        GPIO_InitStruct.Pull = GPIO_PULLUP;
        GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
        GPIO_InitStruct.Alternate = GPIO_AF6_SPI3;
        
        GPIO_InitStruct.Pin = GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12;
        HAL_GPIO_Init(GPIOC , &GPIO_InitStruct);
        
//        rcc_periph_clk_init.PeriphClockSelection = RCC_PERIPHCLK_SPI3;
//        rcc_periph_clk_init.Spi123ClockSelection = RCC_SPI123CLKSOURCE_PLL;
//        HAL_RCCEx_PeriphCLKConfig(&rcc_periph_clk_init);
               
        g_spi3_handler.Instance = SPI3;
        g_spi3_handler.Init.Mode = SPI_MODE_MASTER;
        g_spi3_handler.Init.Direction = SPI_DIRECTION_2LINES;
        g_spi3_handler.Init.DataSize = SPI_DATASIZE_8BIT;
        g_spi3_handler.Init.CLKPolarity = SPI_POLARITY_LOW;
        g_spi3_handler.Init.CLKPhase = SPI_PHASE_1EDGE;
        g_spi3_handler.Init.NSS = SPI_NSS_SOFT;
        g_spi3_handler.Init.NSSPMode = SPI_NSS_PULSE_DISABLE;
        g_spi3_handler.Init.MasterKeepIOState = SPI_MASTER_KEEP_IO_STATE_ENABLE;
        g_spi3_handler.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_128;
        g_spi3_handler.Init.FirstBit = SPI_FIRSTBIT_MSB;
        g_spi3_handler.Init.TIMode = SPI_TIMODE_DISABLE;
        g_spi3_handler.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
        g_spi3_handler.Init.CRCPolynomial = 7;
        HAL_SPI_Init(&g_spi3_handler);
        
        __HAL_SPI_ENABLE(&g_spi3_handler);
        SPI3_PC10_PC11_PC12_Read_Write_Byte(0xff);
}


void NRF24L01_GPIO_Init(void)
{
        GPIO_InitTypeDef gpio_init_struct;
        NRF24L01_CS_GPIO_CLK_ENABLE;
        NRF24L01_CE_GPIO_CLK_ENABLE;
        
        gpio_init_struct.Mode = GPIO_MODE_OUTPUT_PP;
        gpio_init_struct.Pull = GPIO_PULLUP;
        gpio_init_struct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
        
        gpio_init_struct.Pin = NRF24L01_CS_GPIO_PIN;
        HAL_GPIO_Init(NRF24L01_CS_GPIO_PORT , &gpio_init_struct);
        
        gpio_init_struct.Pin = NRF24L01_CE_GPIO_PIN;
        HAL_GPIO_Init(NRF24L01_CE_GPIO_PORT , &gpio_init_struct);
        
        gpio_init_struct.Mode = GPIO_MODE_INPUT;
        gpio_init_struct.Pin = NRF24L01_IRQ_GPIO_PIN;
        HAL_GPIO_Init(NRF24L01_IRQ_GPIO_PORT , &gpio_init_struct);
        
        NRF24L01_CE_LOW;
        NRF24L01_CS_HIGH;
}


uint8_t NRF24L01_Write_Buf(uint8_t reg , uint8_t *pBuf , uint8_t len)
{
        uint8_t status , u8_ctr;
        
        NRF24L01_CS_LOW;
        
        status = SPI3_PC10_PC11_PC12_Read_Write_Byte(reg);
        for(u8_ctr = 0 ; u8_ctr < len ; u8_ctr ++)
                SPI3_PC10_PC11_PC12_Read_Write_Byte(*pBuf++);
        
        NRF24L01_CS_HIGH;
        
        return status;
}


uint8_t NRF24L01_Read_Buf(uint8_t reg , uint8_t *pBuf , uint8_t len)
{
        uint8_t status , u8_ctr;
        
  NRF24L01_CS_LOW;
        
  status = SPI3_PC10_PC11_PC12_Read_Write_Byte(reg);
        for(u8_ctr = 0 ; u8_ctr < len ; u8_ctr ++)
                pBuf[u8_ctr] = SPI3_PC10_PC11_PC12_Read_Write_Byte(0xff);
        
  NRF24L01_CS_HIGH;
        
  return status;
}


uint8_t NRF24L01_Write_Reg(uint8_t reg , uint8_t value)
{
        uint8_t status;        
        
        NRF24L01_CS_LOW;
        
        status = SPI3_PC10_PC11_PC12_Read_Write_Byte(reg);
        SPI3_PC10_PC11_PC12_Read_Write_Byte(value);
        
        NRF24L01_CS_HIGH;
        
        return(status);
}


uint8_t NRF24L01_Read_Reg(uint8_t reg)
{
        uint8_t reg_val;        
        
        NRF24L01_CS_LOW;
        
        SPI3_PC10_PC11_PC12_Read_Write_Byte(reg);
        reg_val = SPI3_PC10_PC11_PC12_Read_Write_Byte(0XFF);
        
        NRF24L01_CS_HIGH;
        
        return(reg_val);
}


NRF24L01的CS脚,CE脚,IRQ脚使用普通GPIO进行控制:
42.JPG
#define NRF24L01_1_CS_GPIO_PORT                                        GPIOB
#define NRF24L01_1_CS_GPIO_PIN                                         GPIO_PIN_12
#define NRF24L01_1_CS_GPIO_CLK_ENABLE                                        rcu_periph_clock_enable(RCU_GPIOB);
#define NRF24L01_1_CS_HIGH                                                                                                                                GPIO_BOP(NRF24L01_1_CS_GPIO_PORT) = NRF24L01_1_CS_GPIO_PIN;
#define NRF24L01_1_CS_LOW                                                                                                                                        GPIO_BC(NRF24L01_1_CS_GPIO_PORT) = NRF24L01_1_CS_GPIO_PIN;


#define NRF24L01_1_CE_GPIO_PORT                                        GPIOB
#define NRF24L01_1_CE_GPIO_PIN                                         GPIO_PIN_10
#define NRF24L01_1_CE_GPIO_CLK_ENABLE                                        rcu_periph_clock_enable(RCU_GPIOB);
#define NRF24L01_1_CE_HIGH                                                                                                                                GPIO_BOP(NRF24L01_1_CE_GPIO_PORT) = NRF24L01_1_CE_GPIO_PIN;
#define NRF24L01_1_CE_LOW                                                                                                                                        GPIO_BC(NRF24L01_1_CE_GPIO_PORT) = NRF24L01_1_CE_GPIO_PIN;


#define NRF24L01_1_IRQ_GPIO_PORT                                                  GPIOB
#define NRF24L01_1_IRQ_GPIO_PIN                                                   GPIO_PIN_11
#define NRF24L01_1_IRQ_GPIO_CLK_ENABLE                                            rcu_periph_clock_enable(RCU_GPIOB);
#define NRF24L01_1_IRQ_READ                                                                                                                    gpio_input_bit_get(NRF24L01_1_IRQ_GPIO_PORT , NRF24L01_1_IRQ_GPIO_PIN)


在lv_timer定时器回调函数中进行无线发送:



static void my_timer1(lv_timer_t * timer)
{
。。。


nrf_buf[0] = 0xaa;
        nrf_buf[1] = 0xbb;
       
        nrf_buf[2] = 2;
       
        nrf_buf[3] = (bme680fd.temperature >> 8) & 0xff;
        nrf_buf[4] = bme680fd.temperature & 0xff;
       
        nrf_buf[5] = (bme680fd.pressure >> 24) & 0xff;
        nrf_buf[6] = (bme680fd.pressure >> 16) & 0xff;
        nrf_buf[7] = (bme680fd.pressure >> 8) & 0xff;
        nrf_buf[8] = bme680fd.pressure & 0xff;
       
        nrf_buf[9] = (bme680fd.humidity >> 24) & 0xff;
        nrf_buf[10] = (bme680fd.humidity >> 16) & 0xff;
        nrf_buf[11] = (bme680fd.humidity >> 8) & 0xff;
        nrf_buf[12] = bme680fd.humidity & 0xff;

        nrf_buf[30] = 0xcc;
        nrf_buf[31] = 0**;
       
        if(NRF24L01_TxPacket(nrf_buf) == TX_OK)
        {
                printf("NRF24L01_TxPacket succeed.\n");
        }
        else
        {
                printf("NRF24L01_TxPacket failed.\n");
        }
。。。
}



演示效果,使用另外一块MCU板接上另一个NRF24L01模块进行轮询接收:

43.JPG




收藏 评论0 发布时间:2026-7-25 02:25

举报

0个回答

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版