📄 jd1a.c
字号:
//CAN to RS232
//CAN232.C wangjian 20030903
//CPU:AT89S52
//Board CAN_RS232_1a.PCB
//20030926 看门狗周期设置
//CAN2321d.c 20030927 For Motor3C.PCB
//JD1a.C 20050429 实验车CAN节点
#include "absacc.h"
#include "reg52.h"
#include "string.h"
#include "stdio.h"
#include "stdlib.h"
#include "math.h"
#include "INTRINS.H"
#define SJA_BaseAdr 0x7F00
#include "SJA_BcanConf.H"
#define DEFAULTMYID 0xF0 //主机 ID 号
#define DEFAULTSID 0x10 //从机1 ID 号
#define FILENAME "JD1A.C@20050511"
//X25045 ***********************************************************************
//#define unit unsigned int
//#define uchar unsigned char
#define WREN_INST 0x06 //Write enable latch instruction (WREN)
#define WRDI_INST 0x04 /* ;Write disable latch instruction (WRDI)*/
#define WRSR_INST 0x01 /*;Write status register instruction (WRSR)*/
#define RDSR_INST 0x05 /*;Read status register instruction (RDSR)*/
#define WRITE_INST 0x02 /* ;Write memory instruction (WRITE)*/
#define READ_INST 0x03 /*;Read memory instruction (WRITE)*/
#define STATUS_REG 0x00 /* ;Status register*/
#define INIT_STATE 0x09 /* ;Init value for port1*/
#define SLIC 0x30
#define MAX_POLL 0x99
#define STACK_TOP 0x60 /* ;STACK UP*/
//X25045 函数
void Xoutbyte(unsigned char byte);
unsigned char Xinbyte();
Xwren_cmd();
Xwrdi_cmd();
void Xwrsr_cmd(unsigned char ch);
unsigned char Xrdsr_cmd();
Xwip_poll();
unsigned char Xbyte_read(unsigned int addr); //从25045的addr地址中读入1个字节
Xbyte_write(unsigned int addr,unsigned char byte); //向25045的addr地址中写入1个字节byte
void rst_dog(); //喂狗
sbit CS=P3^5;
sbit SO=P1^2;
sbit SCK=P1^3;
sbit SI=P1^1;
sbit SPEAKER=P1^7;
//我的有关子程序 ****************************************************************
//CAN BUS Functions Definition **********************************************************
bit BCAN_CREATE_COMMUNATION(void);
bit BCAN_ENTER_RETMODEL(void);
bit BCAN_QUIT_RETMODEL(void);
bit BCAN_SET_BANDRATE(unsigned char CAN_ByteRate);
bit BCAN_SET_OBJECT(unsigned char BCAN_ACR,unsigned char BCAN_AMR);
bit BCAN_SET_OUTCLK (unsigned char Out_Control,unsigned char Clock_Out);
bit BCAN_DATA_WRITE(unsigned char *SendDataBuf);
bit BCAN_DATA_RECEIVE(unsigned char *RcvDataBuf);
bit BCAN_CMD_PRG(unsigned char cmd);
void TestSJA1000(void);
void InitSJA1000(bit ResetStyle);
unsigned char idata uchERRORCOUNT=20; //错误计时器,20 次可自己定义
bit ErrorFlag=1; //错误标志
unsigned char idata uchSendBuff[10]; //can 报文发送缓冲区
unsigned char idata uchRcvBuff[10]; //can 报文发送缓冲区
void intx0(void);
//我的子程序定义 *******************************************************************
int hex2i(unsigned char *s); //将十六进制的字符串转换为数字
void i2hex2(unsigned char ch,unsigned char *s);
void delayms(unsigned int n); //延时 n ms at 12MHZ
unsigned char nop;
void testhardware();
union ib
{
unsigned int ii;
unsigned char ch[2];
};
#define IDADDR 0x20
#define AMRADDR 0x21
#define BTR0ADDR 0x22
#define BTR1ADDR 0x23
#define OCRADDR 0x24
#define SETFLAGADDR 0x28
unsigned char MasterID=0xF0,Slave1ID=0x10;
unsigned char MyID,MyAMR,MyBTR0,MyBTR1;
bit CANSend=0;
// 串行通讯 **************************************************************************
// 通讯口函数
void ints(void); //串行口中断函数
void traxstring(unsigned char *s); //发送1个字符串s
unsigned char idata buff[33];
unsigned char comnum;
bit ROK=0;
//LCD12864 的引脚定义和函数说明
sbit LCDCS = P1^4;
sbit SID = P1^5;
sbit SCLK = P2^0;
sbit LCDLighter = P1^6;
void LCDInit(); //初始化12864LCD显示屏
void LCDClear(); //清屏 12864 LCD
void LCDDisplay(unsigned char x,unsigned char y,unsigned char *LCDBuff); //显示 LCDBuff 中的数据
//ADC0832 有关的函数 ***************************************************************
sbit ADCS=P1^0;
sbit ADCLK=P1^3;
sbit ADDO=P1^2;
sbit ADDI=P1^1;
unsigned char ADC0832(bit ch);
//PCF8574 操作函数
sbit ICSDA = P3^2;
sbit ICSCL = P3^3;
unsigned char Read8574();
sbit DQ =P3^4;//根据实际情况定义端口
int Read_Temperature(void); //读取温度
main()
{
unsigned char idata string[21];
unsigned char i,j,k,ch;
unsigned int count1;
unsigned int ii,xaddr,num;
int wendu;
float f;
bit Flash=0,TestFlag=0;
unsigned char xdata x;
SP=0xd0; //设置SP
P2=0xff;
P3=0xFF;
delayms(100); //延时 100MS 秒,测试系统时钟
rst_dog(); //--------------------
Xwrsr_cmd(0x30); //启动看门狗计数器 0x00-1.4S 0x10-600ms 0x20-200ms 0x30-Disable
delayms(100);
ch=Xrdsr_cmd(); //读取看门狗状态字
Xbyte_write(0x00,0x30);
ch=Xbyte_read(0x00);
MyID=0x00;
Slave1ID=DEFAULTSID;
// testhardware();
// Xbyte_write(SETFLAGADDR,'N');
//读取各设置参数 *************************************************************************************************
//读取设置值,若没有设置,则设为默认值
for(i=0;i<8;i++)
string[i]=Xbyte_read(SETFLAGADDR+i);
string[i]=0;
if(strncmp(string,"HAVSET",6))
{
Xbyte_write(IDADDR,MyID);
Xbyte_write(AMRADDR,0x0f);
Xbyte_write(BTR0ADDR,0x43);
Xbyte_write(BTR1ADDR,0x2f);
strcpy(string,"HAVSETDF");
for(i=0;i<8;i++)
Xbyte_write(SETFLAGADDR+i,string[i]);
}
MyID=Xbyte_read(IDADDR);
MyAMR=Xbyte_read(AMRADDR);
MyBTR0=Xbyte_read(BTR0ADDR);
MyBTR1=Xbyte_read(BTR1ADDR);
// 初始化 CAN 控制器 SJA1000 ****************************************************
CAN_CONTROL=0x09;
while((CAN_CONTROL & 0x01)==0)
{
CAN_CONTROL=0x09;
}
CAN_CDR=0x08;
CAN_COMMAND = 0x0E;//Command Register: Rv Rv Rv GTS CDO RRB AT TR
_nop_();
//设置验收代码寄存器
CAN_ACR =MyID; // MasterID; //主机
_nop_();
//设置屏蔽寄存器
CAN_AMR = MyAMR; //0x0f; //识别码字节的高 4 位标识控制器的 ID号,后 4 位无效
_nop_();
// 0x81,0xfa, //;200KBPS 的预设值
CAN_BTR0 =MyBTR0; //0x81fa-200kbps; 0x43,0x2f-100k bps
_nop_();
CAN_BTR1 =MyBTR1;
_nop_();
CAN_OCR= 0xaa;
_nop_();
CAN_CONTROL = 0x1E;
_nop_();
while((CAN_CONTROL&0x01)==1)
{
CAN_CONTROL = 0x1E;
_nop_();
}
EX0=0;
EA=0;
//初始化 SJA1000 结束 --------------------------------------------------
ch=CAN_STATUS;
//初始化串行口
TMOD=0x22; //T1串行通讯定时
// T0 is used as clock source for PCA
TH0=0xF8;
TL0=0xF8;
TR0=1;
// T2 is used as RPM0 clock
RCLK=0;TCLK=0;
CP_RL2=0;
RCAP2L=0xb0;
RCAP2H=0xff;
TL2=0x66;
TH2=0xff;
TR2=1;
ET2=1;
// T1 is used as Baund Generator
TH1=0xff; //9600 BPS-0xfd, 4800 BPS-0xfa @11.0592MHz
TL1=0xff;
SCON=0x50;
PCON=0x80; //PCON=0x80 TH1=0xff 115200BPS @ 11.0592MHz
TR1=1;
PS=1; //串行通讯中断优先级设为高级
ES=1;
LCDLighter=0;
LCDInit(); delayms(100);
LCDClear();
delayms(500);
LCDDisplay(0,0,"北京航空航天大学"); //在第1行
LCDDisplay(1,0,"汽车电子综合实验");
LCDDisplay(2,0," CAN 总线节点 ");
LCDDisplay(3,0," 2005-05-18 ");
delayms(1000);
delayms(1000);
//主循环开始 ***********************************************************************
begin:
rst_dog();
delayms(100);
EA=1;
if(count1) count1--;
if(count1) SPEAKER=0;
else SPEAKER=1;
ch=ADC0832(0); f=ch*5.0/255.0;
sprintf(string,"ADC0=0x%02bx %4.1fV",ch,f);
LCDDisplay(0,0,string);
ch=ADC0832(1); f=ch*5.0/255.0;
sprintf(string,"ADC1=0x%02bx %4.1fV",ch,f);
LCDDisplay(1,0,string);
strcpy(string,"开关量: ");
ch=Read8574();
for(i=0;i<8;i++)
{
if(ch & 0x80) string[8+i]='1';
else string[8+i]='0';
ch<<=1;
}
LCDDisplay(2,0,string);
wendu=Read_Temperature(); //读取温度
f=wendu*0.0625;
sprintf(string,"温度: %7.3f ℃",f);
LCDDisplay(3,0,string);
i=ADC0832(0);
j=ADC0832(1);
ch=CAN_STATUS;
if(BCAN_DATA_RECEIVE(uchRcvBuff)==0)
{
CAN_COMMAND=0x04;
ch=CAN_STATUS;
count1=200;
// if(uchRcvBuff[0]==MyID)
{
string[0]='{';string[1]=0;
traxstring(string);
for(i=0;i<10;i++)
{
i2hex2(uchRcvBuff[i],string);
traxstring(string);
}
string[0]='}';string[1]=0;
traxstring(string);
}
}
if(ROK)
{
if(buff[0]=='$')
{
//从X5045中读入二进制数据 数量没有限制
if(buff[1]=='R') //从X5045中读入二进制数据 数量没有限制
{
for(i=0;i<3;i++)
string[i]=buff[2+i];
string[3]=0;
xaddr=hex2i(string);
for(i=0;i<3;i++)
string[i]=buff[i+5];
string[3]=0;
num=hex2i(string);
for(ii=0;ii<num;ii++){
j=Xbyte_read(xaddr+ii);
i2hex2(j,string);
strcat(string," ");
traxstring(string);
}
strcpy(string,"\r\n");
traxstring(string);
}
//向X5045中写入二进制数据 每次最多写32个数据
else if(buff[1]=='W') //WXXX***DDddDDddDDdd XXX-BeginAddr *** Data Number(<=32) DD-Data(hex)
{
for(i=0;i<3;i++)
string[i]=buff[i+2];
string[3]=0;
xaddr=hex2i(string);
for(i=0;i<3;i++)
string[i]=buff[i+5];
string[3]=0;
num=hex2i(string);
for(i=0;i<num;i++){
string[0]=buff[i*2+8];
string[1]=buff[1+i*2+8];
string[2]=0;
k=hex2i(string);
Xbyte_write(xaddr+i,k);
}
strcpy(string,"WriteOK\r\n");
traxstring(string);
}
else if(buff[1]=='S') //设置 CAN RS232 参数
{
string[0]=buff[2];
string[1]=buff[3];
string[2]=0;
k=hex2i(string);
Xbyte_write(IDADDR,k);
string[0]=buff[4];
string[1]=buff[5];
string[2]=0;
k=hex2i(string);
Xbyte_write(AMRADDR,k);
string[0]=buff[6];
string[1]=buff[7];
string[2]=0;
k=hex2i(string);
Xbyte_write(BTR0ADDR,k);
string[0]=buff[8];
string[1]=buff[9];
string[2]=0;
k=hex2i(string);
Xbyte_write(BTR1ADDR,k);
strcpy(string,"HAVSETCM");
for(i=0;i<8;i++)
Xbyte_write(SETFLAGADDR+i,string[i]);
}
else if(buff[1]=='C' && buff[2]=='A' && buff[3]=='N') //取得CAN接收寄存器数据
{
ch=CAN_STATUS;
i2hex2(ch,string);
strcat(string," ");
traxstring(string);
for(i=0;i<10;i++)
{
i2hex2(uchRcvBuff[i],string);
strcat(string," ");
traxstring(string);
}
strcpy(string,"\r\n");
traxstring(string);
}
else if(buff[1]=='T') //发送CAN指令
{
for(i=0;i<10;i++)
{
string[0]=buff[i*2+2];
string[1]=buff[i*2+3];
string[2]=0;
uchSendBuff[i]=hex2i(string);
}
BCAN_DATA_WRITE(uchSendBuff);
CAN_COMMAND=0x01;
ch=CAN_STATUS;
ch=CAN_STATUS;
// CANSend=0;
}
else if(buff[1]=='A') //发送CAN指令
{
ch=CAN_STATUS;
num=strlen(buff);
num=num/8;
for(i=0;i<num;i++)
{
do {
ch=CAN_STATUS;
} while(!(ch & 0x08));
string[0]=buff[2+i*8+0];
string[1]=buff[2+i*8+1];
string[2]=0;
uchSendBuff[0]=hex2i(string);
uchSendBuff[1]=0x08;
uchSendBuff[2]=0x00;
string[0]=buff[2+i*8+2];
string[1]=buff[2+i*8+3];
string[2]=0;
uchSendBuff[3]=hex2i(string);
string[0]=buff[2+i*8+4];
string[1]=buff[2+i*8+5];
string[2]=0;
uchSendBuff[4]=hex2i(string);
string[0]=buff[2+i*8+6];
string[1]=buff[2+i*8+7];
string[2]=0;
uchSendBuff[5]=hex2i(string);
uchSendBuff[6]=0;
uchSendBuff[7]=0;
uchSendBuff[8]=0;
uchSendBuff[9]=0;
BCAN_DATA_WRITE(uchSendBuff);
CAN_COMMAND=0x01;
ch=CAN_STATUS;
// delayms(5);
}
}
else if(buff[1]=='V') //取得版本号
{
strcpy(string,"57600,N,8,1 ");
traxstring(string);
strcpy(string,FILENAME);
traxstring(string);
strcpy(string," By WANGJIAN\r\n");
traxstring(string);
}
else if(buff[1]=='G' && buff[2]=='R')
{
ch=Xrdsr_cmd();
// Xwrsr_cmd(00);
// ch=Xrdsr_cmd();
strcpy(string,"X5045 Status=0x");
traxstring(string);
i2hex2(ch,string);
traxstring(string);
strcpy(string,"\r\n");
traxstring(string);
}
else if(buff[1]=='G' && buff[2]=='W')
{
string[0]=buff[3];
string[1]=buff[4];
string[2]=0;
ch=hex2i(string);
Xwrsr_cmd(ch);
}
else
{
strcpy(string,"Error\r\n");
traxstring(string);
}
}
ROK=0;
}
goto begin;
}
void intx0(void) interrupt 0 using 1
{
unsigned char ch;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -