打印
[STM8]

STM8S003,控制七彩跑马灯的问题——中断

[复制链接]
1723|9
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
CARL_SUN|  楼主 | 2016-12-27 11:25 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 CARL_SUN 于 2016-12-27 11:53 编辑

   本人只是一个新手。野路子,没有经过专业的学习,所以写出代码不怎么规范,更不懂运用一些公式。所定代码也像本人的表达一样杂乱无章,也拖沓无序。占用大量空间,然而,这不是我要讲的重点。最近自己玩一款市场上常用的RGB控制。类似TM1804的那玩意。需要单线通讯。
需要功能是:一串40颗灯,共两串一起工作做摩托车的左右氛围灯与转向灯。氛围做三种闪烁花样。每种花样的各种颜色隔一段时间自动变化。三种花样用摩托大灯开关一个条线控制,闪大灯一次,变换一次花样。大灯时间开超过1秒,认为是开大灯,不变换花样。另需要两条转向线,分左右转向。一边转向时,对应边的灯暂停花样,改为用R/G混成的黄光亮。转向信号消失,相应边完全不亮。消失时间达到1.5秒左右,返回到花样闪烁。
现在的思路是这样:
用两个I/O做输出(做两串的控制输出),用TIM4定时器做时间记时,变换颜色。用一个I/O中断做花样变换。
写好代码,出现问题了。
如图中:通讯方式,此通讯需要快速传输编码。并且在传码过程中连续传输,不能中断。而关闭中断后,记时与变换多少会出现问题。

代码:一种闪烁花样:
void led_fhl (u8 j, u8 biaozhi)   //j为LED的组数
  {

      u8 a;
      do_rest();
      color();

      if(turn_l_status)
        {

           if(turn_l)
             {
                g_date_l = 255 ;
                r_date_l = 50 ;
                b_date_l = 0 ;
             }
           else
             {
                g_date_l = 0 ;
                r_date_l = 0 ;
                b_date_l = 0 ;
             }
           u8 m;
           for( m = 0; m < led_number ; m++)
             {
               write_single_l( r_date_l );
               write_single_l( g_date_l );
               write_single_l( b_date_l );
             }

        }
    if(turn_r_status)
       {
        if(turn_r)
          {
             g_date_r = 255 ;
             r_date_r = 50 ;
             b_date_r = 0 ;
           }
         else
          {
             g_date_r = 0 ;
             r_date_r = 0 ;
             b_date_r = 0 ;
           }
         u8 n;
           for( n = 0; n< led_number ; n++)
             {
               write_single_r( r_date_r );
               write_single_r( g_date_r );
               write_single_r( b_date_r );
             }
      }

      __disable_interrupt();
     for( a = 0; ((a < j)&&(turn_r_status == 0)) ; a++)
       {

            write_single_r(led_pwm_r[biaozhi+0]*r_status);
            write_single_r(led_pwm_r[biaozhi+0]*g_status);
            write_single_r(led_pwm_r[biaozhi+0]*b_status);

            write_single_r(led_pwm_r[biaozhi+1]*r_status);
            write_single_r(led_pwm_r[biaozhi+1]*g_status);
            write_single_r(led_pwm_r[biaozhi+1]*b_status);

            write_single_r(led_pwm_r[biaozhi+2]*r_status);
            write_single_r(led_pwm_r[biaozhi+2]*g_status);//*(!turn_r_status)+(g_date_r*turn_r_status));
            write_single_r(led_pwm_r[biaozhi+2]*b_status);

            write_single_r(led_pwm_r[biaozhi+3]*r_status);
            write_single_r(led_pwm_r[biaozhi+3]*g_status);
            write_single_r(led_pwm_r[biaozhi+3]*b_status);

            write_single_r(led_pwm_r[biaozhi+4]*r_status);
            write_single_r(led_pwm_r[biaozhi+4]*g_status);
            write_single_r(led_pwm_r[biaozhi+4]*b_status);

            write_single_r(led_pwm_r[biaozhi+5]*r_status);
            write_single_r(led_pwm_r[biaozhi+5]*g_status);
            write_single_r(led_pwm_r[biaozhi+5]*b_status);

            write_single_r(led_pwm_r[biaozhi+6]*r_status);
            write_single_r(led_pwm_r[biaozhi+6]*g_status);
            write_single_r(led_pwm_r[biaozhi+6]*b_status);

            write_single_r(led_pwm_r[biaozhi+7]*r_status);
            write_single_r(led_pwm_r[biaozhi+7]*g_status);
            write_single_r(led_pwm_r[biaozhi+7]*b_status);//*(!turn_r_status)+(b_date_r*turn_r_status));

          }
     for( a = 0; ((a < j)&&(turn_l_status == 0)) ; a++)
       {
           write_single_l(led_pwm_l[biaozhi+7]*r_status);//*(!turn_l_status)+(r_date_l*turn_l_status));
           write_single_l(led_pwm_l[biaozhi+7]*g_status);//*(!turn_l_status)+(g_date_l*turn_l_status));
           write_single_l(led_pwm_l[biaozhi+7]*b_status);//*(!turn_l_status)+(b_date_l*turn_l_status));

           write_single_l(led_pwm_l[biaozhi+6]*r_status);//*(!turn_l_status)+(r_date_l*turn_l_status));
           write_single_l(led_pwm_l[biaozhi+6]*g_status);//*(!turn_l_status)+(g_date_l*turn_l_status));
           write_single_l(led_pwm_l[biaozhi+6]*b_status);//*(!turn_l_status)+(b_date_l*turn_l_status));

           write_single_l(led_pwm_l[biaozhi+5]*r_status);//*(!turn_l_status)+(r_date_l*turn_l_status));
           write_single_l(led_pwm_l[biaozhi+5]*g_status);//*(!turn_l_status)+(g_date_l*turn_l_status));
           write_single_l(led_pwm_l[biaozhi+5]*b_status);//*(!turn_l_status)+(b_date_l*turn_l_status));

           write_single_l(led_pwm_l[biaozhi+4]*r_status);//*(!turn_l_status)+(r_date_l*turn_l_status));
           write_single_l(led_pwm_l[biaozhi+4]*g_status);//*(!turn_l_status)+(g_date_l*turn_l_status));
           write_single_l(led_pwm_l[biaozhi+4]*b_status);//*(!turn_l_status)+(b_date_l*turn_l_status));

           write_single_l(led_pwm_l[biaozhi+3]*r_status);//*(!turn_l_status)+(r_date_l*turn_l_status));
           write_single_l(led_pwm_l[biaozhi+3]*g_status);//*(!turn_l_status)+(g_date_l*turn_l_status));
           write_single_l(led_pwm_l[biaozhi+3]*b_status);//*(!turn_l_status)+(b_date_l*turn_l_status));

           write_single_l(led_pwm_l[biaozhi+2]*r_status);//*(!turn_l_status)+(r_date_l*turn_l_status));
           write_single_l(led_pwm_l[biaozhi+2]*g_status);//*(!turn_l_status)+(g_date_l*turn_l_status));
           write_single_l(led_pwm_l[biaozhi+2]*b_status);//*(!turn_l_status)+(b_date_l*turn_l_status));

           write_single_l(led_pwm_l[biaozhi+1]*r_status);//*(!turn_l_status)+(r_date_l*turn_l_status));
           write_single_l(led_pwm_l[biaozhi+1]*g_status);//*(!turn_l_status)+(g_date_l*turn_l_status));
           write_single_l(led_pwm_l[biaozhi+1]*b_status);//*(!turn_l_status)+(b_date_l*turn_l_status));

           write_single_l(led_pwm_l[biaozhi+0]*r_status);//*(!turn_l_status)+(r_date_l*turn_l_status));
           write_single_l(led_pwm_l[biaozhi+0]*g_status);//*(!turn_l_status)+(g_date_l*turn_l_status));
           write_single_l(led_pwm_l[biaozhi+0]*b_status);//*(!turn_l_status)+(b_date_l*turn_l_status));

         }         


        EnableInterrupt;                  

   //biaozhi ++ ;
   //EnableInterrupt;
}



各中断检测:
__interrupt void EXTI_PORTA_IRQHandler(void)  //这是闪大灯检测
{
  if(brake)
     {
        _DELAY_(0XFF);
        if(brake)
          {
            brake_off =0;
            brake_count = 0;
            brake_status = 1;
          }
      }
  if(brake == 0)
    {
      brake_off =1;
    }

}


__interrupt void EXTI_PORTB_IRQHandler(void)  //右转向检测
{
  if(turn_r)
      {
        _DELAY_(0XFF);
        if(turn_r)
          {
             turn_r_count = 0;
             turn_r_status = 1;
          }
      }
   if(turn_r == 0)
      {
        turn_r_count = 0;
      }
}



__interrupt void EXTI_PORTC_IRQHandler(void) //左转向检测
{

   if(turn_l)
      {
        _DELAY_(0XFF);
        if(turn_l)
          {
             turn_l_count = 0;
             turn_l_status = 1;
          }
      }
    if(turn_l == 0)
      {
        turn_l_count = 0;
      }


}



定时器:
__interrupt void TIM4_UPD_OVF_IRQHandler(void)
{
  TIM4_SR &=~(0x01);  //清除T4 OVP更新OVP标志


  TIM4_CNTR=0;
  tim4_count ++;
   if(send_status == 0)
     {
       send_fq ++;
       if(send_fq == 100)
         {
            send_fq = 0;
            b ++ ;
            if( b >= 8)
              {
                b = 0;
              }
            send_status = 1;
         }
     }

  if(tim4_count == 0Xfff) //颜色变化
    {
      tim4_count = 0;
      color_mode ++;
      if( color_mode >= 8)
        {
          color_mode = 1;
        }
    }

   if(turn_l_status == 1) //左转向1.5秒延时
     {
        if(turn_l)
          {
            turn_l_count = 0;
          }
        turn_l_count ++;
        if(turn_l_count == 500)
          {
            turn_l_count = 0;
            turn_l_status = 0;
          }
     }
  if(turn_r_status == 1) //右转向1.5秒延时
     {
        if(turn_r)
          {
            turn_r_count = 0;
          }
        turn_r_count ++;


        if(turn_r_count == 500)
          {
            turn_r_count = 0;
            turn_r_status = 0;
          }
     }
  if(brake_status == 1)  //闪大灯检测处理
    {

       brake_count ++;
       if(brake_count == 1000)
         {
           brake_status = 0;
         }
    }
  if(brake_off == 1)
    {
       if(brake_count <=200)
         {
           brake_count = 0;
           mode++;
           if(mode==3)
             {
               mode = 1;
             }
         }
       else
         {
           brake_count = 0;
         }
       brake_off = 0;
    }
}



这样的代码写进去,会有卡顿现象出现

QQ图片20161227101518.png (142.36 KB )

QQ图片20161227101518.png

QQ图片20161227101549.png (144.05 KB )

QQ图片20161227101549.png

QQ图片20161227101609.png (91.47 KB )

QQ图片20161227101609.png
沙发
jlhgold| | 2016-12-27 12:10 | 只看该作者
这个我记得网上有不少开源的

使用特权

评论回复
板凳
CARL_SUN|  楼主 | 2016-12-27 13:51 | 只看该作者
jlhgold 发表于 2016-12-27 12:10
这个我记得网上有不少开源的

嗯,网上是有蛮多。都没有用到中断,如果不用中断这个程序运行也很OK。

使用特权

评论回复
地板
CARL_SUN|  楼主 | 2016-12-27 13:52 | 只看该作者
jlhgold 发表于 2016-12-27 12:10
这个我记得网上有不少开源的

主要在运行发码时,需要关闭总中断。记时停掉之后,存在误差。

使用特权

评论回复
5
oufuqiang| | 2016-12-27 16:40 | 只看该作者
0.4us,这个时间也太短了,软件模拟不好弄啊。

使用特权

评论回复
6
CARL_SUN|  楼主 | 2016-12-27 17:10 | 只看该作者
oufuqiang 发表于 2016-12-27 16:40
0.4us,这个时间也太短了,软件模拟不好弄啊。

是啊,可是这个IC在市场上应用很广泛。一个码周期1.25US。一个24位数据也就30US。

使用特权

评论回复
7
wuhuikai| | 2016-12-27 19:25 | 只看该作者
有没有板子多,我有兴趣想写一个

使用特权

评论回复
8
CARL_SUN|  楼主 | 2016-12-27 20:03 | 只看该作者
wuhuikai 发表于 2016-12-27 19:25
有没有板子多,我有兴趣想写一个

板正在打样。我测试用的手工板。板回来给你一个

使用特权

评论回复
9
oufuqiang| | 2016-12-28 11:23 | 只看该作者
CARL_SUN 发表于 2016-12-27 17:10
是啊,可是这个IC在市场上应用很广泛。一个码周期1.25US。一个24位数据也就30US。 ...

应该有对应的编码芯片吧,能买到最好了,软件模拟太浪费CPU性能了,感觉不值啊。
要不自己用门电路搭一个时序产生电路,来硬的。

使用特权

评论回复
10
wuhuikai| | 2016-12-28 14:36 | 只看该作者
CARL_SUN 发表于 2016-12-27 20:03
板正在打样。我测试用的手工板。板回来给你一个

谢谢

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

主题

17

帖子

0

粉丝