STM8 捕获模式HS0038 红外遥控解码

本文介绍了一次使用STM8S003芯片进行红外遥控解码的实践过程,详细记录了从选择芯片、初始化定时器到实现NEC协议解码的全部步骤。文章深入探讨了采用TIM1捕获信号下降沿和TIM2记录空闲时间的方法,以完成对遥控信号的准确解码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

123

 

天热了坐着就不站着、躺着就不坐着,风扇手动换挡简直很要命,某宝买了一个遥控改装后按键失去作用了很不爽,于是自己换芯片改装呗,第一次做红外遥控不知所措,百度一堆解码过程最多的就是使用定时器判断解码 ,后来找到一种简单的解码就是通过PWM输入捕获,判断两个下降沿的宽度完成解码,标准NEC协议则是 同步(9+4.5ms) 、数据1 (2.25ms),数据 0(1.12ms),具体可参考协议。

于是开搞了 第一次用了PIC16F616 做完发现芯片内存不够,于是转STM8S003 ,记录一下调试代码:

方法则是采用TIM1 捕获信号的下降沿 ,TIM2 则记录输入空闲时间 ,当超过设定空闲时间后认为当前帧已经结束了(有的遥控发出的信息会多2bit ,至今不明原因所以采用此方法)

#include "time.h"
#include "iostm8s003f3.h"
#include "sys.h"

#define      CAPSIZEMAX         100
uint16_t captureint[CAPSIZEMAX]={0}; 
uint8_t  capcount =0;
uint8_t  lastcapcount =0;
uint16_t caplasttiak =0;

void time_s_init(void)//tim2
{
  TIM2_IER = 0x00;
 //分频值(1024分频)16MHZ / 1024 = 15,625HZ,fCK_CNT =fCK_PSC / 2 ^(PSCR[3:0])
  TIM2_PSCR =0xf;//15 ,16Mhz /32768 =?488.28125? hz = 2.048ms
  // 最大计数时间 :2.048ms *65536 =134.217秒
  TIM2_CNTRH =0;
  TIM2_CNTRL=0;
  TIM2_CR1 |= 0x01;//enable timer2
  TIM2_SR1 = 0; // 清除更新中断   
}
void Timer1CaptureInit(void)
{
  TIM1_CNTRH = 0x00;//清零计数器高8位
  TIM1_CNTRL = 0x00;//清零计数器低8位
  //计数器的时钟频率(fCK_CNT)等于fCK_PSC/( PSCR[15:0]+1)
  //16Mhz / =16 =1Mhz =1us
  TIM1_PSCRH = 0x00;//计数器时钟分频高8位
  TIM1_PSCRL = 0x0F;//计数器时钟分频低8位15+1分频
  TIM1_CCER2 &= (unsigned char)~0x01;//清零TIM1_CCER3中的CC3E位,之后才可配置TIM1_CCMR3
  TIM1_CCMR3 = 0x01;//配置TIM1_CCMR3中的CC1S位为1,CC3通道配置为输入,IC3映射到TI3FP1上
  //无滤波器、无预分频器(捕获输入口上检测到的每一个边沿都触发一次捕获)
  TIM1_CCER2 |= 0x02;//下降沿触发
  TIM1_IER |= 0x08;//CC3IE=1,使能捕获/比较3中断
  TIM1_CCER2 |= 0x01;//捕获使能
  TIM1_CR1 |= 0x01;//使能定时/计数器
}
//软件解码
#define		SYNC_L		(13558-200)//13558
#define		SYNC_H		(13558+200)
#define		LOW_L		(1135-200)
#define		LOW_H		(1135+200)//1135
#define		HIGH_L		(2243-200)
#define		HIGH_H		(2243+200)//2243
uint8_t IRDACMD(uint8_t *ret)
{
	uint8_t tempbuf[4]={0};
	uint8_t i,j,retv=0;
	uint16_t det,CUR;
        uint16_t *src=captureint;
        if(lastcapcount!=capcount)//收到数据。。
        {
          CUR =TIM2_CNTRH;
          CUR<<=8;
          CUR|=TIM2_CNTRL;//得到现在时间 
          det = (CUR>caplasttiak)?(CUR-caplasttiak):\
            (0xffff-caplasttiak+CUR+1);
          if(det>=50)//50*2.048ms = 102.4ms超时时间,认定当前帧接收完毕
          {
            if(capcount<34)//数据帧失效
            {
              goto errto;
            }
          }
          else
          {
            return 0;//继续接收
          }
        }
        else //未接收到数据
        {
          return 1;
        }
        det =(src[1]>=src[0])?(src[1]-src[0]):(0xffff-src[0]+src[1]+1);//计算控制周期
        if((det>SYNC_L)&&(det<SYNC_H)){;}// 同步头 (13.655667ms) /0.001ms = 13,655.667  
        else{ goto errto;}
        src++;
        for(i=0;i<4;i++)//包含4个数据
        {
          tempbuf[i]=0;//clear
          for(j=0;j<8;j++)// 8bit
          {
              det =(src[1]>=src[0])?(src[1]-src[0]):(0xffff-src[0]+src[1]+1);//计算控制周期
              src++;
              if((det>LOW_L)&&(det<LOW_H)){;} //0 逻辑:1.143917ms /0.001ms =1,143.917
              else if((det>HIGH_L)&&(det<HIGH_H))//1逻辑:2.259583ms/0.001ms =2,259.583
              {
                    tempbuf[i]|=(1<<j); //低位在前,
              }
              else {retv =1;goto errto;}
          }
        }
        ret[0] =tempbuf[0]; ret[1] =tempbuf[2];
        retv= 0x80;  
errto:
      capcount =0;
      lastcapcount=capcount;//失效
      return retv;
}
#pragma vector=TIM1_CAPCOM_CC3IF_vector//TIM1CA3
__interrupt void TIM1_CAPCOM_CC3IF(void)//  捕获
{
  captureint[capcount] =TIM1_CCR3H;
  captureint[capcount]<<=8;
  captureint[capcount]|=TIM1_CCR3L;
  caplasttiak = TIM2_CNTRH;//当前计数器tim2
  caplasttiak<<=8;
  caplasttiak|=TIM2_CNTRL;
  if(++capcount>=CAPSIZEMAX){capcount=0;}
  TIM1_SR1 &= (unsigned char)~0x08;//清除CC3IF标志
return;
}

 

<think>嗯,用户想做一个基于STM32F103的电子相册,需要设计方案或者教程。首先,我需要回顾一下相关的知识,看看如何组织这个回答。根据用户提供的引用内容,他们提到了SD卡存储图片、TFT显示、红外遥控以及图片解码这些关键点。 首先,硬件部分,用户需要STM32F103的最小系统板,加上TFT显示屏、SD卡模块、红外接收模块和按键。这些都是基础的外设,需要正确的连接。比如SD卡通常用SPI或者SDIO接口,TFT可能用FSMC或者SPI,红外接收头可能需要定时器或者外部中断来解码信号。 然后是软件设计。图片存储方面,需要文件系统来读取SD卡中的图片,比如FATFS。图片解码部分,可能需要支持BMP、JPEG等格式,可能需要使用到ST提供的库或者第三方库,比如LibJPEG。显示驱动方面,需要编写TFT的驱动程序,能够将解码后的图像数据发送到屏幕上。 另外,用户提到了两种模式:自动切换和手动切换。自动模式可能需要定时器中断来触发图片切换,而手动模式则需要处理按键和红外遥控的信号,这里可能涉及到状态机的设计,或者中断处理函数。 还要考虑内存管理,特别是处理大图片时,可能要用到动态内存或者缓冲机制。比如JPEG解码可能需要较大的缓冲区,或者分块解码。同时,STM32F103的资源有限,需要注意内存的使用情况,避免溢出。 用户可能遇到的挑战包括图片解码的速度、SD卡读取的稳定性、红外遥控的响应速度等。可能需要优化代码,比如使用DMA来传输数据,或者调整解码算法以提高效率。 此外,参考资料里的正点原子教程可能有现成的例程,可以推荐用户参考他们的开发指南,特别是图片显示实验部分。同时,可能需要提醒用户在实现过程中注意文件系统的挂载、路径处理,以及不同图片格式的支持情况。 最后,用户可能需要了解如何将各个模块整合起来,比如在主循环中处理模式切换、图片加载和解码、显示刷新等。测试时建议分模块验证,先确保SD卡能正确读取,再测试图片解码,最后整合红外和按键功能。</think>### 基于STM32F103的电子相册设计方案及实现步骤 #### 一、硬件设计 1. **核心模块** - 主控芯片:STM32F103RCT6(支持SDIO/SPI、FSMC接口,满足显示与存储需求)[^2] - 显示屏:2.8寸TFT-LCD(建议使用带ILI9341等常见驱动芯片的屏幕,通过FSMC接口连接) - 存储模块:SD卡(FAT32格式,存放BMP/JPG格式图片)+ SD卡插槽模块(SPI模式) - 输入设备:红外接收头(如HS0038,连接外部中断引脚)+ 物理按键(模式切换、前后翻页) 2. **硬件连接示例** ```c // FSMC接口连接TFT (以ILI9341为例) FSMC_D0~D15 -> LCD数据线 FSMC_A16 -> LCD寄存器/数据选择(RS) // SPI连接SD卡 SPI1_SCK -> SD_CLK SPI1_MISO -> SD_DOUT SPI1_MOSI -> SD_DIN GPIO_PA4 -> SD_CS ``` #### 二、软件设计 1. **系统框架** ``` SD卡文件系统 → 图片解码 → TFT显示 ↑ ↑ 用户输入(按键/红外) ``` 2. **关键代码模块** - **FATFS文件系统集成** 使用`FatFs R0.14`库实现SD卡文件遍历与读取: ```c FRESULT res = f_open(&file, "0:/IMG001.JPG", FA_READ); f_read(&file, buffer, sizeof(buffer), &br); ``` - **图片解码库** - **BMP格式**:直接读取像素数据(需处理位图头) - **JPEG格式**:集成`LibJPEG`库实现软解码[^2] ```c jpeg_decompress_struct cinfo; jpeg_create_decompress(&cinfo); jpeg_mem_src(&cinfo, jpeg_data, jpeg_size); jpeg_read_header(&cinfo, TRUE); ``` - **显示驱动优化** 使用DMA加速图像数据传输(针对FSMC接口): ```c LCD_WriteRAM_Prepare(); // 准备写入GRAM DMA_Init(DMA_Channel1, &dma_config); // 配置DMA传输 ``` 3. **功能逻辑实现** - **自动播放模式** 通过定时器中断触发图片切换: ```c TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE); void TIM3_IRQHandler() { if (mode == AUTO) current_img_index++; } ``` - **红外遥控解码** 使用NEC协议解码(外部中断+定时器捕获): ```c void EXTI15_10_IRQHandler() { if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_11) == 0) { // 捕获下降沿时间计算键值 } } ``` #### 三、关键问题与优化 1. **内存管理** - 使用`malloc`动态分配解码缓冲区(建议预留50KB以上RAM) - 分块解码JPEG图片以减少内存占用 2. **性能提升** - 启用STM32硬件CRC加速文件校验 - 对SD卡预读取多扇区数据(`SD_ReadMultiBlocks`) #### 四、参考实现路径 1. 从正点原子提供的《图片显示实验》基础代码入手,添加文件遍历功能 2. 扩展红外遥控模块(参考其红外解码例程) 3. 整合自动/手动切换逻辑(状态机设计)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值