标题: Proteus仿真WS2812+51单片机源程序 [打印本页]

作者: iojj    时间: 2021-1-7 17:42
标题: Proteus仿真WS2812+51单片机源程序
跟据示波波形,反复调试,同时优化程序,使高电平最小时间接近0.5us,如示波器图所示,这时可利用程序驱动WS2812,否则会因程序运行速度过慢而无法驱动。
为了简化程序,加快代码运行速度,采用汇编与C语言混合编程
#pragma ASM
SETB P2.5
CLR  P2.5
CLR  P2.5
#pragma ENDASM

因单片机时钟周期限制,在仿真的调试过程中加入for,while循环会使ws2812的驱动波形出现长时间的低电平,导致不能正常点亮led,故此程序没有使用for循环,而是多条语句重复使用,造成了代码量很大,因本人能力有限,没有精力进行简化,望使用的大佬能进一步完善。

仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)


单片机源程序如下:
  1. #include <reg51.h>
  2. #include <LCD1602.h>
  3. #include <GY25.h>
  4. #include <WS2812.h>
  5. #include <stdio.h>
  6. #define PIXEL_COUNT 16



  7. sbit led1=P2^3;
  8. sbit led2=P2^4;

  9. int flag_now=0,flag_last=0;
  10. char strTemp[10]= {'0','1','2','3','4','5','6','7','8','9'};



  11. int RR,GG,BB;
  12. int i;
  13. int US100;
  14. int MS1;
  15. void display()
  16. {
  17.     LCD_set_position(0);
  18.     LCD_printc(strTemp[YPR/1000]);
  19.     LCD_printc(strTemp[YPR/100%10]);
  20.     LCD_printc(strTemp[YPR/10%10]);
  21.     LCD_printc(strTemp[YPR%10]);
  22. }
  23. void led_init()
  24. {
  25.     led1=1;
  26.     led2=1;
  27. }
  28. void delay10ms(void)   //误差 0.000000000000us
  29. {
  30.     unsigned char a,b;
  31.     for(b=235;b>0;b--)
  32.         for(a=57;a>0;a--);
  33. }
  34. int count=0;
  35. void control()
  36. {
  37.     if(YPR<10&&YPR>-10)
  38.         flag_now=1;
  39.     else
  40.         flag_now=2;
  41.     if(flag_now==1)
  42.     {
  43.         led1=0;
  44.         led2=1;
  45.     }
  46.     if(flag_now==2)
  47.     {
  48.         led1=1;
  49.         led2=0;
  50.     }
  51.     if(flag_last!=flag_now)
  52.                 {
  53.                         
  54.                                 if(flag_now==1)
  55.                                                         for(count=1;count<=32;count++)
  56.                                                  {
  57.                                                          ws2812_led(count);
  58.                                                          delay10ms();
  59.                                                  }
  60.                                 if(flag_now==2)
  61.                                                                 for(count=32;count>0;count--)
  62.                                                          {
  63.                                                                  ws2812_led(count);
  64.                                                                  delay10ms();
  65.                                                          }
  66.                   ws2812_led(0);
  67.                 }
  68.                
  69.     flag_last=flag_now;
  70. }
  71. void main(void)
  72. {
  73.     InitUART();
  74.     led_init();
  75.           SBUF = 0XA5;
  76.     while(!TI);
  77.           SBUF = 0X52;
  78.     while(!TI);
  79.           delay10ms();
  80.     while(1)
  81.     {
  82.       control();
  83.     }
  84. }
复制代码

Keil代码与Proteus8.8版本仿真51hei下载:
本人初学,仅供参考,存在错误和不足之处,请大家回帖多多指教,切勿照搬,文件下载:
WS2812.zip (1.56 MB, 下载次数: 151)

作者: 人人学会单片机    时间: 2021-1-7 18:00
WS2812是一个通信速度比较快的芯片,而89单片机是比较慢的单片机。
89单片机使用32M晶振、12T模式,用IO口直接驱动WS2812灯珠。
这是我发在51hei的贴子 http://www.51hei.com/bbs/dpj-170855-1.html
作者: iojj    时间: 2021-1-9 16:48
人人学会单片机 发表于 2021-1-7 18:00
WS2812是一个通信速度比较快的芯片,而89单片机是比较慢的单片机。
89单片机使用32M晶振、12T模式,用IO口 ...

我尝试了你的代码,但在Proteus上不好用
作者: liao026    时间: 2022-8-30 12:26
Proteus原理图需要用8.8版本才可以打开,代码也不好用,只能呵呵,还弄我下了几次
作者: iojj    时间: 2023-1-16 16:46
liao026 发表于 2022-8-30 12:26
Proteus原理图需要用8.8版本才可以打开,代码也不好用,只能呵呵,还弄我下了几次

gif动图在那里,亲,您是哪里不好用呢




欢迎光临 (http://www.51hei.com/bbs/) Powered by Discuz! X3.1