找回密码
 立即注册

QQ登录

只需一步,快速开始

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

STM8S单片机红外接收解码程序 带1602显示

[复制链接]
跳转到指定楼层
楼主
这几天在网上找了很多关于红外接收解码的程序,但都不是很理想。一般都是用延时来作为0和1的数据,或者注释不是很详细的,所以自己鼓捣了一个。
本程序是采用外部中断加定时器1来实现红外解码,STM8S单片机ABCD口都可作为外部中断,使用的遥控器为市面上大多数的。
需要的朋友们可以作为参考。

制作出来的实物图如下:


单片机源程序如下:
  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]; //存放码值 分别为用户码 用户反码 数据码 数据反码

  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为仅下降沿触发

  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)  //将二进制码转换为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程序的优先级配置为3级(关总中断)
  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程序的优先级由3级降低至0级(开总中断)
  224.   
  225.   while(1);//死循环
  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, 下载次数: 65)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

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

使用道具 举报

沙发
ID:59609 发表于 2021-6-1 08:33 | 只看该作者
不错,思路很重要
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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