找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 4320|回復: 1
收起左側(cè)

STM8S單片機紅外接收解碼程序 帶1602顯示

[復制鏈接]
ID:370779 發(fā)表于 2019-5-12 22:36 | 顯示全部樓層 |閱讀模式
這幾天在網(wǎng)上找了很多關(guān)于紅外接收解碼的程序,但都不是很理想。一般都是用延時來作為0和1的數(shù)據(jù),或者注釋不是很詳細的,所以自己鼓搗了一個。
本程序是采用外部中斷加定時器1來實現(xiàn)紅外解碼,STM8S單片機ABCD口都可作為外部中斷,使用的遙控器為市面上大多數(shù)的。
需要的朋友們可以作為參考。

制作出來的實物圖如下:

效果圖

效果圖


單片機源程序如下:
  1. /***************可識別用戶碼 解碼成功后顯示在1602并LED閃爍一次*****************/

  2. #include "iostm8s208mb.h"//主控芯片的頭文件

  3. #define u8  unsigned char
  4. #define u16 unsigned int
  5. #define u32 unsigned long


  6. #define LED      PI_ODR_ODR3
  7. #define IR_IN    PC_IDR_IDR1
  8. #define LCD_EN   PF_ODR_ODR4
  9. #define LCD_RS   PF_ODR_ODR0
  10. #define LCD_DATA PB_ODR
  11. //#define BUSY     PB_ODR_ODR7


  12. u16 LowTime,HighTime; //存儲高低電平的寬度
  13. u8 Counter_Time_H,Counter_Time_L;

  14. u8 a[4]; //存放碼值 分別為用戶碼 用戶反碼 數(shù)據(jù)碼 數(shù)據(jù)反碼

  15. u8 tab[ ]= {"1602IR-CODE TEST"};

  16. void delay_us(u16 n)
  17. {
  18.   n<<=2;
  19.   while(--n);
  20. }

  21. void delay_ms(u16 t)
  22. {
  23.   while(t--)
  24.   {
  25.     delay_us(1000);
  26.   }
  27. }

  28. void GPIO_Init(void)
  29. {
  30.   EXTI_CR1|=0x20;//配置PC為僅下降沿觸發(fā)

  31.   PI_DDR_DDR3=1;//LED
  32.   PI_CR1_C13=1;
  33.   PI_CR2_C23=1;
  34.   LED=1;
  35.   
  36.   PC_DDR_DDR1=0;//IR_IN
  37.   PC_CR1_C11=1;
  38.   PC_CR2_C21=1;
  39.   
  40.   PF_DDR_DDR4=1;//EN
  41.   PF_CR1_C14=1;
  42.   PF_CR2_C24=1;
  43.   
  44.   PF_DDR_DDR0=1;//RS
  45.   PF_CR1_C10=1;
  46.   PF_CR2_C20=1;
  47.   
  48.   PB_DDR=0xff;//DATA
  49.   PB_CR1=0xff;
  50.   PB_CR2=0xff;  
  51. }

  52. void Write_Com(u8 com)
  53. {
  54.   LCD_RS=0;
  55.   LCD_DATA=com;
  56.   delay_ms(5);
  57.   LCD_EN=1;
  58.   delay_ms(5);
  59.   LCD_EN=0;
  60. }

  61. void Write_Data(u8 data)
  62. {
  63.   LCD_RS=1;
  64.   LCD_DATA=data;
  65.   delay_ms(5);
  66.   LCD_EN=1;
  67.   delay_ms(5);
  68.   LCD_EN=0;
  69. }

  70. void LCD_Init(void)
  71. {
  72.   LCD_EN=0;
  73.   Write_Com(0x38);
  74.   Write_Com(0x0c);
  75.   Write_Com(0x06);
  76.   Write_Com(0x01);
  77. }

  78. void TIM1_Init(void)
  79. {
  80.   TIM1_CR1=0x00;   //close timer1
  81.   
  82.   TIM1_IER = 0x01; //允許更新中斷
  83.   
  84.   TIM1_PSCRH=0x00;    //16Mhz/16=1us,16分頻
  85.   TIM1_PSCRL=0x0f;  
  86.   
  87. //  TIM1_CNTRH=0x00;
  88. //  TIM1_CNTRL=0x00;
  89.   
  90.   TIM1_ARRH=0xff;     //自動裝載最大值
  91.   TIM1_ARRL=0xff;
  92. }

  93. void Clock_Init(void)
  94. {
  95.   CLK_CKDIVR=0x00; //16M                  
  96. }

  97. void LED_ACT(void)                //延時時間太大會影響靈敏度
  98. {
  99.   LED=0;
  100.   delay_ms(10);
  101.   LED=1;
  102.   delay_ms(10);
  103. }

  104. u8 DeCode(void)
  105. {
  106.    u8  i,j;
  107.    u8 temp;    //暫存變量
  108.    for(i=0;i<4;i++)      //
  109.    {
  110.      for(j=0;j<8;j++)  //
  111.      {
  112.         temp=temp>>1;  //                                                               
  113.         
  114.         TIM1_CNTRH=0;
  115.         TIM1_CNTRL=0;
  116.         TIM1_CR1|=0x01;
  117.         
  118.         while(IR_IN==0);   //先判斷是否為0
  119.         TIM1_CR1=0x00;
  120.         
  121.         Counter_Time_H=TIM1_CNTRH;
  122.         Counter_Time_L=TIM1_CNTRL;      
  123.         LowTime=Counter_Time_H*256+Counter_Time_L;    //
  124.         
  125.         TIM1_CNTRH=0;
  126.         TIM1_CNTRL=0;
  127.         TIM1_CR1|=0x01;
  128.         
  129.         while(IR_IN==1);  //再判斷是否為1                          
  130.         TIM1_CR1=0x00;       
  131.         
  132.         Counter_Time_H=TIM1_CNTRH;
  133.         Counter_Time_L=TIM1_CNTRL;      
  134.         HighTime=Counter_Time_H*256+Counter_Time_L;      
  135.         
  136.         if((LowTime<420)||(LowTime>690))
  137.         return 0;                                      //太大或太小舍去                         
  138.         if((HighTime>460)&&(HighTime<660))            
  139.         temp=temp&0x7f;                                //"0"   560us+-100
  140.         if((HighTime>1480)&&(HighTime<1880))           
  141.         temp=temp|0x80;                                //"1"   1680us+-500
  142.     }                                     
  143.         a[i]=temp;                                                                                                                                                                                                               
  144.   }                                                    
  145. //  if(a[2]==~a[3])     
  146.          return 1;     
  147. }

  148. void two_2_bcd(u8 data)  //將二進制碼轉(zhuǎn)換為BCD碼
  149. {

  150.    u8 temp; //暫存
  151.    temp=data;
  152.    data&=0xf0;
  153.    data>>=4;                    
  154.    data&=0x0f;                  
  155.    if(data<=0x09)
  156.    {                 
  157.      Write_Data(0x30+data);    //顯示0-9        
  158.    }
  159.    else
  160.    {
  161.      data=data-0x09;
  162.      Write_Data(0x40+data);    //顯示A-F
  163.    }
  164.    data=temp;
  165.    data&=0x0f;
  166.    if(data<=0x09)
  167.    {
  168.      Write_Data(0x30+data);            
  169.    }
  170.    else
  171.    {
  172.      data=data-0x09;
  173.      Write_Data(0x40+data);
  174.    }
  175.    Write_Data(0x48);          //顯示“H”
  176. }

  177. void Disp_1(void) //顯示第二行:碼值
  178. {  
  179.     Write_Com(0x80+0x40);
  180.     two_2_bcd(a[0]);
  181.    
  182.     Write_Data(0x20); //空格
  183.     two_2_bcd(a[1]);
  184.    
  185.     Write_Data(0x20); //空格
  186.     two_2_bcd(a[2]);
  187.    
  188.     Write_Data(0x20); //空格
  189.     two_2_bcd(a[3]);
  190. }

  191. void Disp_2(void) //顯示第一行:固定字符
  192. {
  193.   u8 num; //
  194.   
  195.   Write_Com(0x80);
  196.   for(num=0;num<16;num++)
  197.   {
  198.     Write_Data(tab[num]);
  199.     delay_ms(5);
  200.   }
  201. }

  202. void CHECK_User(void)
  203. {
  204. //  if((a[0]==0x00)&&(a[1]==0xff)) //判別用戶碼及反碼
  205. //  {
  206.     LED_ACT();
  207. //  }
  208. }

  209. void main(void)
  210. {
  211.   asm("sim");//MAIN程序的優(yōu)先級配置為3級(關(guān)總中斷)
  212.   
  213.   GPIO_Init();
  214.   Clock_Init();
  215.   TIM1_Init();
  216.   LCD_Init();
  217. //  delay_ms(10);
  218.   
  219.   Write_Com(0x01); //清屏
  220.   
  221.   Disp_2();
  222.   
  223.   asm("rim");//MAIN程序的優(yōu)先級由3級降低至0級(開總中斷)
  224.   
  225.   while(1);//死循環(huán)
  226. }

  227. #pragma vector=0x07
  228. __interrupt void EXTI_PORTC_IRQHandler(void)
  229. {
  230.   PC_CR2_C21=0;//禁止PC0端口外部中斷
  231.   
  232.   TIM1_CNTRH=0;
  233.   TIM1_CNTRL=0;
  234.   TIM1_CR1=0x01;   //open timer1
  235.   
  236.   while(IR_IN==0);
  237.   TIM1_CR1=0x00;   //
  238.   
  239.   Counter_Time_H=TIM1_CNTRH;
  240.   Counter_Time_L=TIM1_CNTRL;   
  241.   LowTime=Counter_Time_H*256+Counter_Time_L;
  242.   
  243.   TIM1_CNTRH=0;         //
  244.   TIM1_CNTRL=0;         //
  245.   TIM1_CR1=0x01;         //
  246.       
  247.   while(IR_IN==1);   //
  248.   TIM1_CR1=0x00;        //   

  249.   Counter_Time_H=TIM1_CNTRH;
  250.   Counter_Time_L=TIM1_CNTRL;  
  251.   HighTime=Counter_Time_H*256+Counter_Time_L;
  252.   
  253.   if((LowTime>8500)&&(LowTime<9500)&&(HighTime>4000)&&(HighTime<5000))  //引導碼9000us+-500  4500us+-500
  254.   {
  255.     if(DeCode()==1)
  256.     {     
  257.       Disp_1();
  258.       CHECK_User();
  259.     }
  260.   }
  261.   
  262.   PC_CR2_C21=1;//使能PC0端口外部中斷
  263. }

  264. #pragma vector=0x0D
  265. __interrupt void TIM1_UPD_OVF_TRG_BRK_IRQHandler(void)
  266. {
  267.   TIM1_SR1&=0xfe;//清除溢出中斷標志位"UIF"  
  268. }
復制代碼

所有資料51hei提供下載:
hw-1602.rar (274.26 KB, 下載次數(shù): 65)

評分

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

查看全部評分

回復

使用道具 舉報

ID:59609 發(fā)表于 2021-6-1 08:33 | 顯示全部樓層
不錯,思路很重要
回復

使用道具 舉報

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

本版積分規(guī)則

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

Powered by 單片機教程網(wǎng)

快速回復 返回頂部 返回列表