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

📄 voltage_can.c

📁 pci单片机实现四节点电压温度采集
💻 C
字号:
# include "p18f458.h"
//unsigned int a[12]={0};
void InterruptHandlerHigh(void);
int	CAN_FLAG;		//定义标志寄存器
unsigned char t,c;
unsigned int V;
float b[12];
unsigned char VL=0,VH=0;
unsigned int dataL=0,dataH=0;
unsigned int date1l,date1h,date2l,date2h,date3l,date3h,date4l,date4h,date5l,date5h,date6l,date6h,date7l,date7h,date8l,date8h,date9l,date9h,date10l,date10h,date11l,date11h,date12l,date12h;
int j,k=0;
//...............高优先级中断向量..............
#pragma code InterruptVectorHigh=0x08
void InterruptVectorHigh(void)
{
   _asm
   goto InterruptHandlerHigh
   _endasm
}
//................高优先级中断服务程序.........
#pragma code
#pragma interrupt InterruptHandlerHigh
void InterruptHandlerHigh(void)
{   
        if(PIR3bits.RXB0IF==1)	
    	CAN_FLAG=1;
        PIR3bits.RXB0IF=0;					//清接收中断标志
        t=RXB0D0;                           //点名赋值
	    RXB0CON=RXB0CON|0X80;		//关闭接受寄存器
}
void delay(unsigned  int x)
{ 
   unsigned int d;
   d=x;
   while(--d)
   {;}
}
void initial()
{
  TRISD=0x00;   //设D口为输出
  PORTD=0x10;   //关闭74HC154
  delay(10);     //延时
  TRISE=0x00;   //设E口为输出
  PORTEbits.RE0=1;   //屏蔽4052BE
  delay(10);
}

void AD_initial()
{ 
  INTCON=0x00;
  ADCON0=0x49;   //选择通道1,打开A/D在工作状态
  ADCON1=0x80;   //选择右对齐,参考电压为的单片机工作电压,(实际应使用RA3口输入电压)
  PIR1bits.ADIF==0; //转换标志位清零
  TRISA|=0x02;   //设置RA1为输入
  delay(1);
}
void can_initial()
{
   TRISB=(TRISB|0X08)&0XFB;		//设置CANRX/RB3为输入,CANTX/RB2为输出
//设置CAN的波特率为125K,在Fosc=4M时,Tbit=8us,假设BRP=01h
//则TQ=[2*(1+BRP)]/Fosc=2*(1+1)/4=1us。
//NOMINAL BIT RATE=8TQ,SJW=1,Sync_Seg=1TQ,Prog _Seg=1TQ,Phase_Seg1=3TQ,Phase_Seg2=3TQ
CANCON=0X80;				//请求进入CAN配置模式REQOP=100	
	while(CANSTAT&0X80==0){;}		//等待进入CAN配置模式OPMODE=100
	BRGCON1=0X01;				//设置SJW和BRP,SJW=1TQ,BRP=01H
	BRGCON2=0X90;				//设置Phase_Seg1=3TQ和Prog _Seg=1TQ
	BRGCON3=0X42;				//设置Phase_Seg2=3TQ

//设置发送邮箱0标识符号和发送的数据
	TXB0CON=0X03;		//发送优先级为最高优先级,TXPRI=11
	TXB0SIDH=0X00;	//设置发送缓冲器0的标准标识符,本程序采用标准识符
	TXB0SIDL=0X00;
	TXB0DLC=0X08;		//设置数据长度为8个字节
	TXB0D0=0X00;		//写发送缓冲器数据区的数据
	TXB0D1=0X01;
	TXB0D2=0X02;
	TXB0D3=0X03;
	TXB0D4=0X04;
	TXB0D5=0X05;
	TXB0D6=0X06;
	TXB0D7=0X07;

//设置接收邮箱0的标识符和初始化数据
	RXB0SIDH=0XFF;	//设置接收缓冲器0的标识符	
	RXB0SIDL=0XE0;
	RXB0CON=0X20;		//仅仅接收标准标识符的有效信息,FILHIT0=0表示RXB0采用filter0
	RXB0DLC=0X08;		//设置接收缓冲器0的数据区长度
	RXB0D0=0X00;		//初始化接收缓冲器0的数据区数据
	RXB0D1=0X00;
	RXB0D2=0X00;
	RXB0D3=0X00;
	RXB0D4=0X00;
	RXB0D5=0X00;
	RXB0D6=0X00;
	RXB0D7=0X00;
//初始化接收滤波器0和接收屏蔽,很重要
	RXF0SIDH=0XFF;
	RXF0SIDL=0XE0;//与接收缓冲器标识符相同
	RXM0SIDH=0X00;//不屏蔽
	RXM0SIDL=0X00;

//使CAN进入某种工作模式模式
	CANCON=0X00;			//=0X40,进入自测试模式;=0x00,正常操作模式
	while(CANSTAT&0XE0!=0){;}
//初始化CAN的中断
	PIR3=0X00;			//清所有中断标志
    PIE3=0X01;			//使能接收缓冲器0的接收中断
	IPR3=0X01;			//接收缓冲器0的接收中断为最高优先级
}

void ADtest_V()
{   
//..........................测试第1个电池...................................

  PORTE=0x00;   //打开测试1—4个电池的通道
  PORTD=0x00;   //打开通道1 测试第1个电池电压
  delay(200);     //延时 
  for(j=0;j<10;j++)
   { 
    ADCON0bits.GO=1;  //  使能AD转换
    while(PIR1bits.ADIF==0);
    PIR1bits.ADIF==0;
    VL=ADRESL;
    VH=ADRESH;
    dataL+=VL;
    dataH+=VH;
   }
  V=dataL+(dataH<<8); 
  V=V/10;
  date1l=V;
  date1h=V>>8;
  dataL=0;
  dataH=0; 
//..........................测试第2个电池................................... 
 
  PORTD=0x01;   //打开通道2 测试第2个电池电压
  delay(200);     //延时 
    for(j=0;j<10;j++)
   { 
    ADCON0bits.GO=1;  //  使能AD转换
    while(PIR1bits.ADIF==0);
    PIR1bits.ADIF==0;
    VL=ADRESL;
    VH=ADRESH;
    dataL+=VL;
    dataH+=VH;
   }
  V=dataL+(dataH<<8); 
  V=V/10;
  date2l=V;
  date2h=V>>8;
  dataL=0;
  dataH=0; 
//..........................测试第3个电池...................................  

  PORTD=0x02;   //打开通道3 测试第3个电池电压
  delay(200);     //延时 
   for(j=0;j<10;j++)
   { 
    ADCON0bits.GO=1;  //  使能AD转换
    while(PIR1bits.ADIF==0);
    PIR1bits.ADIF==0;
    VL=ADRESL;
    VH=ADRESH;
    dataL+=VL;
    dataH+=VH;
   }
  V=dataL+(dataH<<8); 
  V=V/10;
   date3l=V;
  date3h=V>>8;
  dataL=0;
  dataH=0; 
//  ..........................测试第4个电池................................... 
 
  PORTD=0x03;   //打开通道4测试第4个电池电压
  delay(200);     //延时 
    for(j=0;j<10;j++)
   { 
    ADCON0bits.GO=1;  //  使能AD转换
    while(PIR1bits.ADIF==0);
    PIR1bits.ADIF==0;
    VL=ADRESL;
    VH=ADRESH;
    dataL+=VL;
    dataH+=VH;
   }
  V=dataL+(dataH<<8); 
  V=V/10;
   date4l=V;
  date4h=V>>8;
  dataL=0;
  dataH=0;  
//..........................测试第5个电池...................................  

  PORTE=0x02;   //打开测试5—8个电池的通道
  PORTD=0x04;   //打开通道5测试第5个电池电压
  delay(200);     //延时 
   for(j=0;j<10;j++)
   { 
    ADCON0bits.GO=1;  //  使能AD转换
    while(PIR1bits.ADIF==0);
    PIR1bits.ADIF==0;
    VL=ADRESL;
    VH=ADRESH;
    dataL+=VL;
    dataH+=VH;
   }
  V=dataL+(dataH<<8); 
  V=V/10;
  date5l=V;
  date5h=V>>8;
  dataL=0;
  dataH=0;  
//..........................测试第6个电池................................... 
 
  PORTD=0x05;   //打开通道6测试第6个电池电压
  delay(200);     //延时 
    for(j=0;j<10;j++)
   { 
    ADCON0bits.GO=1;  //  使能AD转换
    while(PIR1bits.ADIF==0);
    PIR1bits.ADIF==0;
    VL=ADRESL;
    VH=ADRESH;
    dataL+=VL;
    dataH+=VH;
   }
  V=dataL+(dataH<<8); 
  V=V/10;
  date6l=V;
  date6h=V>>8;
  dataL=0;
  dataH=0;  
//..........................测试第7个电池...................................
  
  PORTD=0x06;   //打开通道7测试第一个电池电压
  delay(200);     //延时 
    for(j=0;j<10;j++)
   { 
    ADCON0bits.GO=1;  //  使能AD转换
    while(PIR1bits.ADIF==0);
    PIR1bits.ADIF==0;
    VL=ADRESL;
    VH=ADRESH;
    dataL+=VL;
    dataH+=VH;
   }
  V=dataL+(dataH<<8); 
  V=V/10;
   date7l=V;
  date7h=V>>8;
  dataL=0;
  dataH=0;  
//..........................测试第8个电池...................................  

  PORTD=0x07;   //打开通道8测试第8个电池电压
  delay(200);     //延时 
    for(j=0;j<10;j++)
   { 
    ADCON0bits.GO=1;  //  使能AD转换
    while(PIR1bits.ADIF==0);
    PIR1bits.ADIF==0;
    VL=ADRESL;
    VH=ADRESH;
    dataL+=VL;
    dataH+=VH;
   }
  V=dataL+(dataH<<8); 
  V=V/10;
   date8l=V;
  date8h=V>>8;
  dataL=0;
  dataH=0;  
//..........................测试第9个电池...................................  

  PORTE=0x04;   //打开测试9—12个电池的通道
  PORTD=0x08;   //打开通道9测试第9个电池电压
  delay(200);     //延时 
    for(j=0;j<10;j++)
   { 
    ADCON0bits.GO=1;  //  使能AD转换
    while(PIR1bits.ADIF==0);
    PIR1bits.ADIF==0;
    VL=ADRESL;
    VH=ADRESH;
    dataL+=VL;
    dataH+=VH;
   }
  V=dataL+(dataH<<8); 
  V=V/10;
   date9l=V;
  date9h=V>>8;
  dataL=0;
  dataH=0;  
//..........................测试第10个电池...................................  

  PORTD=0x09;   //打开通道10测试第10个电池电压
  delay(200);     //延时 
   for(j=0;j<10;j++)
   { 
    ADCON0bits.GO=1;  //  使能AD转换
    while(PIR1bits.ADIF==0);
    PIR1bits.ADIF==0;
    VL=ADRESL;
    VH=ADRESH;
    dataL+=VL;
    dataH+=VH;
   }
  V=dataL+(dataH<<8); 
  V=V/10;
   date10l=V;
  date10h=V>>8;
  dataL=0;
  dataH=0;  
//..........................测试第11个电池...................................  

  PORTD=0x0A;   //打开通道11 测试第11个电池电压
  delay(200);     //延时 
   for(j=0;j<10;j++)
   { 
    ADCON0bits.GO=1;  //  使能AD转换
    while(PIR1bits.ADIF==0);
    PIR1bits.ADIF==0;
    VL=ADRESL;
    VH=ADRESH;
    dataL+=VL;
    dataH+=VH;
   }
  V=dataL+(dataH<<8); 
  V=V/10;
   date11l=V;
  date11h=V>>8;
  dataL=0;
  dataH=0;  
//..........................测试第12个电池...................................  

  PORTD=0x0B;   //打开通道12 测试第12个电池电压
  delay(200);     //延时 
   for(j=0;j<10;j++)
   { 
    ADCON0bits.GO=1;  //  使能AD转换
    while(PIR1bits.ADIF==0);
    PIR1bits.ADIF==0;
    VL=ADRESL;
    VH=ADRESH;
    dataL+=VL;
    dataH+=VH;
   }
  V=dataL+(dataH<<8); 
  V=V/10;
   date12l=V;
  date12h=V>>8;
  dataL=0;
  dataH=0;  
}
main()
{
    INTCON=0x00;	//禁止所有中断	
	WDTCON=0;		//=1,看门狗使能;=0,禁止看门狗
    initial();
    AD_initial();
    can_initial();
    INTCON=0xc0;			//使能中断 
    TXB0CON=TXB0CON&0XF7;	    //禁止发送
    RXB0CON=RXB0CON|0X80;		//关闭接受寄存器
for(;;)
  {   
    RXB0CON=RXB0CON&0X7F;	//打开接收缓冲器来接收新信息    
    while(CAN_FLAG==0);	    //等待接收数据
	CAN_FLAG=0;				//清接收到标志
    while(t!=0xBB);         //判断是否被点名
    for(c=0;c<100;c++)  //发送10个电压数据组
      {
    ADtest_V();
//...............................发第一组4个电压数据....................................... 
    TXB0SIDH=0X00;	//设置发送缓冲器0的标准标识符,本程序采用标准识符
	TXB0SIDL=0X00; //告诉上位机发第一组电压
    delay(10);	
    TXB0D0=date1l;			
	TXB0D1=date1h;
	TXB0D2=date2l;
	TXB0D3=date2h;
	TXB0D4=date3l;
	TXB0D5=date3h;
	TXB0D6=date4l;
	TXB0D7=date4h;
	TXB0CON=TXB0CON|0x08;		 //请求发送,TXREQ=1
	while(PIR3bits.TXB0IF!=1){;} //等待发送完成
	TXB0CON=TXB0CON&0XF7;	    //禁止发送
	delay(500);				   //delay for some time, then send another

//...............................发第二组4个电压数据.......................................    
    TXB0SIDH=0X00;	//设置发送缓冲器0的标准标识符,本程序采用标准识符
	TXB0SIDL=0X20;
	delay(10);	
    TXB0D0=date5l;			
	TXB0D1=date5h;
	TXB0D2=date6l;
	TXB0D3=date6h;
	TXB0D4=date7l;
	TXB0D5=date7h;
	TXB0D6=date8l;
	TXB0D7=date8h;
	TXB0CON=TXB0CON|0x08;		 //请求发送,TXREQ=1
	while(PIR3bits.TXB0IF!=1){;} //等待发送完成
	TXB0CON=TXB0CON&0XF7;	    //禁止发送
	delay(500);				   //delay for some time, then send another 

//...............................发第三组4个电压数据....................................... 
   
    TXB0SIDH=0X00;	//设置发送缓冲器0的标准标识符,本程序采用标准识符
	TXB0SIDL=0X40;
	delay(10);	
    TXB0D0=date9l;			
	TXB0D1=date9h;
	TXB0D2=date10l;
	TXB0D3=date10h;
	TXB0D4=date11l;
	TXB0D5=date11h;
	TXB0D6=date12l;
	TXB0D7=date12h;
	TXB0CON=TXB0CON|0x08;		 //请求发送,TXREQ=1
	while(PIR3bits.TXB0IF!=1){;} //等待发送完成
	TXB0CON=TXB0CON&0XF7;	    //禁止发送
	delay(500);				  //delay for some time, then send another 
   }
delay(1000);
 }
}

⌨️ 快捷键说明

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