找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4977|回复: 4
打印 上一主题 下一主题
收起左侧

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, 下载次数: 141)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏6 分享淘帖 顶1 踩
回复

使用道具 举报

沙发
ID:390416 发表于 2021-1-7 18:00 | 只看该作者
WS2812是一个通信速度比较快的芯片,而89单片机是比较慢的单片机。
89单片机使用32M晶振、12T模式,用IO口直接驱动WS2812灯珠。
这是我发在51hei的贴子 http://www.51hei.com/bbs/dpj-170855-1.html
回复

使用道具 举报

板凳
ID:386857 发表于 2021-1-9 16:48 | 只看该作者
人人学会单片机 发表于 2021-1-7 18:00
WS2812是一个通信速度比较快的芯片,而89单片机是比较慢的单片机。
89单片机使用32M晶振、12T模式,用IO口 ...

我尝试了你的代码,但在Proteus上不好用
回复

使用道具 举报

地板
ID:546379 发表于 2022-8-30 12:26 | 只看该作者
Proteus原理图需要用8.8版本才可以打开,代码也不好用,只能呵呵,还弄我下了几次
回复

使用道具 举报

5#
ID:386857 发表于 2023-1-16 16:46 | 只看该作者
liao026 发表于 2022-8-30 12:26
Proteus原理图需要用8.8版本才可以打开,代码也不好用,只能呵呵,还弄我下了几次

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

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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