找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5|回复: 0
收起左侧

初学者使用PY32F002B如何用PWM控制WS2812B灯珠,求大佬帮忙

[复制链接]
ID:904694 发表于 2025-9-8 10:53 | 显示全部楼层 |阅读模式
最近用普冉的PY32F002B,采用PWM中断的方式驱动WS2812B灯珠,先发送了一个0x55,用逻辑分析仪查看波形,发现波形不对,应显示01010101,波形显示却是7个0码,8个1码,8个0码,8个1码,8个0码,8个1码,8个0码,7个1码,纠结了几天未找到解决方法,故来此地向各位大佬求助。
/******************/
int main(void)
{
    // 系统时钟初始化
    HAL_Init();
    SystemClockConfig();
   PWM_Interrupt_Init();
   SendByte(0x55);   
while (1)
    {   
    }
}

/********************/
static volatile uint8_t current_bit_to_send = 0;
static volatile uint8_t byte_to_send = 0;
static volatile uint8_t bit_index = 0;


TIM_HandleTypeDef    TimHandle;
TIM_OC_InitTypeDef   sConfig;
RGB_Color leds[LED_COUNT];

void PWM_Interrupt_Init(void)
{
    TimHandle.Instance = TIM1;                                                      /* TIM1 */
    TimHandle.Init.Period            = TOTAL_TIME - 1;                                      /* Period = 30 - 1 */
    TimHandle.Init.Prescaler         = 1 - 1;                                       /* Prescaler = 0 */
    TimHandle.Init.ClockDivision     = TIM_CLOCKDIVISION_DIV1;                      /* ClockDivision = 0 */
    TimHandle.Init.CounterMode       = TIM_COUNTERMODE_UP;                          /* Counter direction = Up */
    TimHandle.Init.RepetitionCounter = 1 - 1;                                       /* Repetition = 0 */
    TimHandle.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;              /* Auto-reload register not buffered */
    if (HAL_TIM_PWM_Init(&TimHandle) != HAL_OK)                                    /* Initialize TIM1 */
    {
        Error_Handler();
    }               

    sConfig.OCMode       = TIM_OCMODE_PWM1;            /* Set output compare mode: PWM1 */                        
    sConfig.OCPolarity   = TIM_OCPOLARITY_HIGH;        /* OC channel output high level effective */                                
    sConfig.OCFastMode   = TIM_OCFAST_DISABLE;         /* Disable OC FastMode */      
    sConfig.OCNPolarity  = TIM_OCNPOLARITY_HIGH;                   /* OCN channel output high level effective */
    sConfig.OCNIdleState = TIM_OCNIDLESTATE_RESET;                 /* Idle state OC1N output low level */
    sConfig.OCIdleState  = TIM_OCIDLESTATE_RESET;           /* Idle state OC1 output low level*/
    sConfig.Pulse = 0;  
    if (HAL_TIM_PWM_ConfigChannel(&TimHandle, &sConfig, TIM_CHANNEL_1) != HAL_OK)
    {
        Error_Handler();
    }   

}

void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef *htim)
{
    GPIO_InitTypeDef   GPIO_InitStruct = {0};

    //使能时钟
    __HAL_RCC_TIM1_CLK_ENABLE();                           
    __HAL_RCC_GPIOA_CLK_ENABLE();

    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;                  
    GPIO_InitStruct.Pull = GPIO_PULLUP;                       
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    GPIO_InitStruct.Pin = GPIO_PIN_5;
    GPIO_InitStruct.Alternate = GPIO_AF2_TIM1;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    HAL_NVIC_SetPriority(TIM1_BRK_UP_TRG_COM_IRQn, 0, 0);       //最高优先级   
    HAL_NVIC_EnableIRQ(TIM1_BRK_UP_TRG_COM_IRQn);                          
}


void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
        if (htim->Instance == TIM1)
        {
    bit_index++;
    if(bit_index < 8)
    {
        current_bit_to_send = (byte_to_send << bit_index) & 0x80;
        SendBit(current_bit_to_send);
    }
    else
    {
        // 停止PWM输出并禁用中断
                                        HAL_TIM_PWM_Stop(&TimHandle, TIM_CHANNEL_1);
                                        __HAL_TIM_DISABLE_IT(&TimHandle, TIM_IT_UPDATE);     
    }
        }
}

// 发送一位数据
void SendBit(uint8_t bit)
{       
    if (bit)
    {
        // 发送1码:高电平0.9us,低电平0.35us                       
        __HAL_TIM_SET_COMPARE(&TimHandle, TIM_CHANNEL_1, 22);         
    }
    else
    {               
        // 发送0码:高电平0.35us,低电平0.9us
        __HAL_TIM_SET_COMPARE(&TimHandle, TIM_CHANNEL_1, 8);       

    }

}
// 发送一个字节数据(8位)
void SendByte(uint8_t byte)
{
    byte_to_send = byte;
    bit_index = 0;
       
    current_bit_to_send = (byte_to_send << bit_index) & 0x80;
       
    HAL_TIM_PWM_Start(&TimHandle, TIM_CHANNEL_1);
          SendBit(current_bit_to_send);
        __HAL_TIM_ENABLE_IT(&TimHandle, TIM_IT_UPDATE);
}
/**********************/

主要程序附上,请问如何解决
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表