STM32系列(HAL库)——F103C8T6驱动WS2812全彩RGB模块(PWM+DMA方式)

这篇具有很好参考价值的文章主要介绍了STM32系列(HAL库)——F103C8T6驱动WS2812全彩RGB模块(PWM+DMA方式)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1.软件准备

(1)编程平台:Keil5

(2)CubeMX

2.硬件准备

(1)某宝买的RGB模块(4个灯珠级联)

STM32系列(HAL库)——F103C8T6驱动WS2812全彩RGB模块(PWM+DMA方式)

(2)F1的板子,本例使用经典F103C8T6

STM32系列(HAL库)——F103C8T6驱动WS2812全彩RGB模块(PWM+DMA方式)

(3)ST-link 下载器

STM32系列(HAL库)——F103C8T6驱动WS2812全彩RGB模块(PWM+DMA方式)

(4)杜邦线若干

STM32系列(HAL库)——F103C8T6驱动WS2812全彩RGB模块(PWM+DMA方式)

3.模块资料

(1)模块简介:

没什么比手册讲得更加清楚了,模块中文数据手册:ws2812b中文资料_数据手册_参数

(2)驱动原理:

STM32系列(HAL库)——F103C8T6驱动WS2812全彩RGB模块(PWM+DMA方式)

         以上这是数据手册中提到的,WS2812驱动用的是单线归零码的通讯方式。不同占空比的方波代表1码或者0码,这里不同的占空比就是  0码或1码高电平时间 / 方波周期时间 。对于本次例程,我们就是改变PWM的占空比实现0码或1码的传输。

(3)PWM+DMA原理:

        关于DMA的详细解析,我推荐这篇文章:DMA原理,步骤超细详解,一文看懂DMA

        PWM+DMA可以实现数量和占空比可控的脉冲,具体实现原理是在开启DMA的情况下,定时器在每次计数满后,会自动将DMA传输过来的数据作为新一轮的比较数值。如果DMA传输的数据每次不同,那么每次的方波占空比就不一样的。在本例程中,我们将数据存放在一个数组,通过DMA传输数组的内容,根据数组中数据的个数和每个数据的大小,就能实现数量和占空比可控的PWM。

4.CubeMX配置

(1)芯片选择

STM32系列(HAL库)——F103C8T6驱动WS2812全彩RGB模块(PWM+DMA方式)

 (2)配置RCC、SYS、时钟树

STM32系列(HAL库)——F103C8T6驱动WS2812全彩RGB模块(PWM+DMA方式)

配置RCC

STM32系列(HAL库)——F103C8T6驱动WS2812全彩RGB模块(PWM+DMA方式)

配置SYS

STM32系列(HAL库)——F103C8T6驱动WS2812全彩RGB模块(PWM+DMA方式)

配置时钟树

(3)配置定时器TIM1

STM32系列(HAL库)——F103C8T6驱动WS2812全彩RGB模块(PWM+DMA方式)

         在定时器配置中,我们根据WS2812的最大传输速率800kbps,设置定时器不分频和计数周期为89+1,这样下来波形的频率为  72M /(89+1) = 800K  ,并且一个波形的周期为  1 / 800 = 1.25us

(4)开启DMA

STM32系列(HAL库)——F103C8T6驱动WS2812全彩RGB模块(PWM+DMA方式)

 (5)设置路径、生成代码工程 

5、Keil5代码

(1)创建RGB.c和RGB.h文件

(2)添加上述的RGB.c文件进工程

——————上述两步参考之前系列教学步骤,在此不再赘述(点击跳转)

(3)RGB.c和RGB.h代码

 RGB.h

#ifndef __RGB_H
#define __RGB_H
#include "main.h"
#define Hight_Data            ( 64  )                           //1 码相对计数值
#define Low_Data              ( 36  )                           //0 码相对计数值
#define Reste_Data            ( 80  )                           //80 复位电平相对计数值
#define Led_Num               (  4  )                           //WS2812灯个数
#define Led_Data_Len          ( 24  )                           //WS2812数据长度,单个需要24个字节
#define WS2812_Data_Len   (Led_Num * Led_Data_Len)              //ws2812级联后需要的数组长度

//uint16_t RGB_buffur[Reste_Data + WS2812_Data_Len] = { 0 }; //数据缓存数组


void WS2812_Display_1(uint32_t Color, uint16_t num);
void WS2812_Display_2( uint8_t red, uint8_t green, uint8_t blue,uint16_t num);

void WS2812_Number_4(uint32_t Color1,uint32_t Color2,uint32_t Color3,uint32_t Color4);//封装好的四个灯函数,只需要分别输入四个灯的颜色即可


#endif


 RGB.c

#include "RGB.h"
#include "main.h"
#include "tim.h"

uint16_t RGB_buffur[Reste_Data + WS2812_Data_Len] = { 0 }; //数据缓存数组

void WS2812_Display_1(uint32_t Color, uint16_t num)
{
   
    //指针偏移:需要跳过复位信号的N个0
    uint16_t* p = (RGB_buffur + Reste_Data) + (num * Led_Data_Len);
    
    for (uint8_t i = 0; i < 8; ++i)         
	p[i+8]= (((Color << i) & 0X800000) ? Hight_Data :Low_Data);
    for (uint8_t i = 8; i < 16; ++i)
	p[i-8]= (((Color << i) & 0X800000) ? Hight_Data :Low_Data);
    for (uint8_t i = 16; i < 24; ++i)
	p[i]= (((Color << i) & 0X800000) ? Hight_Data :Low_Data);  
       
}


void WS2812_Display_2( uint8_t red, uint8_t green, uint8_t blue,uint16_t num)
{
            
            uint8_t i;
            uint32_t Color=(green << 16 | red << 8 | blue);//将2个8位数据合并转化为32位数据类型
    
            //指针偏移:需要跳过复位信号的N个0
            uint16_t* p = (RGB_buffur + Reste_Data) + (num * Led_Data_Len);
    
            for (i = 0; i < 24; ++i)    //对数组进行编辑
			p[i]= (((Color << i) & 0X800000) ? Hight_Data : Low_Data);	
                        
}


void WS2812_Number_4(uint32_t Color1,uint32_t Color2,uint32_t Color3,uint32_t Color4)
{
    
    uint16_t  RGB_Buff_4[Reste_Data + 4 * WS2812_Data_Len] = { 0 };
    uint16_t* p;
    uint32_t Color;
    
    for( uint8_t k=0;k<4;k++)
  {      
      switch (k)    //进行指针偏移
      {
        case 0: p= (RGB_Buff_4 + Reste_Data) + (0 * Led_Data_Len),Color=Color1;break;
        case 1: p= (RGB_Buff_4 + Reste_Data) + (1 * Led_Data_Len),Color=Color2;break;
        case 2: p= (RGB_Buff_4 + Reste_Data) + (2 * Led_Data_Len),Color=Color3;break;
        case 3: p= (RGB_Buff_4 + Reste_Data) + (3 * Led_Data_Len),Color=Color4;break;
        default : ;break;     
      }
      
     for (uint8_t i = 0; i < 8; ++i)   //对数组进行编辑
    {   
        for (uint8_t i = 0; i < 8; ++i)
        p[i+8]= (((Color << i) & 0X800000) ? Hight_Data :Low_Data);
        for (uint8_t i = 8; i < 16; ++i)
        p[i-8]= (((Color << i) & 0X800000) ? Hight_Data :Low_Data);
        for (uint8_t i = 16; i < 24; ++i)
        p[i]= (((Color << i) & 0X800000) ? Hight_Data :Low_Data);
    } 
   
 }   
  
    HAL_TIM_PWM_Start_DMA(&htim1,TIM_CHANNEL_1,(uint32_t *)RGB_Buff_4,(176));//启动DMA传输
    
}

 //  DMA 传输完成回调函数
void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim)
{
    HAL_TIM_PWM_Stop_DMA(&htim1,TIM_CHANNEL_1);
}



(4)main函数

#include "RGB.h"



int main(void)
{
 
  extern uint16_t RGB_buffur[Reste_Data + WS2812_Data_Len];
 
  HAL_Init();
 
  SystemClock_Config();

  MX_GPIO_Init();
  MX_DMA_Init();
  MX_TIM1_Init();
  /* USER CODE BEGIN 2 */

//        //点亮4个灯
//        WS2812_Display_1(0x180000, 0);
//        WS2812_Display_1(0x001800, 1);
//        WS2812_Display_1(0x000018, 2);
//        WS2812_Display_1(0x181818, 3);
//        HAL_TIM_PWM_Start_DMA(&htim1,TIM_CHANNEL_1,(uint32_t *)RGB_buffur,(176));//启动DMA传输        


//        //以下代码和上述效果一致,只是颜色数据表示形式不一样
//        WS2812_Display_2( 22 , 0 , 0, 0);
//        WS2812_Display_2(  0 , 22, 0, 1);
//        WS2812_Display_2(  0 , 0, 22, 2);
//        WS2812_Display_2( 22, 22 , 22, 3);
//        HAL_TIM_PWM_Start_DMA(&htim1,TIM_CHANNEL_1,(uint32_t *)RGB_buffur,(176));//启动DMA传输 

 
 
  while (1)
  {
      
      //流水效果
    WS2812_Number_4(0x180000,0x001800,0x000018,0);
    HAL_Delay(500);
    WS2812_Number_4(0,0x180000,0x001800,0x000018);
    HAL_Delay(500);
    WS2812_Number_4(0x000018,0,0x180000,0x001800);
    HAL_Delay(500);
    WS2812_Number_4(0x001800,0x000018,0,0x180000);
    HAL_Delay(500);
     
    
  }
 
}

        因时间问题,代码没有做过多注释。后续再补上。

6.接线图及效果

        关于接线:定时器1的通道1为PA8,将PA8和模块IN引脚连接,并注意供电充足即可。

STM32系列(HAL库)——F103C8T6驱动WS2812全彩RGB模块(PWM+DMA方式)

STM32系列(HAL库)——F103C8T6驱动WS2812全彩RGB模块(PWM+DMA方式)文章来源地址https://www.toymoban.com/news/detail-410595.html

  本例程源码下载:点击跳转 

到了这里,关于STM32系列(HAL库)——F103C8T6驱动WS2812全彩RGB模块(PWM+DMA方式)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • STM32F103C8T6(HAL库)驱动舵机

    常见的舵机分为360°和180°两种,本次对180°舵机进行驱动,舵机驱动需要通过PWM信号进行驱动。本文通过定时器中的PWM信号设定使得SG90舵机进行不同角度的转动。 对于舵机的驱动,需要20ms的脉冲,高电平时间在0.5ms-2.5ms区间即可控制舵机在0-180°角度进行转动。常见角度对应

    2024年02月05日
    浏览(20)
  • stm32(F103c8t6)自学笔记@阿布君

    1.注意头文件和C文件的包含关系,C文件自身应包含自身的H头文件以及用到的外部头文件,而自身头文件只需包含头文件需要用到的资源文件即可。 参考文献:http://t.csdn.cn/o2GmL 注释: 红色 表示:与电源相关 蓝色 是最小系统相关的引脚 绿色 是IO口、功能口 S代表电源、I代表

    2024年02月03日
    浏览(22)
  • STM32 F103C8T6学习笔记5:定时器输出不同占空比PWM驱动舵机旋转角度

    现在学习使用STM32 F103C8T6的定时器PWM模式,使用PWM驱动舵机转动不同角度,文章提供源码,测试工程,测试动态效果图。 目录 基础原理:  实验目标: 测试视频结果: 测试工程下载: 这次依旧拿出之前学习过的舵机DS3115,它的基础原理不多加介绍,在往期讲MSP432的文章有所

    2024年02月13日
    浏览(19)
  • STM32 F103C8T6学习笔记7:双机无线串口通信

    今日尝试配通俩个C8T6单片机之间的无线串口通信,文章提供原理,源码,测试效果图,测试工程下载: 目录 传输不规范问题: 串口通信资源: 单个串口资源理解: 单片机串口资源: 测试目标与测试硬件连接: 串口初始化与串口中断接收逻辑: 串口初始化: 初步测试能否

    2024年02月09日
    浏览(20)
  • STM32 F103C8T6学习笔记6:IIC通信__驱动MPU6050 6轴运动处理组件—一阶互补滤波

    今日主要学习一款倾角传感器——MPU6050,往后对单片机原理基础讲的会比较少,更倾向于简单粗暴地贴代码,因为经过前些日子对MSP432的学习,对原理方面也有些熟络了,除了在新接触它时会对其引脚、时钟、总线等进行仔细一些的研究之外,其余驱动方面便是照搬经验了~

    2024年02月13日
    浏览(21)
  • STM32 F103C8T6学习笔记12:红外遥控—红外解码-位带操作

    今日学习一下红外遥控的解码使用,红外遥控在日常生活必不可少,它的解码与使用也是学习单片机的一个小过程,我们将通过实践来实现它。 文章提供源码、测试工程下载、测试效果图。 目录 红外遥控原理:  红外遥控特点: 红外发射装置:  红外接收示意图:  NEC协议

    2024年02月11日
    浏览(15)
  • STM32CubeIDE + HAL + STM32f103C8T6 系列教程1 ---板载PC13LED闪烁

    之前的系列教程都是基于Arduino的,但是公司招聘51和stm32的开发还是多些,所以特别开了一个stm32的系列。 这个系列特点是注重了 Arduino 编程思维和习惯下向STM32开发的过渡 。前期没有涉及到太多寄存器相关的知识,利用HAL库和STM32CubeIDE快速入手STM32的数字输入/输出、模拟输

    2024年02月16日
    浏览(15)
  • STM32 F103C8T6学习笔记1:开发环境与原理图的熟悉

    作为一名大学生,学习单片机有一段时间了,也接触过嵌入式ARM的开发,但从未使用以及接触过STM32C8T6大开发使用,于是从今日开始,将学习使用它~ 本文介绍STM32C8T6最小系统开发环境搭建注意问题,STM32C8T6单片机资源介绍, 目录 开发环境与下载问题: 1.电脑上需要安装相应

    2024年02月14日
    浏览(15)
  • STM32 F103C8T6学习笔记3:串口配置—串口收发—自定义Printf函数

    今日学习使用STM32 C8T6的串口,我们在经过学习笔记2的总结归纳可知,STM32 C8T6最小系统板上有三路串口,如下图:  今日我们就着手学习如何配置开通这些串口进行收发,这里不讲串口通信概念与基础,可以自行网上查找,本文直接开始介绍库函数与编程实现:          

    2024年02月10日
    浏览(16)
  • STM32 F103C8T6学习笔记4:时钟树、滴答计时器、定时器定时中断

    今日理解一下STM32F103 C8T6的时钟与时钟系统、滴答计时器、定时器计时中断的配置,文章提供原理,代码,测试工程下载。 目录 时钟树与时钟系统: 滴答计时器: 定时器计时中断: 测试结果: 测试工程下载: 该系统介绍在 STM32F10x-中文参考手册 P56页开始 微控制器的时钟系

    2024年02月13日
    浏览(16)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包