找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1419|回复: 4
收起左侧

单片机七彩渐变循环程序问题

[复制链接]
ID:237797 发表于 2021-10-17 16:09 | 显示全部楼层 |阅读模式
我用STC15W201S把网上资料用定时器1改成定时器2实现七彩灯渐变。主程序中的while(1),我注解后工作不正常的变化了,变成绿灯闪烁了。我自己的理解没有while(1),就不循环了,渐变一次就会停止,灯灭。怎么不是我想的那样?这种现象如何理解?单片机程序如下:
#include"stc15wxx.h"

#define uchar unsigned char
#define uchar unsigned char//字浮型宏定义
#define uint unsigned int//整型宏定义
#define shudu 30//LED渐变速度调整
#define dengji 1//LED变化等级调整
uchar Rout,Bout,Gout;//红绿兰3个变量

sbit R1=P3^1; //   轮流七彩变色呼吸   3.0 红色
sbit G1=P5^5;//                       3.1 绿色
sbit B1=P3^0; //                      3.2 蓝色

/***************************************************/
/**********************延时子程序*******************/
/***************************************************/
void delay(uint z)
{
uint x,y;//局部变量定义
for(x=0;x<5;x++)//延时外循环
for(y=0;y<z;y++);//延时内循环
}
/**********************************************/
/**********PWM控制红绿兰3种灯亮灭时间**********/
/**********************************************/
void RGBpwm(uchar Rou,uchar Gou,uchar Bou)//3个局部变量,些部分为带参数函数
{
     if(Rou!=0)//如果红灯变量不等于0就亮红灯
     {
      R1=1;//红灯亮
      delay(Rou);//红灯亮起时间
      R1=0;//红灯灭
     }
     if(Gou!=0)//如果红灯变量不等于0就亮绿灯
     {
      G1=1;//绿灯亮
      delay(Gou);//绿灯亮起的时间 
      G1=0;//绿灯灭
     }
     if(Bou!=0)//如果红灯变量不等于0就亮蓝灯
     {
      B1=1;//兰灯亮
      delay(Bou);//兰灯亮起的时间
      B1=0;//兰灯灭
     }
}

/***********************************************/
/********************主程序*********************/
/***********************************************/
void main()
{
//     TMOD=0x01;//选择定时器在方式1下工作
//     EA=1;//打开总中断
//     ET0=1;//打开定时器中断
//     TR0=1;//打开定时器
//     R1=0;//开机将红灯关闭
//     G1=0;//开机将绿灯关闭
//     B1=0;//开机将兰灯关闭
//     TH0=(65536-256)/256;//给定时器高8位赋值
//     TL0=(65536-256)%256;//给定时器低8位赋值

        AUXR &= 0xFB;                //定时器时钟12T模式
        T2L = 0xB4;                //设置定时初始值 FEB4 30us
        T2H = 0xFE;                //设置定时初始值
        AUXR |= 0x10;                //定时器2开始计时
    EA = 1;
    IE2 |= 0X04;
    R1=0;//开机将红灯关闭
    G1=0;//开机将绿灯关闭
    B1=0;//开机将兰灯关闭

while(1)//程序主循环:次句注解后现象变成绿灯闪烁,没有注解渐变正常
{
  RGBpwm(Rout,Gout,Bout);//调用RGBpwm子程序
}
}
/*************************************************/
/*中断服务子程序(控制LED红绿兰亮灭时间占空比例)*/
/*************************************************/
//void zhong() interrupt 1//中断向量位为1
void zhong() interrupt 12//中断向量位为12
{
uint num;//定时器计数变量
uint ji;//亮度等级控制变量
// TH0=(65536-256)/256;//给定时器高8位赋值
// TL0=(65536-256)%256;//给定时器低8位赋值

        T2L = 0xB4;                //设置定时初始值 FEB4 30us
        T2H = 0xFE;                //设置定时初始值

num++;//将定时计数变自动增加1
if(num==shudu)//如果速度变量等于定时计数器变量就执行下面大括号语句
{
  num=0;//将计数器清0
  ji++;//将亮度等级控制变量加1
  if((ji>0)&&(ji<100))//如果亮度等级控制变量ji小于100,红灯亮起时间变量为240
  {
   Rout=240;//红灯亮起变量为240
   Gout=0;//绿灯亮起变量为0
   Bout=0;//兰灯亮起变量为0
  }
  if((ji>100)&&(ji<340))/*如果亮度等级控制变量ji大于100小于340(刚好240个等级),
  红灯亮起时间变量由原来的240,慢慢减小到0,同时绿灯由原来的0慢慢增到240,形成
  红灯到绿灯的渐变过程*/
  {
   Rout-=dengji;//将红灯变量减1。因为dengji为亮度变化等级(本程序变化等级为1),
   Gout+=dengji;//将绿灯变量加1
   Bout=0;//兰灯不变
  }
  if((ji>340)&&(ji<440))/*亮度等级控制变量ji大于340小于440时,让绿灯变量停一段时间
  这样就形成了当红灯过度到绿灯时,绿灯会停一会儿的效果。*/
  {
   Rout=0;//红灯灭
   Gout=240;//绿灯亮
   Bout=0;//兰灯灭
  }
  if((ji>440)&&(ji<680))//同理:亮度等级控制变量ji大于440小于680时,由绿灯到兰灯过度
  {
   Rout=0;//红灯变量不变
   Gout-=dengji;//将绿灯变量减1
   Bout+=dengji;//将兰灯变量加1
  }
  if((ji>680)&&(ji<780))//亮度等级控制变量ji大于680小于780时,让兰灯变量停一段时间
  {
   Rout=0;//红灯灭
   Gout=0;//绿灯灭
   Bout=240;//兰灯亮一会儿
  }
  if((ji>780)&&(ji<1020))//亮度等级控制变量ji大于780小于1020时,由兰灯到白灯过度
  {
   Rout+=dengji;//将红灯变量加1
   Gout+=dengji;//绿灯变量加1
   Bout=240;//兰灯不变
  }
  if((ji>1020)&&(ji<1025))//亮度等级控制变量ji大于1020小于1025时,由兰灯到白灯过度
  {
   Rout=240;//将红灯变量加1
   Gout=240;//绿灯变量加1
   Bout=240;//兰灯不变
  }
  if((ji>1025)&&(ji<1265))//亮度等级控制变量ji大于1025小于1265时,由白光到红光过度
  {
   Rout=240;//红灯变量不变
   Gout-=dengji;//绿灯变量自动减1
   Bout-=dengji;//兰灯变量自动减1
  }
  if(ji>1265)//当亮度等级控制变量ji大于1210时,就将它清0
  ji=0;//将亮度控制等级清0
}
}


回复

使用道具 举报

ID:624769 发表于 2021-10-17 20:39 | 显示全部楼层
一般,主程序不能没有while(1), 不然程序不会停,反而会乱跑,如果你学过汇编会知道,程序结束必须要有一个SJMP $ 让程序停下来。你如果要确保运行一次就停,就在主程序的末尾,加一个 while(1);  让程序停在那里。或者主程序最后用: PCON = 0x02; 来关机。
回复

使用道具 举报

ID:237797 发表于 2021-10-18 08:15 | 显示全部楼层
188610329 发表于 2021-10-17 20:39
一般,主程序不能没有while(1), 不然程序不会停,反而会乱跑,如果你学过汇编会知道,程序结束必须要有一个 ...

我在程序末尾加个while(1);程序下载到单片机里,直接就没有反应了,不亮灯了。
回复

使用道具 举报

ID:161164 发表于 2021-10-18 17:40 | 显示全部楼层
lclbf 发表于 2021-10-18 08:15
我在程序末尾加个while(1);程序下载到单片机里,直接就没有反应了,不亮灯了。

因为渐变是一个从零到255的过程
你只运行一次当然不会亮
如想只渐变一次就停止,
可用188610329总的代码PCON = 0x02;
放到完成一次渐变的地方

提示:ji>XXXX
回复

使用道具 举报

ID:237797 发表于 2021-10-19 09:01 | 显示全部楼层
lkc8210 发表于 2021-10-18 17:40
因为渐变是一个从零到255的过程
你只运行一次当然不会亮
如想只渐变一次就停止,

谢谢你的回复,根据你的提示我改成:
if(ji<1265)
RGBpwm(Rout,Gout,Bout);

能注意看出渐变的效果。
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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