⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 51

📁 51单片机应用系统典型模块开发大全
💻
📖 第 1 页 / 共 2 页
字号:
/*
描述:    独立的CAN 控制器SJA1000基本硬件头文件定义BasicCAN 工作方式
*/
#include  <string.h>
#include<reg51.h>            
#include<stdio.h>
#include<intrins.h>
#include <absacc.h>
#define uchar unsigned char
#define uint unsigned int
sbit CS7221  = P1^1;								// 7221的片选
sbit DIN7221 = P1^0;								// 7221的数据端
sbit CLK7221 = P1^2;								// 7221的时钟端
sbit wr_0804=P3^7;									//0804读端
sbit rd_0804=P3^6;									//0804写端
sbit intr_0804=P2^2;								//0804中断端
sbit cs_0804=P2^1;									//0804片选端
uchar temp,c[4];									//温度暂存
uchar DATA_BUF[6];									//发送数据暂存
/************************************************************************
 *SJA1000与微处理器的接口是以外部存储器的方式,所以以下的基址定义,用户 *
 *应根据自己的实际电路来进行调整                                        *
 ************************************************************************/
#define 	SJA_Adr			0xfe00     				//定义sja1000的片选基址
//计算SJA1000在电路中的实际地址:基址+内部寄存器地址
/************************************************************************
 * 以下的定义为SJA1000的内部寄存器的地址,不可修改                      *
 *     各寄存器的具体功能清参阅sja1000的数据手册                        *
 ************************************************************************/
#define		REG_CONTROL    	SJA_Adr+0x00      		//内部控制寄存器
#define		REG_COMMAND    	SJA_Adr+0x01      		//命令寄存器
#define		REG_STATUS     	SJA_Adr+0x02      		//状态寄存器
#define		REG_INTERRUPT  	SJA_Adr+0x03      		//中断寄存器
#define		REG_ACR        	SJA_Adr+0x04      		//验收代码寄存器
#define		REG_AMR        	SJA_Adr+0x05      		//验收屏蔽寄存器
#define		REG_BTR0       	SJA_Adr+0x06      		//总线定时寄存器0 
#define		REG_BTR1       	SJA_Adr+0x07			//总线定时寄存器1 
#define		REG_OCR        	SJA_Adr+0x08      		//输出控制寄存器
#define		REG_TEST	   	SJA_Adr+0x09      		//测试寄存器  
//以下为发送缓冲区寄存器定义
#define		REG_TxBuf1     	SJA_Adr+0x0A     		//发送缓冲区1
#define		REG_TxBuf2     	SJA_Adr+0x0B  			//发送缓冲区2
#define		REG_TxBuf3     	SJA_Adr+0x0C			//发送缓冲区3
#define		REG_TxBuf4     	SJA_Adr+0x0D    		//发送缓冲区4
#define		REG_TxBuf5     	SJA_Adr+0x0E     		//发送缓冲区5
#define		REG_TxBuf6     	SJA_Adr+0x0F     		//发送缓冲区6
#define		REG_TxBuf7     	SJA_Adr+0x10    		//发送缓冲区7
#define		REG_TxBuf8     	SJA_Adr+0x11     		//发送缓冲区8
#define		REG_TxBuf9     	SJA_Adr+0x12     		//发送缓冲区9
#define		REG_TxBuf10    	SJA_Adr+0x13     		//发送缓冲区10
//以下为接收缓冲区寄存器定义
#define		REG_RxBuf1     	SJA_Adr+0x14     		//接收缓冲区1
#define		REG_RxBuf2     	SJA_Adr+0x15     		//接收缓冲区2
#define		REG_RxBuf3     	SJA_Adr+0x16     		//接收缓冲区3
#define		REG_RxBuf4     	SJA_Adr+0x17    		//接收缓冲区4
#define		REG_RxBuf5     	SJA_Adr+0x18    		//接收缓冲区5
#define		REG_RxBuf6     	SJA_Adr+0x19      		//接收缓冲区6
#define		REG_RxBuf7     	SJA_Adr+0x1A     		//接收缓冲区7
#define		REG_RxBuf8     	SJA_Adr+0x1B    		//接收缓冲区8
#define		REG_RxBuf9     	SJA_Adr+0x1C     		//接收缓冲区9
#define		REG_RxBuf10    	SJA_Adr+0x1D     		//接收缓冲区10
/************************************************************************
 *内部地址 01EH 备用                                                    *
 ************************************************************************/
/************************************************************************
 *时钟分频寄存器(内部地址01FH)                                          *
 ************************************************************************/
#define     REG_CDR   		SJA_Adr+0x1F      		//时钟分频寄存器
/************************************************************************
 *定义指针                                                              *
 ************************************************************************/
uchar		xdata  			*SJA_BCANAdr;    
/************************************************************************
 *定义命令字                                                            *
 ************************************************************************/ 
#define     TR_CMD       	0x01          			//发送请求命令
#define     AT_CMD       	0x02          			//夭折发送命令
#define     RRB_CMD      	0x04          			//释放接收缓冲区
#define     COS_CMD      	0x08          			//清除超载状态
#define     GTS_CMD      	0x10          			//进入睡眠状态命令
/************************************************************************
 *定义12M的晶体下,CAN总线波特率                                        *
 ************************************************************************/
#define     bps_20k      	0x00          			//波特率20kbps
#define     bps_40k      	0x01          			//波特率40kbps
#define     bps_50k      	0x02          			//波特率50kbps
#define     bps_80k      	0x03          			//波特率80kbps
#define     bps_100k     	0x04          			//波特率100kbps
#define     bps_125k     	0x05          			//波特率125kbps
#define     bps_200k     	0x06          			//波特率200kbps
#define     bps_250k     	0x07          			//波特率250kbps
#define     bps_400k     	0x08          			//波特率400kbps
#define     bps_500k     	0x09          			//波特率500kbps
#define     bps_666k     	0x0a          			//波特率666kbps
#define   	bps_800k     	0x0b          			//波特率800kbps
#define     bps_1000k    	0x0c          			//波特率1000kbps
/*-------------------------------------------------------------------------------------------
 *  以下为BASICCAN SJA1000的错误字                                                          *
 -------------------------------------------------------------------------------------------*/
#define 	INTERFACE_0K 	0                   	//SJA1000接口正常 
#define     BUS_0K     		0                       //CAN总线工作正常
#define     INTERFACE_ERR 	0XFF                    //SJA1000接口错误? 
#define     ENTRESET_ERR   	0XFE                    //SJA1000不能进入复位模式
#define     QUITRESET_ERR 	0XFD                    //SJA1000不能退出复位模式
#define     INITOBJECT_ERR 	0XFC                    //初始化报文验收滤波器错
#define     INITBTR_ERR    	0XFB                    //初始化总线定时器器错
#define     INITOUTCTL_ERR  0XFA                    //初始化输出控制错误
#define     INTCLKDIV_ERR  	0XF9                    //初始化时钟分频控制器错
#define     BUS_ERR        	0XF8                    //SJA1000发送数据错
#define     NO_BANDRATE_SIZE    0xe7               	//

/************************************************************************
 *以下为基本的函数说明(BasicCAN)                                       *
 ************************************************************************/
bit   CREATE_COMMUNATION(void); 					//检测CAN控制器的接口是否正常     
bit   ENTER_RETMODEL(void);							//CAN控制器进入复位工作模式 
bit   QUIT_RETMODEL(void);							//CAN控制器退出复位工作模式 
bit   SET_BANDRATE(uchar CAN_bps);					//设置CAN控制器SJA1000通信波特率
bit	  SET_OBJECT(uchar  BCAN_ACR,uchar  BCAN_AMR);	//设置CAN节点的通讯对象
bit   SET_OUTCLK (uchar Out_Control,uchar  Clock_Out);//设置SJA1000的输出模式和时钟分频     
bit   HW_INIT(uchar  BCAN_ACR,uchar  BCAN_AMR,uchar  Bus_Timing0,
	         uchar  Bus_Timing1,uchar  Out_Control,uchar  Clock_Out);                         
													//CAN控制器的初始化
bit   DATA_WRITE(uchar *SendDataBuf);				//发送特定帧各式的数据                                            
bit   RECEIVE(uchar *RcvDataBuf);					//CAN控制器接收数据
bit   CMD_PRG(uchar cmd);							//执行sja1000命令 
void  sja1000();									//SJA1000初始化
void Initial7221(void);								//MAX7221初始化
void WR7221(uchar addr,uchar Data);					//MAX7221写程序
void Max7221Display(uchar *buffer);					//MAX7221显示程序
void read_0804();									//读AD转换电压值
void wdcl_0804();									//转换电压值
void delay(uint n);		     						//延时程序

main() 
{
	sja1000();										//SJA1000初始化
	while(1)
	{
		uchar k;
		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******/
void read_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;	
}
void wdcl_0804()
{
	temp=(temp*2-273)*10;							//提取一位小数
	c[0]=temp/1000;									//千位
	c[1]=temp/100%10;								//百位
	c[2]=temp/10%10;								//十位
	c[3]=temp%10;									//个位
}

void delay(uint n)		     						//延时程序
{
    uint i1,j1;
    for (i1=0;i1<n;i1++)
        for (j1=0;j1<1140;j1++);
}
void WR7221(uchar addr,uchar Data)					//MAX7221的写子程序
{
    uchar i;
    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;		     						//片选无效
}

void Initial7221(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,哪一位就支持编码
}

void Max7221Display(uchar *buffer)					//MAX7221显示子程序
{
    uchar i;
    for (i=0;i<8;i++)								//MAX7221的8个数码管显示
    {
        WR7221(i+1,*(buffer+i));					//调MAX7221的写子程序
    }
}



void sja1000()
{
	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控制器的接口是否正常                            *
 ************************************************************************/
bit   CREATE_COMMUNATION(void)
{  
	SJA_BCANAdr=REG_TEST;                     		//访问测试寄存器    
    *SJA_BCANAdr   =0xaa;                     		//写入测试值
    if(*SJA_BCANAdr == 0xaa)
    {
		return  0;                          		//读测试正确
    }
    else
    {    
		return  1;
    } 
}       

/************************************************************************
 *说明:      CAN控制器进入复位工作模式                                  *
 ************************************************************************/ 
bit   ENTER_RETMODEL(void)
{
	uchar   TempData;
    SJA_BCANAdr  = REG_CONTROL;                   //访问地址指向控制寄存器 
    TempData=  *SJA_BCANAdr;                      //保存原始值

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -