實例說明:
1、本實例是利用STM8單片機定時器TIM1的PWM輸入捕獲模式測量紅外遙控碼。
2、紅外遙控碼格式為NEC紅外編碼。 #define uchar unsigned char uchar IrRecStep = 0; //接收步驟 //--------引導碼低電平范圍------------------ //延時程序 //紅外接收端口初始化 //使用TIM1的PWM輸入捕獲 TIM1_CCER1 &= 0xee;//禁止輸入捕獲1,2 //紅外接收程序
3、紅外接收信號輸入接PC1(TIM1輸入通道1)。
4、采用外部晶振16M。
5、采用IAR FOR STM8開發環境。
6、程序代碼如下:
//--------------------------------------------------------------------
#include
#define uint unsigned int
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;
}
void Ir_PWM_Init(void)
{
TIM1_PSCRH = 0;
TIM1_PSCRL = REMOTE_CLK_DIV;
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為主時鐘源*/
上一篇:stm8s開發(九) EEPROM的使用:使用EEPROM存儲數據!
下一篇:基于IOT的LED智能照明控制系統
推薦閱讀
史海拾趣