找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5614|回复: 5
收起左侧

STM8红外程序(外中断接收)

[复制链接]
ID:268765 发表于 2017-12-29 11:04 | 显示全部楼层 |阅读模式
STM8红外程序
单片机源程序如下:
  1. #include "stm8s.h"
  2. #include "stm8s003f3p.h"
  3. #include "STM8_IR.h"
  4. #include "STM8_DELAY.h"

  5. #define IR_READ (PC_IDR&(0x01<<7))
  6. volatile uchar Flag_ir_start = 0;//启动标志位

  7. volatile uint IR_time = 0;

  8. volatile unsigned long IR_data;

  9. volatile uchar IR_temp[4];


  10. void LED_Init(void)
  11. {
  12.         PA_DDR |= (0x01<<3);//设置PA3为输出
  13.         PA_CR1 |= (0x01<<3);//设置PA3为推挽输出,速度为2MHz
  14.         PA_CR2 &=(uchar)(~(0x01<<3));
  15.        
  16.         PA_ODR &=(uchar)(~(0x01<<3)); //关闭led
  17. }


  18. void TIM1_Init(void)
  19. {
  20.         TIM1_CR1 = 0x00;  //向上的计数方向,中断计数不停
  21.    
  22.         TIM1_IER = 0x01;
  23.    
  24.         TIM1_PSCRH = 0x00;  //进行16分频
  25.         TIM1_PSCRL = 0x0f;  //16Mhz/(15+1)=1Mhz-->1us
  26.    
  27.         TIM1_ARRH = 0x00;
  28.         TIM1_ARRL = 20;   //20us
  29.    
  30.         TIM1_CR1 |=0x01;
  31.    
  32. }

  33. //外中断接收红外数据
  34. void EXIT_Init(void)
  35. {
  36.         //01是PA,23是PB,45是PC,67是PD引脚
  37.         //P?IS[1:0] 设置触发方式,00是下降沿触发
  38.         EXTI_CR1 &=(uchar)(~(0x03<<4));  // PC下降沿触发
  39.         EXTI_CR1 |= (0x01<<5);
  40. }

  41. void IR_Init(void)
  42. {
  43.        
  44.         PC_DDR &=(uchar)(~(0x01<<7));
  45.         PC_CR1 &=(uchar)(~(0x01<<7));
  46.         //PC_CR1 |= (0x01<<7);//上拉输入
  47.         PC_CR2 |= (0x01<<7);//打开外部中断
  48.     EXIT_Init();//RISING and falling EDGE

  49. }

  50. //位反转算法
  51. uchar reverse8( uchar c )
  52. {
  53.      c = ( c & 0x55 ) << 1 | ( c & 0xAA ) >> 1;
  54.      c = ( c & 0x33 ) << 2 | ( c & 0xCC ) >> 2;
  55.      c = ( c & 0x0F ) << 4 | ( c & 0xF0 ) >> 4;
  56.      return c;
  57. }

  58. void IR_rx(void)
  59. {
  60.         static uchar Flag_end=0;
  61.         static uchar IR_num = 0;
  62.        
  63.         uchar i,temp;
  64.        
  65.         //TIM1_CR1 &=(uchar)(~(0x01<<0));//关闭计数器
  66.        
  67.         TIM1_CR1 |= (0x01<<0);  //开启计数器
  68.        
  69.         //800us,17000us
  70.         if(IR_time<=40)////杂波
  71.         {
  72.                 IR_data=0;
  73.                 IR_num=0;
  74.                 IR_time=0;
  75.                
  76.                 //TIM1_CR1 &=(uchar)(~(0x01<<0));//关闭计数器
  77.                
  78.                 return ;
  79.         }
  80.         //13000us
  81.         if(IR_time >= 650)//13ms则启动成功
  82.         {
  83.                 Flag_ir_start = 1;
  84.                 IR_num = 0;
  85.                 IR_data=0;
  86.         }
  87.        
  88.         if((Flag_ir_start==1)&&(IR_time<=130))//2600us
  89.         {
  90.                
  91.                 IR_data<<=1;
  92.                 if(IR_time>=85)//1700us
  93.                 {
  94.                         IR_data |= (0x01<<0);
  95.                 }
  96.                 IR_num++;
  97.                 if(IR_num>31)
  98.                 {
  99.                         Flag_end = 1;
  100.                         Flag_ir_start=0;
  101.                         IR_time = 0;
  102.                 }
  103.         }
  104.        
  105.         if(Flag_end)
  106.         {
  107.                 Flag_end = 0;
  108.                
  109.                 TIM1_CR1 &=(uchar)(~(0x01<<0));//关闭计数器
  110.                
  111.                 IR_temp[0] = (uchar)((IR_data>>0)&0xff);
  112.                 IR_temp[1] = (uchar)((IR_data>>8)&0xff);
  113.                 IR_temp[2] = (uchar)((IR_data>>16)&0xff);
  114.                 IR_temp[3] = (uchar)((IR_data>>24)&0xff);
  115.                
  116.                 IR_data=0;
  117.                 IR_num=0;
  118.                
  119.                 if(IR_temp[0]!=(uchar)(~IR_temp[1]))
  120.                 {
  121.                         //校验失败
  122.                         //PA_ODR ^= (0x01<<3);
  123.                 }
  124.                 else
  125.                 {
  126.                         IR_temp[1] = reverse8(IR_temp[1]);//位反转算法
  127.                        
  128.                         if(IR_temp[1]==0x45)//0xa2
  129.                         {
  130.                                 //PA_ODR ^= (0x01<<3);
  131.                                 PA_ODR |= (0x01<<3);
  132.                         }
  133.                         if(IR_temp[1]==0x46)
  134.                         {
  135.                                 PA_ODR &=(uchar)(~(0x01<<3));
  136.                                 //PA_ODR |= (0x01<<3);
  137.                         }
  138.                         //PA_ODR &=(uchar)(~(0x01<<3));
  139.                 }
  140.                
  141.         }
  142.        
  143.         IR_time = 0;
  144. }

  145. @far @interrupt void EXTI_PORTC_IRQHandler(void)
  146. {
  147.         IR_rx();
  148. }


  149. //定时器1溢出中断服务
  150. @far @interrupt void timer1_isr(void)   //10us
  151. {
  152.         //TIM1_CR1 &=~(0x01<<0);  //关闭计数器
  153.         TIM1_SR1 &=~(0x01<<0);  //清除中断标志
  154.    
  155.         IR_time++;
  156.        
  157.     //TIM1_CR1 |= (0x01<<0);  //开启计数器
  158.    
  159.         //PA_ODR |= (0x01<<3);
  160.        
  161.         //return ;
  162. }



  163. /*
  164. void IR_rx(void)
  165. {
  166.         static uchar Flag_end=0;
  167.         static uchar IR_num = 0;
  168.        
  169.        
  170.         TIM1_CR1 &=(uchar)(~(0x01<<0));//关闭计数器
  171.        
  172.         //800us,17000us
  173.         if(IR_time<=80)////杂波
  174.         {
  175.                 IR_data=0;
  176.                 IR_num=0;
  177.                 IR_time=0;
  178.                 //PA_ODR ^= (0x01<<3);
  179.                 return ;
  180.         }//
  181.         //13000us
  182.         if(IR_time >= 1300)//13ms则启动成功
  183.         {
  184.                 Flag_ir_start = 1;
  185.                 IR_num = 0;
  186.                 IR_data=0;
  187.                 //
  188.                 //PA_ODR |= (0x01<<3);
  189.         }
  190.        
  191.         //
  192.         if((Flag_ir_start==1)&&(IR_time<=260))//2600us
  193.         {
  194.                
  195.                 IR_data<<=1;
  196.                 if(IR_time>=170)//1700us
  197.                 {
  198.                         IR_data |= (0x01<<0);
  199.                 }
  200.                 IR_num++;
  201.                 if(IR_num>31)
  202.                 {
  203.                         Flag_end = 1;
  204.                         Flag_ir_start=0;
  205.                        
  206.                         //PA_ODR ^= (0x01<<3);
  207.                        
  208.                 }
  209.                
  210.         }
  211.        
  212.         if(Flag_end)
  213.         {
  214.                 Flag_end = 0;
  215.                
  216.                 IR_temp[0] = (uchar)((IR_data>>0)&0xff);
  217.                 IR_temp[1] = (uchar)((IR_data>>8)&0xff);
  218.                 IR_temp[2] = (uchar)((IR_data>>16)&0xff);
  219.                 IR_temp[3] = (uchar)((IR_data>>24)&0xff);
  220.                
  221.                 IR_data=0;
  222.                 IR_num=0;
  223.                
  224.                 if(IR_temp[0]!=(uchar)(~IR_temp[1]))
  225.                 {
  226.                        
  227.                 }
  228.                 else
  229.                 {
  230.                         //PA_ODR ^= (0x01<<3);
  231.                        
  232.                        
  233.                         if(IR_temp[1]==0xa2)
  234.                         {
  235.                                 //PA_ODR ^= (0x01<<3);
  236.                                 PA_ODR |= (0x01<<3);
  237.                         }
  238.                         if(IR_temp[1]<0x7f)
  239.                         {
  240.                                 PA_ODR &=(uchar)(~(0x01<<3));
  241.                                 //PA_ODR |= (0x01<<3);
  242.                         }
  243.                         //PA_ODR &=(uchar)(~(0x01<<3));
  244.                 }
  245.                
  246.         }
  247.        
  248.         IR_time = 0;
  249.        
  250.         TIM1_CR1 |= (0x01<<0);//开计数器
  251. }*/

复制代码
  1. /********************************************\

  2.                    _ooOoo_
  3.                   o8888888o
  4.                   88" . "88
  5.                   (| -_- |)
  6.                   O\  =  /O
  7.                ____/`---'\____
  8.              .'  \\|     |//  `.
  9.             /  \\|||  :  |||//  \
  10.            /  _||||| -:- |||||-  \
  11.            |   | \\\  -  /// |   |
  12.            | \_|  ''\---/''  |   |
  13.            \  .-\__  `-`  ___/-. /
  14.          ___`. .'  /--.--\  `. . __
  15.       ."" '<  `.___\_<|>_/___.'  >'"".
  16.      | | :  `- \`.;`\ _ /`;.`/ - ` : | |
  17.      \  \ `-.   \_ __\ /__ _/   .-` /  /
  18. ======`-.____`-.___\_____/___.-`____.-'======
  19.                    `=---='
  20. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

  21.         佛祖保佑          永无BUG
  22.                                  
  23.                 楠A407舍长出品
  24.                                                        
  25. \********************************************/

  26. #include "stm8s.h"
  27. #include "stm8s003f3p.h"


  28. #include "STM8_IR.h"


  29. #define uchar unsigned char
  30. #define uint  unsigned int

  31. _Bool Flag_ir = 0;





  32. void STM8_CLK_Init(void)
  33. {
  34.    
  35.     CLK_HSICmd(ENABLE);//HSI = 16MHz
  36.    
  37.     CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1); //f_psc = 16MHz/1
  38.    
  39.    
  40. }

  41. //--------------------主函数分割线---------------------
  42. //
  43. //
  44. //-----------------------------------------------------
  45. void main(void)
  46. {
  47.         unsigned char re ;
  48.         unsigned char reg;
  49.        
  50.         _asm("sim");//关全部中断
  51.   
  52.         STM8_CLK_Init();//内部HSI,16MHz
  53.        
  54.         LED_Init();

  55.         IR_Init();
  56.        
  57.         TIM1_Init();
  58.        
  59.         _asm("rim");//开全部中断
  60.        
  61.         while(1)
  62.         {
  63.                
  64.                 //IR_test();
  65.                
  66.                
  67.         }
  68. }
复制代码

所有资料51hei提供下载:
STM8_IR_test.rar (4.02 MB, 下载次数: 79)

评分

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

查看全部评分

回复

使用道具 举报

ID:373 发表于 2018-4-26 10:42 | 显示全部楼层
学习下,不知道能不能用上
回复

使用道具 举报

ID:106794 发表于 2018-7-23 08:55 | 显示全部楼层
感谢分享
回复

使用道具 举报

ID:538350 发表于 2019-5-22 15:54 | 显示全部楼层
楼主程序不对呀
回复

使用道具 举报

ID:146191 发表于 2019-6-1 15:48 | 显示全部楼层
Null520 发表于 2019-5-22 15:54
楼主程序不对呀

是不对。。定时器是不是开早了。而且没见到差值或清0 CNTR
回复

使用道具 举报

ID:439389 发表于 2019-7-9 21:58 | 显示全部楼层
不错,学习学习!
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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