標題:
求助!單片機紅外接收異常 上電后第一次正常
[打印本頁]
作者:
kaixin8318
時間:
2020-2-4 09:52
標題:
求助!單片機紅外接收異常 上電后第一次正常
上電后第一次識別是正常的,第二次識別有一部分按鍵就會識別錯誤! 請高手指點下!
單片機源程序如下:
#include "stc15f2k60s2.h"
#include <intrins.h>
#include "delay.h"
#include "hongwaifashe.h"
#define uchar unsigned char
#define UINT unsigned int
uchar setdata[3];//發(fā)送紅外用的 用戶碼 用戶碼 數(shù)據(jù)碼
uchar IRtime; //儲存檢測紅外高低電平持續(xù)時間
uchar IRcord[4]; //儲存解碼后的4個字節(jié)數(shù)據(jù)
uchar IRdata[33]; //包含起始碼在內(nèi)的33位數(shù)據(jù)
bit IRpro_ok; //解碼后4個字節(jié)數(shù)據(jù)接收完成標志位
bit IRok; //33位數(shù)據(jù)接收完成標志
uchar RX_Data[]=0; //用于串口1接收數(shù)據(jù)數(shù)組保存變量定義
uchar TX_Data[]=0;
//======================================================================
/* Variable definition */
//======================================================================
/* 串口1相關(guān)變量定義 */
#define FOSC 22118400L //系統(tǒng)晶振頻率(單位:HZ)
#define BAUD 9600 //串口1波特率
#define NONE_PARITY 0 //無校驗
#define ODD_PARITY 1 //奇校驗
#define EVEN_PARITY 2 //偶校驗
#define MARK_PARITY 3 //標記校驗
#define SPACE_PARITY 4 //空白校驗
#define PARITYBIT NONE_PARITY //定義校驗位(無校驗)
#define S1_S0 0x40 //P_SW1.6
#define S1_S1 0x80 //P_SW1.7
UINT CNT_RX; //用于串口1接收數(shù)據(jù)計數(shù)保存變量定義
UINT DAT_RX; //用于串口1接收數(shù)據(jù)保存變量定義
UINT JDE_RX; //用于串口1接收數(shù)據(jù)判斷保存變量定義
UINT DAT_Check; //用于串口1發(fā)送的HDT數(shù)據(jù)的校驗和計算保存變量定義
/* 串口中斷變量定義 */
uchar K,H; //用于循環(huán)計數(shù)變量定義
//======================================================================
/* Function declaration */
//======================================================================
void INIT_UART(void); //串口初始化子函數(shù)定義(定時器中斷2)
void SEND_UART(uchar DAT); //串口發(fā)送數(shù)據(jù)子函數(shù)定義
/***********************************************************************/
//======================================================================
// MAIN FUNCTION
//======================================================================
/***********************************************************************/
void time0() interrupt 1
{
IRtime++;//255us
if(IRtime==100) {CNT_RX=0; JDE_RX=1; }
}
//外部中斷0 存入33次脈寬
void int0() interrupt 0
{
static uchar i;//靜態(tài)變量用于存入33次數(shù)據(jù)計數(shù)
static bit startflag;//開始儲存脈寬標志位
if(startflag)
{
/*判斷引導(dǎo)碼,如果是引導(dǎo)碼則從起始碼開始存*/
if((IRtime < 63) && (IRtime >= 33)) i = 0; //
IRdata[i] = IRtime;//以TO溢出的次數(shù)來計算脈寬把這個時間存放在數(shù)組中
IRtime = 0;//計數(shù)清零
i++;//計數(shù)脈寬存入次數(shù)自加
if(i == 33) //i等于33那么就表示已經(jīng)存入了33次脈寬
{
IRok = 1; //脈寬檢查完成
i = 0; //把脈寬計數(shù)清零準備下次存入
}
}
else
{
IRtime = 0; //定時器0計數(shù)清零
startflag = 1;//開始處理標志位置1
}
}
//把提取的33次脈寬進行解碼 NEC協(xié)議
void IRcordpro()
{
uchar i;//i是用于計數(shù)處理4個字節(jié)
uchar j;//j用于計數(shù)處理1個字節(jié)的8位數(shù)據(jù)
uchar k;//k用于計數(shù)處理33次脈寬
k = 1;//從第一位脈寬開始處理,丟掉起始碼
for(i = 0; i < 4; i++)
{
for(j = 0; j < 8; j++)
{
//如果脈寬大于數(shù)據(jù)0標準的1125us那么就判定為數(shù)據(jù)1
if(IRdata[k] > 5
) IRcord[i] |= 0x80;//寫1
//只能右移7次,如果右移8次則會把第一位數(shù)據(jù)移出去
if(j < 7) IRcord[i] >>= 1;
k++; //處理下一次脈寬
}
}
IRpro_ok = 1;//解碼完成
}
void main(void)
{
/*===========================================================
===========================================================*/
//上電,IO口初始化
P3M1=0x00; P3M0=0x00; //準雙向IO口
P5M1=0x00; P5M0=0xff; //推挽
P3=P5=0xFF;
//上電,定時器中斷0初始化
AUXR|=0x80; //定時器時鐘為1T模式
TMOD&=0xF0; //定時計數(shù)器0, 工作方式1
TL0 = 0xF8; //設(shè)置定時初值
TH0 = 0xE9; //設(shè)置定時初值 //設(shè)置定時初值 255us
ET0=1; //允許定時/計數(shù)器0 中斷
TR0=1; //啟動定時/計數(shù)器0 中斷
//上電,允許外部中斷0
IT0 = 1;//設(shè)置外部中斷0跳變沿觸發(fā)方式
EX0 = 1;//開外部中斷0中斷
//上電,串口中斷初始化
INIT_UART(); //串口中斷初始化
EA=1; //打開總中斷
/*===========================================================
===========================================================*/
while(1)
{
uchar i; //計數(shù)串口發(fā)送字節(jié)數(shù)
if(IRok)//判斷33次脈寬是否提取完成
{
IRcordpro();//根據(jù)脈寬解碼出4個字節(jié)的數(shù)據(jù)
IRok = 0;//清零脈寬檢查完成標志位等待下一次脈寬檢查
if(IRpro_ok)//判斷解碼是否完成
{
// if( IRcord[2]==~IRcord[3] )
//
// {
for(i = 0; i < 4; i++) //串口發(fā)送4個字節(jié)數(shù)據(jù)
SEND_UART(IRcord[i]) ;
// }
//
IRpro_ok = 0;//清零解碼標志位
for(i = 0; i < 4; i++){
IRdata[i]=0;}
}
}
if(JDE_RX==2) // 接收到指令
{
if(RX_Data[1]==0xf1)
{
setdata[0]= RX_Data[2] ;
setdata[1]= RX_Data[3] ;
setdata[2]= RX_Data[4] ;
hongwaifashe( );
JDE_RX=1; // 允許接收
CNT_RX=0; // 接收數(shù)量清零
}
}
}//while
}//main
/***********************************************************************/
//======================================================================
// UART interrupt service routine
// 數(shù)據(jù)格式:0xFF,0x0A,0x05,0x06,0x00,0x00
//======================================================================
/***********************************************************************/
void Uart_Isr() interrupt 4 using 1
{
if(RI)
{
RI=0; //清除RI位
DAT_RX=SBUF; //讀取串口1數(shù)據(jù)
/* 串口1接收數(shù)據(jù)和判斷數(shù)據(jù)結(jié)束 */
if(JDE_RX==1) //接收數(shù)據(jù)保存判斷
{
IRtime=0; //計時器清零
if((DAT_RX==0xFA)&(CNT_RX==0)) //避免少發(fā)數(shù)據(jù)出錯情況 每次接到FA 就會清空
{
for(K=0;K<8;K++){RX_Data[K]=0;} //串口接收的數(shù)據(jù)清0
}
RX_Data[CNT_RX]=DAT_RX;
CNT_RX++; //接收數(shù)量+1
if(CNT_RX==5) //接收5個字節(jié)
{
JDE_RX=2; //串口接收數(shù)據(jù)判斷變量置2 接收完畢
}
}
}
//if(TI){ TI=0; } //清除TI位
}
/***********************************************************************/
//======================================================================
// 子函數(shù)定義
//======================================================================
/***********************************************************************/
//串口初始化子函數(shù)定義(定時器中斷2)
void INIT_UART(void)
{
ACC = P_SW1;
ACC &= ~(S1_S0 | S1_S1); //S1_S0=0 S1_S1=0
P_SW1 = ACC; //(P3.0/RxD, P3.1/TxD)
if(PARITYBIT==NONE_PARITY){ SCON = 0x50; } //8位可變波特率
if((PARITYBIT==ODD_PARITY)|(PARITYBIT==EVEN_PARITY)|(PARITYBIT==MARK_PARITY)){ SCON = 0xda; } //9位可變波特率,校驗位初始為1
if(PARITYBIT==SPACE_PARITY){ SCON = 0xd2; } //9位可變波特率,校驗位初始為0
PCON = 0x80; //波特率不倍增
T2L = (65536-(FOSC/4/BAUD)); //設(shè)置波特率重裝值
T2H = (65536-(FOSC/4/BAUD))>>8;
AUXR |= 0x14; //T2為1T模式, 并啟動定時器2
AUXR |= 0x01; //選擇定時器2為串口1的波特率發(fā)生器
ES = 1; //使能串口1中斷
}
//串口發(fā)送數(shù)據(jù)子函數(shù)定義
void SEND_UART(UCHAR DAT)
{
SBUF=DAT;
while(!TI); //等特數(shù)據(jù)傳送
TI=0; //清除數(shù)據(jù)傳送標志
}
復(fù)制代碼
作者:
12abcfef
時間:
2020-2-4 13:55
各連接處固定后上電 接觸松動 造成局部電壓不穩(wěn)
作者:
仰空
時間:
2020-2-4 15:41
我以前在學(xué)單片機,看著你的代碼感覺我自己要加油呀
作者:
kaixin8318
時間:
2020-2-4 18:10
電路沒有虛連的情況,只要上電第一次解碼 肯定是正常的,第2次開始 有一部分按鍵的數(shù)據(jù)或者數(shù)據(jù)反碼 就會出現(xiàn)一位的錯誤
就是說解碼部分運行一次就不正常了!~
作者:
kaixin8318
時間:
2020-2-4 18:12
而且我試過解碼成功發(fā)送完畢后,我從新執(zhí)行一次上電初始化的內(nèi)容也不管用
歡迎光臨 (http://www.torrancerestoration.com/bbs/)
Powered by Discuz! X3.1