完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
实例说明:
1、本实例是利用STM8单片机定时器tiM1的PWM输入捕获模式测量红外遥控码。 2、红外遥控码格式为NEC红外编码。 3、红外接收信号输入接PC1(TIM1输入通道1)。 4、采用外部晶振16M。 5、采用IAR FOR STM8开发环境。 6、程序代码如下: //-------------------------------------------------------------------- #i nclude #define uchar unsigned char #define uint unsigned int uchar IrRecStep = 0; //接收步骤 uchar IrIndex = 0; //接收位数 uchar IrRecFlag = 0; //接收完标志 uchar IrRecBuff[4]; //接收缓冲区 uchar IrRecAddr1; //红外地址码 uchar IrRecAddr2; uchar IrRecData1; //红外数据码 uchar IrRecData2; uint IrCycle = 0; //红外周期 uint IrHigh = 0; //占空比 const uchar IrCode[8]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80}; //--------引导码低电平范围------------------ #define IrHeadLow_Max 2300 //2300*4 = 9200us #define IrHeadLow_Min 2100 //2100*4 = 8400us //--------引导码高电平范围------------------ #define IrHeadHigh_Max 1250 //1250*4 = 5000us #define IrHeadHigh_Min 1050 //1050*4 = 4200us //--------数据0的周期范围------------------- #define IrData00_Max 300 //300*4 = 1200us #define IrData00_Min 260 //260*4 = 1040us //--------数据1的周期范围------------------- #define IrData10_Max 580 //580*4 = 2320us #define IrData10_Min 540 //540*4 = 2160us //--------数据0的占空比(高电平)范围--------- #define IrData0_Max 160 //160*4 = 640us #define IrData0_Min 120 //120*4 = 480us //--------数据1的占空比(高电平)范围--------- #define IrData1_Max 440 //440*4 = 1760us #define IrData1_Min 400 //400*4 = 1600us //---------------------------------------------------------- #define REMOTE_CLK_DIV 63 //63+1=64----16Mh/64=4us #define REMOTE_ICF_FILTER 0x30 //延时程序 void Delay_ms( uint ms ) { uint i,j; for( j=0; j { for( i=0; i<1000; i++ ) {;} } } //红外接收端口初始化 void Ir_Init(void) { PC_DDR_DDR1 = 0; //PC1为输入 PC_CR1_C11 = 1; PC_CR2_C21 = 0; } //使用TIM1的PWM输入捕获 void Ir_PWM_Init(void) { TIM1_PSCRH = 0; TIM1_PSCRL = REMOTE_CLK_DIV; TIM1_CCER1 &= 0xee;//禁止输入捕获1,2 TIM1_CCMR1 |= (REMOTE_ICF_FILTER + 0x01);// ch1到ti1fp1 TIM1_CCER1 &= 0xec;//ch1 上升沿触发 TIM1_CCMR2 |= (REMOTE_ICF_FILTER + 0x02);// ch2选择 ti1fp2上 TIM1_CCER1 |= 0x20;//ch1 下降沿触发 ic2 TIM1_SMCR |= 0x54;//选源触发源和触发方式 复位 TIM1_CCER1 |= 0x11;//使能输入捕获1,2 TIM1_CR1 |= 0x05; } //红外接收程序 void Ir_Receive(void) { switch(IrRecStep) { case 0: IrIndex = 0; if ((TIM1_SR1_CC1IF == 1)&&(TIM1_SR1_CC2IF == 1)) { IrHigh = (uint)(TIM1_CCR2H); IrHigh = (IrHigh << 8) + TIM1_CCR2L; //IrHigh占空比 IrCycle = (uint)(TIM1_CCR1H); IrCycle = (IrCycle << 8) + TIM1_CCR1L; //IrCycle周期 //是否在引导码低电平范围内 if (((IrCycle - IrHigh) < IrHeadLow_Max)&&((IrCycle - IrHigh) > IrHeadLow_Min)) { IrRecStep = 1; TIM1_SR1_CC1IF = 0; TIM1_SR1_CC2IF = 0; TIM1_SR2_CC1OF = 0; TIM1_SR2_CC2OF = 0; TIM1_SR1_UIF = 0; IrRecBuff[0] = 0; IrRecBuff[1] = 0; IrRecBuff[2] = 0; IrRecBuff[3] = 0; } } break; case 1: if ((TIM1_SR2_CC1OF==1) || (TIM1_SR2_CC2OF==1) || (TIM1_SR1_UIF==1)) { IrRecStep = 0; } else { if ((TIM1_SR1_CC1IF == 1)&&(TIM1_SR1_CC2IF == 1)) { IrHigh = (uint)(TIM1_CCR2H); IrHigh = (IrHigh << 8) + TIM1_CCR2L; IrCycle = (uint)(TIM1_CCR1H); IrCycle = (IrCycle << 8) + TIM1_CCR1L; //是否在引导码高电平范围内 if ((IrHigh < IrHeadHigh_Max)&&(IrHigh > IrHeadHigh_Min)) { IrRecStep = 2; } } } break; case 2: if ((TIM1_SR2_CC1OF==1) || (TIM1_SR2_CC2OF==1) || (TIM1_SR1_UIF==1)) { IrRecStep = 0; } else { if ((TIM1_SR1_CC1IF == 1)&&(TIM1_SR1_CC2IF == 1)) { IrHigh = (uint)(TIM1_CCR2H); IrHigh = (IrHigh << 8) + TIM1_CCR2L; IrCycle = (uint)(TIM1_CCR1H); IrCycle = (IrCycle << 8) + TIM1_CCR1L; //周期是否在数据0范围内 if ((IrCycle > IrData00_Min)&&(IrCycle < IrData00_Max)) { //高电平是否在数据0范围内 if ((IrHigh > IrData0_Min)&&(IrHigh < IrData0_Max)) { IrIndex++; } else { IrRecStep = 0; } } //周期是否在数据1范围内 else if ((IrCycle > IrData10_Min)&&(IrCycle < IrData10_Max)) { //高电平是否在数据1范围内 if ((IrHigh > IrData1_Min)&&(IrHigh < IrData1_Max)) { IrRecBuff[IrIndex >> 3] |= IrCode[IrIndex & 0x07]; IrIndex++; } else { IrRecStep = 0; } } else { IrRecStep = 0; } if(IrIndex >= 32) { IrRecStep = 0; IrRecFlag = 1; } } } break; } } //时钟初始化 void CLK_Init(void) { CLK_ECKR=0x03;//外部时钟寄存器 外部时钟准备就绪,外部时钟开 CLK_SWCR=0x02;//切换控制寄存器 使能切换机制 CLK_SWR=0xB4;//主时钟切换寄存器 选择HSE为主时钟源*/ while (!(CLK_SWCR & 0x08)); CLK_CSSR=0x01;//时钟安全系统寄存器 } //初始化 void Devices_Init(void) { Delay_ms(200); CLK_Init(); Ir_Init(); Ir_PWM_Init(); } //主程序 void main( void ) { Devices_Init(); while(1) { Ir_Receive(); if(IrRecFlag == 1) { IrRecAddr1 = IrRecBuff[0]; IrRecAddr2 = IrRecBuff[1]; IrRecData1 = IrRecBuff[2]; IrRecData2 = IrRecBuff[3]; IrRecFlag = 0; } } } |
|
相关推荐
17 个讨论
|
|
|
不错的东西。。终于找到了。。
|
|
|
|
|
|
|
|
|
不错啊,楼主,你这效果怎么样,我最近也要用到呢。。。
|
|
|
|
|
|
|
|
|
楼主还有个问题 你把那个9ms直接当作地电平,这可以,但是4.5ms 那个不是发送38KHZ的1/3占空比的载波吗,你怎么把他直接 当高电平了。。。望楼主解答一下,谢了。。。
|
|
|
|
|
|
|
|
|
谢谢楼主分享!!!!
|
|
|
|
|
|
|
|
你正在撰写讨论
如果你是对讨论或其他讨论精选点评或询问,请使用“评论”功能。
STM32F405驱动DS1302时钟模块,输出时间错乱该怎么排查?
2810 浏览 2 评论
stm32f405rgt6驱动DS1302ZN出现时间错乱问题
2420 浏览 1 评论
stm32用fsmc读取ad7606采集数据,数据不变,只有开发版复位才更新数据
2288 浏览 0 评论
2404 浏览 1 评论
1643 浏览 1 评论
/9
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2025-12-2 05:31 , Processed in 1.195485 second(s), Total 83, Slave 72 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191

淘帖
6659