本帖最后由 lbq691477940 于 2019-6-1 16:06 编辑
单片机蓝牙遥控模块 红外遥控学习转发模块 附源程序
用安卓手机按制所有带红外遥控器的家电、设备 一个APP界面可以学习家里所有以38K红外载波编码的任意红外遥控器,再也不用看场电视要拿好几个红外遥控器了。 如:空调、电视、机顶盒、风扇、台灯..........等等,常用的按键学习在手机APP中,从而达到一机在手控制家里的所有家电的目的。
单片机源程序如下:
- /***************************************************************************************************
- 单片机:
- STC11F02E或兼容芯片
- 晶振:
- 11.0592Mhz
- 波特率:57600
- 红外接收:
- P3.3口即外部中断1(此引脚不可自由更改)
- 定时器0:
- 1.接收红外码时为12T/16位计数模式不使用定时器0中断功能
- 2.发射红外码时为1T/8位自重载模式且用定时器0产生38Khz=13uS中断功能
- 定时器1:
- 为1T/8位自重载模式作为串口波特率发生器(使能波特率加倍)
- 红外发射管:
- 为P1.0口驱动NPN三极管(此引脚可自由更改)
- 红外发射状态指标灯:
- 为P3.4口驱动LED低电平有效(此引脚可自由更改)
- /***************************************************************************************************/
- #include <STC12C5A60S2.H>
- #define uchar unsigned char
- #define uint unsigned int
- /***************************************************************************************************/
- #define IR_BYTE 200 //接收的最大位数为500位
- /***************************************************************************************************/
- sbit IR_IN = P3^3; //一体化红外接收头的输出脚连到此脚作为红外线输入
- sbit LED = P3^4; //状态指标灯
- sbit IR_out = P1^0; //红外发射管控制脚,驱动NPN三极管J3印字即S8050贴片
- /***************************************************************************************************/
- bit UART_RI; //串口接收完成标志位
- bit flag; //发射高电平码还是低电平码标志位
- bit IR_OK; //红外线接收完成标志位
- uchar idata IR_data[IR_BYTE]; //红外接收及串口接收缓冲区
- uint IR_re; //红外接收的数据个数计数器
- uint UART_re; //串口接收的数据个数计数器
- uint count; //中断计数
- /***************************************************************************************************
- 名称:sys_initial
- 功能:系统初始化
- //如果外部中断是仅下降沿触发,要求必须在相应的引脚维持高电平至少1个系统时钟,而且低电平也要持续至少一个系统
- 时钟,才能确保该下降沿被CPU检测到
- //如果外部中断是低电平可触发,则要求必须在相应的引脚维持低电平至少2个系统时钟,这样才能确保CPU能够检测到该低电平信号
- /***************************************************************************************************/
- void sys_initial()
- {
- PCON |= 0x80; //使能波特率倍速位SMOD
- SCON = 0x50; //8位数据,可变波特率
- AUXR |= 0x40; //定时器1时钟为Fosc,即1T
- AUXR &= 0xFE; //串口1选择定时器1为波特率发生器
- TMOD &= 0x0F; //清除定时器1模式位
- TMOD |= 0x21; //设定定时器1为8位自动重装方式/设定定时器0为16位方式
- TH1 = TL1 = 0xF4; //设定定时初值 11.0592Mhz / 57600
- ET1 = 0; //禁止定时器1中断
- TR1 = 1; //启动定时器1
-
- ES = REN = 1; //允许串口接收中断
- IT1 = 1; //设置INT1的中断类型 (1:低电平触发 0:下降沿触发)
- EX1 = 1; //使能INT1中断
- EA = 1; //使能总中断
- IR_OK = 0;
- }
- /***************************************************************************************************
- 名称:com
- 功能:串口发送字符数据;
- 形参:TS=数据指针;n=字符长度
- /***************************************************************************************************/
- void UART1_SEND(uchar *TS,uchar n)
- {
- uchar m;
- for(m = 0;m < n;m++)
- {
- SBUF = *(TS + m);
- while(!TI);
- TI = 0;
- }
- }
- /***************************************************************************************************/
- void main()
- {
- uint i;
- sys_initial();
- LED = 0;
- while(1)
- {
- if(UART_RI) //接收成功
- {
- ES = 0; //禁止串口中断
- UART_RI = 0; //清除串口接收完成标志位
- /***************************************************************************************************************/
- if((IR_data[0] == 0xFE) && (IR_data[1] == 0xFD) && (UART_re > 10))
- {//判断接收到的前二个指令码是否为 0xFE和0xFD且大于10个数据
- EX1 = 0; //进行红外发码前先关闭外部中断0
- PT0 = ET0 = 1; //设定时器0中断优先及允许定时器0中断
- if(UART_re % 2) //如果收到的是单个字节则自行加一个缓冲区数据
- {
- UART_re += 1;
- IR_data[UART_re] = 2;//随便给个值即可
- }
- /***************************************************************************************/
- for(i = 2;i < UART_re;i++)
- {
- flag = ~(bit)(i % 2); //红外发送标志=1
- TF0 = count = 0; //中断计数=0
- TR0 = 1; //启动定时器0
- // if(IR_data[ i] <= 5)
- // {
- // IR_data[ i] = 5;
- // }
- while(count < (IR_data[ i] * 90 / 13));
- TR0 = 0; //关闭定时器0
- }
- /***************************************************************************************
- for(i = 2;i < UART_re;)
- {
- //编码中的低电平
- flag = 1; //红外发送标志=1
- TF0 = count = 0; //中断计数=0
- TR0 = 1; //启动定时器0
- while(count < (IR_data[ i] * 90 / 13));
- TR0 = 0;
- i++;//关闭定时器0
- //编码中的高电平
- flag = 0; //红外发送标志
- TF0 = count = 0; //中断计数=0
- TR0 = 1; //启动定时器0
- while(count < (IR_data[ i] * 90 / 13));
- TR0 = 0; //关闭定时器0
- }
- /***************************************************************************************/
- SBUF = 0xFC; //发射完成返回一个0xFC给PC机表示发射完毕
- while(!TI);
- TI = 0;
- /***************************************************************************************/
- EX1 = 1; //红外发码发完后才再次允许外部中断0
- }
- for(UART_re = IR_BYTE;UART_re > 0;UART_re--)
- IR_data[UART_re] = 0; //清除串口接收区,且将UART_re清0
- LED = IR_out = 0; //红外管 = 0不发光
- ES = 1; //重新允许串口中断
- /***************************************************************************************************************/
- }
- }
- }
- /***************************************************************************************************************/
- void timer0(void) interrupt 1
- {
- count += 1;
- if(flag == 1) //如果红外发送标志=1
- {
- //这里可以改为=1不取反另用ne555产生38K信号与IR_out口的信号相与后接IR
- LED = ~LED; //红外发射指示状态=取反
- }
- else
- {
- IR_out = 0; //红外管=0不发光
- }
- }
- /***************************************************************************************************************/
复制代码
|