手机控制蓝牙花式点灯制作

蓝牙花式点灯制作

本产品是基于51单片机金沙滩开发板并结合UART串口通信,进行制作。
注:本教材是利用App Inventor进行安卓应用开发,所以要求学者具备一定的App Inventor的使用能力。建议读者到网易云公开课学习App Inventor课程。

1、 资料准备:
HC06蓝牙模块 1个
51 单片机最小系统 1个
手机(安卓系统) 1台
LED灯 若干个

2、 手机安卓程序代码
① 首先登陆网 http://app.gzjkw.net/login/
② 然后用QQ登陆
在这里插入图片描述③ 安卓开发程序
在这里插入图片描述④ 下载程序到手机中
在这里插入图片描述⑤ 然后用手机扫描二维码即可下载并安装应用

3、 程序代码
mian.c程序:

#include <reg52.h>

//74HC138译码器引脚定义
sbit ADDR0 = P1^0;
sbit ADDR1 = P1^1;
sbit ADDR2 = P1^2;
sbit ADDR3 = P1^3;
sbit ENLED = P1^4;

//全局变量定义
//串口接收和发送的字符
unsigned char ch;               
//选择那个灯的形式标志位
unsigned char flagls = 0;   

//函数声明
//串口配置函数
void ConfigUART(unsigned int baud); 
//第一个  左移
extern void leftLED();
//第二个  右移
extern void rightLED(); 
//第三个  来回移动
extern void BothWay();
//第四个  1 3 5 7 灯闪烁
extern void LED1(); 
//第五个  2 4 6 8 灯闪烁
extern void LED2(); 
//第六个  自左向右移动,每次加一个灯
extern void LED3(); 
//第七个,自右向左移动,每次加一个灯
extern void LED4();
//第八个,全部灯闪烁

void main()
{
    //74HC138译码器选择LED灯
    ENLED = 0;                              
    ADDR3 = 1;
    ADDR2 = 1;
    ADDR1 = 1;
    ADDR0 = 0;

    //使能总中断打开
    EA = 1;         
    //设置波特率9600   
    ConfigUART(9600);                       
    
    while(1)
    {
        //第一个  左移
        if(flagls == 1)             
        {   
             leftLED();
        }
        //第二个  右移
        if(flagls == 2)             
        {
            rightLED();
        }
        //第三个  来回移动
        if(flagls == 3)             
        {
            BothWay();
        }
        //第四个  1 3 5 7 灯闪烁
        if(flagls == 4)             
        {
            LED1();
        }
        //第五个  2 4 6 8 灯闪烁
        if(flagls == 5)             
        {
            LED2();
        }
        //第六个  自左向右移动,每次加一个灯
        if(flagls == 6)             
        {
            LED3();
        }
        //第七个,自右向左移动,每次加一个灯
        if(flagls == 7)             
        {
            LED4();

        }   
    }
}


void ConfigUART(unsigned int baud)
{
    //选择串口通讯模式1
    SCON = 0x50;    
    //选择定时器工作模式2  
    TMOD &= 0x0F;
    TMOD |= 0x20;                   
    //计算T1重载值 
    TH1 = 256 - (11059200/12/32)/baud;  
    //初值等于重载值
    TL1 = TH1;  
    //禁止T1中断    
    ET1 = 0;    
    //使能串口中断    
    ES = 1; 
    //启动T1定时器 
    TR1 = 1;                                                        
}

void InterruptUART() interrupt 4
{
    //接收到字节
    if(RI)                                                  
    {
        //手动清零接收中断标志位
        RI = 0;     
        //将接收到数据发送给ch     
        ch = SBUF;                                  
        switch(ch)         
        {
            case'a': flagls=1; break;       
            case'b': flagls=2; break;       
            case'c': flagls=3; break;       
            case'd': flagls=4; break;       
            case'e': flagls=5; break;       
            case'f': flagls=6; break;       
            case'g': flagls=7; break;           
            default: break;     
            
        }
    }
    //字节发送完毕
    if(TI)                                  
    {
        //手动清零发送中断标志位
        TI = 0;                             
    }
}

led.c程序:

#include <reg52.h>

//定义循环变量i,用于软件延时
unsigned int i = 0;   
//定义移位方向变量dir,用于控制移位的方向
unsigned char dir = 0;   
//定义循环移位变量shift,并赋初值0x01
unsigned char shift = 0x01;  
unsigned int cnt = 0;

//LED左移函数
void leftLED()               
{
    P0 = ~(0x01 <<cnt);
    for(i=0; i<23000; i++);
    cnt++; 
    cnt = cnt & 0x07;
}

//LED右移函数
void rightLED()         
{
    P0 = ~(0x80 >>cnt);
    for(i=0; i<23000; i++);
    cnt++; 
    cnt = cnt & 0x07;
}

//来回移动
void BothWay()          
{
    //P0等于循环移位变量取反,控制8个LED
    P0 = ~shift;     
    //软件延时  
    for (i=0; i<23000; i++);  
    //移位方向变量为0时,左移
    if (dir == 0)             
    {
            //循环移位变量左移1位
            shift = shift << 1;  
            //左移到最左端后,改变移位方向        
            if (shift == 0x80)    
            {
                    dir = 1;
            }
    }
    //移位方向变量不为0时,右移
    else                      
    {
            //循环移位变量右移1位
            shift = shift >> 1; 
            //右移到最右端后,改变移位方向        
            if (shift == 0x01)   
            {
                    dir = 0;
            }
    }
}

//第一个  左移
void LED1()
{
    P0 = 0xAA;
    for(i=0; i<23000; i++);
    P0 = 0xFF;
    for(i=0; i<23000; i++);
}

//第二个  右移
void LED2()
{
    P0 = 0x55;
    for(i=0; i<23000; i++);
    P0 = 0xFF;
    for(i=0; i<23000; i++);
}

//第三个  来回移动
void LED3()
{
    P0 = 0xFE;
    for(i=0; i<23000; i++);
    P0 = 0xFC;
    for(i=0; i<23000; i++);
    P0 = 0xF8;
    for(i=0; i<23000; i++);
    P0 = 0xF0;
    for(i=0; i<23000; i++);
    P0 = 0xE0;
    for(i=0; i<23000; i++);
    P0 = 0xC0;
    for(i=0; i<23000; i++);
    P0 = 0x80;
    for(i=0; i<23000; i++);
    P0 = 0x00;
    for(i=0; i<23000; i++);
    P0 = 0x00;
    for(i=0; i<23000; i++);
    P0 = 0xFF;
    for(i=0; i<23000; i++);
}

//第四个  1 3 5 7 灯闪烁
void LED4()
{
    P0 = 0x7F;
    for(i=0; i<23000; i++);
    P0 = 0x3F;
    for(i=0; i<23000; i++);
    P0 = 0x1F;
    for(i=0; i<23000; i++);
    P0 = 0x0F;
    for(i=0; i<23000; i++);
    P0 = 0x07;
    for(i=0; i<23000; i++);
    P0 = 0x03;
    for(i=0; i<23000; i++);
    P0 = 0x01;
    for(i=0; i<23000; i++);
    P0 = 0x00;
    for(i=0; i<23000; i++);
    P0 = 0x00;
    for(i=0; i<23000; i++);
    P0 = 0xFF;
    for(i=0; i<23000; i++);
}

//第五个  2 4 6 8 灯闪烁
void LED5()
{
    P0 = 0xFE;
    for(i=0; i<23000; i++);
    P0 = 0xFC;
    for(i=0; i<23000; i++);
    P0 = 0xF8;
    for(i=0; i<23000; i++);
    P0 = 0xF0;
    for(i=0; i<23000; i++);
    P0 = 0xE0;
    for(i=0; i<23000; i++);
    P0 = 0xC0;
    for(i=0; i<23000; i++);
    P0 = 0x80;
    for(i=0; i<23000; i++);
    P0 = 0x00;
    for(i=0; i<23000; i++);
    P0 = 0x7F;
    for(i=0; i<23000; i++);
    P0 = 0x3F;
    for(i=0; i<23000; i++);
    P0 = 0x1F;
    for(i=0; i<23000; i++);
    P0 = 0x0F;
    for(i=0; i<23000; i++);
    P0 = 0x07;
    for(i=0; i<23000; i++);
    P0 = 0x03;
    for(i=0; i<23000; i++);
    P0 = 0x01;
    for(i=0; i<23000; i++);
    P0 = 0x00;
    for(i=0; i<23000; i++);
    P0 = 0xFF;
    for(i=0; i<23000; i++);
}

//第六个  自左向右移动,每次加一个灯
void LED6()
{
    P0 = 0x00;
    for(i=0; i<23000; i++);
    P0 = 0xFF;
    for(i=0; i<23000; i++);
}

//第七个,自右向左移动,每次加一个灯
void LED7()
{
    P0 = 0xFF;
}

4、 蓝牙模块HC-06与单片机线连接
蓝牙模块HC-06的
TX --> P3^0(51单片机的RX)
RX --> P3^1(51单片机的TX)
VCC --> +5V
GND --> GND

5、连接完成后即可可以使用安卓手机进行控制LED灯的流动。

### 中断实现复杂 LED 控制的教程 在 Proteus 和 Keil 的配合下,可以利用中断机制来实现更复杂的 LED 控制逻辑。以下是详细的讲解: #### 1. 中断的概念及其应用 中断是一种硬件或软件事件触发 CPU 暂停当前执行的任务并转向处理特定服务程序的过程[^3]。通过配置外部中断源(如按钮按下),可以在满足条件时切换 LED 的状态。 #### 2. 配置 Proteus 中的硬件环境 在 Proteus 中设计电路图时,需连接单片机与外设: - 单片机 IO 口接 LED 正极,负极接地。 - 使用开关或其他输入设备作为中断信号源,将其连接到单片机指定的中断引脚上。 具体步骤如下: - 打开 Proteus 软件新建项目文件。 - 添加 AT89C51/STC89C52 类型芯片至工作区。 - 将电阻串联于 P1.x 或其他可用端口与 LED 之间。 - 设置按键的一侧接到 GND,另一侧连入 INT0/P3.2 引脚用于触发下降沿中断[^4]。 #### 3. 编写基于中断的服务程序 下面是一个简单的例子展示如何设置定时器溢出中断改变两个不同颜色 LEDs 的闪烁频率: ```c #include<reg52.h> sbit RedLed=P1^0; //定义红色LED连接P1.0 sbit GreenLed=P1^1; //定义绿色LED连接P1.1 unsigned char flag=0; void Timer_Init(void){ TMOD |= 0x01; //设定模式1为计数方式 TH0=(65536-500)/256;//初始化TH0寄存器值,约每500ms产生一次中断 TL0=(65536-500)%256; EA=1; //开启全局中断使能位 ET0=1; //允许T0中断 } void main(){ Timer_Init(); //调用初始化函数 while(1){ //无限循环等待中断发生 ; } } // 定义 T0 中断服务子程序 void Time_ISR() interrupt 1{ static unsigned int count=0; TR0=0; //关闭定时器 if(++count >=2 ){ count =0; if(flag==0){ RedLed=~RedLed; //翻转红状态 }else { GreenLed=~GreenLed;//翻转绿状态 } flag=!flag; //每次进入都取反标志变量 } TH0=(65536-500)/256; //重新加载初值 TL0=(65536-500)%256; TR0=1; //再次启动定时器 } ``` 此代码片段展示了基本的时间管理技巧以及如何运用这些技术去操控多个独立工作的组件[^5]。 #### 4. 下载调试运行 完成以上两步之后,在Keil编译生成hex文件,并下载到Proteus中的虚拟目标板卡里即可观察实际效果。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值