基于51单片机的CAN总线的远距离水位监控系统程序.docx
《基于51单片机的CAN总线的远距离水位监控系统程序.docx》由会员分享,可在线阅读,更多相关《基于51单片机的CAN总线的远距离水位监控系统程序.docx(19页珍藏版)》请在冰豆网上搜索。
基于51单片机的CAN总线的远距离水位监控系统程序
/*
描述:
独立的CAN控制器SJA1000基本硬件头文件定义BasicCAN工作方式
*/
#include
#include
#include
#include
#include
#defineucharunsignedchar
#defineuintunsignedint
sbitCS7221=P1^1;//7221的片选
sbitDIN7221=P1^0;//7221的数据端
sbitCLK7221=P1^2;//7221的时钟端
sbitwr_0804=P3^7;//0804读端
sbitrd_0804=P3^6;//0804写端
sbitintr_0804=P2^2;//0804中断端
sbitcs_0804=P2^1;//0804片选端
uchartemp,c[4];//温度暂存
ucharDATA_BUF[6];//发送数据暂存
/************************************************************************
*SJA1000与微处理器的接口是以外部存储器的方式,所以以下的基址定义,用户*
*应根据自己的实际电路来进行调整*
************************************************************************/
#defineSJA_Adr0xfe00//定义sja1000的片选基址
//计算SJA1000在电路中的实际地址:
基址+内部寄存器地址
/************************************************************************
*以下的定义为SJA1000的内部寄存器的地址,不可修改*
*各寄存器的具体功能清参阅sja1000的数据手册*
************************************************************************/
#defineREG_CONTROLSJA_Adr+0x00//内部控制寄存器
#defineREG_COMMANDSJA_Adr+0x01//命令寄存器
#defineREG_STATUSSJA_Adr+0x02//状态寄存器
#defineREG_INTERRUPTSJA_Adr+0x03//中断寄存器
#defineREG_ACRSJA_Adr+0x04//验收代码寄存器
#defineREG_AMRSJA_Adr+0x05//验收屏蔽寄存器
#defineREG_BTR0SJA_Adr+0x06//总线定时寄存器0
#defineREG_BTR1SJA_Adr+0x07//总线定时寄存器1
#defineREG_OCRSJA_Adr+0x08//输出控制寄存器
#defineREG_TESTSJA_Adr+0x09//测试寄存器
//以下为发送缓冲区寄存器定义
#defineREG_TxBuf1SJA_Adr+0x0A//发送缓冲区1
#defineREG_TxBuf2SJA_Adr+0x0B//发送缓冲区2
#defineREG_TxBuf3SJA_Adr+0x0C//发送缓冲区3
#defineREG_TxBuf4SJA_Adr+0x0D//发送缓冲区4
#defineREG_TxBuf5SJA_Adr+0x0E//发送缓冲区5
#defineREG_TxBuf6SJA_Adr+0x0F//发送缓冲区6
#defineREG_TxBuf7SJA_Adr+0x10//发送缓冲区7
#defineREG_TxBuf8SJA_Adr+0x11//发送缓冲区8
#defineREG_TxBuf9SJA_Adr+0x12//发送缓冲区9
#defineREG_TxBuf10SJA_Adr+0x13//发送缓冲区10
//以下为接收缓冲区寄存器定义
#defineREG_RxBuf1SJA_Adr+0x14//接收缓冲区1
#defineREG_RxBuf2SJA_Adr+0x15//接收缓冲区2
#defineREG_RxBuf3SJA_Adr+0x16//接收缓冲区3
#defineREG_RxBuf4SJA_Adr+0x17//接收缓冲区4
#defineREG_RxBuf5SJA_Adr+0x18//接收缓冲区5
#defineREG_RxBuf6SJA_Adr+0x19//接收缓冲区6
#defineREG_RxBuf7SJA_Adr+0x1A//接收缓冲区7
#defineREG_RxBuf8SJA_Adr+0x1B//接收缓冲区8
#defineREG_RxBuf9SJA_Adr+0x1C//接收缓冲区9
#defineREG_RxBuf10SJA_Adr+0x1D//接收缓冲区10
/************************************************************************
*内部地址01EH备用*
************************************************************************/
/************************************************************************
*时钟分频寄存器(内部地址01FH)*
************************************************************************/
#defineREG_CDRSJA_Adr+0x1F//时钟分频寄存器
/************************************************************************
*定义指针*
************************************************************************/
ucharxdata*SJA_BCANAdr;
/************************************************************************
*定义命令字*
************************************************************************/
#defineTR_CMD0x01//发送请求命令
#defineAT_CMD0x02//夭折发送命令
#defineRRB_CMD0x04//释放接收缓冲区
#defineCOS_CMD0x08//清除超载状态
#defineGTS_CMD0x10//进入睡眠状态命令
/************************************************************************
*定义12M的晶体下,CAN总线波特率*
************************************************************************/
#definebps_20k0x00//波特率20kbps
#definebps_40k0x01//波特率40kbps
#definebps_50k0x02//波特率50kbps
#definebps_80k0x03//波特率80kbps
#definebps_100k0x04//波特率100kbps
#definebps_125k0x05//波特率125kbps
#definebps_200k0x06//波特率200kbps
#definebps_250k0x07//波特率250kbps
#definebps_400k0x08//波特率400kbps
#definebps_500k0x09//波特率500kbps
#definebps_666k0x0a//波特率666kbps
#definebps_800k0x0b//波特率800kbps
#definebps_1000k0x0c//波特率1000kbps
/*-------------------------------------------------------------------------------------------
*以下为BASICCANSJA1000的错误字*
-------------------------------------------------------------------------------------------*/
#defineINTERFACE_0K0//SJA1000接口正常
#defineBUS_0K0//CAN总线工作正常
#defineINTERFACE_ERR0XFF//SJA1000接口错误?
#defineENTRESET_ERR0XFE//SJA1000不能进入复位模式
#defineQUITRESET_ERR0XFD//SJA1000不能退出复位模式
#defineINITOBJECT_ERR0XFC//初始化报文验收滤波器错
#defineINITBTR_ERR0XFB//初始化总线定时器器错
#defineINITOUTCTL_ERR0XFA//初始化输出控制错误
#defineINTCLKDIV_ERR0XF9//初始化时钟分频控制器错
#defineBUS_ERR0XF8//SJA1000发送数据错
#defineNO_BANDRATE_SIZE0xe7//
/************************************************************************
*以下为基本的函数说明(BasicCAN)*
************************************************************************/
bitCREATE_COMMUNATION(void);//检测CAN控制器的接口是否正常
bitENTER_RETMODEL(void);//CAN控制器进入复位工作模式
bitQUIT_RETMODEL(void);//CAN控制器退出复位工作模式
bitSET_BANDRATE(ucharCAN_bps);//设置CAN控制器SJA1000通信波特率
bitSET_OBJECT(ucharBCAN_ACR,ucharBCAN_AMR);//设置CAN节点的通讯对象
bitSET_OUTCLK(ucharOut_Control,ucharClock_Out);//设置SJA1000的输出模式和时钟分频
bitHW_INIT(ucharBCAN_ACR,ucharBCAN_AMR,ucharBus_Timing0,
ucharBus_Timing1,ucharOut_Control,ucharClock_Out);
//CAN控制器的初始化
bitDATA_WRITE(uchar*SendDataBuf);//发送特定帧各式的数据
bitRECEIVE(uchar*RcvDataBuf);//CAN控制器接收数据
bitCMD_PRG(ucharcmd);//执行sja1000命令
voidsja1000();//SJA1000初始化
voidInitial7221(void);//MAX7221初始化
voidWR7221(ucharaddr,ucharData);//MAX7221写程序
voidMax7221Display(uchar*buffer);//MAX7221显示程序
voidread_0804();//读AD转换电压值
voidwdcl_0804();//转换电压值
voiddelay(uintn);//延时程序
main()
{
sja1000();//SJA1000初始化
while
(1)
{
uchark;
read_0804();//读AD转换电压值
wdcl_0804();//转换电压值
Max7221Display(&c[0]);//显示
DATA_BUF[0]=0xaa;//ID高8位为10101010=0xaa
DATA_BUF[1]=0xb4;//ID低3位为101数据帧数据长度为4位
for(k=0;k<=3;k++)//要发送的4位数据
{
DATA_BUF[2+k]=c[k];//
}
DATA_WRITE(&DATA_BUF[0]);//通过CAN总线向计算机发送数据
delay(100);//延时
}
}
/****adc0804******/
voidread_0804()//读AD转换电压值
{
intr_0804=1;
cs_0804=1;
wr_0804=1;
rd_0804=1;
intr_0804=0;
_nop_();_nop_();
cs_0804=0;//0804片选有效
wr_0804=0;//0804写地址
_nop_();_nop_();
intr_0804=1;
rd_0804=0;//0804读
_nop_();_nop_();
temp=P0;//读AD转换数据
cs_0804=1;
wr_0804=1;
rd_0804=1;
}
voidwdcl_0804()
{
temp=(temp*2-273)*10;//提取一位小数
c[0]=temp/1000;//千位
c[1]=temp/100%10;//百位
c[2]=temp/10%10;//十位
c[3]=temp%10;//个位
}
voiddelay(uintn)//延时程序
{
uinti1,j1;
for(i1=0;i1for(j1=0;j1<1140;j1++);
}
voidWR7221(ucharaddr,ucharData)//MAX7221的写子程序
{
uchari;
CS7221=0;//片选有效
for(i=0;i<8;i++)//写8位地址
{
CLK7221=0;//时钟低
DIN7221=(addr&(0x80>>i))?
1:
0;//先发高位依次到低位
_nop_();
_nop_();
CLK7221=1;//时钟高上升沿锁数据
_nop_();
_nop_();
}
for(i=0;i<8;i++)//写8位数据
{
CLK7221=0;//时钟低
DIN7221=(Data&(0x80>>i))?
1:
0;//先发高位依次到低位
_nop_();
_nop_();
CLK7221=1;//时钟高上升沿锁数据
_nop_();
_nop_();
}
CS7221=1;//片选无效
}
voidInitial7221(void)//MAX7221初始化
{
WR7221(0x0A,0x0A);//亮度地址0AH,0x00~0x0F,0x0F最亮
WR7221(0x0B,0x07);//扫描LED个数地址0BH,0x00~0x07,最多扫描8个数码管
WR7221(0x0C,0x01);//工作模式地址0x0C.0x00:
关断;0x01:
正常
WR7221(0x09,0xFF);//编码模式地址0x09.0x00~0xFF:
哪一位为1,哪一位就支持编码
}
voidMax7221Display(uchar*buffer)//MAX7221显示子程序
{
uchari;
for(i=0;i<8;i++)//MAX7221的8个数码管显示
{
WR7221(i+1,*(buffer+i));//调MAX7221的写子程序
}
}
voidsja1000()
{
do{;}while(CREATE_COMMUNATION()==1);//检测CAN控制器的接口是否正常
do{;}while(ENTER_RETMODEL()==1);//进入复位工作模式
HW_INIT(0xaa,0x00,0xc9,0xc9,0xff,0x48);//CAN控制器的初始化
do{;}while(QUIT_RETMODEL()==1);//退出复位工作模式
}
/************************************************************************
*说明:
该函数用于检测CAN控制器的接口是否正常*
************************************************************************/
bitCREATE_COMMUNATION(void)
{
SJA_BCANAdr=REG_TEST;//访问测试寄存器
*SJA_BCANAdr=0xaa;//写入测试值
if(*SJA_BCANAdr==0xaa)
{
return0;//读测试正确
}
else
{
return1;
}
}
/************************************************************************
*说明:
CAN控制器进入复位工作模式*
************************************************************************/
bitENTER_RETMODEL(void)
{
ucharTempData;
SJA_BCANAdr=REG_CONTROL;//访问地址指向控制寄存器
TempData=*SJA_BCANAdr;//保存原始值
*SJA_BCANAdr=(TempData|0x01);//置位复位请求
if((*SJA_BCANAdr&0x01)==1)
{
return0;
}
else
{
return1;
}
}
/************************************************************************
*说明:
CAN控制器退出复位工作模式*
************************************************************************/
bitQUIT_RETMODEL(void)
{
ucharTempData;
SJA_BCANAdr=REG_CONTROL;//访问地址指向控制寄存器
TempData=*SJA_BCANAdr;//保存原始值
*SJA_BCANAdr=(TempData&0xfe);//清除复位请求
if((*SJA_BCANAdr&0x01)==0)
{
return0;//
}
else
{
return1;//退出成功
}
}
/************************************************************************
;*说明:
设置CAN控制器SJA1000通信波特率.SJA1000的晶振为必须为16MHZ,*
;*其它晶体的频率的值的波特率,需自己计算。
该子程序只能用于*
;*复位模式*
;************************************************************************/
ucharcodeSJA_BTR_CODETAB[]={
0x53,0x2F,//;20KBPS的预设值
0x87,0xFF,//;40KBPS的预设值
0x47,0x2F,//;50KBPS的预设值
0x83,0xFF,//;80KBPS的预设值
0x43,0x2f,//;100KBPS的预设值
0x03,0x1c,//;125KBPS的预设值
0x81,0xfa,//;200KBPS的预设值
0x0