/*------------------------------------------------------------------------------------
* 项目名称:
带单片机8位全彩流水灯模板程序V1.0
* 功能描述:
1、两个按键采用中断形式,一个控制显示模式,一个控制显示颜色
* 版权信息:
(c) 飞翼电子, 2016.
* 历史版本:
2016-01-27:
- 初始版本 V1.0.0;
* 配置说明:
- MCU :STC15W204S
- CPU频率:30MHz
-------------------------------------------------------------------------------------*/
/**************************************子函数声明*************************************/
//子程序名称:IO_Init(void) 功能:端口初始化,使能中断
void System_Init(void);
/**************************************包含头文件*************************************/
#include "STC15W.h"
#include "ws2812.h" //包含LED驱动程序
#include "delay.h" //包含延时程序
/***************************************硬件接口**************************************/
sbit BTN1 = P3^2; //按钮1连接P3.2
sbit BTN2 = P3^3; //按钮2连接P3.3
/***************************************全局变量**************************************/
unsigned char mode=0; //控制显示模式
unsigned char color=0; //控制显示颜色
//9种颜色数据
code unsigned char colorArr[9][3]={{126,249,7},{242,212,241},{122,14,197},{42,238,27}
,{234,251,38},{35,218,3},{64,24,114},{250,18,20},{18,231,250}};
//定义一个二维,每个括号内的三个数据对应一个像素点
//16像素点的数组,每个像素点的颜色由3个字节绝对{绿,红,蓝}
unsigned char s[16][3]={{50,5,5},{50,5,5},{50,5,5},{50,5,5},{50,5,5},{50,5,5},
{50,5,5},{50,5,5},{50,5,5},{50,5,5},{50,5,5},{50,5,5},{50,5,5},{50,5,5},
{50,5,5},{50,5,5}};
//8像素点的数组,每个像素点的颜色由3个字节绝对{绿,红,蓝}
//unsigned char s[16][3]={{50,5,5},{50,5,5},{50,5,5},{50,5,5},{50,5,5},{50,5,5},
//{50,5,5},{50,5,5}};
//定义一个拖尾数组
unsigned char tail[5][3]={{50,5,5},{50,5,5},{50,5,5},{50,5,5},{50,5,5}};
//定义两个消减比
code unsigned char cut[5]={3,2,0,2,3};
code unsigned char cut2[5]={1,2,3,2,1};
/***************************************主程序****************************************/
void main()
{
unsigned char i,j,k;
unsigned char side=0;
DelayMs(100); //上电延时
System_Init(); //系统初始化
EA = 1; //使能中断
//上电让所有LED灭掉
for(i=0;i<16;i++)
{
s[i][0]=0; //修改数组中的数据
s[i][1]=0;
s[i][2]=0;
}
SendOneFrame(s); //显示数组中的数据
Delay100Ms(1);
//主循环
while(1)
{
//模式0,16位LED单侧反复循环
switch (mode)
{
//模式0:固定显示单一颜色
case 0:
{
//循环修改数组数据,然后显示
for(i=0;i<SNUM;i++)
{
s[i][0]=colorArr[color][0];
s[i][1]=colorArr[color][1];
s[i][2]=colorArr[color][2];
}
//发送显示数据
SendOneFrame(s);
Delay100Ms(1);
//每显示一次,检查是否模式mode已改变,如果改变了则退出
if(mode!=0)
{
break;
}
//本模式执行完,跳出
break;
}
//模式1:单色从左到右循环显示
case 1:
{
//进入循环显示前让所有LED灭掉
for(i=0;i<SNUM;i++)
{
s[i][0]=0;
s[i][1]=0;
s[i][2]=0;
}
SendOneFrame(s);
Delay100Ms(1);
//循环修改数组数据,然后显示
for(i=0;i<SNUM;i++)
{
s[i][0]=colorArr[color][0];
s[i][1]=colorArr[color][1];
s[i][2]=colorArr[color][2];
SendOneFrame(s);
Delay100Ms(1);
//每显示一次,检查是否模式mode已改变,如果改变了则退出
if(mode!=1)
{
break;
}
}
//本模式执行完,跳出
break;
}
//模式2:9色静态切换
case 2:
{
for(j=0;j<9;j++)
{
for(i=0;i<SNUM;i++)
{
s[i][0]=colorArr[j][0];
s[i][1]=colorArr[j][1];
s[i][2]=colorArr[j][2];
}
SendOneFrame(s);
Delay100Ms(5);
//每显示一次,检查是否模式mode已改变,如果改变了则退出
if(mode!=2)
{
break;
}
}
//本模式执行完,跳出
break;
}
//模式3:9色流水显示
case 3:
{
//进入循环显示前让所有LED灭掉
for(i=0;i<SNUM;i++)
{
s[i][0]=0;
s[i][1]=0;
s[i][2]=0;
}
SendOneFrame(s);
Delay100Ms(1);
//9中颜色循环显示
for(j=0;j<9;j++)
{
//先让所有LED灭
for(i=0;i<SNUM;i++)
{
s[i][0]=0;
s[i][1]=0;
s[i][2]=0;
}
SendOneFrame(s);
Delay100Ms(1);
//循环修改数组数据,然后显示
for(i=0;i<SNUM;i++)
{
s[i][0]=colorArr[j][0];
s[i][1]=colorArr[j][1];
s[i][2]=colorArr[j][2];
SendOneFrame(s);
Delay100Ms(1);
//每显示一次,检查是否模式mode已改变,如果改变了则退出
if(mode!=3)
{
break;
}
}
//每显示一次,检查是否模式mode已改变,如果改变了则退出
if(mode!=3)
{
break;
}
}
//本模式执行完,跳出
break;
}
//模式4:底色加弱拖尾
case 4:
{
//计算拖尾
for(j=0;j<5;j++)
{
tail[j][0]=colorArr[8-color][0]>>cut[j];
tail[j][1]=colorArr[8-color][1]>>cut[j];
tail[j][2]=colorArr[8-color][2]>>cut[j];
}
for(j=0;j<SNUM+5;j++)
{
//上底色
for(i=0;i<SNUM;i++)
{
s[i][0]=colorArr[color][0];
s[i][1]=colorArr[color][1];
s[i][2]=colorArr[color][2];
}
//修改数值
for(i=j,k=0;i>0&&k<5;i--,k++)
{
if(i<=SNUM)
{
s[i-1][0]=(colorArr[color][0]>>cut2[k])+tail[k][0];
s[i-1][1]=(colorArr[color][1]>>cut2[k])+tail[k][1];
s[i-1][2]=(colorArr[color][2]>>cut2[k])+tail[k][2];
}
}
SendOneFrame(s);
DelayMs(50);
//每显示一次,检查是否模式mode已改变,如果改变了则退出
if(mode!=4)
{
break;
}
}
break;
}
//模式5:底色加流水
case 5:
{
//计算拖尾
for(j=0;j<5;j++)
{
tail[j][0]=colorArr[8-color][0]>>cut[j];
tail[j][1]=colorArr[8-color][1]>>cut[j];
tail[j][2]=colorArr[8-color][2]>>cut[j];
}
for(j=0;j<SNUM+5;j++)
{
//上底色
for(i=0;i<SNUM;i++)
{
s[i][0]=colorArr[color][0];
s[i][1]=colorArr[color][1];
s[i][2]=colorArr[color][2];
}
//修改数值
for(i=j,k=0;i>0&&k<5;i--,k++)
{
if(i<=SNUM)
{
s[i-1][0]=tail[k][0];
s[i-1][1]=tail[k][1];
s[i-1][2]=tail[k][2];
}
}
SendOneFrame(s);
DelayMs(50);
//每显示一次,检查是否模式mode已改变,如果改变了则退出
if(mode!=5)
{
break;
}
}
break;
}
//默认模式:让所有LED灭
default:
{
//上电让所有LED灭掉
for(i=0;i<SNUM;i++)
{
s[i][0]=0; //修改数组中的数据
s[i][1]=0;
s[i][2]=0;
}
SendOneFrame(s); //显示数组中的数据
Delay100Ms(1);
break;
}
}
}
}
//-------------------------------------------------------------------------------
//子程序名称:System_Init(void)
//功能:端口初始化,使能中断
//-------------------------------------------------------------------------------
void System_Init(void)
{
BTN1=1;
BTN2=1;
//使能INT0中断
INT0 = 1;
IT0 = 1; //设置INT0的中断类型 (1:仅下降沿 0:上升沿和下降沿)
EX0 = 1; //使能INT0中断
//使能INT1中断
INT1 = 1;
IT1 = 1; //设置INT1的中断类型 (1:仅下降沿 0:上升沿和下降沿)
EX1 = 1; //使能INT1中断
}
/**************************************中断服务程序*********************************/
//按键1中断入口:模式切换
void Btn1Int() interrupt 0
{
//进来先关中断
EA = 0;
INT_CLKO &= 0xEF;
INT_CLKO &= 0xDF;
//延时一段时间
DelayMs(40);
mode++;
if(mode==6)
{
mode=0;
}
//走时开中断
EA = 1;
INT_CLKO |= 0x10;
INT_C