圣源电子制作

 找回密码
 立即注册
查看: 11146|回复: 1

tc9012 芯片的遥控-C51 C语言程序

[复制链接]
发表于 2011-10-10 15:36:11 | 显示全部楼层 |阅读模式
使用tc9012芯片的遥控


TC9012是一块用于东芝系列红外遥控系统中的专用发射集成电路,采用 CMOS工艺制造。它可外接 32个按键,提供 8种用户编码,另外还具有 3种双重按键功能。TC9012的管脚设置和外围应用线路都进行了高度优化,以配合 PCB的布图和低成本的要求。

主要特点
z 低压 CMOS工艺制造
z 低功耗超小静态电流
z 低工作电压(VDD=2.0~5.0V
z 32+3条指令码
z 8种用户编码可选择
z TSOP-20SOP20COB可选的封装形式
应用范围

z 电视机、组合音响设备、录音卡座、VCD、DVD播放机
TC9012红外_img_0.jpg

管脚说明
TC9012红外_img_1.jpg
管脚号
名称
类型
描述
1~4
KI0-KI4
IN
4位输入脚用于键盘扫描输入(平时为低电平,内置下拉电阻)
5
REM
OUT
带载波的遥控信号输出
6
VDD
电源正端(2.0V~4.0V3V(典型)
7
NC
空脚
8
OSCO
OUT
晶振输出
9
OSCI
IN
晶振输入
10
VSS
电源负端(接地)
19~12
KO0-KO7
OUT
8位输出脚用于键盘扫描输出
11
LMP
OUT
指示灯输出
20
SEL
IN
用于用户编码选择跳线(平时为高电平,内置下拉电阻)

参数说明
极限参数(除非特别说明,Tamb=25℃)
参数
符号
最小值
最大值
单位
电源电压
VDD
1.8
4.0
V
输入电压
VIN
-0.5
VDD +0.5
V
输出电压
VO
-0.5
VDD +0.5
V
输出电流
IO
20
mA
功耗
PD
250
mw
贮存温度
Tstg  
-40~+125
工作温度
Topr  
-20~+75
推荐工作条件(除非特别说明,Tamb=25℃)
参数
符号
最小值
典型值
最大值
单位
电源电压
VDD
2.0
3.0
3.6
V
振荡频率
Fosc
400
455
500
KHz
输入电压
VIN
0
--
VDD
V
电气参数(除非特别说明,Tamb=25℃,VDD=3.0V
参数
符号
测试条件
最小值
典型值
最大值
单位
电源电压
VDD
2.0
3.0
3.6
V
工作电流
ICC1
按键按下,VDD=3.0VFosc=455KHz,不接红外管、led
1.0
mA
静态电流
ICC2
VDD=3.0V,没有按键按下,晶振停振,红外管,led管均不工作
1
uA
KI高电平输入电压
VIH
VDD =3.0V
0.7 VDD
VDD
V
KI低电平输入电压
VIL
VDD =3.0V
0
03 VDD
V
REM高电平输出电流
IOH
VOH=1.5V,VDD=3V
5
5
mA
LMP低电平输出电流
IOL
VOL=1.5V,VDD=3V
1
mA
输入下拉电阻
RON
VDD=3.0V
30
50
100
KΩ

三.遥控器输出波形
TC9012红外_img_5.jpg

以下为遥控器布图的注意事项: 1、将电源滤波电容尽可能靠近IC;电源滤波电容只需要使用104的瓷片电容即可;2、尽可能避免电源和地线走线过长或过细; 3、尽可能把晶振电路放置在离芯片较近的位置; 4、建议在三极管的发射极使用2欧姆的限流电阻;

5、建议晶振旁边的两个谐振电容使用 150pf以上,这样可以防止高频谐波。
6、上图中 SEL脚和 KO7相连,所以客户码选择为:0E0E;
图 6 TC9012参考应用电路图

TC9012红外_img_13.jpg

封装外形图
TC9012红外_img_17.jpg

提供 三个  51C程序
  1. #include <AT89X51.H>

  2. #define c(x) (x*110592/120000)

  3. sbit Ir_Pin=P3^5;

  4. unsigned char code Led_Tab[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,

  5. 0xf8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E}; //共阳极数码显示码0-F.

  6. unsigned char code Led_Sel[]={0xfe,0xfd,0xfb,0xf7};        //显示位控

  7. unsigned char Led_Buf[4]; //显示缓冲区

  8. char Led_Index; //位选

  9. unsigned char Ir_Buf[4]; //用于保存解码结果

  10. //==============================================================

  11. //数码管扫描

  12. timer0() interrupt 1 using 1

  13. {

  14. TL0=(65536-1000)%256;

  15. TH0=(65536-1000)/256; //定时器0设定约1000us中断一次,用于数码管扫描

  16. P0=0xff;

  17. P2=Led_Sel[Led_Index]; //位选

  18. P0=Led_Tab[Led_Buf[Led_Index]]; //段选

  19. if(++Led_Index>3) Led_Index=0; //四个扫描完了,到第一个数码管

  20. }

  21. //==============================================================

  22. unsigned int Ir_Get_Low()

  23. {

  24. TL1=0;

  25. TH1=0;

  26. TR1=1;

  27. while(!Ir_Pin && (TH1&0x80)==0); //当P3.5为低 且 TH1<0x80时 等待

  28. TR1=0;

  29. return TH1*256+TL1;

  30. }

  31. //=============================================================

  32. unsigned int Ir_Get_High()

  33. {

  34. TL1=0;

  35. TH1=0;

  36. TR1=1;

  37. while(Ir_Pin && (TH1&0x80)==0);

  38. TR1=0;

  39. return TH1*256+TL1;

  40. }

  41. //==============================================================

  42. main()

  43. {

  44. unsigned int temp;

  45. char i,j;

  46. Led_Index=1;

  47. TMOD=0x11;

  48. TL0=(65536-1000)%256;

  49. TH0=(65536-1000)/256; //定时器0设定约1000us中断一次,用于数码管扫描

  50. EA=1;

  51. ET0=1;

  52. TR0=1;

  53. Led_Buf[0]=0;

  54. Led_Buf[1]=0;

  55. Led_Buf[2]=0;

  56. Led_Buf[3]=0; //显示区设成0

  57. do{

  58. restart:

  59. while(Ir_Pin);

  60. temp=Ir_Get_Low();

  61. if(temp<c(4000) || temp>c(5000)) continue;//引导脉冲低电平9000

  62. temp=Ir_Get_High();

  63. if(temp<c(4000) || temp>c(5000)) continue;//引导脉冲高电平4500

  64. for(i=0;i<4;i++) //4个字节

  65.         for(j=0;j<8;j++) //每个字节8位
  66.        
  67.                 {
  68.                
  69.                         temp=Ir_Get_Low();
  70.                        
  71.                         if(temp<c(200) || temp>c(800)) goto restart;
  72.                        
  73.                         temp=Ir_Get_High();
  74.                        
  75.                         if(temp<c(200) || temp>c(2000)) goto restart;

  76.                         Ir_Buf[i]>>=1;
  77.                        
  78.                         if(temp>c(1120)) Ir_Buf[i]|=0x80;
  79.                
  80.                 }

  81. Led_Buf[0]=Ir_Buf[2]&0xf;           //低四位数据码
  82.                                                           
  83. Led_Buf[1]=(Ir_Buf[2]/16)&0xf; //高四位数据码

  84. Led_Buf[2]=Ir_Buf[0]&0xf;           //低四位用户码

  85. Led_Buf[3]=(Ir_Buf[0]/16)&0xf; //高四位用户码

  86. }while(1);

  87. }
复制代码
  1. 提供C51测试程序。

  2. //接收用HX1838或HT0038
  3. ///C51的红外解码程序,可以根据需要自己修改:LED数码管显示
  4. //11.0592Mhz
  5. #include <STC_NEW_8051.H>
  6. #include <intrins.h>
  7. #include "HT1623.C"//数码管显示程序
  8. //根据自己的接线来改
  9. sbit IRIN = P3^2;         //红外接收器数据线
  10. sbit led = P4^1;          //指示灯
  11. ////////////////////////////////////////////
  12. //定义数组IRCOM,分别装解码后得到的数据
  13. //IRCOM[0]   低8位地址码
  14. //IRCOM[1]   高8位地址码
  15. //IRCOM[2]   8位数据码
  16. //IRCOM[3]   8位数据码的反码     
  17. /////////////////////////////////////////////


  18. #define uchar unsigned char
  19. #define uint unsigned int

  20. uchar IRCOM[4];
  21. bit flag=0;

  22. void delay014ms(unsigned char x);    //x*0.14MS
  23. void IR_init(void);
  24.    
  25. void delay014ms(unsigned char x)    //x*0.14MS STC10F04延时约0.15MS
  26. {
  27. unsigned char i;
  28. while(x--)
  29. {
  30. for (i = 0; i<125; i++) //13
  31.      {;}
  32. }
  33. }
  34. ///////////////
  35. //初始化
  36. ////////////
  37. void disp()
  38. {
  39.   uchar date1;
  40.   date1=IRCOM[3];               //如果得到的数据原码和数据反码相反
  41.    displaydata[0]=LEDseg[date1/16];
  42.     displaydata[2]=LEDseg[date1%16];
  43. show_all_led();   

  44. }
  45. void IR_init(void)
  46. {
  47.    EA=1;
  48.    EX0=1;                 //允许总中断中断,使能 INT0 外部中断
  49.    IT0=1;               //触发方式为脉冲负边沿触发  
  50.    IRIN=1;                    //I/O口初始化
  51. }
  52. //////////
  53. //解码过程
  54. //////////////
  55. void IR_CODE(void) interrupt 0   //在外部中断子程序中解码
  56. {
  57. unsigned char j,k,N=0;
  58.      EX0 = 0;
  59. delay014ms(1);
  60. if (IRIN==1)
  61.      { EX0 =1;
  62.     return;
  63.    }                           //确认IR信号出现
  64. while (!IRIN)            //等IR变为高电平,跳过9ms的前导低电平信号。
  65.     {delay014ms(1);}
  66. for (j=0;j<4;j++)         //收集四组数据
  67. {
  68. for (k=0;k<8;k++)        //每组数据有8位
  69. {
  70.    while (IRIN)            //等 IR 变为低电平,跳过4.5ms的前导高电平信号。
  71.      {delay014ms(1);}
  72.     while (!IRIN)          //等 IR 变为高电平
  73.      {delay014ms(1);}
  74.      while (IRIN)           //计算IR高电平时长
  75.       {
  76.     delay014ms(1);
  77.     N++;      
  78.     if (N>=30)
  79. { EX0=1;
  80. return;}              //0.14ms计数过长自动离开。
  81.       }                        //高电平计数完毕            
  82.      IRCOM[j]=IRCOM[j] >> 1;                  //数据最高位补"0"
  83.      if (N>=8) {IRCOM[j] = IRCOM[j] | 0x80;} //数据最高位补"1"
  84.      N=0;
  85. }
  86. }
  87.    if (IRCOM[2]!=~IRCOM[3]) //不等的话表示解码失败
  88.    {
  89. IRCOM[4]=0;
  90. EX0=1;
  91.       return;
  92.     }

  93.    flag = !flag;//pro();//解码成功后运行的程序
  94. disp();
  95. //如果解码成功,flag就取一次,在主程序中,就根据flag的值来闪灯,
  96. EX0=1;

  97. return;
  98. }


  99. //主程序

  100. void main(void)
  101.           {
  102.           IR_init( ); //初始化外部中断0
  103.        lint_val_display();
  104.      flag = 0;
  105.      while(1)
  106.            {
  107.          led=flag; //正确接收后的led闪灯的现像。
  108.    disp();
  109.        }
  110.     }
复制代码


  1. //使用12M晶振 适用于TC9012芯片,其他芯片请自行更改解码时序
  2. #include<reg52.h>
  3. #include<stdio.h>
  4. #include<intrins.h>

  5. ////////////////////////////////////////////////
  6. #define TURE 1
  7. #define FALSE 0

  8. ////////////////////////////////////////////////

  9. sbit IR=P3^2;//红外接口标志

  10. unsigned char const dofly[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
  11. ////////////////////////////////////////////

  12. unsigned char irtime;//红外用全局变量

  13. bit irpro_ok,irok;
  14. unsigned char IRcord[4];
  15. unsigned char   irdata[33];

  16. //////////////////////////////////////////////

  17. void Delay(unsigned char mS);
  18. void Ir_work(void);
  19. void Ircordpro(void);

  20. //////////////////////////////////////////////////////////////////

  21. void tim0_isr (void) interrupt 1 using 1//定时器0中断服务函数
  22. {
  23. irtime++;
  24. }

  25. ///////////////////////////////////////////////////////////////////////
  26. void ex0_isr (void) interrupt 0 using 0//外部中断0服务函数
  27. {
  28. static unsigned char i;
  29. static bit startflag;

  30. if(startflag)
  31. {
  32.   
  33.     if(irtime<42&&irtime>=33)//引导码 TC9012的头码
  34.             i=0;
  35.    
  36.        irdata[i]=irtime;//一次存储32位电平宽度
  37.        irtime=0;
  38.        i++;
  39.        if(i==33)
  40.           {
  41.        irok=1;
  42.      i=0;
  43.        }
  44.           }

  45. else
  46.    {irtime=0;startflag=1;}

  47. }

  48. ////////////////////////////////////////////////////////////////////
  49. void TIM0init(void)//定时器0初始化
  50. {

  51. TMOD=0x02;//定时器0工作方式2,TH0是重装值,TL0是初值
  52. TH0=0x00;//reload value
  53. TL0=0x00;//initial value
  54. ET0=1;//开中断
  55. TR0=1;
  56. }
  57. ///////////////////////////////////////////////////////////////////
  58. void EX0init(void)
  59. {
  60. IT0 = 1;   // Configure interrupt 0 for falling edge on /INT0 (P3.2)
  61. EX0 = 1;   // Enable EX0 Interrupt
  62. EA = 1;
  63. }
  64. /****************************************************************/

  65. /******************************************************************/

  66. void Ir_work(void)//红外键值散转程序
  67. {
  68.        switch(IRcord[2])//判断第三个数码值
  69.           {
  70.     case 0:P0=dofly[1];break;//1 显示相应的按键值
  71.     case 1:P0=dofly[2];break;//2
  72.     case 2:P0=dofly[3];break;//3
  73.     case 3:P0=dofly[4];break;//4
  74.     case 4:P0=dofly[5];break;//5
  75.     case 5:P0=dofly[6];break;//6
  76.     case 6:P0=dofly[7];break;//7
  77.     case 7:P0=dofly[8];break;//8
  78.     case 8:P0=dofly[9];break;//9

  79.     }

  80.   

  81.     irpro_ok=0;//处理完成标志

  82. }

  83. /*****************************************************************/
  84. void Ircordpro(void)//红外码值处理函数
  85. {
  86. unsigned char i, j, k;
  87. unsigned char cord,value;

  88. k=1;
  89. for(i=0;i<4;i++)//处理4个字节
  90.      {
  91.       for(j=1;j<=8;j++) //处理1个字节8位
  92.          {
  93.           cord=irdata[k];
  94.           if(cord>7)//大于某值为1
  95.       {
  96.              value=value|0x80;
  97.     }
  98.           else
  99.       {
  100.              value=value;
  101.     }
  102.           if(j<8)
  103.       {
  104.     value=value>>1;
  105.     }
  106.            k++;
  107.          }
  108.      IRcord[i]=value;
  109.      value=0;   
  110.      } irpro_ok=1;//处理完毕标志位置1
  111.    
  112. }


  113. /////////////////////////////////////////////////////////////////

  114. void main(void)
  115. {
  116. EX0init(); // Enable Global Interrupt Flag
  117. TIM0init();//初始化定时器0

  118. P2=0x00;//1位数码管全部显示

  119. while(1)//主循环
  120.    {
  121.     if(irok)
  122.    {  
  123.     Ircordpro();//码值处理
  124.      irok=0;
  125.    }

  126.     if(irpro_ok)//step press key
  127.    {
  128.     Ir_work();//码值识别散转
  129.    }
  130.    }
  131. }
复制代码



程序
tc9012.rar (11.46 KB, 下载次数: 34)
回复

使用道具 举报

发表于 2012-8-20 22:06:50 | 显示全部楼层
谢谢   学习一下
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|联系我们|闽公网安备 35012102000020号|圣源电子 ( 闽ICP备11020110号 )

GMT+8, 2019-6-26 02:30 , Processed in 0.736913 second(s), 21 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表