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

📄 3d can例程.c

📁 ControlCAN 开发程序例程1
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <reg51.h>
#include <math.h>
#include <intrins.h>
#include<absacc.h>
/*****************************************************************/
#define XBYTE ((unsigned char volatile xdata *) 0)
#define uchar unsigned char
#define uint  unsigned int
#define True  1
#define False 0
/*****************************************************************/

sbit RUNLED = P3^3 ;  //RUN指示,频率输出测试指示。
sbit ADCLK = P1^6;
sbit ADIN  = P1^7;
sbit ADOUT = P1^2;
sbit ResetCAN = P1^3;  
sbit ADCS  = P1^4;
sbit DACS  = P1^5;
sbit DACLK = P1^6;
sbit DADAT = P1^7;

sfr  P4    = 0xE8;
sbit DI0   = P4^0;
sbit DI1   = P4^1;
sbit DI2   = P4^2;
sbit DI3   = P4^3;

sbit DO0   = P1^0;
sbit DO1   = P1^1;
sbit DO2   = P3^4;
sbit DO3   = P3^5;

sbit LEDCH3   = P3^0;   
sbit LEDCH2   = P3^1;   

#define WDG    XBYTE [0x8400]   /*外部wtachdog*/
sfr WDT_CONTR = 0xe1 ;          /*定义CPU 看门狗地址*/
sfr AUXR = 0x8e ;               /*声明寄存器的地址*/


/* *********  CAN控制器的控制及状态寄存器地址定义 ************** */
#define	ModeControlReg	XBYTE[0x8000]       /* 控制寄存器  */
#define RM_RR_BIT	0x01	                /* Reset Mode ( Request ) bit */
#define	InterruptEnReg	XBYTE[0x8000]       /* 地址和位定义 中断允许和控制寄存器 */
#define ClrByte     0x00                    /* 默认的寄存器复位值,清除寄存器 */                                            
#define ClrIntEnSJA ClrByte | RM_RR_BIT
#define	RIE_Bit		0x02                    /* 接收中断允许模式位 */
#define	TIE_Bit		0x04                    /* 发送中断允许模式位 */
#define	EIE_Bit		0x08                    /* 错误(故障)中断允许模式位 */
#define	DOIE_Bit	0x10                    /* 超载中断允许模式位 */
	
#define	CommandReg	XBYTE[0x8001]           /* 命令寄存器地址和位定义 */
	
#define	TR_Bit		0x01                    /* 发送请求位 */
#define	AT_Bit		0x02                    /* 终止传送位 */
#define	ERB_Bit		0x04                    /* 释放接收缓冲器位 */
#define	CDO_Bit		0x08	                /* 清除数据超载位 */
#define	GTS_Bit		0x10                    /* 进入睡眠状态位 */
	
#define	StatusReg	XBYTE[0x8002]           /* 状态寄存器地址和位定义 */
	
#define	RBS_Bit		0x01                    /* 接收缓冲器状态位 */
#define	DOS_Bit		0x02                    /* 数据超载状态位 */
#define	TBS_Bit		0x04                    /* 发送缓冲器状态位 */
#define	TCS_Bit		0x08	                /* 传送完成状态位 */
#define	RS_Bit		0x10                    /* 接收状态位 */
#define	TS_Bit		0x20                    /* 发送状态位 */
#define	ES_Bit		0x40                    /* 错误状态位 */
#define	BS_Bit		0x80                    /* 总线状态位 */

#define	InterruptReg XBYTE[0x8003]          /* 中断寄存器地址和位定义 */

#define	RI_Bit		0x01                    /* 接收中断位 */
#define	TI_Bit		0x02                    /* 发送中断位 */
#define	EI_Bit		0x04                    /* 错误警告中断位 */
#define	DOI_Bit		0x08	                /* 数据超载中断位 */
#define	WUI_Bit		0x10	                /* 唤醒中断位 */ 
	
#define BusTiming0Reg	XBYTE[0x8006]       /* 总线时序地址和位定义 */
#define BusTiming1Reg	XBYTE[0x8007]

#define	SAM_Bit		0x80                    /* 采样模式位:1==采样三次
                                                          0==采样一次 */
#define	OutControlReg	XBYTE[0x8008]       /* 输出控制寄存器地址和位定义 */
	
#define	BiphaseMode	0x00                    /* 双向输出模式 */
#define	NormalMode	0x02                    /* 正常输出模式 */
#define	ClkOutMode	0x03                    /* 时钟输出模式 */
                                            /* 输出引脚配置 TX1 */
#define	OCPOL1_Bit	0x20	                /* 输出极性控制位 */
#define	Tx1Float	0x00                    /* 配置为浮空 */
#define	Tx1PullDn	0x40                    /* 配置为下拉 */
#define	Tx1PullUp	0x80                    /* 配置为上拉 */
#define	Tx1PshPull	0xc0                    /* 配置为推挽模式 */
                                            /* 输出引脚配置 TX0 */
#define	OCPOL0_Bit	0x04                    /* 输出极性控制位 */
#define	Tx0Float	0x00                    /* 配置为浮空 */
#define	Tx0PullDn	0x08                    /* 配置为下拉 */
#define	Tx0PullUp	0x10                    /* 配置为上拉 */
#define	Tx0PshPull	0x18                    /* 配置为推挽模式 */

#define AcceptCodeReg	XBYTE[0x8004]       /* 接收过滤码和屏蔽寄存器地址和位定义 */
#define AcceptMaskReg	XBYTE[0x8005]

#define	TxBuffer1	XBYTE[0x800a]           /* 发送缓冲器地址定义 */
#define	TxBuffer2	XBYTE[0x800b]
#define	TxBuffer3	XBYTE[0x800c]
#define	TxBuffer4	XBYTE[0x800d]
#define	TxBuffer5	XBYTE[0x800e]
#define	TxBuffer6	XBYTE[0x800f]
#define	TxBuffer7	XBYTE[0x8010]
#define	TxBuffer8	XBYTE[0x8011]
#define	TxBuffer9	XBYTE[0x8012]
#define	TxBuffer10	XBYTE[0x8013]

#define	RxBuffer1	XBYTE[0x8014]           /* 接收缓冲器地址定义 */
#define	RxBuffer2	XBYTE[0x8015]
#define	RxBuffer3	XBYTE[0x8016]
#define	RxBuffer4	XBYTE[0x8017]
#define	RxBuffer5	XBYTE[0x8018]
#define	RxBuffer6	XBYTE[0x8019]
#define	RxBuffer7	XBYTE[0x801a]
#define	RxBuffer8	XBYTE[0x801b]
#define	RxBuffer9	XBYTE[0x801c]
#define	RxBuffer10	XBYTE[0x801d]
	
#define	ClockDivideReg	XBYTE[0x801f]     /* 时钟分频器地址和位定义 */

#define	DivBy1		0x07                  /* CLKOUT = Fosc */
#define	DivBy2		0x00                  /* CLKOUT = 1/2 Fosc */
	
#define	ClkOff_Bit	0x08                  /* CLKOUT OFF 控制时钟输出位 */
	
#define	RXINTEN_Bit	0x20                  /* TX1引脚配置成接收中断输出 */
#define	CBP_Bit		0x40                  /* CAN比较器旁路控制位 */
#define	CANMode_Bit	0x80                  /* CAN模式定义位 0==BasicCAN Mode*/

uchar data  SelfStationNo  ;              /*接收站号*/

/* CAN 通讯速度因子表 kbps   80KBPS                                     */
#define DBT0        0x83
#define DBT1        0xff

uchar data rxdbuff [ 15 ]   ;           //  _at_ 0x0000 ; /* 从SJ1000接收来的每个站的数据 */
uchar data txdbuff [ 10 ]   ;           //  _at_ 0x0010 ; /* 从SJ1000要发送的数据 */

/* *********  CAN控制器的控制及状态寄存器地址定义 ************** */

uchar data  SendOverTime ;
uchar data  i ;
uchar data  runcount ;
uchar data dbt0 , dbt1 ;

uchar data StatusReg_ES ;
uchar data StatusReg_RX ;
uchar data StatusReg_TX ;
uchar data berkControl_P;
uchar data inth_h ;
uchar data inth_l ;

unsigned char xdata DAT_FX[32768] ; 
unsigned int  XDAVLM ;

unsigned int  dacs01 ;
unsigned int  dacs02 ;
unsigned int  dacsvl ;
unsigned char data ch = 0,ch2 = 0;      //A/D   read
unsigned long data TPtimer ;
unsigned long data TPAtimer ;
unsigned long data TPAcount ;     //频率输出周期控制,(低频)
unsigned long data ZSGcount ;     //从CAN总线上,收不到 车速 报文 计时控制时间。
unsigned long data FKYcount ;     //从CAN总线上,收不到 压力 报文 计时控制时间。
unsigned long data zhuanS ;
unsigned long data Contrtimer ;   //制动信号定时发送

unsigned int advalue[4];          //A/D indata

bit Rcv_Head_Flag0 , Rcv_Head_Flag1 , Rcv_Head_Flag2 , Rcv_Head_Flag3 , Rcv_Head_Flag4 ;
bit Rcv_Head_Flag4 ;
bit Sending , senddataflag ;   /* 正在发送标志和内部RAM中有报文要发送 */

uchar berkControl ;
bit berkControl_B7 ;
bit berkControl_b32 ;
bit F_outfpot ;
bit RXDbuf_Er ;     //Receive Erro
bit TXTbuf_Er ;     //Transmit Erro

#define	berkc_Bit  0x80

extern void _nop_     ( void ) ;

void clrwdt ( void )
{
    _nop_ ( ) ;
}  

// 延时子函数
void DELAYFOR(unsigned long mDATA)
{
    unsigned long i ;
    for (i=0;i<mDATA;i++) ;
}
//计算输出频率对应的周期
float fout_t(unsigned long speed)
{
    float timer_t ;
    timer_t=((speed*0.01315)*45/40) ;      
    timer_t=1000000/timer_t ;              
    timer_t=timer_t / 2 ;                  
    return (timer_t) ;
}
//定时器预置初值计算(对应的周期)
unsigned long fout_tt(unsigned long speed)
{
    unsigned long timer_tt ;
    timer_tt = (12*65536-speed*22)/12 ;    
    return (timer_tt) ;  
}
//  换算D/A输出值
unsigned long DA_out(unsigned long MPA_Z)
{
    unsigned long MPA_V ;
    MPA_V = (MPA_Z*4095)/5000 ;            
    return (MPA_V) ;  
}
//  Send CAN
void  Send_CAN ( void )     //制动信息送CAN总线
{
  do {  StatusReg_TX = StatusReg ;
        StatusReg_TX = StatusReg_TX & TBS_Bit ;
      }while ( !( StatusReg_TX ==0x04 ) ) ;          //等待发送寄存器释放,是则发送

        TxBuffer1 = txdbuff [ 0x00 ] ;               //0x25  ID:128
        TxBuffer2 = txdbuff [ 0x01 ] ;               //0x01
        TxBuffer3 = txdbuff [ 0x02 ] ; 

        CommandReg = CDO_Bit | TR_Bit | ERB_Bit ;    // 请求数据发送,同时清除数据超载,释放接收缓冲区
        Sending = False ;
}

// Send CAN 调试用
//void  SendTT_CAN ( void )                          //输出频率送CAN总线
//{
//  do {  StatusReg_TX = StatusReg ;
//        StatusReg_TX = StatusReg_TX & TBS_Bit ;
//      }while ( !( StatusReg_TX ==0x04 ) ) ;      //等待发送寄存器释放,是则发送

//       TxBuffer1 = txdbuff [ 0x00 ] ;            //0x25 ID:128
//       TxBuffer2 = txdbuff [ 0x01 ] ;            //0x02
//       TxBuffer3 = txdbuff [ 0x02 ] ; 
//      TxBuffer4 = txdbuff [ 0x03 ] ;

//       SendOverTime = 0x00 ;
//       CommandReg = CDO_Bit | TR_Bit | ERB_Bit ; // 请求数据发送,同时清除数据超载,释放接收缓冲区
//       Sending = False ;
//}

void init ( void )
 {
   Rcv_Head_Flag0 = Rcv_Head_Flag1 = Rcv_Head_Flag2 = Rcv_Head_Flag3 = Rcv_Head_Flag4 =False ;
   Rcv_Head_Flag4 = False ;
   
   ResetCAN = 1 ;
   
   SelfStationNo = 0x67 ;      //接收站号 24和63

   Sending = False ;
   senddataflag = False ;

   SendOverTime = 0x00 ;
   berkControl = 0x00 ;
   berkControl_P = 0x08 ;
   berkControl_B7 = False ;
   DI0=1,DI1=1,DI2=1,DI3=1 ;    //输入初始化
   DO0=1,DO1=1,DO2=0,DO3=0 ;    //输出初始化
   Rcv_Head_Flag2 = 1 ;         //制动信息输入端初值,如果初始状态此输入端为1,则初值为1;否则相反。
   LEDCH2 = LEDCH3 = RUNLED = 1 ; //Rxd,Txd 关暗 RUN关暗
   ZSGcount =0 ;                //转速收不到,计时单元
   Contrtimer = 0 ;             //制动信号定时发送
   FKYcount =0 ;                //压力收不到,计时单元

   WDG=0;WDG=1;                 //清除watchdog
   WDT_CONTR = 0x37 ;           //喂狗
 }

// 多主模式,固定通讯速度=80Kbps
void init_can ( void )
 {
   unsigned char i ;

   ModeControlReg = RIE_Bit | RM_RR_BIT | EIE_Bit | DOIE_Bit | TIE_Bit ;

   while ( ( ModeControlReg &  RM_RR_BIT ) == ClrByte )
     {
        ModeControlReg = RIE_Bit | RM_RR_BIT | EIE_Bit | DOIE_Bit | TIE_Bit ;
        _nop_ ( ) ;
        _nop_ ( ) ;
     }

   DELAYFOR (3);

   AcceptCodeReg = SelfStationNo ;  // 高3位为类型,低5位为站号
   AcceptMaskReg = 0x67 ;           // 验收屏蔽码

   BusTiming0Reg = dbt0 ;           // 80Kbps
   BusTiming1Reg = dbt1 ;

   OutControlReg = Tx1Float | Tx0PshPull | NormalMode ;

   ClockDivideReg = 0x00 ;          // CAN模式定义位 0==BasicCAN Mode
   
   ModeControlReg = RIE_Bit | 0x60 ;                   // 允许CAN接收中断,同步
   
   for ( i = 0x00 ; i < 3 ; i ++ )_nop_ ( );

   CommandReg = CDO_Bit | ERB_Bit | TR_Bit ;           // 释放接收缓冲区,清除超载,允许CAN接收,发送请求

   SendOverTime = 0x00 ;
   while ( SendOverTime < 2 ) _nop_ ( ) ;              // 20 ms

 }

//CAN 接收函数
uchar Receive ( void )
{
    StatusReg_ES=StatusReg ;
	if ((StatusReg_ES&ES_Bit)==0x40)
	{
       Sending= False;
	}
    StatusReg_ES=StatusReg ;

	if (( StatusReg_ES & DOS_Bit ) == 0x20)
	{
       Sending= False;
	}
    StatusReg_RX = StatusReg ;                    /*状态寄存器*/

    if ((StatusReg_RX & RBS_Bit)==0x01)           /* 接收缓冲器状态位*/ 
    {
        do
        {           
	        rxdbuff [ 0x00 ] = RxBuffer1 ;        /* 消息正常接收中断时执行*/
	        rxdbuff [ 0x01 ] = RxBuffer2 ;
            rxdbuff [ 0x02 ] = RxBuffer3 ;
            rxdbuff [ 0x03 ] = RxBuffer4 ;
            rxdbuff [ 0x04 ] = RxBuffer5 ;
            rxdbuff [ 0x05 ] = RxBuffer6 ;
            rxdbuff [ 0x06 ] = RxBuffer7 ;
            rxdbuff [ 0x07 ] = RxBuffer8 ;
            rxdbuff [ 0x08 ] = RxBuffer9 ;
            rxdbuff [ 0x09 ] = RxBuffer10 ;
        
			if ( rxdbuff [ 0x00 ] == 0x24 )        // 收到 转速 报文
	     	{
		          Rcv_Head_Flag4 = True ;          
		    }

            if ( rxdbuff [ 0x00 ] == 0x63 )        // 收到 压力反馈 报文
		    {
		          Rcv_Head_Flag3 = True ;          
		    }

	        CommandReg =  ERB_Bit ;                /* 释放接收缓冲*/
          
	        StatusReg_RX = StatusReg ;             /*状态寄存器*/

        } while ((StatusReg_RX & RBS_Bit)==0x01) ; /* 若队列中还有消息,则反复读取,直到将队列清空**/

        rxdbuff [ 10 ] = InterruptReg ;            /* 清除接收中断 */

        return True ;
	}
	else
	{
        rxdbuff [ 10 ] = InterruptReg ;           /* 清除接收中断 */
		CommandReg = CDO_Bit | ERB_Bit ;          /* 释放接收缓冲区,清除超载,允许CAN接收 */
        RXDbuf_Er  = True ;                       /* 接收错误标识 */
    	return False ;                            /* 不做接收数据处理 */
	}
}

//A/D输入函数
//unsigned int readad(unsigned char channel)
//{
//   unsigned int i=0,ndata=0;
//	ADCLK = 0;
//    ADCS = 0;
//	ADOUT = 1;
//    for(i=0;i<12;i++)
//    {
//	    if ((channel & 0x08) == 0)
//		    ADIN = 0;
//		else
//		    ADIN = 1;
//		    channel = channel << 1;
//                  ADCLK = 1;
//                  ndata = ndata << 1;
//                  ndata = ndata | ADOUT;
//		    ADCLK = 0;
//    }
//	ADCS = 1;
//	return ndata;
//}

// D/A OUT
void writeda(unsigned int ndata1,ndata2)
{
    unsigned int i=0;

	ndata2 |= 0x1000;
	DACLK = 1;
    DACS = 0;
    for(i=0;i<16;i++)
    {
	    if ((ndata2 & 0x8000) == 0)
		    DADAT = 0;
		else
		    DADAT = 1;
		DACLK = 0;
		ndata2 = ndata2 << 1;
        DACLK = 1;
    }
	DACS = 1;
	DACLK = 0;

	ndata1 |= 0x8000;
	DACLK = 1;
    DACS = 0;
    for(i=0;i<16;i++)
    {
	    if ((ndata1 & 0x8000) == 0)

⌨️ 快捷键说明

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