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

基于STM32C031 gpio模拟时序经验分享

[复制链接]
攻城狮Melo 发布时间:2023-4-3 18:33
前言
WS2812的驱动方式目前大致为gpio,spi,time+pwm  
gpio会占用cpu,spi或spi+dma需要对spi频率进行配置,time+pwm+dma用起来相对复杂些。
本次用的是gpio通过 ` __NOP() ` 延时来模拟ws2812的时序。
为啥不用spi或pwm是因为spi无法配置为7MHZ或14MHZ stm32c031的时钟48mhz可以/2/4/8/16/32 这几种分频。实际是驱动不了,显示乱的。pwm的话本人实力有限,也不好用丢数据

一、CUBEMX配置

29bfebd66bb6479d812cdc9be3e22821.png

529b92c591f549a9b89074466244615c.png

b893cfca9eee4275814ae81bbc04ced5.png

900afbff7a21498f9db2de87ece9ecb1.png

二、WS2812驱动时序
通过示波器将 __NOP();的用时记录然后逐次增加
一个nop大概占用30-40ns
0码为400+850ns
1码为850+400ns

1.WS2812.C
代码如下(示例):
  1. #include "ws2812.h"


  2. uint8_t ws_data[WS_ARRAY_SIZE]={0};


  3. void  WS_0(void)
  4. {

  5.     LL_GPIO_SetOutputPin(LED1_GPIO_Port, LED1_Pin);
  6.     __NOP();__NOP();__NOP();__NOP();__NOP();
  7.     __NOP();__NOP();__NOP();__NOP();__NOP();       
  8.     __NOP();__NOP();__NOP();

  9.     LL_GPIO_ResetOutputPin(LED1_GPIO_Port, LED1_Pin);
  10.     __NOP();__NOP();__NOP();__NOP();__NOP();       
  11.     __NOP();__NOP();__NOP();__NOP();__NOP();               
  12.     __NOP();__NOP();__NOP();__NOP();__NOP();               
  13.     __NOP();__NOP();__NOP();__NOP();__NOP();               
  14.     __NOP();

  15. }


  16. void WS_1(void)
  17. {
  18.     LL_GPIO_SetOutputPin(LED1_GPIO_Port, LED1_Pin);
  19.     __NOP();__NOP();__NOP();__NOP();__NOP();
  20.     __NOP();__NOP();__NOP();__NOP();__NOP();
  21.     __NOP();__NOP();__NOP();__NOP();__NOP();
  22.     __NOP();__NOP();__NOP();__NOP();__NOP();
  23.     __NOP();__NOP();__NOP();__NOP();__NOP();       
  24.                 __NOP();__NOP();__NOP();__NOP();__NOP();

  25.     LL_GPIO_ResetOutputPin(LED1_GPIO_Port, LED1_Pin);
  26.     __NOP();__NOP();__NOP();__NOP();__NOP();
  27.     __NOP();__NOP();__NOP();__NOP();__NOP();
  28.     __NOP();__NOP();__NOP();

  29. }
  30. void WS_RST(void)
  31. {
  32.                 uint16_t i=0;
  33.             LL_GPIO_ResetOutputPin(LED1_GPIO_Port, LED1_Pin);
  34.                         for(i=0;i<860;i++)
  35.                         {
  36.                                 __NOP();
  37.                         }

  38. }

  39. void ws2812_set_num(uint16_t num ,uint8_t r,uint8_t g,uint8_t b)
  40. {
  41.         ws_data[(num-1)*3]=g;
  42.         ws_data[(num-1)*3+1]=r;
  43.         ws_data[(num-1)*3+2]=b;
  44. }


  45. void ws2812_rgb_all(u8 ws_count,u8 ws_r,u8 ws_g,u8 ws_b)       
  46. {
  47.         static uint8_t rgb_wsi;
  48.         for(rgb_wsi=1;rgb_wsi<=ws_count;rgb_wsi++)
  49.         {
  50.                 ws_data[(rgb_wsi-1)*3]=ws_g;
  51.                 ws_data[(rgb_wsi-1)*3+1]=ws_r;
  52.                 ws_data[(rgb_wsi-1)*3+2]=ws_b;
  53.         }
  54.         //ws2812_refresh(ws_count);
  55. }



  56. void ws2812_refresh(u8 ws_count)
  57. {
  58.         uint8_t ws_ri=0;
  59.    
  60.         for(;ws_ri<ws_count*3;ws_ri++)
  61.         {
  62.                 if((ws_data[ws_ri]&0x80)==0)        WS_0();        else WS_1();
  63.                 if((ws_data[ws_ri]&0x40)==0)        WS_0();        else WS_1();
  64.                 if((ws_data[ws_ri]&0x20)==0)        WS_0();        else WS_1();
  65.                 if((ws_data[ws_ri]&0x10)==0)        WS_0();        else WS_1();
  66.                 if((ws_data[ws_ri]&0x08)==0)        WS_0();        else WS_1();
  67.                 if((ws_data[ws_ri]&0x04)==0)        WS_0();        else WS_1();
  68.                 if((ws_data[ws_ri]&0x02)==0)        WS_0();        else WS_1();
  69.                 if((ws_data[ws_ri]&0x01)==0)        WS_0();        else WS_1();
  70.         }
  71.    
  72.     //延时一段时间
  73.         WS_RST();
  74. }



复制代码

2.WS2812.H
代码如下(示例):
  1. #ifndef _WS2812_H_

  2. #define _WS2812_H_

  3. #include "gpio.h"

  4. typedef unsigned char u8;

  5. #define WS_ARRAY_SIZE   64

  6. void ws2812_refresh(u8 ws_count);//显示
  7. void ws2812_rgb_all(u8 ws_count,u8 ws_r,u8 ws_g,u8 ws_b);//所有LED颜色配置
  8. void ws2812_set_num(uint16_t num ,uint8_t r,uint8_t g,uint8_t b);//配置单个显示

  9. #endif

复制代码

3.显示
  1. while (1)
  2.     {
  3.         /* USER CODE END WHILE */

  4.         /* USER CODE BEGIN 3 */


  5.         for(i = 1; i < 29; i++)//显示28个
  6.         {
  7.             ws2812_set_num(i, 1, 0, 0);//红色

  8.         }
  9.             ws2812_refresh(28);//显示全部数据
  10.             ws2812_rgb_all(28, 0, 0, 0);//清除数据
  11.             HAL_Delay(800);
  12.         for(i = 1; i < 29; i++)//显示28个
  13.         {
  14.             ws2812_set_num(i, 0, 1, 0);//绿色

  15.         }
  16.             ws2812_refresh(28);
  17.             ws2812_rgb_all(28, 0, 0, 0);
  18.             HAL_Delay(800);
  19.         for(i = 1; i < 29; i++)//显示28个
  20.         {
  21.             ws2812_set_num(i, 0, 0, 1);//蓝色

  22.         }
  23.             ws2812_refresh(28);
  24.             ws2812_rgb_all(28, 0, 0, 0);
  25.             HAL_Delay(800);

  26.     }
复制代码


实验现象

dd36ade69e4e43e580fe95d87e80d574.gif

————————————————
版权声明:xiaoqi976633690
如有侵权请联系删除

收藏 评论0 发布时间:2023-4-3 18:33

举报

0个回答

所属标签

相似分享

官网相关资源

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