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

📄 car_3.c

📁 通过对其他国家对超载问题的治理措施及研究现状的深入分析
💻 C
📖 第 1 页 / 共 2 页
字号:
//-----------------------变量定义-----------------------------------//
#include <reg51.h>
#include <intrins.h>
#include <absacc.h>
#define base_Adr 0x6000   //定义寻址的基址
#define SJA_BTR0 0xC9   //定义总线定时寄存器的值
#define SJA_BTR1 0xC9                                 
#define SJA_ACR 0xAA    //验收代码寄存器的值
#define SJA_AMR 0x00    //验收屏蔽寄存器的值
#define SJA_OCR 0xFF    //输出控制寄存器的值
#define SJA_CDR 0x48    //始终分频寄存器的值
#define TR_CMD  0x01    //发送请求命令
#define AT_CMD  0x02    //夭折发送命令
#define RRB_CMD 0x04    //释放接收缓冲区
#define COS_CMD 0x08    //清除超载状态
#define GTS_CMD 0x10    //进入睡眠状态命令 
#define uc unsigned char
#define on 0
#define off 1
#define A0 0
#define Am 30000
#define Nm 255
#define a  0.95                  //定义滤波系数
#define DISPORT XBYTE[0x2000]   //定义显示接口地址
#define  timer_data  (256-100) //定时器预置值,12M时钟是,定时0.1ms
#define  PWM_T 100         //定义PWM的周期T为10ms
unsigned char xdata *SJA_base_Adr = base_Adr;  //定义地址指针,指向基址
bit bdata connect_OK=0;    //connect_OK=1设备连接正常,connect_OK=0设备连接故障
bit bdata SJA_workmode=1; //SJA_workmode=1SJA工作在工作模式,SJA_workmode=0工作在复位模式
unsigned char PWM_t;       //PWM_t为脉冲宽度(0~100)时间为0~10ms
int PWM_count=0;            //输出PWM周期计数
unsigned char time_count;  //定时计数
bit direction;             //方向标志为
bit setting_rate_success;  //设置SJA波特率成功标志位
bit setting_clk_success;   //设置SJA输出始终类型成功标志位
bit setting_dataselect_success; //设置SJA接收数据类型成功标志位
sbit PWM=P1^7;             //PWM波形输出 
sbit DR=P3^4;              //方向控制
sbit buffer=P1^6;          //报警控制
sbit TXEN=P3^5;
sbit  int0 = P3^2;
long Car_weight=0;        //车辆载重值
unsigned char value=0;
unsigned char new_value=0;
unsigned char Nx=0;
unsigned int count=1;     //控制油门计数变量
uc code seg[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xbf,0xff,0xfe,0x7f};
uc code seg1[]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};
uc code carinfo[]={0xff,0x00,0x12,0x34,0x56,0x78,0x90,0x15,0xf0};
uc buf[6];
struct BASICCAN_BUFstruct{
               unsigned char FrameID_H;
               unsigned char FrameLENTH ;
			   unsigned char FrameKIND  ;
			   unsigned char FrameID_L3 ;
			   unsigned char Frame_Data[8];
			   }BASICCAN_FRAME,receive_BUF,send_BUF;  //定义SJA1000读写缓冲区的数据结构
//--------------------------------------------------------------------------------//

//-----------------------函数声明------------------------------------------------//
unsigned char adconvert(char channel);  //AD转化函数
void display(void);                     //动态显示函数
void delay(unsigned int N);             //延时子程序
void timer1_init(void);                 //定时器1初始化函数
void setting_PWM(void);                 //设置PWM波
void UART_init(void);                   //串口初始化函数
void COM_send(void);                    //串口发送函数
void SJA1000_init(void);                //SJA初始化
bit Write_SJAsendBUF(void);             //写SJA发送缓存器           
bit read_SJAreceiveBUF(void);           //读SJA接收缓存器
void CANREG_write(unsigned char SJAREG_ADR, unsigned char setting);  //写SJA的寄存器
unsigned char CANREG_read(unsigned char SJAREG_ADR);    //读SJA的寄存器
void SJAconnect_judge(void);            // 判断SJA1000与控制器连接是否正常
void setting_SJA_resetmode(void);       // 设置SJA工作在复位模式
void setting_SJA_workingmode(void);     // 设置SJA工作在复位模式
void setting_SJA_rate(void);             // 设置SJA波特率
void setting_SJA_dataselect(void);       // 设置SJA接收数据类型
void setting_SJA_CLK(void);              // 设置SJA输出始终类型
void setting_SJA_interrupt(void);       // 设置SJA中断类型和中断状态
void cansend(void);                     // 设置SJA发送
bit  BCAN_CMD_PRG(unsigned char cmd);   // 设置SJA命令寄存器
//---------------------------------------------------------------------------------//

//-----------------------中断服务函数------------------------------------------------//
void IntTimer0() interrupt 1      //定时器0中断服务程序,用于AD转化
{ 
   TH0=0xee;
   TL0=0x00;
   display();
   Nx=adconvert(0);
}

void IntTimer1() interrupt 3   //定时器1中断服务程序,用于PWM波形输出
{ 
 if(PWM_count<10000)
 {
	time_count++;
    DR=direction;
    if(time_count>=PWM_T)
     {
	  time_count=0;
	  PWM_count++;
	 }
	if(time_count<PWM_t)
	PWM=1;
	else 
	PWM=0;
 }
 else
 {   TR1=0;                   //停止定时器1计数
     PWM=0;                  //停止PWM输出
     count++;              //控制油门计数
 }

}

void SJA_INTR() interrupt 0 using 1	//CanBus接口芯片产生中断(INTR0)
{
  unsigned char sta;
  unsigned char temp;
  EX0 = 0;
  sta = CANREG_read(3);		       //读中断寄存器
  temp = sta & 0x20;
  if(temp == 0x20)
    SJA1000_init(); 
  temp = sta & 0x04;
  if(temp == 0x04)
    SJA1000_init();			        //消极错误中断,错误报警中断,均导致重启
  temp = sta & 0x02;
  if(temp == 0x02)                  //发送中断处理
    {
	  ;
	}
  temp = sta & 0x01;
  if(temp == 0x01)		             //接收中断,接收数据
  {
   read_SJAreceiveBUF();
  }  
  EX0 = 1;
}
//---------------------------------------------------------------------------------//

//---------------------------主函数----------------------------------------//
main()
{
 unsigned int i,j;
 TMOD=0x21;                            //定时器0工作在方式1定时方式                               
 TH0=0xee;                             //定时器0定时初值
 TL0=0x00;
 ET0=1;                                //开放定时器0中断
 TR0=1;                                //开放定时器0计数
 EA=1;                                 //开放中断
 SJA1000_init();                       //初始化SJA1000
 setting_PWM();                        //设置PWM
while(1)
{
        Car_weight=(long)(Am-A0)*Nx/Nm+A0;  //工程量转化
	    buf[5]=Car_weight%10;
	    buf[4]=Car_weight%100/10;
	    buf[3]=Car_weight/100%10;
	    buf[2]=Car_weight/100/10%10;
        buf[1]=Car_weight/10000;
	    buf[0]=17;
		cansend();                  //向CAN总线发送数据
       if(Car_weight>6000)              //当超载20%时,蜂鸣器报警
		{
		 for(j=0;j<1000;j++)
		 {	for(i=0;i<1000;i++)
				buffer=1;
			for(i=0;i<1000;i++)
				buffer=0;
		 }
		}

	   if((Car_weight>15000)&&(Car_weight<18000)&&(count%2!=0))    //当超载50%时,初始化定时器1,输出PWM波形,控制直流电机封油门
		{                                             
            direction=~direction;
		    timer1_init();
		}
       if((Car_weight<15000)&&(count%2==0))    //当采取措施使超载小于50%,,解除油门封锁
        { 
          direction=~direction;
          timer1_init();
        }
        if(Car_weight>18000)                           //当超载60%时,通过串口向PTR2000传送数据,启动无线发送
			{
			  UART_init();
			  TXEN=1;
			  delay(311);        //延时5ms
              COM_send();
			  TXEN=0;
			}


	}
}
//---------------------------------------------------------------------------------//

//---------------------------函数定义----------------------------------------//

//---------------------------------
// 函数名称 delay
// 函数功能 延时子程序,实现(16*N+24)us的延时
// 特殊要求 系统采用11.0592MHz的时钟
//---------------------------------
void delay(unsigned int N)
{
  unsigned int i;
  for(i=0;i<N;i++)
  _nop_();
}

//---------------------------------
// 函数名称 display
// 函数功能 LED动态显示
// 特殊要求 无
//---------------------------------
void display()
{
 uc i,j,temp;
 temp=0xfe;                  //动态扫描LED
 for(i=0;i<7;i++)
  {  if(i==4)
       DISPORT=seg1[buf[4]];   //读段码
     else 
	   DISPORT=seg[buf[i]];
     P1=temp;
     for(j=0;j<50;j++)         //延时
    _nop_();
    temp=temp*2+1;              //扫描位码
  }
}

//---------------------------------
// 函数名称 adconvert
// 函数功能 进行AD转化
// 特殊要求 无
//---------------------------------
unsigned char adconvert(char channel)
{
  unsigned char result;
  unsigned char xdata *adport;
  adport=0x0000+channel;   //选择AD转化通道
  *adport=0;
  value=new_value;
  delay(5);               //延时100us,等待AD转化结束
  _nop_();_nop_();
   new_value=*adport;
   result=(unsigned char)(a*new_value+(1-a)*value);   //进行数字滤波
   return result;
}

//---------------------------------
// 函数名称 timer1_init
// 函数功能 定时器1初始化
// 特殊要求 无
//---------------------------------
void timer1_init()
     {
	  TMOD=0x21; /*定时器1为工作模式2(8位自动重装),0为模式2(8位自动重装) */
      PCON=0x00;
      TF1=0; 
      TH1=timer_data;   //保证定时时长为0.1ms
      TL1=TH1;
      ET1=1;
	  TR1=1;            //开始计数
      EA=1;             //中断允许
	  }

//---------------------------------
// 函数名称 setting_PWM
// 函数功能 设置PWM的脉冲宽度和设定方向
// 特殊要求 无
//---------------------------------
void setting_PWM(void)
      {
	  if(PWM_count==0)  //初始设置
	  {
	  PWM_t=20;
	  direction=0;
	  }
	  }

//---------------------------------
// 函数名称 UART_init
// 函数功能 串口初始化
// 特殊要求 无
//---------------------------------
void UART_init(void)
{
 PCON=0x00;           
 SCON=0x58;          //选择串口工作方式,打开接收允许
 TMOD=0x21;          //定时器1工作在方式2,定时器0工作在方式1
 TH1=0xfd;           //实现波特率9600(系统时钟11.0592MHZ)
 TR1=1;              //启动定时器T1
 ET1=0; 
}

//---------------------------------
// 函数名称 COM_send
// 函数功能 串口发送
// 特殊要求 无
//---------------------------------
void COM_send(void)
{
	uc point;
for(point=0;point<=9,TI=1;point++)	     //连续发送十位数据
                                      //把缓存区的数据都发送到串口
  {
   SBUF=carinfo[point];
   TI=0;
   }
}


//---------------------------------
// 函数名称 CANREG_write
// 函数功能 写SJA1000的寄存器
//---------------------------------
void CANREG_write(unsigned char SJAREG_ADR, unsigned char setting)
           {
                    *(SJA_base_Adr+SJAREG_ADR)=setting;
            }

//---------------------------------
// 函数名称 CANREG_read
// 函数功能 读SJA1000的寄存器
//---------------------------------
unsigned char CANREG_read(unsigned char SJAREG_ADR)
{
unsigned char SJAREG_data;
SJAREG_data=*(SJA_base_Adr+SJAREG_ADR);

⌨️ 快捷键说明

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