標題:
單片機TM1650驅(qū)動+紅外遙控解碼源程序
[打印本頁]
作者:
liuhailan5757
時間:
2021-3-6 13:20
標題:
單片機TM1650驅(qū)動+紅外遙控解碼源程序
N年前在網(wǎng)上買了一個TM1650的測試版,今天突然看到了,倒騰了一下。寫了個程序。希望對大家有用,不喜勿噴。
TM1650測試板.jpg
(148.66 KB, 下載次數(shù): 95)
下載附件
TM1650顯示驅(qū)動加紅外解碼
2021-3-6 13:11 上傳
單片機源程序如下:
/*程序功能:TM1650驅(qū)動程序加紅外遙控解碼程序 。遙控解碼后顯示在數(shù)碼管上
IO 分配:查看位定義
時鐘頻率:11.0592MHz
版 本:VER0
作 者:劉海蘭
日 期:2021.03.06
備 注:如果要在程序中使用此代碼,請在程序中注明使用了51黑單片機liuhailan5757博主的程序
但是由此造成的后果與本博主無關(guān),
*/
#include<stc15.h>
sbit scl = P3^3; //TM1650時鐘通訊IO
sbit sda = P3^2;//TM1650數(shù)據(jù)通訊IO
sbit ir = P3^4;//紅外輸入口
sbit led = P3^5;//測試用指示燈,在調(diào)試紅外遙控時可用
unsigned char ir_time = 0; //紅外信號的時間,這個寄存器是為了在解碼0/1(數(shù)據(jù))的時候,用來計低電平的時間
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位數(shù)據(jù)
unsigned char num[]={0,0,0,0};//紅外的4組8位的數(shù)據(jù),就是用戶碼,用戶碼反碼,數(shù)據(jù)碼,數(shù)據(jù)碼反碼
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 這兩個寄存器在轉(zhuǎn)換成可顯示的數(shù)據(jù)要用到
void delay(unsigned int time)
{
while(time--);
}
void tm1650_start(); //TM1650通訊的開始信號
void tm1650_end();//TM1650通訊的結(jié)束信號
void tm1650_ack();//TM1650通訊的應(yīng)答信號
void write_1();//TM1650數(shù)據(jù)通訊 寫1
void write_0();//TM1650數(shù)據(jù)通訊 寫0
void write_byte(unsigned char tem);//寫一個字節(jié)
void TM0_Isr() interrupt 1 //紅外解碼,定時器的時基是50us中斷一次
{
INT_CLKO &= 0xef; //關(guān)閉外部中斷
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,所以這里的值就設(shè)為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開始解碼數(shù)據(jù)
{
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 //如果轉(zhuǎn)為高電平了,
{
ir_d = 1; //低電平標志位置一,要去判斷高電平的時間了
ir_time = 0;//時間清零
}
}
else //如果低電平標志位為1,就是進入判斷IR高電平的時間了,這個高電平的時間就是判斷數(shù)據(jù)是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 就是數(shù)據(jù)1
ir_dat |= 0x80;
else //否則就是數(shù)據(jù)0
ir_dat &= 0x7f;
shuwei++;
if(shuwei==8) //8bit 組成1byte
{
num[shuwei1]=ir_dat;
shuwei = 0;
shuwei1++; //總共4byte
if(shuwei1==4) //4組數(shù)據(jù)接收完了就接收解碼
{
// 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為低 就進入此中斷,開啟解碼,解碼中這個中斷是關(guān)閉的,只有退出了解碼,才會進入這個中斷
{
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; //設(shè)置定時初值
TH0 = 0xFD; //定時器0設(shè)為50us中斷一次
TR0 = 0; //啟動定時器
ET0 = 1; //使能定時器中斷
INT_CLKO |= 0x10; //(EX2 = 1)使能INT2中斷
EA = 1;
while(1)
{
tm1650_start();
write_byte(0x48); //數(shù)碼顯示模式
tm1650_ack();
write_byte(0x11); //1級亮度,開顯示。這里的指令數(shù)據(jù) 詳情參閱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,是因為我們解碼的數(shù)據(jù)是第2組數(shù)據(jù),也就是數(shù)據(jù)碼(第0組數(shù)據(jù)是用戶碼,1是用戶碼反碼,2是數(shù)據(jù)碼,3是數(shù)據(jù)碼反碼)
tm1650_ack();
tm1650_end();
if(ir_ok)
{
ir_ok = 0; //清掉解碼標志位
reg1 = (num[2]&0x0f); // 數(shù)據(jù)低4位送顯示 把數(shù)據(jù)轉(zhuǎn)為0-F
reg2 = (num[2]&0xf0);//數(shù)據(jù)的高四位送顯示
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;
}
}
復(fù)制代碼
以上程序下載:
TM1650+紅外解碼.zip
(150.58 KB, 下載次數(shù): 93)
2021-3-6 13:19 上傳
點擊文件名下載附件
TM1650+紅外解碼
下載積分: 黑幣 -5
作者:
ssk7793
時間:
2021-7-15 16:42
單片機用的是什么型號的
作者:
liuhailan5757
時間:
2021-8-14 15:02
STC15W104,,STC的單片機都可以,IO口對應(yīng)好就行,看宏定義。
歡迎光臨 (http://www.torrancerestoration.com/bbs/)
Powered by Discuz! X3.1