OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 103|回复: 8

求助,STM32F030C8T6芯片PB9(TIM17_CH1)作为红外输入引脚问题

[复制链接]

0

主题

5

帖子

0

精华

新手入门

积分
15
金钱
15
注册时间
2022-7-25
在线时间
9 小时
发表于 2025-1-8 14:18:13 | 显示全部楼层 |阅读模式
20金钱
本帖最后由 wangyong555828 于 2025-1-11 15:29 编辑

求助,新人学习,使用STM32F030C8T6芯片的PB9(TIM17_CH1)引脚作为红外遥控输入,遥控器测试,用示波器检测红外接收头VS1838B有波形输出,并核对波形符合红外遥控传输规律,就是芯片无响应,硬件检查连接正常,蜂鸣器在其他功能下动作正常,请各位老师指导点拨,万分感谢!!!
  1. void remoteInit(void)                              
  2. {  
  3.     GPIO_InitTypeDef GPIO_InitStructure;
  4.     NVIC_InitTypeDef NVIC_InitStructure;
  5.     TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;        //声明要放在前边
  6.     TIM_ICInitTypeDef  TIM_ICInitStructure;  

  7.     RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);         //使能AHB外设时钟  IO口
  8.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM17,ENABLE);        //TIM17 时钟使能
  9.         
  10.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;                                 //PB9 输入
  11.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
  12.     GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;    //上拉                ******输入模式和电路匹配******
  13. //    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;    //下拉        
  14.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;       //速度50MHZ  (1/2/3级对应2/10/50MHZ)
  15.     GPIO_Init(GPIOB, &GPIO_InitStructure);
  16.     GPIO_SetBits(GPIOB,GPIO_Pin_9);                        //初始化GPIOB.9   拉高
  17. //    GPIO_ResetBits(GPIOB, GPIO_Pin_9);                  //IO口拉低        

  18. //        GPIO_PinAFConfig(GPIOB, GPIO_PinSource9, GPIO_AF_2);        //复用模式才需要这句

  19.     TIM_TimeBaseStructure.TIM_Period = 10000; //设定计数器自动重装值 最大10ms溢出   1s/(48MHZ/48)*10000个数=0.01s
  20.     TIM_TimeBaseStructure.TIM_Prescaler =(48-1);         //预分频器,1M的计数频率,1us加1.         
  21.     TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim
  22.     TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
  23.    
  24.     TIM_TimeBaseInit(TIM17, &TIM_TimeBaseStructure); //根据指定的参数初始化TIMx

  25.     TIM_ICInitStructure.TIM_Channel = TIM_Channel_1;  // 选择输入端 IC1映射到TI1上
  26.     TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;        //上升沿捕获
  27.     TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
  28.     TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;         //配置输入分频,不分频
  29.     TIM_ICInitStructure.TIM_ICFilter = 0x03;//IC1F=0011 0x03  配置输入滤波器  8个定时器时钟周期滤波器   不用滤波器的话就是0
  30.     TIM_ICInit(TIM17, &TIM_ICInitStructure);//初始化定时器输入捕获通道

  31.     TIM_Cmd(TIM17,ENABLE );         //使能定时器17

  32.     NVIC_InitStructure.NVIC_IRQChannel = TIM17_IRQn;  //TIM17中断
  33.         NVIC_InitStructure.NVIC_IRQChannelPriority =0x03;               //优先级别
  34.     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
  35.     NVIC_Init(&NVIC_InitStructure);  //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器        

  36.     TIM_ITConfig( TIM17,TIM_IT_Update|TIM_IT_CC1,ENABLE);//允许更新中断 ,允许CC1捕获中断        
  37.         
  38. }


  39. /*-------------------------协议--------------------------

  40. 开始拉低9ms,接着是一个4.5ms的高脉冲,通知器件开始传送数据了
  41. 接着是发送4个8位二进制码,第一二个是遥控识别码(REMOTE_ID=0),第一个为
  42. 正码(0),第二个为反码(255),接着两个数据是键值,第一个为正码
  43. 第二个为反码.发送完后40ms,遥控再发送一个9ms低,2ms高的脉冲,
  44. 表示按键的次数,出现一次则证明只按下了一次,如果出现多次,则可
  45. 以认为是持续按下该键.
  46. NEC协议:引导码(低9ms+高4.5ms)+用户码(8位)+用户码反码(8位)+键码(8位)+键码反码(8位)+连发码
  47. ---------------------------------------------------------*/
  48. /******收到同步码(引导码),就将[7]RmtSta=1,开始解析后边数据,解析完后边没有连发码,就将[7]RmtSta=0,方便下次再次接收数据,此次按键结束*******************/
  49. //遥控器接收状态  u8 RmtSta=0;   
  50. //[7]:收到了引导码标志(同步码)  
  51. //[6]:得到了一个按键的所有信息,数据解析完的话,就把[6]=1  
  52. //[5]:保留        
  53. //[4]:标记上升沿是否已经被捕获         捕获上升沿时标1,之后捕获下降沿时清0                                                            
  54. //[3:0]:溢出计时器       10ms溢出一次,就RmtCnt++
  55. u8         RmtSta=0;        //遥控器接收状态              
  56. u16 Dval;                //下降沿时计数器的值   
  57. u32 RmtRec=0;        //红外接收到的数据                       
  58. u8  RmtCnt=0;        //按键按下的次数(连发码的次数)         
  59. //定时器17中断服务程序         
  60. void TIM17_IRQHandler(void)
  61. {                              

  62.         if(TIM_GetITStatus(TIM17,TIM_IT_Update)!=RESET) //更新定时器中断,实际上是溢出 10ms  正常按键时,无论引导码、用户码、键码的高电位时间都不超过10ms,只要操过,要么是连发码,要么就是没有按键按下
  63.         {
  64.                 if(RmtSta&0x80)                                                                //上次有数据被接收到了时位[7]=1  0x80 对应二进制1000 0000
  65.                 {        
  66.                         RmtSta&=~0X10;                                                        //取消上升沿已经被捕获标记  ~0X10=~(0001 0000)=1110 1111    计算结果,相当于位[4]=0,其他位保持不变
  67.                         if((RmtSta&0X0F)==0X00)        RmtSta|=1<<6;        //标记已经完成一次按键的键值信息采集  1<<6 = 100 0000    计算结果,位[6]=1
  68.                         if((RmtSta&0X0F)<14)        RmtSta++;       //连发码的时间约130ms,10ms一次中断,计数13次,此处用<14来指13
  69.                         else                                    //超过130ms,说明按键已经松开了
  70.                         {
  71.                                 RmtSta&=~(1<<7);                                        //清空引导标识        位[7]=0
  72.                                 RmtSta&=0XF0;                                                //清空计数器        位[3:0] =0000
  73.                         }                                                                                    
  74.                 }                                                            
  75.         }
  76.         if(TIM_GetITStatus(TIM17,TIM_IT_CC1)!=RESET)    //捕获中断  要么捕获上升沿,要么捕获下降沿
  77.         {         
  78.                 if(RDATA)//上升沿捕获    #define RDATA         PBin(9)                 //红外数据输入脚
  79.                 {
  80.                           TIM_OC1PolarityConfig(TIM17,TIM_ICPolarity_Falling);                        //CC1P=1        设置为下降沿捕获
  81.                         TIM_SetCounter(TIM17,0);                                                        //清空定时器值
  82.                         RmtSta|=0X10;                                                        //标记上升沿已经被捕获
  83.                 }else //下降沿捕获
  84.                 {
  85.                         Dval=TIM_GetCapture1(TIM17);                                        //读取CCR1也可以清CC1IF标志位
  86.             TIM_OC1PolarityConfig(TIM17,TIM_ICPolarity_Rising);                                //CC1P=0        设置为上升沿捕获
  87.                         if(RmtSta&0X10)                                                        //完成一次高电平捕获  
  88.                         {
  89.                                  if(RmtSta&0X80)//判断之前是否接收到了引导码                接受了引导码,开始组合接收到的数据,一位一位拼合在一起,放在RmtRec中
  90.                                 {
  91.                                        
  92.                                         if(Dval>300&&Dval<800)                        //560为标准值,560us                接收到0
  93.                                         {
  94.                                                 RmtRec<<=1;                                        //左移一位.
  95.                                                 RmtRec|=0;                                        //接收到0           
  96.                                         }else if(Dval>1400&&Dval<1800)        //1680为标准值,1680us        接收到1
  97.                                         {
  98.                                                 RmtRec<<=1;                                        //左移一位.
  99.                                                 RmtRec|=1;                                        //接收到1
  100.                                         }else if(Dval>2200&&Dval<2600)        //得到按键键值增加的信息 2500为标准值2.5ms  连发码
  101.                                         {
  102.                                                 RmtCnt++;                                         //按键次数增加1次
  103.                                                 RmtSta&=0XF0;                                //清空计时器               
  104.                                         }
  105.                                  }else if(Dval>4200&&Dval<4700)                //判断目前是否接受引导码,Dval宽度为4500为标准值4.5ms,  
  106.                                 {
  107.                                         RmtSta|=1<<7;                                        //标记成功接收到了引导码        结果是保证第7位为1,其他不管
  108.                                         RmtCnt=0;                                                //清除按键次数计数器
  109.                                 }                                                
  110.                         }
  111.                         RmtSta&=~(1<<4);        //1<<4 = 0001 0000   ~(1<<4)=1110 1111  结果是保证第4位为0,其他不管
  112.                 }                                                                                                            
  113.         }
  114.         TIM_ClearITPendingBit(TIM17,TIM_IT_Update|TIM_IT_CC1);                 //清楚TIM17的定时器更新中断或者捕获中断   
  115. }

  116. //处理红外键盘
  117. //返回值:
  118. //         0,没有任何按键按下
  119. //其他,按下的按键键值.
  120. u8 Remote_Scan(void)
  121. {        
  122.         u8 sta=0;      
  123.     u8 t1,t2;  
  124.         if(RmtSta&(1<<6))                                                //得到一个按键的所有信息了  1<<6  =  0100 0000 结果是保证第6位,其他不管
  125.         {
  126.             t1=RmtRec>>24;                                                //得到地址码
  127.             t2=(RmtRec>>16)&0xff;                                //得到地址反码
  128.              if((t1==(u8)~t2)&& t1==REMOTE_ID)        //检验遥控识别码(ID)及地址
  129.             {
  130.                 t1=RmtRec>>8;                                        //u8数据,高于8位的数据自动丢失
  131.                 t2=RmtRec;         
  132.                 if(t1==(u8)~t2)sta=t1;                        //键值正确         
  133.                 }   
  134.                 if((sta==0)||((RmtSta&0X80)==0))        //按键数据错误/遥控已经没有按下了
  135.                 {
  136.                          RmtSta&=~(1<<6);                                //清除接收到有效按键标识
  137.                         RmtCnt=0;                                                //清除按键次数计数器
  138.                 }
  139.         }  
  140.     return sta;
  141. }

  142. __task void taskRemote(void)
  143. {
  144.     u8 key;
  145.    
  146.     while(1)
  147.     {
  148.         key = Remote_Scan();
  149.                 if(key != 0 )
  150.                 {         
  151.          
  152.                         switch(key)
  153.                         {
  154.                                 case 128:
  155.                                 {
  156.                                         BUZZER = BUZZER_ON;
  157.                                         os_dly_wait(500);
  158.                                         BUZZER = BUZZER_OFF;
  159.                                         os_dly_wait(500);
  160.                                         BUZZER = BUZZER_ON;
  161.                                         os_dly_wait(500);
  162.                                         BUZZER = BUZZER_OFF;
  163.                                         os_dly_wait(500);
  164.                                         BUZZER = BUZZER_ON;
  165.                                         os_dly_wait(500);
  166.                                         BUZZER = BUZZER_OFF;                                
  167.                                 }break;                           
  168.                                 case 88:
  169.                                 {
  170.                                         BUZZER = BUZZER_ON;
  171.                                         os_dly_wait(500);
  172.                                         BUZZER = BUZZER_OFF;
  173.                                         os_dly_wait(500);
  174.                                         BUZZER = BUZZER_ON;
  175.                                         os_dly_wait(500);
  176.                                         BUZZER = BUZZER_OFF;
  177.                                         os_dly_wait(500);
  178.                                         BUZZER = BUZZER_ON;
  179.                                         os_dly_wait(500);
  180.                                         BUZZER = BUZZER_OFF;                                
  181.                                 }break;
  182.                         }
复制代码


正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

0

主题

5

帖子

0

精华

新手入门

积分
15
金钱
15
注册时间
2022-7-25
在线时间
9 小时
 楼主| 发表于 2025-1-8 14:23:58 | 显示全部楼层
本帖最后由 wangyong555828 于 2025-1-8 14:37 编辑

一直在分析原因,尝试更换其他引脚,也尝试了更换其他遥控器,都不行,初始化有问题?还是中断程序问题?
回复

使用道具 举报

0

主题

5

帖子

0

精华

新手入门

积分
15
金钱
15
注册时间
2022-7-25
在线时间
9 小时
 楼主| 发表于 2025-1-9 10:12:38 | 显示全部楼层
本帖最后由 wangyong555828 于 2025-1-9 16:03 编辑

程序也是参照原子哥的,至于接收到的用户名和键码,我上传一张一个开关键的示波器图示,我核对了图示,是符合NEC协议:引导码(低9ms+高4.5ms)+用户码(8位)+用户码反码(8位)+键码(8位)+键码反码(8位)   开关机键示波器图示.jpg
回复

使用道具 举报

0

主题

5

帖子

0

精华

新手入门

积分
15
金钱
15
注册时间
2022-7-25
在线时间
9 小时
 楼主| 发表于 2025-1-9 10:53:32 | 显示全部楼层
从示波器分析波形对应 引导码+用户码0000 0001+用户反码1111 1110 +键码1000 0000+键码反码0111 1111
回复

使用道具 举报

0

主题

5

帖子

0

精华

新手入门

积分
15
金钱
15
注册时间
2022-7-25
在线时间
9 小时
 楼主| 发表于 2025-1-10 17:07:24 | 显示全部楼层
路过的老师指导一下?或者同道的伙伴一起分析一下
回复

使用道具 举报

8

主题

540

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2845
金钱
2845
注册时间
2016-5-13
在线时间
180 小时
发表于 昨天 18:05 | 显示全部楼层
1、波形和数据顺序是反的。你检测的时候比如看示波器是111000,数据检测的管脚读上来的是000111。这个你要注意。
2、外部中断只是检测有上升沿或者下降沿。实际判断是要在定时器里加switch的。就是就是检测到开始的头,就要改变switch的case跳转。
3、main的while里的delay要优化,这牵扯到中断优先级。不能让delay抢占了红外的中断。
4、tim7里不能有检查管脚的操作。你看你写了多少。逻辑不对哦。比如中断里有检查下降沿来了,就让switch(step),这里全局的step=1。(默认是0)
  当step延时1ms 和9ms后 再看下中断有来没有,这个要看下时间差。所以你的定时器至少要是0.1ms的单位,0.01ms更好。
虽然不明白你们在说什么,但感觉很厉害的样子。
回复

使用道具 举报

8

主题

540

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2845
金钱
2845
注册时间
2016-5-13
在线时间
180 小时
发表于 昨天 18:17 | 显示全部楼层
Ir_decode.h
/*
******************************************************************************
*
*        模块名称 : 红外遥控解码
*
******************************************************************************
*/

#ifndef __IR_DECODE_H__
#define __IR_DECODE_H__

#include "stm8s.h"

//typedef  unsigned char u8;
//typedef  unsigned int u16;
//typedef  unsigned long int u32;

//红外遥控识别码(ID)

//#define REMOTE_ID 2     

                /*
02BE
03 01/02 07
    15
17 14 18
    16


NEC1=18e9
04      08

    b8
be  17  ba
    bc
25     46
  49 48
       
01/02     03
                 04
05   06   07
     08
09   10   11
     12
               
*/


#define Ir_Power          0x09
#define Ir_Home           0x51
#define Ir_Up             0x45
#define Ir_Left           0x0C
#define Ir_Ok             0x46
#define Ir_Right          0x52
#define Ir_Down           0x1B
#define Ir_Return         0x12
#define Ir_NoVol          0x1E
#define Ir_Menu           0x1D
#define Ir_SubVol         0x5D
#define Ir_AddVol         0x0D
#define Ir_F1             0x07
#define Ir_F2             0x17

#define IR_REPEAT_NUM     3
      

extern u8 Ir_Status;
extern u8 Ir_Receive_Count;
extern u8 Ir_receive_ok;
extern u32 Ir_Receive_Data;
extern u8 Ir_Repeat_Count;

extern u8 Ir_menu_ok;
extern u8 Ir_Power_flag;
extern uint8_t key_val;
//extern uint8_t key_val_test;

//extern u32 just_for_test;

u8 reverse8( u8 c );
//u8 Remote_Scan(void);
void Ir_Init(void);
u8 Ir_Process(void);
void Ir_Receive_Handle(void);
void TIM_IT_Updata_Handdle(void);
void Ir_handle(void);

#endif









虽然不明白你们在说什么,但感觉很厉害的样子。
回复

使用道具 举报

8

主题

540

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2845
金钱
2845
注册时间
2016-5-13
在线时间
180 小时
发表于 昨天 18:17 | 显示全部楼层
Ir_decode.c
/*
******************************************************************************
*
*        模块名称 : 红外遥控解码
*
   引导码   地址码   地址反码   数据码  数据反码
\ 9+4.5ms \ c0-c07 \ c0-c07 \ c0-c07 \ c0-c07 \
******************************************************************************
*/
#include "IO_config.h"
#include "ir_decode.h"
#include "uart1.h"
#include "timer.h"
#include "stm8s_exti.h"
//#include "stm8s_iwdg.h"
//#include "iwdg.h"

u8 Ir_Status=0;                 //红外接收处理状态
u8  Ir_Receive_Count=0;         //红外接收数据位计数
u32 Ir_Receive_Data=0;          //32位的红外接收数据
u8 Ir_Repeat_Count=0;
u8 Ir_receive_ok=0;             //红外接收完成标志
//u32 just_for_test=0;
//u8 Address_1=0;
u8 Ir_Power_flag=0;
u8 Ir_menu_ok=0;
u8 key_val=0;

void TIM2_init(void)
{
//        TIM2_DeInit();
    TIM2->CR1 = (uint8_t)TIM2_CR1_RESET_VALUE;
    TIM2->IER = (uint8_t)TIM2_IER_RESET_VALUE;
    TIM2->SR2 = (uint8_t)TIM2_SR2_RESET_VALUE;

    /* Disable channels */
    TIM2->CCER1 = (uint8_t)TIM2_CCER1_RESET_VALUE;
    TIM2->CCER2 = (uint8_t)TIM2_CCER2_RESET_VALUE;


    /* Then reset channel registers: it also works if lock level is equal to 2 or 3 */
    TIM2->CCER1 = (uint8_t)TIM2_CCER1_RESET_VALUE;
    TIM2->CCER2 = (uint8_t)TIM2_CCER2_RESET_VALUE;
    TIM2->CCMR1 = (uint8_t)TIM2_CCMR1_RESET_VALUE;
    TIM2->CCMR2 = (uint8_t)TIM2_CCMR2_RESET_VALUE;
    TIM2->CCMR3 = (uint8_t)TIM2_CCMR3_RESET_VALUE;
    TIM2->CNTRH = (uint8_t)TIM2_CNTRH_RESET_VALUE;
    TIM2->CNTRL = (uint8_t)TIM2_CNTRL_RESET_VALUE;
    TIM2->PSCR = (uint8_t)TIM2_PSCR_RESET_VALUE;
    TIM2->ARRH  = (uint8_t)TIM2_ARRH_RESET_VALUE;
    TIM2->ARRL  = (uint8_t)TIM2_ARRL_RESET_VALUE;
    TIM2->CCR1H = (uint8_t)TIM2_CCR1H_RESET_VALUE;
    TIM2->CCR1L = (uint8_t)TIM2_CCR1L_RESET_VALUE;
    TIM2->CCR2H = (uint8_t)TIM2_CCR2H_RESET_VALUE;
    TIM2->CCR2L = (uint8_t)TIM2_CCR2L_RESET_VALUE;
    TIM2->CCR3H = (uint8_t)TIM2_CCR3H_RESET_VALUE;
    TIM2->CCR3L = (uint8_t)TIM2_CCR3L_RESET_VALUE;
    TIM2->SR1 = (uint8_t)TIM2_SR1_RESET_VALUE;

//  TIM2_TimeBaseInit(TIM2_PRESCALER_16, 60000); //定时器设置1M的计数频率,1US的分辨率
  /* Set the Prescaler value */
        TIM2->PSCR = (uint8_t)(TIM2_PRESCALER_16);
        /* Set the Autoreload value */
        TIM2->ARRH = (uint8_t)(60000 >> 8);
        TIM2->ARRL = (uint8_t)(60000);
               
//  TIM2_ClearFlag(TIM2_FLAG_UPDATE);
        TIM2->SR1 = (uint8_t)(~((uint8_t)(TIM2_FLAG_UPDATE)));
        TIM2->SR2 = (uint8_t)(~((uint8_t)((uint8_t)TIM2_FLAG_UPDATE >> 8)));
       
  /* Enable update interrupt (使能更新中断)*/
//  TIM2_ITConfig(TIM2_IT_UPDATE, ENABLE);
  TIM2->IER |= (uint8_t)TIM2_IT_UPDATE;
  /* Disable TIM2 */
  //TIM2_Cmd(DISABLE);
//        TIM2_Cmd(ENABLE);
        TIM2->CR1 |= (uint8_t)TIM2_CR1_CEN;
       
}
/*
********************************************************************************
            定时器溢出中断内处理
********************************************************************************
*/
void TIM_IT_Updata_Handdle(void)
{
    Ir_Status=0;
//    TIM2_ClearITPendingBit(TIM2_IT_UPDATE);
                TIM2->SR1 = (uint8_t)(~TIM2_IT_UPDATE);
//    TIM2_SetCounter(0);
                TIM2->CNTRH = 0;
                TIM2->CNTRL = 0;
//    TIM2_Cmd(DISABLE);
                TIM2->CR1 &= (uint8_t)(~TIM2_CR1_CEN);
}
/*
********************************************************************************
                          红外解码初始化函数
********************************************************************************
*/
void Ir_Init(void)
{
  GPIO_Init(GPIOD, GPIO_PIN_4, GPIO_MODE_IN_PU_IT);                      // 配置引脚上拉中断输入
  //EXTI_SetExtIntSensitivity(EXTI_PORT_GPIOD, EXTI_SENSITIVITY_FALL_ONLY);// 下降沿中断
       
        EXTI->CR1 &= (uint8_t)(~EXTI_CR1_PDIS);
        EXTI->CR1 |= (uint8_t)((uint8_t)(EXTI_SENSITIVITY_FALL_ONLY) << 6);
       
  EXTI->CR2 &= (uint8_t)(~EXTI_CR2_PEIS);
        EXTI->CR2 |= (uint8_t)(EXTI_SENSITIVITY_FALL_ONLY);
  TIM2_init();
}

//位反转算法
u8 reverse8( u8 c )
{
     c = ( c & 0x55 ) << 1 | ( c & 0xAA ) >> 1;
     c = ( c & 0x33 ) << 2 | ( c & 0xCC ) >> 2;
     c = ( c & 0x0F ) << 4 | ( c & 0xF0 ) >> 4;
     return c;
}

  //u8 Address_H,Address_L;       //地址码,地址反码
  //u8 Data_H,Data_L;             //数据码,数据反码
       
/*
********************************************************************************
                          红外接收数据处理函数
********************************************************************************
*/
u8 Ir_Process(void)
{
  u8 Ir_num=0;                  //最终处理后的键值返回值
  u8 Address_H,Address_L;       //地址码,地址反码
  u8 Data_H,Data_L;             //数据码,数据反码
  
  if(Ir_receive_ok==1)          //接收完成
        {
                Address_H=Ir_Receive_Data>>24;              //得到地址码
                Address_H=reverse8(Address_H);
                Address_L=(Ir_Receive_Data>>16)&0xff;       //得到地址反码
                Address_L=reverse8(Address_L);
                //if((Address_H==(u8)~Address_L)&&(Address_H==REMOTE_ID))//检验遥控识别码(ID)及地址
                //if((Address_H==(u8)~Address_L))// 检验遥控识别码(ID)及地址
    //  检验遥控识别码(ID)及地址
                // 1011 1110  0000 0010
                if((Address_H==0x35)&&(Address_L==0xCA))
                {
                        Data_H=Ir_Receive_Data>>8;              //得到数据码
                        Data_L=Ir_Receive_Data;                 //得到数据反码
                        Data_H=reverse8(Data_H);
                        Data_L=reverse8(Data_L);
                        if(Data_H==(u8)~Data_L)                 //接收数据码正确
                        {
                                Ir_num=Data_H;                        //正确键值
                                Ir_receive_ok=0;
                        }
                }
        }
   return  Ir_num;      //返回键值
}

/*
********************************************************************************
                          红外接收中断处理函数
********************************************************************************
*/
void Ir_Receive_Handle(void)
{
  u16 Interval_tim=0;//两个下降沿间隔时间
  //IWDG_feed();
  switch(Ir_Status)
        {
    case 0://第一个下降沿,定时器开始计数
                        //TIM2_Cmd(DISABLE);
                        TIM2->CR1 &= (uint8_t)(~TIM2_CR1_CEN);
                        Ir_Status=1;
                        //TIM2_Cmd(ENABLE);
                        TIM2->CR1 |= (uint8_t)TIM2_CR1_CEN;
                        //TIM2_SetCounter(0);                 //定时器计数值清零
                        TIM2->CNTRH = 0;
                        TIM2->CNTRL = 0;
                        break;
    case 1://第二个下降沿,定时器关闭,读取定时器计数值
                        //TIM2_Cmd(DISABLE);
                        TIM2->CR1 &= (uint8_t)(~TIM2_CR1_CEN);
                        Interval_tim=0;
                        //Interval_tim=TIM2_GetCounter();     //读取定时器计数值
                        Interval_tim =  ((uint16_t)TIM2->CNTRH << 8);
                        Interval_tim += (uint16_t)(TIM2->CNTRL);
                        //TIM2_SetCounter(0);                 //定时器计数值清零
                        TIM2->CNTRH = 0;
                        TIM2->CNTRL = 0;
                        //TIM2_Cmd(ENABLE);
                        TIM2->CR1 |= (uint8_t)TIM2_CR1_CEN;
                        //if( (Interval_tim>=9000)&&(Interval_tim<=14500) )//9.0<x<14.5
                        if((Interval_tim>=12500)&&(Interval_tim<=14500))//判断引导码是否正确9+4.5ms
                        {
                                Ir_Status=2;                    //进入下一状态
                        }
                       
                        else if((Interval_tim>=5000)&&(Interval_tim<12500))//判断引导码是否正确9+2.25ms
                        {
                                Ir_Status=0;
                                Ir_Receive_Count=0;
                                //if(Ir_Power_flag){
                                Ir_Repeat_Count=IR_REPEAT_NUM;
                                //}
                        }
                       
                        else                              //引导码错误,从新接收
                        {
                                Ir_Status=0;
                                Ir_Receive_Count=0;
                                Ir_Repeat_Count=IR_REPEAT_NUM;
                        }
                        break;
    case 2://进入32位数据接收
                        //TIM2_Cmd(DISABLE);
                        TIM2->CR1 &= (uint8_t)(~TIM2_CR1_CEN);
                        Interval_tim=0;
                        //Interval_tim=TIM2_GetCounter();
                        Interval_tim =  ((uint16_t)TIM2->CNTRH << 8);
                        Interval_tim += (uint16_t)(TIM2->CNTRL);
                        //TIM2_SetCounter(0);
                        TIM2->CNTRH = 0;
                        TIM2->CNTRL = 0;
                        //TIM2_Cmd(ENABLE); //Enable TIM2
                        TIM2->CR1 |= (uint8_t)TIM2_CR1_CEN;
                        if(Ir_Receive_Count<31)
                        {
                                if((Interval_tim>=1000)&&(Interval_tim<=1300))     //间隔1.12ms ->0
                                {
                                        Ir_Receive_Data=Ir_Receive_Data<<1;
                                        Ir_Receive_Count++;
                                }
                                else if( (Interval_tim>=2000)&&(Interval_tim<=2600))//间隔2.25ms ->1
                                {
                                        Ir_Receive_Data=Ir_Receive_Data<<1;
                                        Ir_Receive_Data=Ir_Receive_Data|0x0001;
                                        Ir_Receive_Count++;
                                }
                                else//不是0,1 接收错误,从新接收
                                {
                                        Ir_Status=0;
                                        Ir_Receive_Data=0;
                                        Ir_Receive_Count=0;
                                }
                                break;  
                        }
                        else//超出接收数据位数,接收下一个
                        {
                                if((Interval_tim>=1000)&&(Interval_tim<=1300))     //间隔1.12ms ->0
                                {
                                        Ir_Receive_Data=Ir_Receive_Data<<1;
                                        Ir_Receive_Count++;
                                }
                                else if( (Interval_tim>=2000)&&(Interval_tim<=2600))//间隔2.25ms ->1
                                {
                                        Ir_Receive_Data=Ir_Receive_Data<<1;
                                        Ir_Receive_Data=Ir_Receive_Data|0x0001;
                                        Ir_Receive_Count++;
                                }
                                else//不是0,1 接收错误,从新接收
                                {
                                        Ir_Status=0;
                                        Ir_Receive_Data=0;
                                        Ir_Receive_Count=0;
                                        break;
                                }
                               
                                Ir_receive_ok=1;//红外接收完成
                                Ir_Status=0;
                                Ir_Receive_Count=0;
                                break;
                        }
                        break;
    default :
                                break;
        }
}
/*
#define Ir_Power          0x09
#define Ir_Home           0x51
#define Ir_Up             0x45
#define Ir_Left           0x0C
#define Ir_Ok             0x46
#define Ir_Right          0x52
#define Ir_Down           0x1B
#define Ir_Return         0x12
#define Ir_NoVol          0x1E
#define Ir_Menu           0x1D
#define Ir_SubVol         0x5D
#define Ir_AddVol         0x0D
#define Ir_F1             0x07
#define Ir_F2             0x17
*/
u8 hextoasc(u8 dat)
{
        if(dat>9)return dat+0x37;
        else return dat+0x30;
}

void Ir_handle()
{
        if(Ir_receive_ok == 1) //一帧红外数据接收完成
        {
                        key_val = Ir_Process();
                        Ir_receive_ok=0;
        }
        if(key_val!=0){
                if(Ir_Power_flag){
                        Ir_Power_flag=0;
                        GPIO_WriteHigh(PWN_CTL_GPIO, PWN_CTL_PIN);
                }
               
                switch(key_val)
                {
                        case Ir_Power:
                                Ir_Power_flag=1;
                                Ir_Repeat_Count=IR_REPEAT_NUM;
                                GPIO_WriteLow(PWN_CTL_GPIO, PWN_CTL_PIN);
                                //Power_step=10;
                        break;/*
                        case Ir_Home:
                        break;
                        case Ir_Up:
                        break;
                        case Ir_Left:
                        break;
                        case Ir_Ok:
                        break;
                        case Ir_Right:
                        break;
                        case Ir_Down:
                        break;
                        case Ir_Return:
                        break;
                        case Ir_NoVol:
                        break;
                        case Ir_Menu:
                        break;
                        case Ir_SubVol:
                        break;
                        case Ir_AddVol:
                        break;
                        case Ir_F1:
                        break;
                        case Ir_F2:
                        break;*/
                        default:
                        uart1_TX_buf[0]='#';
                        uart1_TX_buf[1]='K';
                        uart1_TX_buf[2]=':';
                        uart1_TX_buf[3]=hextoasc(key_val>>4);
                        uart1_TX_buf[4]=hextoasc(key_val&0x0f);
                        uart1_TX_buf[5]='$';
                        uart1_data(uart1_TX_buf,6);
                        break;                       
                }
                key_val=0;       
        }
}




/*

INTERRUPT_HANDLER(EXTI_PORTD_IRQHandler, 6)
{
  Ir_Receive_Handle();
  
}

INTERRUPT_HANDLER(TIM2_UPD_OVF_BRK_IRQHandler, 13)
{        
   TIM_IT_Updata_Handdle();
}

*/













虽然不明白你们在说什么,但感觉很厉害的样子。
回复

使用道具 举报

8

主题

540

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2845
金钱
2845
注册时间
2016-5-13
在线时间
180 小时
发表于 昨天 18:22 | 显示全部楼层
源码给你了,你自己捣鼓一下吧。
虽然不明白你们在说什么,但感觉很厉害的样子。
回复

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-1-18 18:59

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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