|
一、作品介绍
基于迪文EKT043E屏幕的C51内核单片机的开发,配合RGB三色全彩LED模块,实现可调节氛围灯。
二、使用的材料
硬件:开发板,小灯,接线
软件:设计绘制UI,DGUS_TooIV7.643,Keil uVision5。
三、工作原理
RGB LED三色灯是由红、绿、蓝三种颜色的LED组成的,它们可以通过不同的电压来控制颜色的混合,从而实现不同的颜色效果。
在常见的RGB LED三色灯中,每个LED都有三个引脚,分别是R、G、B。通过控制这三个引脚的电压,可以控制LED的颜色。
本次设计使用了PWM调节。
四、操作思维
硬件部分:
P2.0,P2.1,P2.2三个引脚分别连接R G B,另外一个引脚接地。
软件部分:
在程序中设定好了几种固定配色,可以通过色盘直接调节,通过软件控制方式实现闪烁及呼吸灯效。通过RGB值改变电压,从而改变红绿蓝三个灯的亮度,进而起到整体改变颜色的效果。
五、页面设计思维导图及展示
我们的页面设计以学校为主体,充分展现了长医建筑特色。
医学院大门
教学楼
操场
六、代码
#include "sys.h"
#define T0_PERIOD_1MS 0xFF54 //设置10us的定时周期
//定时器0初始化
void timer0_init()
{
//16位定时器工作模式
TMOD &= 0xFC;
TMOD |= 0x01;
//定时周期为10us
TH0 = (u8)(T0_PERIOD_1MS >> 8);
TL0 = (u8)T0_PERIOD_1MS;
ET0 = 1;//使能定时器0中断
EA = 1;//使能总中断
TR0 = 1;//启动定时器0
}
u16 r, g, b, count1, count2, count3,MOD,num,temp;
sbit RED = P2 ^ 0;//红光控制端,0点亮
sbit GREEN = P2 ^ 1;//绿光控制端,0点亮
sbit BLUE = P2 ^ 2;//蓝光控制端,0点亮
//IO口初始化
void io_init()
{
PORTDRV = 0x02; //输出电流为16mA
P2MDOUT |= 0x07; //设置IO口P1.0、P1.1、P1.2为输出
}
//RGB灯的函数每个灯的亮度从0-255
void RGB(u8 R, u8 G, u8 B)
{
if (count1 < R) //设置pwm波的占空比,根据0电平的时长来决定灯的亮度,决定灯的不同颜色
{
RED = 1;
}
else RED = 0;
if (count2 < G)
{
GREEN = 1;
}
else GREEN = 0;
if (count3 < B)
{
BLUE = 1;
}
else BLUE = 0;
}
void fun_read(u16 *r, u16 *g, u16 *b) {
sys_read_vp(0x4100, (u8*)r, 1);//读出变量地址上的值赋给RGB()函数,点亮灯
sys_read_vp(0x4200, (u8*)g, 1);//
sys_read_vp(0x4300, (u8*)b, 1);//
}
void fun_write(u16 r, u16 g, u16 b) {
sys_write_vp(0x4100, (u8*)&r, 1);
sys_write_vp(0x4200, (u8*)&g, 1);
sys_write_vp(0x4300, (u8*)&b, 1);
}
void init() {
sys_init();//系统初始化
io_init();
timer0_init();
r = 0;
g = 0;
b = 0;
count1 = 0; count2 = 0; count3 = 0;
num = 0;
}
void set(u16 a1, u16 a2, u16 a3) {
r = a1;
g = a2;
b = a3;
}
void fun(u16 x) {
switch (x)
{
case 1:set(0x0078, 0x003c, 0x0078); break;
case 2:set(0x000c, 0x001e, 0x001a); break;
case 3:set(0x0066, 0x0066, 0x0066); break;
case 4:set(0x0058, 0x0008, 0x0008); break;
case 5:set(0x00f0, 0x003c, 0x001e); break;
case 6:set(0x003c, 0x001e, 0x00f0); break;
case 7:set(0x001e, 0x003c, 0x00f0); break;
case 8:set(0x005a, 0x0078, 0x003c); break;
case 9:set(0x00b4, 0x0078, 0x003c); break;
case 10:set(0x00b4, 0x0078, 0x001e); break;
case 11:set(0x003c, 0x0096, 0x0028); break;
case 12:set(0x0096, 0x0064, 0x0032); break;
case 13:set(0x0032, 0x0064, 0x00fa); break;
case 14:set(0x0064, 0x0032, 0x00fa); break;
case 15:set(0x00c8, 0x000a, 0x0032); break;
case 16:set(0x000a, 0x00c8, 0x0032); break;
default:set(0x0006, 0x0006, 0x0006);break;
}
}
void main(void)
{
init();
while (1) //主循环
{
sys_read_vp(0x1000, (u8*)&MOD, 1);
sys_read_vp(0x2000, (u8*)&num, 1);
switch (MOD)
{
case 1://正常模式
break;
case 3://呼吸灯
sys_delay_ms(500);
break;
case 5://闪烁
sys_delay_ms(100);
break;
case 7://其他
fun(num);
fun_write(r, g, b);
RGB(r,g,b);
break;
default:
break;
}
fun_read(&r, &g, &b);
RGB(r, g, b);
}
}
//定时器0的中断服务程序
void timer0_isr() interrupt 1
{
//重新装载周期值
TH0 = (u8)(T0_PERIOD_1MS >> 8);
TL0 = (u8)T0_PERIOD_1MS;
count1++;
count2++;
count3++;
if (count1 == 255)count1 = 0;//溢出清零
if (count2 == 255)count2 = 0;
if (count3 == 255)count3 = 0;
//TF0 = 0;硬件会自动清除中断标志位的
}
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
x
|