?? can_z.c
字號:
return 0;
}
/************************************************************************
*函數原型: bit BCAN_CMD_PRG(unsigned char cmd) *
*參數說明: cmd:sja1000運行的命令字 *
* 01:發送請求 *
* 02:中止發送 *
* 04:釋放接收緩沖區 *
* 08:清除超載狀態 *
* 0x10:進入睡眠狀態 *
* *
*返回值: *
* 0 ; 表示命令執行成功 *
* 1 ; 表示命令執行失敗 *
* *
*說明: 執行sja1000命令 *
************************************************************************/
bit BCAN_CMD_PRG(unsigned char cmd)
{
SJA_BCANAdr=REG_COMMAND; //訪問地址指向命令寄存器
*SJA_BCANAdr=cmd; //啟動命令字
switch(cmd)
{
case TR_CMD: //發送請求命令
return 0;
break;
case AT_CMD: //中止發送命令
SJA_BCANAdr = REG_STATUS; //訪問地址指向狀態寄存器
if((*SJA_BCANAdr & 0x20)==0)//判斷是否正在發送
{
return 0;
}
else
{
return 1;
}
break;
case RRB_CMD: //釋放接收緩沖區
SJA_BCANAdr = REG_STATUS; //訪問地址指向狀態寄存器
if((*SJA_BCANAdr & 0x01)==1)//判斷是否釋放成功
{
return 1;
}
else
{
return 0;
}
break;
case COS_CMD: //清除超載狀態
SJA_BCANAdr = REG_STATUS; //訪問地址指向狀態寄存器
if((*SJA_BCANAdr & 0x02)==0)//判斷清除超載是否成功
{
return 0;
}
else
{
return 1;
}
break;
case GTS_CMD: //進入睡眠狀態命令
return 0;
break;
default:
return 1;
break;
}
}
void InitialCAN()
{
SJA_reset=0;
delay(100);
SJA_reset=1;
SJA_BCANAdr=REG_CONTROL; //設置控制寄存器
*SJA_BCANAdr=0x02; //接收中斷使能
do{;}while(BCAN_ENTER_RETMODEL()); //進入復位模式
do{;}while(BCAN_CREATE_COMMUNATION()); //建立連接
do{;}while(BCAN_SET_BANDRATE()); //設置BTR0,BTR1,配置波特率
do{;}while(BCAN_SET_OBJECT(0x00,0x00)); //設置驗收代碼寄存器ACR,驗收屏蔽寄存器AMR,
//自身節點ID號為00000000!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
do{;}while(BCAN_SET_OUTCLK(0xda,0x08)); //設置輸出控制寄存器OC,時鐘分頻器CDR
do{;}while(BCAN_QUIT_RETMODEL()); //進入工作模式
}
void DataReceive() interrupt 0 using 1
{
red=0; //接受指示
EX0=0;
SJA_BCANAdr=REG_INTERRUPT; //讀取中斷寄存器值,判斷中斷類型
interrupt_flag=*SJA_BCANAdr;
if((interrupt_flag&0x01)==1)//接收中斷
{
BCAN_DATA_RECEIVE(SystemBuf); //讀取緩沖區數據
BCAN_CMD_PRG(RRB_CMD); //釋放接收緩沖區
request_flag=1;
}
if((interrupt_flag&0x04)==1)//錯誤中斷
{
SJA_reset=0; //復位
}
EX0=1;
}
void request_data()
{
green=0; //發送指示
SendBuf[0]=0x01; //從機點ID!!!!!!!!!!!!!!!!!!!!!!!!!
SendBuf[1]=0x08;
SendBuf[2]=0x00; //自身ID
SendBuf[3]=0x01;
SendBuf[4]=0x02;
SendBuf[5]=0x03;
SendBuf[6]=0x04; //測試用
SendBuf[7]=0x05; //測試用
SendBuf[8]=0x06; //測試用
SendBuf[9]=0x07; //測試用
BCAN_DATA_WRITE(SendBuf);
BCAN_CMD_PRG(TR_CMD);
}
/***************************lcd********************************/
void bit8_serial_input(uchar ix) //~~液晶八位串輸入信號行
{ //~~ix串行輸入的數
data uchar i,j,nc;
P_E=0; //clk=0;
ab=ix;
for(i=0;i<8;i++){
P_RW=abit7; //din=abit7; ~~輸入最高位
ab<<=1;
P_E=1; //~~鎖存輸入一位
for(j=0;j<10;j++)nc=0;//~~ 延時
P_E=0;
}
}
/*---------------------------------------------------------*/
void instruct(uchar dat) //??光標顯示,顯示控制
{
data uchar ch;
P_RS=1; //選通
ch=0xf8; //~~???
bit8_serial_input(ch);
ch=dat&0xf0; //~~高四位不變低四位請零
bit8_serial_input(ch);
ch=dat<<4;
bit8_serial_input(ch);
P_RS=0; //結束作業
}
void write_abyte(uchar dat) //~~寫入一位數據
{
data uchar ch;
P_RS=1; //讀數據--不選通
ch=0xfa; //RS=1 RW=0; ~~莫非還有寄存器CH就為寫狀態字的
bit8_serial_input(ch);
ch=dat&0xf0; //RS=1 RW=0; ~~??寫兩次還是狀態字高幾位q
bit8_serial_input(ch);
ch=dat<<4;
bit8_serial_input(ch);
P_RS=0; //結束作業
}
/*
寫一個漢字到x,Y坐標處其中X為8列y為4行
*/
void write_word(uint w)
{
data uchar ch,cl;
ch=w>>8; //取高八位ch怎么看不出來
cl=w;
write_abyte(ch);
write_abyte(cl);
}
/*-------------------------------------------*/
/*-------------------------------------------*/
dis_hz_str(uchar x, uchar y, uchar *p_hz) //~~顯示函數可
{ //~~能是顯示文字(也可是字母)串一共
data uchar loc,*p; //可顯示4行漢字由x決定
data uint xi;
code uchar xline[5]={0,1,3,2,4};
x=xline[x];
instruct(home);
loc=((x<<3)+y-9)|0x80;//~~
instruct(loc); p=p_hz;
xi=((*p++)<<8)|*p++;
while(xi){
write_word(xi); //*p++;// );
xi=((*p++)<<8)|*p++; //*p++; xi=xi|*p++;
}
}
/*顯示字母數字在x,y處
*/
void dis_str(uchar x, uchar y, uchar *str)
{
data uchar loc,*p;
code uchar xline[5]={0,1,3,2,4};
p=str;
x=xline[x];
instruct(home);
loc=(16*(x-1)+y-1);
if(loc&0x01){
loc/=2;
instruct(loc|0x80);
//ch=' '; //字符串前加空格(0x20 )
write_abyte(' ');
}else{
loc/=2;
instruct(loc|0x80);
}
while(*p){
write_abyte(*p++);
}
//instruct(0x9e); write_abyte(' ');
}
void initial_screen(void)//~~初始化顯示屏
{
data uchar i,j;
P0=0xff;
P_RS=0; //串行--不選通
//P_PSB=0;
P_E=0; //串行方式
instruct(f_set); //0x30; //8位并行接口 基本指令
for(i=0;i<30;i++){} //~~~延時何用???
for(i=0;i<250;i++){}
for(i=0;i<250;i++){}
instruct(f_set); //0x30; //8位并行接口 基本指令
for(i=0;i<30;i++){}
for(i=0;i<250;i++){}
for(i=0;i<250;i++){}
instruct(dis_on); //0x0f); //開啟屏幕 光標 閃爍
for(i=0;i<30;i++){}
instruct(clear); //0x01); //清屏幕 clear
for(j=0;j<10;j++){
for(i=0;i<250;i++){}
}
instruct(in_mode); //0x06); //光標右移、地址增1 方式
for(i=0;i<30;i++){}
instruct(home);
}
/*---------------------------------------------------------*/
/*---------------------------------------------------------*/
void itoa(int x,unsigned char *str)//BCD碼到ASCII碼
{
unsigned int n;
unsigned char chn,*p,str1[5];
data unsigned char i,j;
if(x<0){
*str++='-';
x=-x;
}
n=x;
p=str1;
j=0;
while(n!=0){
chn=n%10;
n=n/10;
*p++=chn+'0';
j++;
}
if(j!=0){
p--;
for(i=0;i<j;i++)*str++=*p--;
}
else *str++='0';
*str=0;
return;
}
//------------------------------------------------------------------
void b2hex(char ch,char *p)
{
char c1,c2;
c1=((ch&0xf0)>>4)&0x0f;
//c1=c1>>4;
c2=ch&0x0f; //二進制變16進制
if(c1<=9)c1=c1+'0'; else c1=c1-10+'A';
if(c2<=9)c2=c2+'0'; else c2=c2-10+'A';
*p++=c1; *p=c2;
}
//------------------------------------------------------------------
void dis_bin(uchar *buff,uchar n)
{
data uchar i,j,ch,*p,*p1;
idata uchar str[20],str1[3];
p=buff; p1=str; j=0;
for(i=0;i<n;i++){
ch=*p++;
b2hex(ch,str1); //char ch,char *p)
*p1++=str1[0]; *p1++=str1[1];
j=j+2;
}
p=buff;
for(i=0;i<j;i++)*p++=str[i];
}
/*-----------------------------------------------------------------*/
/*---------------------------------------------------------*/
void main(void)
{
red=1;
green=1;
initial_screen();
instruct(0x0c); //關閉光標
InitialCAN();
EX0=1; // 開外部中斷
IT0=0; // 外部中斷源采用邊沿觸發方式
EA=1;//總線初始化后開中斷
request_data();
while(1)
{ dis_str(1,4,"CAN");
dis_hz_str(1,4,"總線主\0\0");
if(request_flag==1)
{
dis_bin(SystemBuf,10);
dis_str(2,1,SystemBuf);
request_flag=0;
delay(49990);
red=1;
request_data();
}
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -