标题:
单片机TM1650驱动+红外遥控解码源程序
[打印本页]
作者:
liuhailan5757
时间:
2021-3-6 13:20
标题:
单片机TM1650驱动+红外遥控解码源程序
N年前在网上买了一个TM1650的测试版,今天突然看到了,倒腾了一下。写了个程序。希望对大家有用,不喜勿喷。
TM1650测试板.jpg
(148.66 KB, 下载次数: 95)
下载附件
TM1650显示驱动加红外解码
2021-3-6 13:11 上传
单片机源程序如下:
/*程序功能:TM1650驱动程序加红外遥控解码程序 。遥控解码后显示在数码管上
IO 分配:查看位定义
时钟频率:11.0592MHz
版 本:VER0
作 者:刘海兰
日 期:2021.03.06
备 注:如果要在程序中使用此代码,请在程序中注明使用了51黑单片机liuhailan5757博主的程序
但是由此造成的后果与本博主无关,
*/
#include<stc15.h>
sbit scl = P3^3; //TM1650时钟通讯IO
sbit sda = P3^2;//TM1650数据通讯IO
sbit ir = P3^4;//红外输入口
sbit led = P3^5;//测试用指示灯,在调试红外遥控时可用
unsigned char ir_time = 0; //红外信号的时间,这个寄存器是为了在解码0/1(数据)的时候,用来计低电平的时间
bit ir_d = 0;//红外信号的高低标志位,
bit ir_ok = 0;//解码OK
unsigned char shuwei = 0;//解码的长度
unsigned char shuwei1 = 0;//解码的长度
unsigned char buzhou = 0;//解码的步骤
unsigned char ir_dat = 0;//红外的8位数据
unsigned char num[]={0,0,0,0};//红外的4组8位的数据,就是用户码,用户码反码,数据码,数据码反码
code unsigned char shuma[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}; //子模0-9,A,B,C,D,E,F
unsigned char reg1 = 0; //通用寄存器1
unsigned char reg2 = 0; //通用寄存器2 这两个寄存器在转换成可显示的数据要用到
void delay(unsigned int time)
{
while(time--);
}
void tm1650_start(); //TM1650通讯的开始信号
void tm1650_end();//TM1650通讯的结束信号
void tm1650_ack();//TM1650通讯的应答信号
void write_1();//TM1650数据通讯 写1
void write_0();//TM1650数据通讯 写0
void write_byte(unsigned char tem);//写一个字节
void TM0_Isr() interrupt 1 //红外解码,定时器的时基是50us中断一次
{
INT_CLKO &= 0xef; //关闭外部中断
if(buzhou==0) //步骤0,判断9ms的低电平
{
if(!ir)
{
ir_time++;
if(ir_time>185) //低电平超时,每一次因为错误退出解码时,一点要清掉用到的那些寄存器!!!!!!这里一点要注意,下面的退出里面也是要清掉
{
ir_d = 0;
ir_time = 0;
buzhou = 0;
TR0 = 0;
INT_CLKO |= 0x10;
}
}
else
{
if((ir_time>175)&&(ir_time<185)) //低电平OK,是正确的9ms ,就跳到步骤1 (9mS除以50uS=180,所以这里的值就设为175和185之间,因为要考虑到一点的误差)
{
ir_time = 0;
//led ^= 1;
buzhou = 1;
}
else //不是正确的9ms
{
buzhou = 0;
TR0 = 0;
INT_CLKO |= 0x10;
}
}
}
if(buzhou==1) //步骤1,判断4.5ms的高电平
{
if(ir)
{
ir_time++;
if(ir_time>95) //高电平超时
{
ir_d = 0;
ir_time = 0;
buzhou = 0;
TR0 = 0;
INT_CLKO |= 0x10;
}
}
else
{
if((ir_time>85)&&(ir_time<95)) //4.5ms高电平OK,就跳到步骤2 这里还可以添加判断连码的程序,如果这里的时间是2mS 那就是连码
{
ir_time = 0;
// led ^= 1;
buzhou = 2;
ir_d = 0;
}
else //不OK
{
buzhou = 0;
TR0 = 0;
INT_CLKO |= 0x10;
}
}
}
if(buzhou==2) //步骤2开始解码数据
{
if(!ir_d) //如果低电平标志为0时,这里是用来判断低电平的时间
{
if(!ir) //如果红外端口为低
{
ir_time++; //计低电平的时间
if(ir_time>13) //低电平时间超时,就退出解码
{
ir_d = 0;
ir_time = 0;
buzhou = 0;
TR0 = 0;
INT_CLKO |= 0x10;
shuwei = 0;
shuwei1 = 0;
}
}
else //如果转为高电平了,
{
ir_d = 1; //低电平标志位置一,要去判断高电平的时间了
ir_time = 0;//时间清零
}
}
else //如果低电平标志位为1,就是进入判断IR高电平的时间了,这个高电平的时间就是判断数据是0还是1
{
if(ir) //如果IR为高
{
ir_time++;//计高电平的是按
if(ir_time>34) //超时了就退出解码
{
ir_d = 0;
ir_time = 0;
buzhou = 0;
TR0 = 0;
INT_CLKO |= 0x10;
shuwei = 0;
shuwei1 = 0;
}
}
else //如果IR为低了,就可以判断高电频的时间了
{
if(ir_time>16) //时间大于16*50us 就是数据1
ir_dat |= 0x80;
else //否则就是数据0
ir_dat &= 0x7f;
shuwei++;
if(shuwei==8) //8bit 组成1byte
{
num[shuwei1]=ir_dat;
shuwei = 0;
shuwei1++; //总共4byte
if(shuwei1==4) //4组数据接收完了就接收解码
{
// if(num[2]==0x45)
// led = 0;
// else
// led = 1;
ir_ok = 1; //解码成功标志位置一
buzhou = 0;
TR0 = 0;
INT_CLKO |= 0x10;
shuwei1 = 0;
}
}
ir_dat>>=1;
ir_time = 0;
ir_d = 0;
}
}
}
}
void INT2_Isr() interrupt 10 //IR为低 就进入此中断,开启解码,解码中这个中断是关闭的,只有退出了解码,才会进入这个中断
{
if(!ir)
{
buzhou = 0;
ir_d = 0;
shuwei = 0;
shuwei1 = 0;
ir_time = 0;
TR0 = 1;
}
}
void main()
{
P3M0 = 0x00;
P3M1 = 0x00;
P3 = 0xff;
AUXR |= 0x80; //定时器时钟1T模式
TMOD = 0x00; //模式0
TL0 = 0xD7; //设置定时初值
TH0 = 0xFD; //定时器0设为50us中断一次
TR0 = 0; //启动定时器
ET0 = 1; //使能定时器中断
INT_CLKO |= 0x10; //(EX2 = 1)使能INT2中断
EA = 1;
while(1)
{
tm1650_start();
write_byte(0x48); //数码显示模式
tm1650_ack();
write_byte(0x11); //1级亮度,开显示。这里的指令数据 详情参阅TM1650的datasheet
tm1650_ack();
tm1650_end();
tm1650_start();
write_byte(0x68);
tm1650_ack();
write_byte(shuma[reg1]);
tm1650_ack();
tm1650_end();
tm1650_start();
write_byte(0x6a);
tm1650_ack();
write_byte(shuma[reg2]);
tm1650_ack();
tm1650_end();
tm1650_start();
write_byte(0x6c);
tm1650_ack();
write_byte(0x5b);//固定显示2
tm1650_ack();
tm1650_end();
tm1650_start();
write_byte(0x6e);
tm1650_ack();
write_byte(0x3f); //固定显示0,这里固定显示02,是因为我们解码的数据是第2组数据,也就是数据码(第0组数据是用户码,1是用户码反码,2是数据码,3是数据码反码)
tm1650_ack();
tm1650_end();
if(ir_ok)
{
ir_ok = 0; //清掉解码标志位
reg1 = (num[2]&0x0f); // 数据低4位送显示 把数据转为0-F
reg2 = (num[2]&0xf0);//数据的高四位送显示
reg2>>=4;
}
}
}
void tm1650_start()
{
sda = 1;
scl = 1;
delay(10);
sda = 0;
delay(5);
}
void tm1650_end()
{
sda = 0;
scl = 1;
delay(6);
sda = 1;
delay(2);
}
void tm1650_ack()
{
while(sda);
delay(5);
scl = 1;
delay(5);
scl = 0;
delay(5);
}
void write_1()
{
sda = 1;
scl = 0;
delay(5);
scl = 1;
delay(10);
scl = 0;
delay(5);
sda = 0;
}
void write_0()
{
sda = 0;
scl = 0;
delay(5);
scl = 1;
delay(10);
scl = 0;
}
void write_byte(unsigned char tem)
{
unsigned char i;
for(i=8;i>0;i--)
{
if(tem&0x80)
write_1();
else
write_0();
tem<<=1;
}
}
复制代码
以上程序下载:
TM1650+红外解码.zip
(150.58 KB, 下载次数: 93)
2021-3-6 13:19 上传
点击文件名下载附件
TM1650+红外解码
下载积分: 黑币 -5
作者:
ssk7793
时间:
2021-7-15 16:42
单片机用的是什么型号的
作者:
liuhailan5757
时间:
2021-8-14 15:02
STC15W104,,STC的单片机都可以,IO口对应好就行,看宏定义。
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1