最近在練習STM32F103的紅外模塊,比較特殊的是沒用TIM計算脈寬,因為板子上紅外接收埠被定在PD10。用了EXTI15_10中斷,在中斷服務函式中呼叫資料接收函式IRC_Judge()。但無奈實驗時只能進入一次中斷函式并把資料列印到LCD1602上,接下來無論如何操作都無法接收第二次資料。本人還是新手,對于中斷除錯不太熟練,想了兩天沒想懂,茶飯不思。
主要的定義
#define IRC_PIN GPIO_Pin_10
#define IRC_PORT GPIOD
#define IRC_PORTSOURCE GPIO_PortSourceGPIOD
#define IRC_PINSOURCE GPIO_PinSource10
#define IRC_EXITLINE EXTI_Line10
#define IRC_IRQCH EXTI15_10_IRQn
#define IRC_PINCHECK GPIO_ReadInputDataBit(IRC_PORT, IRC_PIN)
#define CMD_S 'I'
#define CMD_F 'A'
#define CMD_B 'B'
#define CMD_L 'C'
#define CMD_R 'D'
unsigned char IRC_data[4]; //用于存放紅外資料
char IRC_cmd;
unsigned char IRC_flag;
以下為主函式,IRC_cmd為列印到LCD1602上的字符
int main(void)
{
RCC_Configuration();
NVIC_Configuration();
LCD1602_Init();
IRC_Init();
while(1)
{
if(IRC_flag == 1) //接收到紅外信號
{
IRC_flag = 0;
switch(IRC_cmd)
{
case CMD_F: IRC_cmd=CMD_F; break;
case CMD_B: IRC_cmd=CMD_B; break;
case CMD_L: IRC_cmd=CMD_L; break;
case CMD_R: IRC_cmd=CMD_R; break;
case CMD_S: IRC_cmd=CMD_S; break;
default : break;
}
LCD1602WriteCommand(IRC_cmd);
}
delay_ms(500);
}
}
EXTI15_10中斷服務函式
void EXTI15_10_IRQHandler()
{
if(EXTI_GetITStatus(IRC_EXITLINE) != 0)
{
EXTI_ClearITPendingBit(IRC_EXITLINE);
IRC_Judge(); //紅外資料接收函式
}
}
紅外資料接受函式
void IRC_Judge(void)
{
unsigned char j,k,l=0;
delay140nus(15); //2.1ms延遲
if(IRC_PINCHECK==1) //2.1ms后如果為高電平說明不是引導碼
{
return;
}
while(!IRC_PINCHECK) //拖延9ms引導碼低電平余下時間
{
delay140nus(1);
}
for(j=0;j<4;j++) //記錄四個資料
{
for(k=0;k<8;k++) //每個資料八位
{
while(IRC_PINCHECK==1)
{
delay140nus(1); //拖延4.5ms高電平引導碼
}
while(IRC_PINCHECK==0)
{
delay140nus(1); //拖延低電平時間,等待高電平
}
while(IRC_PINCHECK==1)
{
delay140nus(1);
l++; //累加高電平時間
if(l>=30)
{
return;
}
}
IRC_data[j] = IRC_data[j] >>1; //最高位補0,填入一位資料
if(l>=8)
{
IRC_data[j] = IRC_data[j] | 0x80; //高電平時間大于1.12ms即接受的資料為1
}
l=0;
}
}
k = ~IRC_data[3];
if(IRC_data[2]!=k) //操作碼與操作反碼匹配
{
return;
}
switch(IRC_data[2]) //操作碼與命令匹配
{
case 0x46: IRC_cmd = CMD_F;break;
case 0x44: IRC_cmd = CMD_L;break;
case 0x15: IRC_cmd = CMD_B;break;
case 0x43: IRC_cmd = CMD_R;break;
case 0x40: IRC_cmd = CMD_S;break;
default : return;
}
IRC_flag = 1; //標志接收到資料
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/92842.html
標籤:單片機/工控
上一篇:如何用三極管或mos管代替繼電器
下一篇:uboot 燒寫請教
