找回密码
 立即注册

QQ登录

只需一步,快速开始

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

这个单片机红外自收自发代码怎么改?我把发送和接受放在一个while循环里只能接受

[复制链接]
跳转到指定楼层
楼主
ID:947749 发表于 2021-7-8 17:59 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
有谁能教教我这个代码怎么改吗
内容在附件里,谢谢
  1. //适用于市场上用量最大的HT6121/6122及其兼容的IC编码。
  2. //使用外部中断0接收P3.2
  3. //发射引脚(接PNP三极管b极)
  4. //PNP三极管e极接2Ω电阻,c极接红外发射管
  5. #include<reg52.h>
  6. #include "lcd1602.h"        
  7. #include <intrins.h>
  8. #define uchar unsigned char
  9. #define uint  unsigned int
  10. #define LCD_DATA P0
  11. #define SBM   0x80                //识别码
  12. #define m9    (65536-9000)               //约9mS
  13. #define m4_5  (65536-4500)               //约4.5mS
  14. #define m1_6  (65536-1630)               //约1.65mS
  15. #define m_65  (65536-580)               //约0.65mS
  16. #define m_56  (65536-560)               //约0.56mS
  17. #define m40   (65536-40000)         //约40mS
  18. #define m56   (65536-56000)         //56mS
  19. #define m2_25  (65536-2250)          //约2.25mS
  20. sbit IRR  = P3^6;                                  //定义发射引脚(接PNP三极管基极)
  21. sbit LED  = P2^3;
  22. uchar KEY(void);//按键
  23. void  SanZhuan(void);//键值和ASCII码值的转换
  24. void  ZZ(uchar x);//
  25. void  Z0(uchar temp);
  26. void  TT0(bit BT,uint x);
  27. void  YS(uchar time);
  28. uchar code tab[] = {0X30,0X31,0X32,0X33,0X34,0X35,0X36,0X37,0X38,0X39};
  29. uchar code set[] = {0X30,0X31,0X30,0X30,0X30,0X30,0X30,0X30,0X30,0X30};
  30. uchar code tab1[] = {0X4F,0X31,0X32,0X33,0X34,0X35,0X36,0X37,0X4F,0X39};
  31. uchar code tab2[] = {0X46,0X31,0X32,0X33,0X34,0X35,0X36,0X37,0X4E,0X39};
  32. sbit IR = P3^3;                 //接收引脚
  33. sbit LCD_RS=P2^0;
  34. sbit LCD_RW=P2^1;
  35. sbit LCD_EN=P2^2;
  36. uchar  N[4];                                 //识别码,操作码存放
  37. uchar   X1,X2,X3,X4;
  38. void XSQ(void);


  39. typedef unsigned int u16;          //???????????
  40. typedef unsigned char u8;


  41. sbit IRIN=P3^2; //????
  42. u8 IrValue[4] = {'\0'};
  43. u8 Time;

  44. /*????,i=1?,????10us*/
  45. void delay(u16 i)
  46. {
  47.         while(i--);        
  48. }


  49. /*????*/
  50. void DigDisplay()
  51. {
  52.         u8 i;
  53.         write_com(0x83);
  54.         for(i=0;i<4;i++)
  55.         {
  56.                         if(IrValue[i]/16<10)
  57.                         {
  58.                                 write_data(IrValue[i]/16 + 0x30);        
  59.                         }
  60.                         else
  61.                         {
  62.                                 write_data(IrValue[i]/16 + 0x37);        
  63.                         }

  64.                         if(IrValue[i]%16<10)
  65.                         {
  66.                                 write_data(IrValue[i]%16 + 0x30);        
  67.                         }
  68.                         else
  69.                         {
  70.                                 write_data(IrValue[i]%16 + 0x37);        
  71.                         }
  72.         }               
  73. }


  74. /*??????0(????????)*/
  75. void IrInit()
  76. {
  77.         IT0=1;//?????
  78.         EX0=1;//????0??
  79.         EA=1;        //?????

  80.         IRIN=1;//?????
  81. }


  82. /*???*

  83. /*???????????*/
  84. void ReadIr() interrupt 0
  85. {
  86.         u8 j,k;
  87.         u16 err;
  88.         Time=0;                                         
  89.         delay(700);        //7ms
  90.         if(IRIN==0)                //??????????????
  91.         {         
  92.                
  93.                 err=1000;                                //1000*10us=10ms,????????????
  94.                 /*???????????,????????????????,????????
  95.                 ?,??????*/        
  96.                 while((IRIN==0)&&(err>0))        //????9ms??????                  
  97.                 {                        
  98.                         delay(1);
  99.                         err--;
  100.                 }
  101.                 if(IRIN==1)                        //??????9ms???
  102.                 {
  103.                         err=500;
  104.                         while((IRIN==1)&&(err>0))                 //??4.5ms????????
  105.                         {
  106.                                 delay(1);
  107.                                 err--;
  108.                         }
  109.                         for(k=0;k<4;k++)                //??4???
  110.                         {                                
  111.                                 for(j=0;j<8;j++)        //??????
  112.                                 {

  113.                                         err=60;               
  114.                                         while((IRIN==0)&&(err>0))//???????560us?????
  115.                                         {
  116.                                                 delay(1);
  117.                                                 err--;
  118.                                         }
  119.                                         err=500;
  120.                                         while((IRIN==1)&&(err>0))         //???????????
  121.                                         {
  122.                                                 delay(10);         //0.1ms  
  123.                                                 Time++;
  124.                                                 err--;
  125.                                                 if(Time>30)        //??3ms  ????
  126.                                                 {
  127.                                                         return;
  128.                                                 }
  129.                                         }
  130.                                         IrValue[k]>>=1;         //k???????
  131.                                         if(Time>=8)                        //?????????0.8ms,???1
  132.                                         {
  133.                                                 IrValue[k]|=0x80;
  134.                                         }
  135.                                         Time=0;                //?????????                                                        
  136.                                 }
  137.                         }
  138.                 }
  139.                 if(IrValue[2]!=~IrValue[3]) //?? ??? ????? ???? ?????
  140.                 {
  141.                         return;
  142.                 }
  143.         }                        
  144. }




  145. /***************************************************************
  146. 函数功能:             4×4矩阵键盘
  147. ***************************************************************/
  148. uchar KEY(void)
  149. {
  150. uchar H,L;            //行值,列值
  151. H=0;
  152. L=0;
  153. P1 = 0xf0;            //将键盘端口行值设为1,列值设为0
  154. if(P1!= 0xf0)         //检测是否有按键按下,如果有则hangval必不为0x0f
  155.    {
  156.     YS(10);            //按键去抖动,延时10毫秒
  157.     if(P1!=0xf0)       //确实有按键按下
  158.       {
  159.        H  = P1&0xf0;   //按键后得到按键的行标志位,将行标志位赋值给hangval
  160.        P1 =  0x0f;      //翻转键盘接口输出
  161.        L  = P1&0x0f;   //得到列标志位
  162.       }
  163.         return (H+L);
  164.    }
  165.   return 0;
  166. }
  167. /***************************************************************
  168. 函数功能:散转程序
  169. 入口参数:v
  170. //  13  14  15  16
  171. //  9   10  11  12
  172. //  5   6   7   8
  173. //  1   2   3   4
  174. ***************************************************************/
  175. void SanZhuan(void)
  176. {
  177. uchar v;
  178. v =KEY();
  179. switch(v)
  180. {
  181.   case 0x77:ZZ(0x00);v=0;break;                //"0"
  182.   case 0xb7:ZZ(0x01);v=0;break;                //"1 "
  183.   case 0xd7:ZZ(0x02);v=0;break;                //"2 "
  184.   case 0xe7:ZZ(0x03);v=0;break;                //"3"
  185.   case 0x7b:ZZ(0x04);v=0;break;                //"4 "
  186.   case 0xbb:ZZ(0x05);v=0;break;                //"5"
  187.   case 0xdb:ZZ(0x06);v=0;break;                //"6"
  188.   case 0xeb:ZZ(0x07);v=0;break;                //"7"
  189.   case 0x7d:ZZ(0x08);v=0;break;                //"8"
  190.   case 0xbd:ZZ(0x09);v=0;break;                //"9"
  191.   case 0xdd:ZZ(0x0a);v=0;break;                //"a"
  192.   case 0xed:ZZ(0x0b);v=0;break;                //"b"
  193.   case 0x7e:ZZ(0x0c);v=0;break;                //"c"
  194.   case 0xbe:ZZ(0x0d);v=0;break;                //"d"
  195.   case 0xde:ZZ(0x1e);v=0;break;                //"e"
  196.   case 0xee:ZZ(0x1f);v=0;break;                //"f"
  197.   default:v=0;break;
  198. }

  199. }
  200. /*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
  201. 函数功能:发送主程序
  202. ┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/
  203. void ZZ(uchar x)
  204. {
  205.   TT0(1,m9);                       //高电平9mS
  206.   TT0(0,m4_5);               //低电平4.5mS引导
  207.   /*┈ 发送4帧数据 ┈*/
  208.   Z0(SBM);                                //识别码                                                                                                      
  209.   Z0(~SBM);
  210.   Z0(x);                 //数据码
  211.   Z0(~x);
  212.   /*┈┈ 结束码 ┈┈*/
  213.   TT0(1,m_65);
  214.   TT0(0,m40);
  215.   /*┈┈ 重复码 ┈┈*/
  216.         

  217.   while(KEY())
  218.    {
  219.         TT0(1,m9);
  220.         TT0(0,m2_25);
  221.         TT0(1,m_56); //38khz
  222.         TT0(0,m40);
  223.                 TT0(0,m56);
  224.                 LED = !LED;                  //指示灯                                          
  225.     }
  226.    LED = 1;                    
  227. }
  228. /*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
  229. 函数功能:单帧发送程序
  230. 入口参数:1帧数据
  231. ┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/
  232. void Z0(uchar temp)
  233. {
  234.   uchar v;
  235.   for (v=0;v<8;v++)                     //循环8次移位
  236.        {     
  237.                  TT0(1,m_65);                        //高电平0.65mS         
  238.                          if(temp&0x01==1) TT0(0,m1_6); //发送最低位
  239.                          else          TT0(0,m_56);     
  240.                          temp >>= 1;                //右移一位
  241.         }   
  242. }
  243. /*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
  244. 函数功能:38KHz脉冲发射 + 延时程序
  245. 入口参数:(是否发射脉冲,延时约 x (uS))
  246. ┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/
  247. void TT0(bit BT,uint x)
  248. {
  249.   TH0 = x/256;                    //输入T0初始值
  250.   TL0 =x%256;
  251.   TF0=0;                                //清0
  252.   TR0=1;                                //启动定时器0
  253.   if(BT == 0)
  254.           while(!TF0);        //BT=0时不发射38KHz脉冲只延时;BT=1发射38KHz脉冲且延时;
  255.   else while(1)                            //38KHz脉冲,占空比5:26
  256.          {
  257.                   IRR = 0;
  258.                   if(TF0)break;
  259.                if(TF0)break;
  260.                   IRR = 1;
  261.                 if(TF0)break;
  262.                  if(TF0)break;
  263.                  if(TF0)break;
  264.                   if(TF0)break;
  265.                  if(TF0)break;
  266.                  if(TF0)break;
  267.                  if(TF0)break;
  268.                  if(TF0)break;
  269.                  if(TF0)break;
  270.                   if(TF0)break;
  271.                  }
  272.   TR0=0;                                //关闭定时器0
  273.   TF0=0;                                //标志位溢出则清0
  274.   IRR =1;                                //脉冲停止后,发射端口常态为高电平
  275. }
  276. /***************************************************************
  277. 函数功能:按键消抖    延时程序
  278. 入口参数:1ms×time       (晶振=12MHz)
  279. ***************************************************************/
  280. void YS(uchar time)
  281. {
  282.      uchar i,j;
  283.          for(i=0; i<time; i++)
  284.      for(j=0; j<247; j++)_nop_();
  285. }
  286. /*******************************接收*********************************************/
  287. void delay1(unsigned char t) {
  288.     unsigned char i;
  289.     while(t--)
  290.         for(i = 200; i > 0; i--);
  291. }

  292. void LCD_write_instruction(unsigned char LCD_instruction) { //写指令到LCD
  293.     LCD_RS = 0;
  294.     LCD_RW = 0;
  295.     LCD_DATA = LCD_instruction;
  296.     LCD_EN = 1;
  297.     _nop_();
  298.     LCD_EN = 0;
  299.     delay(1);
  300. }

  301. void LCD_write_data(unsigned char LCD_data) {         //输出一个字节数据到LCD
  302.     LCD_RS = 1;
  303.     LCD_RW = 0;
  304.     LCD_DATA = LCD_data;
  305.     LCD_EN = 1;
  306.     _nop_();
  307.     LCD_EN = 0;
  308.     delay(1);
  309. }

  310. void LCD_set_position(unsigned char x) {              //LCD光标定位到x处
  311.     LCD_write_instruction(0x80|x);
  312. }

  313. void LCD_printc(unsigned char lcd_data) {             //输出一个字符到LCD
  314.     LCD_write_data(lcd_data);
  315. }
  316. void LCD_prints(unsigned char *lcd_string) {           //输出一个字符串到 LCD
  317.     unsigned char i = 0;
  318.     while(lcd_string[i] != 0x00) {
  319.         LCD_write_data(lcd_string[i]);
  320.         i++;
  321.     }
  322. }

  323. void LCD_initial(void) {                           //初始化 LCD
  324.     LCD_write_instruction(0x38);
  325.     LCD_write_instruction(0x0c);
  326.     LCD_write_instruction(0x06);
  327.     LCD_write_instruction(0x01);
  328. }

  329. /**********************LCD显示函数************************/
  330. void XSQ(void)
  331. {
  332.    while(1) {
  333.                            uchar temp1,temp2,temp3,temp4;
  334.                         temp1=tab[X4];
  335.                         temp2=set[X3];
  336.                         temp3=tab1[X1];
  337.                         temp4=tab2[X1];
  338.                         LCD_set_position(0x88); //LCD换行显示
  339.             LCD_printc(temp3);
  340.                         LCD_set_position(0x89); //LCD换行显示
  341.             LCD_printc(temp4);
  342.                         LCD_set_position(0xC8); //LCD换行显示
  343.             LCD_printc(temp2);  
  344.       LCD_set_position(0xC9); //LCD换行显示
  345.             LCD_printc(temp1);
  346.                                  SanZhuan();
  347.       }
  348. }
  349. /********************** 外部中断函数************************/
  350. void exint0() interrupt 1
  351. {         
  352.    uint cnt;
  353.    uchar i;
  354.    EX0 =0;
  355.    cnt = 0;        
  356.    while(!IR) cnt++;                        //记录引导码时间
  357.    if(cnt < 1000){EX0=1;return;}             //9ms的计数值(12MHz:1000< cnt <1500)
  358.               cnt =0;                        
  359.    while(IR) if(cnt++ > 400){EX0=1;return;}     //防卡死,超时保护(12MHz: > 300)
  360.    if(cnt < 200){EX0=1;return;}               //(12MHz不分频: <260)
  361.    for(i=0; i<32; i++)                       //读取32位位码
  362.        {
  363.          cnt =0;        
  364.          while(!IR);                       
  365.          while(IR) if(cnt++ > 200){EX0=1;return;}  //超时保护(12MHz:>=200)
  366.          N[i/8] >>= 1;
  367.          if(cnt>60) N[i/8] |= 0x80;                //0和1的计数界线(12MHz:< 109)
  368.        }
  369.          if(N[0] == ~N[1] && N[2] == ~N[3])         //校验识别码,操作码        
  370.            {
  371.                    X1 =N[0]/16;
  372.                 X2 =N[0]%16;
  373.                 X3 = N[2]/16;
  374.                 X4 = N[2]%16;
  375.            }
  376.         EX0 =1;         
  377. }

  378. /****************** 主函数 *******************/
  379. void main(void)
  380. {

  381.         TMOD = 0x01;         //T0 16位工作方式                                   //发射端口常态为高电平
  382.   IRR=1;        //发射端口常态为高电平
  383.         IrInit(); //????0(?????)
  384.         init_lcd(); //???1602
  385.         while(1)
  386.         {        
  387.                 DigDisplay();        //??        
  388.           SanZhuan();
  389.         }
  390.                
  391.   
  392. }
复制代码
代码.rar (45.91 KB, 下载次数: 4)

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

使用道具 举报

沙发
ID:584814 发表于 2021-7-14 08:27 | 只看该作者
自收自发是啥东东 ?
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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