找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 7270|回复: 11
收起左侧

STM8S003F3P6控制WS2812b时序对不上可以帮帮忙吗

[复制链接]
ID:235359 发表于 2017-11-4 15:37 | 显示全部楼层 |阅读模式
STM8S003F3P6采用内部16M晶振。我看市场上面有使用这个单片机采用内部晶振进行控制的。不知道为什么我总是控制不到。
QQ图片20171104153205.png

2.png


一个NOP是68NS 左右  空指令符合规格书要求Send_Dat = 1; 但是空指令后Send_Dat = 0;时间就变为1.2US了
同样的单片机 我不知道别人怎么做到Send_Dat = 1的时候850NS的。有没有高手指导指导一下。(我i采集过市场上面的他可以做到850NS)
3.png



  1. /*    添加包含芯片的头文件    */
  2. #include<iostm8s103f3.h>
  3. #define nop()  asm("nop");
  4. #define LED             PB_ODR_ODR5  
  5. #define Send_Dat        PC_ODR_ODR7   //数据输出,接pb5脚
  6. #define Number   100
  7. typedef unsigned char uint8;
  8. typedef unsigned int uint16;

  9. //定义全局变量

  10. /*******************************************************************************
  11. **函数名称:void Send_8bit(uchar dat)
  12. **功能描述:发送24个字节
  13. **入口参数:无
  14. **输出:无
  15. *******************************************************************************/
  16. void send_24bits(uint8 dat1,uint8 dat2,uint8 dat3)   //WS2811B
  17. {
  18.     uint8 a;
  19.     for(a=0;a<8;a++)
  20.     {
  21.         if(dat1&0x80)       //code"1"
  22.         {
  23.           Send_Dat = 1;
  24.           nop();
  25.           nop();
  26.           nop();
  27.           nop();
  28.           nop();
  29.           Send_Dat = 0;         
  30.         }
  31.         else
  32.          {
  33.           Send_Dat = 1;   //code"0"
  34.           nop();
  35.           nop();
  36.           nop();
  37.           nop();
  38.           nop();
  39.           nop();
  40.           nop();
  41.           nop();
  42.           nop();
  43.           nop();
  44.           nop();
  45.           nop();
  46.           nop();
  47.           nop();

  48.           Send_Dat = 0;

  49.         }
  50.       dat1 = dat1<<1;
  51.     }

  52.      for(a=0;a<8;a++)
  53.     {
  54.         if(dat2&0x80)       //code"1"
  55.         {
  56.           Send_Dat = 0;
  57.           nop();
  58.           nop();
  59.           nop();
  60.           nop();
  61.           nop();
  62.           Send_Dat = 1;
  63.         }
  64.         else
  65.         {
  66.           Send_Dat = 1;   //code"0"
  67.           nop();
  68.           nop();
  69.           nop();
  70.           nop();
  71.           nop();
  72.           nop();
  73.           nop();
  74.           nop();
  75.           nop();
  76.           nop();
  77.           nop();
  78.           nop();
  79.           nop();
  80.           nop();
  81.           Send_Dat = 0;

  82.         }
  83.       dat1 = dat2<<1;
  84.     }

  85.      for(a=0;a<8;a++)
  86.     {
  87.         if(dat3&0x80)       //code"1"
  88.         {
  89.           Send_Dat = 0;
  90.           nop();
  91.           nop();
  92.           nop();
  93.           nop();
  94.           nop();
  95.           Send_Dat = 1;
  96.         }
  97.         else
  98.         {
  99.           Send_Dat = 1;   //code"0"
  100.           nop();
  101.           nop();
  102.           nop();
  103.           nop();
  104.           nop();
  105.           nop();
  106.           nop();
  107.           nop();
  108.           nop();
  109.           nop();
  110.           nop();
  111.           nop();
  112.           nop();
  113.           nop();
  114.           Send_Dat = 0;

  115.         }
  116.       dat1 = dat3<<1;
  117.     }
  118. }
  119. /*******************************************************************************
  120. **函数名称:void Delay_us(uint16 x)
  121. **功能描述:延时函数
  122. **入口参数:无
  123. **输出:无
  124. *******************************************************************************/
  125. void Delay_us(uint16 x)
  126. {
  127.     uint8 j,k;
  128.     for(j=x;j>0;j--)
  129.       for(k=120;k>0;k--);
  130. }
  131. /*******************************************************************************
  132. **函数名称:rest()
  133. **功能描述:复位函数
  134. **入口参数:无
  135. **输出:无
  136. *******************************************************************************/
  137. void rest()                        //复位
  138. {
  139.    Send_Dat = 0;
  140.    Delay_us(1);
  141. }
  142. /*******************************************************************************
  143. **函数名称:void Timer2Init()
  144. **功能描述:定时器2参数初始化
  145. **入口参数:无
  146. **输出:无
  147. *******************************************************************************/
  148. void Timer2Init()
  149. {
  150.   TIM2_PSCR = 0x00;   //定时器2预分频数为 1 分频,即定时器时钟 = 系统时钟 = 16MHz
  151.   TIM2_ARRH = 0x3e;   //设置1毫秒时间自动重载 16000 = 0x3e80
  152.   TIM2_ARRL = 0x80;   //
  153.   TIM2_CNTRH = 0;     //清除计数寄存器
  154.   TIM2_CNTRL = 0;     //
  155.   TIM2_IER = 0x01;    //使能定时器2允许更新中断
  156.   TIM2_SR1 = 0x00;    //清除所有的中断标示
  157.   TIM2_CR1 = 0x81;    //使能计数器,并允许自动预装
  158. }

  159. /*******************************************************************************
  160. **函数名称:void LED2Init()
  161. **功能描述:LED2->功能引脚初始化
  162. **入口参数:无
  163. **输出:无
  164. *******************************************************************************/


  165. void Init_GPIO()
  166. {
  167.     PB_DDR_DDR5 = 1;
  168.     PB_CR1 = 0xff;
  169.     PB_CR2 = 0x00;
  170.     PC_DDR_DDR7 = 1;
  171.     PC_CR1 = 0xff;
  172.     PC_CR2 = 0x00;  
  173. }

  174. void rest_all()
  175. {
  176.     uint16 i;
  177.     for(i=0;i<Number;i++)
  178.               {
  179.           send_24bits(0,0,0);
  180.         }
  181.         rest();
  182. }

  183. void Five_Color_Flow() //5个同色灯珠流水
  184. {
  185.         uint8 i=0,mode_flag=0;
  186.         char a,b=0;
  187.         rest_all();
  188.         while(1)
  189.   {

  190.                 for(i=0;i<Number;i++)
  191.                 {
  192.                  if(a<5)        send_24bits(255,0,0);
  193.                  else if(a<10)        send_24bits(0,255,0);
  194.                  else if(a<15)  send_24bits(0,0,255);  
  195.                  else if(a<20)  send_24bits(255,255,0);
  196.                  else if(a<25)  send_24bits(0,255,255);
  197.                  else if(a<30)  send_24bits(255,255,0);
  198.                  else           send_24bits(255,255,255);
  199.                  a++;
  200.                  if(a>34) a=0;
  201.                 }
  202.                 rest();
  203.                 Delay_us(150);
  204.                 b--;
  205.                 if(b<0) b=34;
  206.         }
  207. }


  208. /*******************************************************************************
  209. **函数名称:主函数
  210. **功能描述:1=55US
  211. **入口参数:无
  212. **输出:无
  213. *******************************************************************************/
  214. int main(void)
  215. {
  216.   asm("sim");           //先关闭总中断
  217.   CLK_CKDIVR = 0x00;    //CPUDIV = 1 HSIDIV = 1  内部时钟 = 16Mhz
  218.   Init_GPIO();          //初始化IO口
  219.   Timer2Init();         //调用定时器2初始化函数
  220.   asm("rim");           //打开总中断


  221.   while(1)             //进入死循环,等待定时器2周期中断
  222.   {
  223.     send_24bits(255,0,0) ;

  224.   }
  225. }


  226. /*******************************************************************************
  227. **函数名称:__interrupt void TIM2_UPDATE_IRQHandler(void)
  228. **功能描述:定时器2重载更新中断服务函数
  229. **入口参数:无
  230. **输出:无
  231. *******************************************************************************/
  232. #pragma vector = 15     //设置定时器2重载的中断向量号 = 15
  233. __interrupt void TIM2_UPDATE_IRQHandler(void)
  234. {
  235.   TIM2_SR1 = 0x00;      //清除中断标志

  236. /* ms_count++;           //中断使 ms_count++ 做加法,记录1毫秒产生的中断次数
  237.   if(ms_count >= 1000)  //记录达到1000毫秒,即1秒
  238.   {
  239.     ms_count = 0;       //复位记录中断次数
  240.    // PC_ODR ^= 0x80;     //对LED2进行异或取反,使LED2以1秒的周期亮灭
  241.   }
  242. */
  243. }
复制代码
回复

使用道具 举报

ID:273896 发表于 2018-8-24 00:12 | 显示全部楼层
某种原因 程序暂时无法提供,附一张WS2812B时序图,供大家参考!
WS2812B.png

评分

参与人数 1黑币 +50 收起 理由
admin + 50 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

ID:235359 发表于 2017-11-4 15:40 | 显示全部楼层
希望有人可以帮助我谢谢
回复

使用道具 举报

ID:273896 发表于 2018-3-21 13:55 | 显示全部楼层
我搞定了!加Q858554712 发你
回复

使用道具 举报

ID:40043 发表于 2018-4-16 11:29 | 显示全部楼层
楼上高手指点一下啊!
回复

使用道具 举报

ID:397060 发表于 2019-3-1 11:14 | 显示全部楼层
楼主   问题解决了吗,  我前几天刚好遇见和你一样的问题   ,求助啊
回复

使用道具 举报

ID:633536 发表于 2019-11-1 22:08 | 显示全部楼层
我也碰到了这个问题,可能是脉冲时间太短了,单片机无法正常运行到那么多代码,脉冲时间调长一点波形会正常但是又不能符合WS2812的时序,很苦恼啊,楼主解决了没有
回复

使用道具 举报

ID:755407 发表于 2020-8-13 16:09 | 显示全部楼层
设置I/O口设置为高速模式10M
回复

使用道具 举报

ID:87063 发表于 2021-2-3 16:50 | 显示全部楼层
我也遇到这个问题,如何解决啊? 我就不延迟直接反转引脚单片机执行都要1us。。。。。
回复

使用道具 举报

ID:87063 发表于 2021-2-3 16:51 | 显示全部楼层
有没有人解决的,说下怎么回事呢?
回复

使用道具 举报

ID:87063 发表于 2021-2-3 18:10 | 显示全部楼层
我终于解决了,用库实现不了的,推荐寄存器操作
回复

使用道具 举报

ID:411116 发表于 2021-9-22 20:34 | 显示全部楼层
按照不同时钟频率适当加减_nop_();的数量调整时序
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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