#include <INTRINS.H>
//------------------------------------------------------------------------------------------
#define CANCTRL 0x00 //控制暫存器
#define CANSTAT 0x01 //狀態暫存器
#define ERRCNT 0x02 //錯誤計數暫存器
#define BITREG 0x03 //位定時暫存器
#define INTREG 0x04 //中斷暫存器
#define CANTSTR 0x05 //測驗暫存器
#define BRPEXT 0x06 //BRP擴展暫存器
//IF1介面暫存器
//IF1 命令請求暫存器
#define IF1CMDRQST 0x08 //IF1命令請求
#define IF1CMDMSK 0x09 //命令掩碼暫存器
#define IF1MSK1 0x0a //掩碼暫存器1
#define IF1MSK2 0x0b //掩碼暫存器2
#define IF1ARB1 0x0c //仲載暫存器1
#define IF1ARB2 0x0d //仲載暫存器2
//IF1 訊息控制暫存器
#define IF1MSGC 0x0e //訊息控制暫存器
#define IF1DATA1 0x0f //資料A暫存器
#define IF1DATA2 0x10
#define IF1DATB1 0x11 //資料B暫存器
#define IF1DATB2 0x12
//IF2介面暫存器
//IF2命令請求暫存器
#define IF2CMDRQST 0x20
#define IF2CMDMSK 0x21 //命令掩碼暫存器
#define IF2MSK1 0x22 //掩碼暫存器1
#define IF2MSK2 0x23 //掩碼暫存器2
#define IF2ARB1 0x24 //仲裁暫存器1
#define IF2ARB2 0x25 //仲裁暫存器2
//IF2 訊息控制暫存器
#define IF2MSGC 0x26
#define IF2DATA1 0x27 //資料A暫存器
#define IF2DATA2 0x28
#define IF2DATB1 0x29 //資料B暫存器
#define IF2DATB2 0x2a
//==訊息處理器暫存器
//==傳輸請求暫存器==
#define TRANSREQ1 0x40
#define TRANSREQ2 0x41
#define NEWDAT1 0x48 //新資料暫存器
#define NEWDAT2 0x49
//==中斷掛起暫存器
#define INTPEND1 0x50
#define INTPEND2 0x51
#define MSGVAL1 0x58 //訊息有效暫存器
#define MSGVAL2 0x59
//全域變數
char MsgNum; //訊息物件號
char status; //狀態
int m;
sfr16 CAN0DAT = 0xD8;
void main()
{
SFRPAGE=0x0F;
OSCXCN_Init(); //振蕩器初始化
SFRPAGE=0x0F; //埠初始化
IO_Init();
clear_msg_objects(); //清除訊息RAM
//發送用的,在CAN2.0中可不用的
init_msg_object_RX(0x04); //接受初使化函式
EIE2 = 0x20; //使能CAN中斷
start_CAN(); //CAN初使化設定函式
EA = 1;
}
//-----------------------------------------------------------------------------
// 函式名:void clear_msg_objects(void)
// 功 能:清除訊息物件
// 描 述:
//-----------------------------------------------------------------------------
void clear_msg_objects(void)
{
SFRPAGE = CAN0_PAGE;
CAN0ADR = IF1CMDMSK; //指向命令掩碼暫存器
CAN0DATL= 0xff; //將所有訊息物件的方向定為寫
for(m=0;m<33;m++)
{
CAN0ADR = IF1CMDRQST; //清除32個訊息物件
CAN0DATL= m;
}
}
//-----------------------------------------------------------------------------
// 函式名:void init_msg_object_RX(char MsgNum)
// 功 能:接受函式初使化
// 描 述:
//-----------------------------------------------------------------------------
void init_msg_object_RX(char MsgNum)
{
SFRPAGE = CAN0_PAGE;
CAN0ADR = IF2CMDMSK; //指向命令掩碼暫存器1
CAN0DAT = 0x00F8; //將選中的訊息緩沖暫存器的資料發送到命令請求暫存器尋址的訊息物件
//設為寫,并改變所有訊息物件,除了標識掩碼和資料位 //掩碼位不變
//發送ID號+dir+xtd+MsgVal到訊息物件
//發送控制位到訊息物件
//當寫操作時,此位被忽略
//接受位不變
//資料位元組0---3不變
//資料位元組4---7不變
//增加屏蔽位
CAN0ADR = IF2MSK1; //(可接受ID 00 01 10 11)
CAN0DAT = 0x0000;
CAN0DAT =0x0000; //擴展的對接受過濾沒有作用/訊息方向用于接受過濾/11位的屏蔽符全部用上
CAN0ADR = IF2ARB1; //指向仲裁暫存器
CAN0DAT = 0x0000; //將仲裁ID優先級設定最高優先級
CAN0DAT = 0xc000; //訊息物件被配置,并且通過訊息處理來考慮
//設定訊息有效位,沒有擴展ID,方向為接受 //訊息物件使用標準標志符11位
//訊息方向為接受
//11位的識別符號
CAN0ADR = IF2MSGC;
CAN0DAT = 0x1480; //訊息控制暫存器
//設定接受允許,禁止遠程幀 //沒有新的資料寫入這個訊息物件
//從CPU對這個位重置以來,沒有訊息丟失。
//這個訊息物件不是中斷源
//屏蔽忽略(使用)
//在幀的成功傳輸后,中斷掛起來會改變
//在幀的成功接受后,中斷掛起會必設定
//在接受遠程幀時,發送請求不改變
//這個訊息物件沒有等待傳輸
//單個訊息物件或是FIFO最后一個物件
CAN0ADR = IF2CMDRQST; //指向命令請求暫存器
CAN0DATL = MsgNum; //寫訊息物件號,即對哪個訊息物件進行操作。
//在3--6個CAN時鐘周期后,IF暫存器中的內容將被移到CAN存盤器的訊息物件中
}
//-----------------------------------------------------------------------------
// 函式名:void start_CNA(void)
// 功 能:CAN初使化設定函式
// 描 述:
//-----------------------------------------------------------------------------
void start_CAN(void)
{
SFRPAGE = CAN0_PAGE;
CAN0CN = CAN0CN | 0x41; //使能CCE和INIT位
//使能初使化,置開始初使化為1 //正常運行
//CPU有資料寫入到位定時暫存器(當INIT=1)
//啟動訊息干擾自動重傳
//不產生錯誤中斷狀態
//不產生狀態改變中斷
//禁用模塊中斷IRQ_B總是處于高電平
//開始初使化
CAN0ADR = BITREG; //指向位定時器賦值
CAN0DAT = 0x2303; //給位定時器賦值
//增加
// CAN0ADR = CANTSTR;
//CAN0DAT = 0x0004;
//發送用的,在CAN2.0中可以不要
// CAN0ADR = IF1CMDMSK; //指向命令掩碼暫存器1
// CAN0DAT = 0x0087; //寫:
//設定CAN RAM為寫,寫資料位元組, //設定發送請求位
//將發送0---3發送到訊息物件
//將發送4---7發送到訊息物件
CAN0ADR = IF2CMDMSK; //指向命令掩碼暫存器2(設定接收,讀CAN_RAM,讀資料位元組)
CAN0DATL = 0x7f; //設定為接受
//掩碼位不變
//仲裁位不變
//發送控制位到IFx訊息緩沖暫存器
//清除訊息物件中斷掛起位
//清除訊息物件中的NewData位
//將資料位元組0---3位元組發送到訊息緩沖暫存器中
//將資料位元組4---7位元組發送到訊息緩沖暫存器中
CAN0CN = 0x2e; //全域初始化IE和SIE
//啟動中斷,如IRQ_B被置為低電平,并保持低電平直到所有的中斷都被處理
//當一個訊息成功傳輸或檢測到CAN總線出錯時產生一個中斷
//清除CPU沒有資料寫入定時暫存器
//正常運行
}
void receive_data()
{
int h;
char sq;
char SFRPAGE_SAVE = SFRPAGE; //保存SFR頁
SFRPAGE = CAN0_PAGE;
CAN0ADR = INTREG;
sq = CAN0DATL;
CAN0ADR = IF2CMDRQST; //指向命令掩碼暫存器
CAN0DATL = sq; //接受來自訊息物件的新資料
CAN0ADR = IF2DATA1; //指向資料域的第一位
for(h=0;h<4;h++)
{
JSSJ[h]=CAN0DAT;
}
S_SET=1;
T1JSA=0X00;
CAN0ADR = IF2ARB1;
ZC = CAN0DAT;
if(ZC==0x2001)
{
FREQ5Z=JSSJ[0];
FREQ6Z=JSSJ[1];
FREQ7Z=JSSJ[2];
FREQ8Z=JSSJ[3];
if(FREQ5Z!=FREQ5)
{
SETPGNB=0x08;
LEFTJS=1;
here: if(S_SENTING==0)
{
KET00();
}
else
{
goto here;
}
}
}
//來自其他節點的0信號使燈滅
SFRPAGE = SFRPAGE_SAVE;
}
//中斷服務程式
void ISRname(void) interrupt 19
{
char SFRPAGE_SAVE = SFRPAGE;
SFRPAGE = CAN0_PAGE;
status = CAN0STA;
if((status&0x10)!=0)
{
//RxOK位為1,則是由于接收引起的中斷
CAN0STA = ((CAN0STA&0xef)|0x07); //復位RxOK,設定LEC無變化(即表明自從CPU最近一次將其復位后中,表明沒有完整訊息被成功接受,不使用錯誤碼)
receive_data();
}
if((status&0x08)!=0)
{
//TxOK位為1,則是由于發送引起的中斷
CAN0STA = ((CAN0STA&0xF7)|0x07); //復位TxOK,設定LEC無變化(即表明訊息傳輸不成功,)
}
if(((status&0x07)!=0)&&((status&0x07)!=7)) //錯誤中斷,改變LEC
{
CAN0STA = CAN0STA | 0x07; //設定LEC無變化
//為什么在中斷中狀態暫存器改變不了
}
SFRPAGE = SFRPAGE_SAVE;
}
我運行完這個子程式can后 回到主程式時,它影響了定時器T1,定時器T1在運行但是就是不進中斷 求大神解答 十分感謝!!!!
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/72546.html
標籤:單片機/工控
