找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3146|回复: 14
收起左侧

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

[复制链接]
ID:417092 发表于 2019-6-12 00:56 | 显示全部楼层 |阅读模式
1.png
这个写输出效果接近于38K方波

2.jpg

如果写成
3.png

出来的效果就成了。
4.png

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

5.png

如果这样写去掉6次。

6.png

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

7.png

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


高电平时间22uS

多了9uS.
9.png

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

10.png

全部去掉
11.png

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

12.png

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

回复

使用道具 举报

ID:123289 发表于 2019-6-12 08:13 | 显示全部楼层
一开始的设计方案就不对!
回复

使用道具 举报

ID:123289 发表于 2019-6-12 08:14 | 显示全部楼层
加上对单片机的了解不够,问题就出来了。
回复

使用道具 举报

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

使用道具 举报

ID:417092 发表于 2019-6-12 10:45 | 显示全部楼层
yzwzfyz 发表于 2019-6-12 08:14
加上对单片机的了解也肤浅,问题就出来了。

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

使用道具 举报

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

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

使用道具 举报

ID:417092 发表于 2019-6-12 17:43 | 显示全部楼层
yzwzfyz 发表于 2019-6-12 08:14
加上对单片机的了解也不够,问题就出来了。

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

使用道具 举报

ID:514901 发表于 2019-6-12 19:50 | 显示全部楼层
38K赫兹载波,每26us取反一次,用中断与子函数配合着用,没那么复杂的
回复

使用道具 举报

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. }

复制代码
回复

使用道具 举报

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

使用道具 举报

ID:417092 发表于 2019-6-14 01:03 | 显示全部楼层
郑汉松 发表于 2019-6-12 19:50
38K赫兹载波,每26us取反一次,用中断与子函数配合着用,没那么复杂的

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

使用道具 举报

ID:417092 发表于 2019-6-14 01:04 | 显示全部楼层
angmall 发表于 2019-6-12 20:34
我给你来个程序试试

谢谢,我试试。
回复

使用道具 举报

ID:417092 发表于 2019-6-14 01:13 | 显示全部楼层
angmall 发表于 2019-6-12 20:34
我给你来个程序试试

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

使用道具 举报

ID:417092 发表于 2019-6-14 01:20 | 显示全部楼层
angmall 发表于 2019-6-12 20:34
我给你来个程序试试

MCU 还是1T的呀。
回复

使用道具 举报

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 单片机教程网

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