找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3160|回复: 14
打印 上一主题 下一主题
收起左侧

关于51单片机制作38K红外遥控的代码相关问题

[复制链接]
跳转到指定楼层
楼主

这个写输出效果接近于38K方波



如果写成


出来的效果就成了。


高电平时间多了5uS.
如果不循环调用函数。
红外起始信号。9ms就可重复写342次吗???
代码中每位数所0.56mS,就需要重复写21次呀。
如果不使用循环调用函数。写出来的程序。
51单片机容量,还以写进进去吗???



如果这样写去掉6次。



这样一直输出还可以,如果加个变量统计次数,计算时间。高电平时间又变长了怎么办呀。



加个变量,计时做开始信号。加个变量,计时做开始信号。



高电平时间22uS

多了9uS.


程序中已经去掉了6个空指令,
还有6个空指令。
高电平时间还多。9uS如何处理呀。
全去掉,高电平的时间还是多呀。



全部去掉


高电平的时间是15.75uS还是多2.6uS.
还个问题,怎么怎么办呀。



38K高低电平,各占13.157uS.
这个时间是按38K来计算的。
红外一体接收头,接收38K-----40K之间载波。
电平时间可以再短一些。不能再长了。
定时中断产生38K.
反复中断压栈时间就处理不过来。

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:123289 发表于 2019-6-12 08:13 | 只看该作者
一开始的设计方案就不对!
回复

使用道具 举报

板凳
ID:123289 发表于 2019-6-12 08:14 | 只看该作者
加上对单片机的了解不够,问题就出来了。
回复

使用道具 举报

地板
ID:417080 发表于 2019-6-12 09:59 | 只看该作者
51单片机本身执行周期就长,加上你要求这么高的精度,有点难搞。你所看到的高电平多一点,是因为从低电平到高电平的过程中会有波动,也就是常说的抖动,你要从原理上去分析,试着用去抖动的方法来完成。很简单就是判断一下,让它变换的更迅速而已。
回复

使用道具 举报

5#
ID:417092 发表于 2019-6-12 10:45 | 只看该作者
yzwzfyz 发表于 2019-6-12 08:14
加上对单片机的了解也肤浅,问题就出来了。

如何解决呀。让单片机只输出信号的高低电平。不产生38K方波吗。
单片机,外部再加一个,38K方波产生的电路吗???
回复

使用道具 举报

6#
ID:417092 发表于 2019-6-12 10:46 | 只看该作者
sadbkj 发表于 2019-6-12 09:59
51单片机本身执行周期就长,加上你要求这么高的精度,有点难搞。你所看到的高电平多一点,是因为从低电平到 ...

没听明白,是什么意思。。。详细说一下吧。。。
回复

使用道具 举报

7#
ID:417092 发表于 2019-6-12 17:43 | 只看该作者
yzwzfyz 发表于 2019-6-12 08:14
加上对单片机的了解也不够,问题就出来了。

说一下,这个问题,如何解决。。。
回复

使用道具 举报

8#
ID:514901 发表于 2019-6-12 19:50 | 只看该作者
38K赫兹载波,每26us取反一次,用中断与子函数配合着用,没那么复杂的
回复

使用道具 举报

9#
ID:155507 发表于 2019-6-12 20:34 | 只看该作者
我给你来个程序试试


  1. /*---------------------------------------------------------------------*/
  2. /* --- STC MCU Limited ------------------------------------------------*/
  3. /* --- STC 1T Series MCU Demo Programme -------------------------------*/
  4. /* --- Mobile: (86)13922805190 ----------------------------------------*/
  5. /* --- Fax: 86-0513-55012956,55012947,55012969 -----------------------*/
  6. /* --- Tel: 86-0513-55012928,55012929,55012966 ------------------------*/
  7. /* --- Web: www.STCMCU.com --------------------------------------------*/
  8. /* --- Web: www.GXWMCU.com --------------------------------------------*/
  9. /* --- QQ:  800003751 -------------------------------------------------*/
  10. /* 如果要在程序中使用此代码,请在程序中注明使用了STC的资料及程序        */
  11. /*---------------------------------------------------------------------*/



  12. /*************  本程序功能说明  **************


  13. 用户可以在宏定义中改变MCU主时钟频率. 范围 8MHZ ~ 33MHZ.

  14. 红外接收程序。模拟市场上用量最大的NEC的编码。

  15. 用户可以在宏定义中指定用户码.

  16. 使用PCA2高速输出产生38KHZ载波, 1/3占空比, 每个38KHZ周期发射管发射9us,关闭16.3us.

  17. 使用开发板上的16个IO扫描按键, MCU不睡眠, 连续扫描按键.

  18. 当键按下, 第一帧为数据, 后面的帧为重复争,不带数据, 具体定义请自行参考NEC的编码资料.

  19. 键释放后, 停止发送.

  20. ******************************************/


  21. #include    "reg51.h"
  22. #include    "intrins.h"

  23. #define     MAIN_Fosc       11059200L   //定义主时钟

  24. typedef     unsigned char   u8;
  25. typedef     unsigned int    u16;
  26. typedef     unsigned long   u32;

  27. sfr TH2  = 0xD6;
  28. sfr TL2  = 0xD7;
  29. sfr IE2   = 0xAF;
  30. sfr INT_CLKO = 0x8F;
  31. sfr AUXR = 0x8E;
  32. sfr AUXR1 = 0xA2;
  33. sfr P_SW1 = 0xA2;
  34. sfr P_SW2 = 0xBA;
  35. sfr S2CON = 0x9A;
  36. sfr S2BUF = 0x9B;

  37. sfr ADC_CONTR = 0xBC;   //带AD系列
  38. sfr ADC_RES   = 0xBD;   //带AD系列
  39. sfr ADC_RESL  = 0xBE;   //带AD系列
  40. sfr P1ASF = 0x9D;   //只写,模拟输入(AD或LVD)选择

  41. sfr CCON = 0xD8;    //
  42. sbit CCF0  = CCON^0;    //PCA 模块0中断标志,由硬件置位,必须由软件清0。
  43. sbit CCF1  = CCON^1;    //PCA 模块1中断标志,由硬件置位,必须由软件清0。
  44. sbit CCF2  = CCON^2;    //PCA 模块2中断标志,由硬件置位,必须由软件清0。
  45. sbit CR    = CCON^6;    //1: 允许PCA计数器计数,必须由软件清0。
  46. sbit CF    = CCON^7;    //PCA计数器溢出(CH,CL由FFFFH变为0000H)标志。PCA计数器溢出后由硬件置位,必须由软件清0。
  47. sfr CMOD = 0xD9;    //
  48. sfr CCAPM0 = 0xDA;  //PCA模块0的工作模式寄存器。
  49. sfr CCAPM1 = 0xDB;  //PCA模块1的工作模式寄存器。
  50. sfr CCAPM2 = 0xDC;  //PCA模块2的工作模式寄存器。
  51. sfr CL     = 0xE9;  //
  52. sfr CCAP0L = 0xEA;  //PCA模块0的捕捉/比较寄存器低8位。
  53. sfr CCAP1L = 0xEB;  //PCA模块1的捕捉/比较寄存器低8位。
  54. sfr CCAP2L = 0xEC;  //PCA模块2的捕捉/比较寄存器低8位。
  55. sfr CH     = 0xF9;
  56. sfr CCAP0H = 0xFA;      //PCA模块0的捕捉/比较寄存器高8位。
  57. sfr CCAP1H = 0xFB;      //PCA模块1的捕捉/比较寄存器高8位。
  58. sfr CCAP2H = 0xFC;      //PCA模块2的捕捉/比较寄存器高8位。
  59. sfr PCA_PWM0 = 0xF2;    //PCA模块0 PWM寄存器。
  60. sfr PCA_PWM1 = 0xF3;    //PCA模块1 PWM寄存器。
  61. sfr PCA_PWM2 = 0xF4;    //PCA模块2 PWM寄存器。

  62. sbit PPCA   = IP^7;

  63. sfr P4   = 0xC0;
  64. sfr P5   = 0xC8;
  65. sfr P6   = 0xE8;
  66. sfr P7   = 0xF8;
  67. sfr P1M1 = 0x91;    //PxM1.n,PxM0.n     =00--->Standard,    01--->push-pull
  68. sfr P1M0 = 0x92;    //                  =10--->pure input,  11--->open drain
  69. sfr P0M1 = 0x93;
  70. sfr P0M0 = 0x94;
  71. sfr P2M1 = 0x95;
  72. sfr P2M0 = 0x96;
  73. sfr P3M1 = 0xB1;
  74. sfr P3M0 = 0xB2;
  75. sfr P4M1 = 0xB3;
  76. sfr P4M0 = 0xB4;
  77. sfr P5M1 = 0xC9;
  78. sfr P5M0 = 0xCA;
  79. sfr P6M1 = 0xCB;
  80. sfr P6M0 = 0xCC;
  81. sfr P7M1 = 0xE1;
  82. sfr P7M0 = 0xE2;

  83. sbit P00 = P0^0;
  84. sbit P01 = P0^1;
  85. sbit P02 = P0^2;
  86. sbit P03 = P0^3;
  87. sbit P04 = P0^4;
  88. sbit P05 = P0^5;
  89. sbit P06 = P0^6;
  90. sbit P07 = P0^7;
  91. sbit P10 = P1^0;
  92. sbit P11 = P1^1;
  93. sbit P12 = P1^2;
  94. sbit P13 = P1^3;
  95. sbit P14 = P1^4;
  96. sbit P15 = P1^5;
  97. sbit P16 = P1^6;
  98. sbit P17 = P1^7;
  99. sbit P20 = P2^0;
  100. sbit P21 = P2^1;
  101. sbit P22 = P2^2;
  102. sbit P23 = P2^3;
  103. sbit P24 = P2^4;
  104. sbit P25 = P2^5;
  105. sbit P26 = P2^6;
  106. sbit P27 = P2^7;
  107. sbit P30 = P3^0;
  108. sbit P31 = P3^1;
  109. sbit P32 = P3^2;
  110. sbit P33 = P3^3;
  111. sbit P34 = P3^4;
  112. sbit P35 = P3^5;
  113. sbit P36 = P3^6;
  114. sbit P37 = P3^7;
  115. sbit P40 = P4^0;
  116. sbit P41 = P4^1;
  117. sbit P42 = P4^2;
  118. sbit P43 = P4^3;
  119. sbit P44 = P4^4;
  120. sbit P45 = P4^5;
  121. sbit P46 = P4^6;
  122. sbit P47 = P4^7;
  123. sbit P50 = P5^0;
  124. sbit P51 = P5^1;
  125. sbit P52 = P5^2;
  126. sbit P53 = P5^3;
  127. sbit P54 = P5^4;
  128. sbit P55 = P5^5;
  129. sbit P56 = P5^6;
  130. sbit P57 = P5^7;


  131. /*************  红外发送相关变量    **************/
  132. #define User_code   0xFF00      //定义红外用户码

  133. sbit    P_IR_TX   = P3^7;   //定义红外发送端口

  134. u16     PCA_Timer2; //PCA2软件定时器变量
  135. bit     B_Space;    //发送空闲(延时)标志
  136. u16     tx_cnt;     //发送或空闲的脉冲计数(等于38KHZ的脉冲数,对应时间), 红外频率为38KHZ, 周期26.3us
  137. u8      TxTime;     //发送时间


  138. /*************  IO口定义    **************/
  139. sbit    P_HC595_SER   = P4^0;   //pin 14    SER     data input
  140. sbit    P_HC595_RCLK  = P5^4;   //pin 12    RCLk    store (latch) clock
  141. sbit    P_HC595_SRCLK = P4^3;   //pin 11    SRCLK   Shift data clock

  142. /*************  IO键盘变量声明  **************/

  143. u8  IO_KeyState, IO_KeyState1, IO_KeyHoldCnt;   //行列键盘变量
  144. u8  KeyHoldCnt; //键按下计时
  145. u8  KeyCode;    //给用户使用的键码, 1~16有效


  146. /*************  本地函数声明    **************/
  147. void    delay_ms(u8 ms);
  148. void    DisableHC595(void);
  149. void    IO_KeyScan(void);
  150. void    PCA_config(void);
  151. void    IR_TxPulse(u16 pulse);
  152. void    IR_TxSpace(u16 pulse);
  153. void    IR_TxByte(u8 dat);




  154. /********************** 主函数 ************************/
  155. void main(void)
  156. {
  157.     P0M1 = 0;   P0M0 = 0;   //设置为准双向口
  158.     P1M1 = 0;   P1M0 = 0;   //设置为准双向口
  159.     P2M1 = 0;   P2M0 = 0;   //设置为准双向口
  160.     P3M1 = 0;   P3M0 = 0;   //设置为准双向口
  161.     P4M1 = 0;   P4M0 = 0;   //设置为准双向口
  162.     P5M1 = 0;   P5M0 = 0;   //设置为准双向口
  163.     P6M1 = 0;   P6M0 = 0;   //设置为准双向口
  164.     P7M1 = 0;   P7M0 = 0;   //设置为准双向口
  165.    
  166.     PCA_config();
  167.    
  168.     EA = 1;                     //打开总中断
  169.    
  170.     DisableHC595();     //禁止掉学习板上的HC595显示,省电

  171.     while(1)
  172.     {
  173.         delay_ms(30);       //30ms
  174.         IO_KeyScan();

  175.         if(KeyCode != 0)        //检测到键码
  176.         {
  177.             TxTime = 0;
  178.                                 //一帧数据最小长度 = 9 + 4.5 + 0.5625 + 24 * 1.125 + 8 * 2.25 = 59.0625 ms
  179.                                 //一帧数据最大长度 = 9 + 4.5 + 0.5625 + 8 * 1.125 + 24 * 2.25 = 77.0625 ms
  180.             IR_TxPulse(342);    //对应9ms,同步头       9ms
  181.             IR_TxSpace(171);    //对应4.5ms,同步头间隔 4.5ms
  182.             IR_TxPulse(21);     //开始发送数据          0.5625ms

  183.             IR_TxByte(User_code%256);   //发用户码高字节
  184.             IR_TxByte(User_code/256);   //发用户码低字节
  185.             IR_TxByte(KeyCode);         //发数据
  186.             IR_TxByte(~KeyCode);        //发数据反码
  187.             
  188.             if(TxTime < 56)     //一帧按最大77ms发送, 不够的话,补偿时间     108ms
  189.             {
  190.                 TxTime = 56 - TxTime;
  191.                 TxTime = TxTime + TxTime / 8;
  192.                 delay_ms(TxTime);
  193.             }
  194.             delay_ms(31);

  195.             while(IO_KeyState != 0) //键未释放
  196.             {
  197.                 IR_TxPulse(342);    //对应9ms,   同步头        9ms
  198.                 IR_TxSpace(86);     //对应2.25ms,同步头间隔    2.25ms
  199.                 IR_TxPulse(21);     //开始发送数据              0.5625ms
  200.                 delay_ms(96);
  201.                 IO_KeyScan();
  202.             }
  203.             KeyCode = 0;
  204.         }
  205.     }
  206. }
  207. /**********************************************/

  208. //========================================================================
  209. // 函数: void  delay_ms(unsigned char ms)
  210. // 描述: 延时函数。
  211. // 参数: ms,要延时的ms数, 这里只支持1~255ms. 自动适应主时钟.
  212. // 返回: none.
  213. // 版本: VER1.0
  214. // 日期: 2013-4-1
  215. // 备注:
  216. //========================================================================
  217. void  delay_ms(u8 ms)
  218. {
  219.      u16 i;
  220.      do{
  221.           i = MAIN_Fosc / 13000;
  222.           while(--i)    ;   //13T per loop
  223.      }while(--ms);
  224. }



  225. void DisableHC595(void)
  226. {      
  227.     u8  i;
  228.     P_HC595_SER   = 1;
  229.     for(i=0; i<20; i++)
  230.     {
  231.         P_HC595_SRCLK = 1;
  232.         P_HC595_SRCLK = 0;
  233.     }
  234.     P_HC595_RCLK = 1;
  235.     P_HC595_RCLK = 0;                           //锁存输出数据
  236.     P_HC595_RCLK = 1;
  237.     P_HC595_RCLK = 0;                           //锁存输出数据
  238. }


  239. /*****************************************************
  240.     行列键扫描程序
  241.     使用XY查找4x4键的方法,只能单键,速度快

  242.    Y     P04      P05      P06      P07
  243.           |        |        |        |
  244. X         |        |        |        |
  245. P00 ---- K00 ---- K01 ---- K02 ---- K03 ----
  246.           |        |        |        |
  247. P01 ---- K04 ---- K05 ---- K06 ---- K07 ----
  248.           |        |        |        |
  249. P02 ---- K08 ---- K09 ---- K10 ---- K11 ----
  250.           |        |        |        |
  251. P03 ---- K12 ---- K13 ---- K14 ---- K15 ----
  252.           |        |        |        |
  253. ******************************************************/


  254. u8 code T_KeyTable[16] = {0,1,2,0,3,0,0,0,4,0,0,0,0,0,0,0};

  255. void IO_KeyDelay(void)
  256. {
  257.     u8 i;
  258.     i = 60;
  259.     while(--i)  ;
  260. }

  261. void    IO_KeyScan(void)    //50ms call
  262. {
  263.     u8  j;

  264.     j = IO_KeyState1;   //保存上一次状态

  265.     P0 = 0xf0;  //X低,读Y
  266.     IO_KeyDelay();
  267.     IO_KeyState1 = P0 & 0xf0;

  268.     P0 = 0x0f;  //Y低,读X
  269.     IO_KeyDelay();
  270.     IO_KeyState1 |= (P0 & 0x0f);
  271.     IO_KeyState1 ^= 0xff;   //取反
  272.    
  273.     if(j == IO_KeyState1)   //连续两次读相等
  274.     {
  275.         j = IO_KeyState;
  276.         IO_KeyState = IO_KeyState1;
  277.         if(IO_KeyState != 0)    //有键按下
  278.         {
  279.             F0 = 0;
  280.             if(j == 0)  F0 = 1; //第一次按下
  281.             else if(j == IO_KeyState)
  282.             {
  283.                 if(++IO_KeyHoldCnt >= 20)   //1秒后重键
  284.                 {
  285.                     IO_KeyHoldCnt = 18;
  286.                     F0 = 1;
  287.                 }
  288.             }
  289.             if(F0)
  290.             {
  291.                 j = T_KeyTable[IO_KeyState >> 4];
  292.                 if((j != 0) && (T_KeyTable[IO_KeyState& 0x0f] != 0))
  293.                     KeyCode = (j - 1) * 4 + T_KeyTable[IO_KeyState & 0x0f] + 16;    //计算键码,17~32
  294.             }
  295.         }
  296.         else    IO_KeyHoldCnt = 0;
  297.     }
  298.     P0 = 0xff;
  299. }



  300. /************* 发送脉冲函数 **************/
  301. void    IR_TxPulse(u16 pulse)
  302. {
  303.     tx_cnt = pulse;
  304.     B_Space = 0;    //发脉冲
  305.     CCAPM2 = 0x48 | 0x04 | 0x01;    //工作模式 0x00: PCA_Mode_Capture,  0x42: PCA_Mode_PWM,  0x48: PCA_Mode_SoftTimer
  306.     CR = 1;     //启动
  307.     while(CR);
  308. }

  309. /************* 发送空闲函数 **************/
  310. void    IR_TxSpace(u16 pulse)
  311. {
  312.     tx_cnt = pulse;
  313.     B_Space = 1;    //空闲
  314.     CCAPM2 = 0x48 | 0x01;   //工作模式 0x00: PCA_Mode_Capture,  0x42: PCA_Mode_PWM,  0x48: PCA_Mode_SoftTimer
  315.     CR = 1;     //启动
  316.     while(CR);
  317. }


  318. /************* 发送一个字节函数 **************/
  319. void    IR_TxByte(u8 dat)
  320. {
  321.     u8 i;
  322.     for(i=0; i<8; i++)
  323.     {
  324.         if(dat & 1)     IR_TxSpace(63), TxTime += 2;    //数据1对应 1.6875 + 0.5625 ms
  325.         else            IR_TxSpace(21), TxTime++;       //数据0对应 0.5625 + 0.5625 ms
  326.         IR_TxPulse(21);         //脉冲都是0.5625ms
  327.         dat >>= 1;              //下一个位
  328.     }
  329. }

  330. //========================================================================
  331. // 函数: void   PCA_config(void)
  332. // 描述: PCA配置函数.
  333. // 参数: None
  334. // 返回: none.
  335. // 版本: V1.0, 2012-11-22
  336. //========================================================================
  337. void    PCA_config(void)
  338. {
  339.     AUXR1   = (AUXR1 & ~0x30) | 0x10;   //切换IO口, 0x00: P1.2 P1.1 P1.0 P3.7,  0x10: P3.4 P3.5 P3.6 P3.7, 0x20: P2.4 P2.5 P2.6 P2.7

  340.     CCON = 0x00;    //清除所有中断标志
  341.     CCAPM2  = 0x48+ 1;  //工作模式 + 允许中断 0x00: PCA_Mode_Capture,  0x42: PCA_Mode_PWM,  0x48: PCA_Mode_SoftTimer
  342.     CCAPM2 |= 0x04; //允许高速取反输出, 一般用在16位软件定时器
  343.     PCA_Timer2 = 100;   //随便给一个小的初值
  344.     CCAP2L = (u8)PCA_Timer2;            //将影射寄存器写入捕获寄存器,先写CCAPxL
  345.     CCAP2H = (u8)(PCA_Timer2 >> 8); //后写CCAPxH

  346.     PPCA = 1;   //高优先级中断
  347.     CMOD  = (CMOD  & ~0xe0) | 0x08; //选择时钟源, 0x00: 12T, 0x02: 2T, 0x04: Timer0溢出, 0x06: ECI, 0x08: 1T, 0x0A: 4T, 0x0C: 6T, 0x0E: 8T
  348.     CH = 0;
  349.     CL = 0;
  350.     CR = 0;
  351.     tx_cnt = 2;
  352. }

  353. //========================================================================
  354. // 函数: void   PCA_Handler (void) interrupt PCA_VECTOR
  355. // 描述: PCA中断处理程序.
  356. // 参数: None
  357. // 返回: none.
  358. // 版本: V1.0, 2012-11-22
  359. //========================================================================

  360. #define D_38K_DUTY  ((MAIN_Fosc * 26) / 1000000UL + MAIN_Fosc / 3000000UL)  /*  38KHZ周期时间   26.3us */
  361. #define D_38K_OFF   ((MAIN_Fosc * 17) / 1000000UL + MAIN_Fosc / 3000000UL)  /* 发射管关闭时间   17.3us */
  362. #define D_38K_ON    ((MAIN_Fosc * 9) / 1000000UL)                           /* 发射管导通时间   9us */

  363. void    PCA_Handler (void) interrupt 7
  364. {
  365.     CCON = 0x40;    //清除所有中断标志,但不关CR
  366.     if(!B_Space)    //发送载波
  367.     {                               //发送脉冲,交替装载TH0值,溢出时自动重装
  368.         if(P_IR_TX)
  369.         {
  370.             PCA_Timer2 += D_38K_OFF;    //装载高电平时间    17.3us
  371.             if(--tx_cnt == 0)   CR = 0; //pulse has sent,   stop
  372.         }
  373.         else    PCA_Timer2 += D_38K_ON; //装载低电平时间    9us
  374.     }
  375.     else    //发送暂停时间
  376.     {
  377.         PCA_Timer2 += D_38K_DUTY;   //装载周期时间  26.3us
  378.         if(--tx_cnt == 0)   CR = 0; //空闲时间
  379.     }
  380.     CCAP2L = (u8)PCA_Timer2;            //将影射寄存器写入捕获寄存器,先写CCAP0L
  381.     CCAP2H = (u8)(PCA_Timer2 >> 8); //后写CCAP0H
  382. }

复制代码
回复

使用道具 举报

10#
ID:451448 发表于 2019-6-12 22:24 | 只看该作者
做红外的话,单片机的精度可能不够,最好用STM32或者K60做,按着解码的步骤,获取高低电平的时间然后解码就可以了
回复

使用道具 举报

11#
ID:417092 发表于 2019-6-14 01:03 | 只看该作者
郑汉松 发表于 2019-6-12 19:50
38K赫兹载波,每26us取反一次,用中断与子函数配合着用,没那么复杂的

13不是26.
26就成的19KHz了,不是38K了。
回复

使用道具 举报

12#
ID:417092 发表于 2019-6-14 01:04 | 只看该作者
angmall 发表于 2019-6-12 20:34
我给你来个程序试试

谢谢,我试试。
回复

使用道具 举报

13#
ID:417092 发表于 2019-6-14 01:13 | 只看该作者
angmall 发表于 2019-6-12 20:34
我给你来个程序试试

没法用这,这个是什么型号的51呀。。。
怎么还有P5 IO口呀。
回复

使用道具 举报

14#
ID:417092 发表于 2019-6-14 01:20 | 只看该作者
angmall 发表于 2019-6-12 20:34
我给你来个程序试试

MCU 还是1T的呀。
回复

使用道具 举报

15#
ID:417092 发表于 2019-6-14 17:02 | 只看该作者
angmall 发表于 2019-6-12 20:34
我给你来个程序试试

#include <reg52.h>

#define uchar unsigned char
#define uint unsigned int

sbit IR_OUT = P0^0;                //红外发射引脚

//T1 13us产生一次中断 用于产生38K载波
//T0 方式1 16位  用于定时
void Init_Timer(void)
{
        TMOD=0x21;         //T0 mode 1      T1 mode 2  
       
        TH1=243;                                               

        //特殊
        TL1=TH1;
       
        ET1=1;
        EA=1;
}
//发送引导码  发送方:9ms高电平 4.5ms低电平
void Send_Start_Bit(void)    //TR1的值=发送的电平
{
        //9ms 1
        TH0=0xDC;
        TL0=0xD9;
        TR0=1;
        TR1=1;
       
        while(!TF0);
       
        TR1=0;
        TF0=0;
        TR0=0;
       
        IR_OUT=0;
        //4.5ms 0
        TH0=0xEE;  
        TL0=0x6E;
        TR0=1;
        TR1=0;
       
        while(!TF0);
       
        TR1=0;
        TF0=0;
        TR0=0;
       
        IR_OUT=0;
}
//发送0  
void Send_Bit_0(void)
{
        //0.565ms 1
        TH0=0xFD;  
        TL0=0xCB;
        TR0=1;
        TR1=1;
       
        while(!TF0);
       
        TR1=0;
        TF0=0;
        TR0=0;
       
        IR_OUT=0;
        //0.565ms 0
        TH0=0xFD;  
        TL0=0xCB;
        TR0=1;
        TR1=0;
       
        while(!TF0);
       
        TR1=0;
        TF0=0;
        TR0=0;
       
        IR_OUT=0;

}
//发送1
void Send_Bit_1(void)
{
//0.565ms 1
        TH0=0xFD;  
        TL0=0xCB;
        TR0=1;
        TR1=1;
       
        while(!TF0);
       
        TR1=0;
        TF0=0;
        TR0=0;
       
        IR_OUT=0;
        //1.685ms 0
        TH0=0xF9;  
        TL0=0x6C;
        TR0=1;
        TR1=0;
       
        while(!TF0);
       
        TR1=0;
        TF0=0;
        TR0=0;
       
        IR_OUT=0;  
}

void Send_over(void)            //发送一个结束码,因为最后一个位只有遇到下降沿才能读取(发射端的上升沿)
{
//0.500ms 1                            //小于0.5ms 接收端很难识别到
        TH0=0xFE;  
        TL0=0x0C;
        TR0=1;
        TR1=1;
       
        while(!TF0);
       
        TR1=0;
        TF0=0;
        TR0=0;
       
        IR_OUT=0;
        //0.500ms 0
        TH0=0xFE;  
        TL0=0x0C;
        TR0=1;
        TR1=0;
       
        while(!TF0);
       
        TR1=0;
        TF0=0;
        TR0=0;
       
        IR_OUT=0;  
}
//发送一字节 8位
void Send_Char()
{
        unsigned char i,j1,j2,j3,j4;
        j1=0xCC;
        j2=0x1D;
        j3=0x08;
        j4=0xF7;
        Send_Start_Bit();                                                                



Send_Bit_0();
  //发射引导吗
        for(i=0;i<8;i++)
        {
                if(j1&1)
                        Send_Bit_1();
                else
                        Send_Bit_0();
                j1=j1>>1;                                                                

                //先发射低位
        }

        for(i=0;i<8;i++)
        {
                if(j2&1)
                        Send_Bit_1();
                else
                        Send_Bit_0();
                j2=j2>>1;                                                                

                //先发射低位
        }

        for(i=0;i<8;i++)
        {
                if(j3&1)
                        Send_Bit_1();
                else
                        Send_Bit_0();
                j3=j3>>1;                                                                

                //先发射低位
        }
       
        for(i=0;i<8;i++)
        {
                if(j4&1)
                        Send_Bit_1();
                else
                        Send_Bit_0();
                j4=j4>>1;                                                                

                //先发射低位
        }
        Send_over();                                                                       

        //结束符
}
void T1_ISR(void) interrupt 3
{
        IR_OUT=!IR_OUT;
}

void main()
{
        Init_Timer();
        while(1)
        {
        Send_Char();
        }
       
}


这个程序可以吗。。。仿真示波器,看着正常。做成电路,不知道为什么不行。
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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