久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 8698|回復: 2
打印 上一主題 下一主題
收起左側

單片機TM1650驅動+紅外遙控解碼源程序

  [復制鏈接]
跳轉到指定樓層
樓主
N年前在網上買了一個TM1650的測試版,今天突然看到了,倒騰了一下。寫了個程序。希望對大家有用,不喜勿噴。


單片機源程序如下:
  1. /*程序功能:TM1650驅動程序加紅外遙控解碼程序 。遙控解碼后顯示在數碼管上
  2.   IO  分配:查看位定義
  3.   時鐘頻率:11.0592MHz
  4.   版    本:VER0
  5.   作    者:劉海蘭
  6.   日    期:2021.03.06
  7.   備    注:如果要在程序中使用此代碼,請在程序中注明使用了51黑單片機liuhailan5757博主的程序
  8.             但是由此造成的后果與本博主無關,  
  9. */
  10. #include<stc15.h>
  11. sbit scl = P3^3; //TM1650時鐘通訊IO
  12. sbit sda = P3^2;//TM1650數據通訊IO
  13. sbit ir  = P3^4;//紅外輸入口
  14. sbit led = P3^5;//測試用指示燈,在調試紅外遙控時可用
  15. unsigned char ir_time = 0;        //紅外信號的時間,這個寄存器是為了在解碼0/1(數據)的時候,用來計低電平的時間
  16. bit ir_d = 0;//紅外信號的高低標志位,
  17. bit ir_ok = 0;//解碼OK
  18. unsigned char shuwei = 0;//解碼的長度
  19. unsigned char shuwei1 = 0;//解碼的長度
  20. unsigned char buzhou = 0;//解碼的步驟
  21. unsigned char ir_dat = 0;//紅外的8位數據
  22. unsigned char num[]={0,0,0,0};//紅外的4組8位的數據,就是用戶碼,用戶碼反碼,數據碼,數據碼反碼
  23. 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
  24. unsigned char reg1 = 0;        //通用寄存器1
  25. unsigned char reg2 = 0;        //通用寄存器2  這兩個寄存器在轉換成可顯示的數據要用到
  26. void delay(unsigned int time)
  27. {
  28. while(time--);
  29. }
  30. void tm1650_start(); //TM1650通訊的開始信號
  31. void tm1650_end();//TM1650通訊的結束信號
  32. void tm1650_ack();//TM1650通訊的應答信號
  33. void write_1();//TM1650數據通訊 寫1
  34. void write_0();//TM1650數據通訊 寫0
  35. void write_byte(unsigned char tem);//寫一個字節
  36. void TM0_Isr() interrupt 1 //紅外解碼,定時器的時基是50us中斷一次
  37. {
  38.   INT_CLKO &= 0xef;        //關閉外部中斷
  39.   if(buzhou==0)                  //步驟0,判斷9ms的低電平
  40.   {
  41.    if(!ir)
  42.    {
  43.     ir_time++;
  44.         if(ir_time>185)                 //低電平超時,每一次因為錯誤退出解碼時,一點要清掉用到的那些寄存器!!!!!!這里一點要注意,下面的退出里面也是要清掉
  45.         {
  46.          ir_d = 0;
  47.          ir_time = 0;
  48.          buzhou = 0;
  49.      TR0 = 0;
  50.          INT_CLKO |= 0x10;
  51.     }
  52.    }
  53.    else
  54.    {
  55.     if((ir_time>175)&&(ir_time<185)) //低電平OK,是正確的9ms ,就跳到步驟1    (9mS除以50uS=180,所以這里的值就設為175和185之間,因為要考慮到一點的誤差)
  56.     {
  57.          ir_time = 0;
  58.      //led ^= 1;
  59.          buzhou = 1;
  60.     }
  61.     else                 //不是正確的9ms
  62.     {
  63.          buzhou = 0;
  64.      TR0 = 0;
  65.          INT_CLKO |= 0x10;
  66.     }
  67.    }
  68.   }
  69.   if(buzhou==1)                 //步驟1,判斷4.5ms的高電平
  70.   {
  71.    if(ir)
  72.    {
  73.     ir_time++;
  74.         if(ir_time>95)           //高電平超時
  75.         {
  76.          ir_d = 0;
  77.          ir_time = 0;
  78.          buzhou = 0;
  79.      TR0 = 0;
  80.          INT_CLKO |= 0x10;
  81.     }
  82.    }
  83.    else
  84.    {
  85.     if((ir_time>85)&&(ir_time<95))         //4.5ms高電平OK,就跳到步驟2  這里還可以添加判斷連碼的程序,如果這里的時間是2mS 那就是連碼
  86.         {
  87.          ir_time = 0;
  88. //     led ^= 1;
  89.          buzhou = 2;
  90.          ir_d = 0;
  91.         }
  92.         else                          //不OK
  93.         {
  94.          buzhou = 0;
  95.      TR0 = 0;
  96.          INT_CLKO |= 0x10;
  97.         }
  98.    }
  99.   }
  100.   if(buzhou==2)           //步驟2開始解碼數據
  101.   {
  102.    if(!ir_d)         //如果低電平標志為0時,這里是用來判斷低電平的時間
  103.    {
  104.     if(!ir)           //如果紅外端口為低
  105.     {
  106.      ir_time++;                //計低電平的時間
  107.          if(ir_time>13)        //低電平時間超時,就退出解碼
  108.          {
  109.           ir_d = 0;
  110.           ir_time = 0;
  111.           buzhou = 0;
  112.       TR0 = 0;
  113.           INT_CLKO |= 0x10;
  114.           shuwei = 0;
  115.           shuwei1 = 0;
  116.          }
  117.     }
  118.     else           //如果轉為高電平了,
  119.     {
  120.          ir_d = 1;        //低電平標志位置一,要去判斷高電平的時間了
  121.          ir_time = 0;//時間清零
  122.     }
  123.    }
  124.    else           //如果低電平標志位為1,就是進入判斷IR高電平的時間了,這個高電平的時間就是判斷數據是0還是1
  125.    {
  126.     if(ir) //如果IR為高
  127.         {
  128.          ir_time++;//計高電平的是按
  129.          if(ir_time>34)         //超時了就退出解碼
  130.          {
  131.           ir_d = 0;
  132.           ir_time = 0;
  133.           buzhou = 0;
  134.       TR0 = 0;
  135.           INT_CLKO |= 0x10;
  136.           shuwei = 0;
  137.           shuwei1 = 0;
  138.          }
  139.         }
  140.         else         //如果IR為低了,就可以判斷高電頻的時間了
  141.         {
  142.          if(ir_time>16)                 //時間大于16*50us  就是數據1
  143.           ir_dat |= 0x80;
  144.          else                                 //否則就是數據0
  145.           ir_dat &= 0x7f;
  146.         shuwei++;
  147.         if(shuwei==8)           //8bit 組成1byte
  148.         {
  149.          num[shuwei1]=ir_dat;
  150.          shuwei = 0;
  151.          shuwei1++;                 //總共4byte
  152.          if(shuwei1==4)         //4組數據接收完了就接收解碼
  153.          {
  154. //          if(num[2]==0x45)
  155. //           led = 0;
  156. //          else
  157. //           led = 1;
  158.       ir_ok = 1;        //解碼成功標志位置一
  159.           buzhou = 0;
  160.       TR0 = 0;
  161.           INT_CLKO |= 0x10;
  162.           shuwei1 = 0;
  163.          }
  164.         }
  165.         ir_dat>>=1;
  166.         ir_time = 0;
  167.         ir_d = 0;
  168.         }
  169.    }
  170.   }
  171. }
  172. void INT2_Isr() interrupt 10   //IR為低 就進入此中斷,開啟解碼,解碼中這個中斷是關閉的,只有退出了解碼,才會進入這個中斷
  173. {
  174.   if(!ir)
  175.   {
  176.    buzhou = 0;
  177.    ir_d = 0;
  178.    shuwei = 0;
  179.    shuwei1 = 0;
  180.    ir_time = 0;
  181.    TR0 = 1;
  182.   }
  183. }

  184. void main()
  185. {
  186. P3M0 = 0x00;
  187. P3M1 = 0x00;
  188. P3 = 0xff;
  189. AUXR |= 0x80;                //定時器時鐘1T模式
  190. TMOD = 0x00;                                //模式0
  191. TL0 = 0xD7;                //設置定時初值
  192. TH0 = 0xFD;       //定時器0設為50us中斷一次
  193. TR0 = 0;                                    //啟動定時器
  194. ET0 = 1;                                    //使能定時器中斷
  195. INT_CLKO |= 0x10;               //(EX2 = 1)使能INT2中斷
  196. EA = 1;
  197. while(1)
  198. {
  199.   tm1650_start();
  200.   write_byte(0x48);        //數碼顯示模式
  201.   tm1650_ack();
  202.   write_byte(0x11);        //1級亮度,開顯示。這里的指令數據 詳情參閱TM1650的datasheet
  203.   tm1650_ack();
  204.   tm1650_end();

  205.   tm1650_start();
  206.   write_byte(0x68);
  207.   tm1650_ack();
  208.   write_byte(shuma[reg1]);
  209.   tm1650_ack();
  210.   tm1650_end();

  211.   tm1650_start();
  212.   write_byte(0x6a);
  213.   tm1650_ack();
  214.   write_byte(shuma[reg2]);
  215.   tm1650_ack();
  216.   tm1650_end();

  217.   tm1650_start();
  218.   write_byte(0x6c);
  219.   tm1650_ack();
  220.   write_byte(0x5b);//固定顯示2
  221.   tm1650_ack();
  222.   tm1650_end();

  223.   tm1650_start();
  224.   write_byte(0x6e);
  225.   tm1650_ack();
  226.   write_byte(0x3f);         //固定顯示0,這里固定顯示02,是因為我們解碼的數據是第2組數據,也就是數據碼(第0組數據是用戶碼,1是用戶碼反碼,2是數據碼,3是數據碼反碼)
  227.   tm1650_ack();
  228.   tm1650_end();
  229.   if(ir_ok)
  230.   {
  231.    ir_ok = 0; //清掉解碼標志位
  232.    reg1 = (num[2]&0x0f);  //  數據低4位送顯示              把數據轉為0-F
  233.    reg2 = (num[2]&0xf0);//數據的高四位送顯示
  234.    reg2>>=4;
  235.   }
  236. }
  237. }
  238. void tm1650_start()
  239. {
  240. sda = 1;
  241. scl = 1;
  242. delay(10);
  243. sda = 0;
  244. delay(5);
  245. }
  246. void tm1650_end()
  247. {
  248. sda = 0;
  249. scl = 1;
  250. delay(6);
  251. sda = 1;
  252. delay(2);
  253. }
  254. void tm1650_ack()
  255. {
  256. while(sda);
  257. delay(5);
  258. scl = 1;
  259. delay(5);
  260. scl = 0;
  261. delay(5);
  262. }
  263. void write_1()
  264. {
  265. sda = 1;
  266. scl = 0;
  267. delay(5);
  268. scl = 1;
  269. delay(10);
  270. scl = 0;
  271. delay(5);
  272. sda = 0;
  273. }
  274. void write_0()
  275. {
  276. sda = 0;
  277. scl = 0;
  278. delay(5);
  279. scl = 1;
  280. delay(10);
  281. scl = 0;
  282. }
  283. void write_byte(unsigned char tem)
  284. {
  285. unsigned char i;
  286. for(i=8;i>0;i--)
  287. {
  288.   if(tem&0x80)
  289.    write_1();
  290.   else
  291.    write_0();
  292.   tem<<=1;
  293. }
  294. }
復制代碼

以上程序下載:
TM1650+紅外解碼.zip (150.58 KB, 下載次數: 93)


評分

參與人數 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏11 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:424598 發表于 2021-7-15 16:42 來自手機 | 只看該作者
單片機用的是什么型號的
回復

使用道具 舉報

板凳
ID:387856 發表于 2021-8-14 15:02 | 只看該作者
STC15W104,,STC的單片機都可以,IO口對應好就行,看宏定義。
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 国产一区二区成人 | 密色视频 | 国产精品免费看 | 亚洲协和影视 | 成人国产精品一级毛片视频毛片 | 一区二区国产精品 | jizz亚洲人 | 国产精品99视频 | jizz在线免费观看 | 日韩欧美国产成人一区二区 | 自拍偷拍中文字幕 | 国产精品久久久久久久久久久久久 | 国产欧美日韩精品在线观看 | 欧美片网站免费 | 精品国产一区二区三区久久久久久 | 97中文视频 | 日韩在线中文字幕 | 久久久久国产精品 | 午夜羞羞| 久久久久久91 | 国产精品久久欧美久久一区 | 成人深夜福利 | 亚洲 欧美 日韩 在线 | 丝袜一区二区三区 | 亚洲午夜视频在线观看 | 午夜资源| 亚洲福利在线观看 | 国产专区在线 | 91亚洲国产成人久久精品网站 | 玖玖免费 | 黄色片视频网站 | 国产日韩视频在线 | 一级毛片色一级 | 一级网站 | 国产中文字幕在线 | 欧美黄色一级毛片 | 在线a视频网站 | 91久久视频| 免费毛片网| 欧美精品一区二区三区蜜桃视频 | av性色|