标题:
通过CAN总线单字节发送0-F 仪表寿命驱动程序
[打印本页]
作者:
lzj666666
时间:
2018-2-6 13:10
标题:
通过CAN总线单字节发送0-F 仪表寿命驱动程序
//===================================================================================
// 工程名称: 通过CAN总线单字节发送0-F
// 功能描述: CAN通信测试程序,CAN中继器的功能
// IDE环境: ICCAVR
// 组成文件: main.c, REG51.h 2515.h, CAN.h ,function.h
// Content:
// Init2515: 2515初始化程序
// CAN_ Send: CAN发送子程序,查询发送
// CAN_Receive:CAN接收子程序,中断接收
//
// 硬件连接: AT89S51/52+MCP2515
//
// 维护记录: 2009-6-17 v1.0
//===================================================================================
#include<iom8v.h>
#include<bit.h>
#include <macros.h>
#include <math.h>
#include "2515.h"
#include "SPI_Ctrl.h"
#include "Function.h"
#include "CAN0.h"
#define uint unsigned int
#define uchar unsigned char
//sbit key=P2^5; //Button按键
#define key_si1 PINDBIT1
#define key_si2 PINDBIT2
#define key_si3 PINDBIT3
//sbit P3_5=P3^5;//数码管位选
//sbit P2_6=P2^6;
#define IGN_CLR PORTC &= ~(1 << PC0)
#define IGN_SET PORTC |= (1 << PC0)
#define BATT_CLR PORTC &= ~(1 << PC1)
#define BATT_SET PORTC |= (1 << PC1)
#define TTH_CLR PORTC &= ~(1 << PC2)
#define TTH_SET PORTC |= (1 << PC2)
#define TTL_CLR PORTC &= ~(1 << PC3)
#define TTL_SET PORTC |= (1 << PC3)
#define RESI_CLR PORTC &= ~(1 << PC4)
#define RESI_SET PORTC |= (1 << PC4)
char runmodel=000; //全局运行模式编码
char i=0; //i是单双周期判断变量
char Counter = 0; // 10mS计数变量清零 ,变量声明
long num=0; //转速can信号变量
long num1=800; //转速can信号变量
char can=0; //转速can信号变量
char rev=0; //转速can信号变量
long p=1; //档位显示变量
int pc; //档位显示变量
long t2=1; //t2完成变量
unsigned char msg;
unsigned char kflag = 0;
unsigned char gRXFlag = 0;
#define fosc 6000000
//晶振6MHZ
unsigned int j;
unsigned int k;
char CanKeepCNT =0;
int CanCNT=0;
char Counter1 = 0; // 1S计数变量清零 ,变量声明
#pragma interrupt_handler timer1_ovf_isr:9
#pragma interrupt_handler timer0_ovf:10
/**************************************************************定时器0中断函数*/
void timer0_ovf(void)
{
TIMSK&=~(1<<TOIE0); //关闭T0溢出中断
TCNT0 =146; //重装计数初值
/*********************************************************************/
if(rev==0)
{
if (num<=150) Send_prndl_ON(1);
if ((num>150)&(num<=300)) Send_prndl_ON(2);
if ((num>300)&(num<=450)) Send_prndl_ON(3);
if ((num>450)&(num<=600)) Send_prndl_ON(4);
if ((num>600)&(num<=750)) Send_prndl_ON(5);
if (num>750) Send_prndl_ON(6);
}
else
{
if (num<=100) Send_prndl_ON(12);
if ((num>100)&(num<=250)) Send_prndl_ON(10);
if ((num>250)&(num<=400)) Send_prndl_ON(9);
if ((num>400)&(num<=650)) Send_prndl_ON(8);
if (num>650) Send_prndl_ON(7);
}
/*********************************************************************/
delay_ms(1);
if(rev==0)
{
if (num>=790)
{
if (CanKeepCNT<40)//最大位置后等待
{
Send_Tacho(num*10);
CanKeepCNT=CanKeepCNT+1;
}
else
{
rev=1;
CanKeepCNT=0;
}
}
else
{
num=num+3;
Send_Tacho(num*10);
j=num/5+10;
//TIMSK|=(1<<TOIE1); //T/C1 溢出中断允许
if (k<=10)
{
k++;
}
else
{
PWM_out(j);
k=0;
}
}
}
else
{
if (num<=0)
{
if (CanKeepCNT<30)//最小位置后等待
{
Send_Tacho(0);
j=0;
CanKeepCNT=CanKeepCNT+1;
TCCR1B = 0; //stop
}
else
{
rev=0;
CanKeepCNT=0;
num=0;
Send_Tacho(0);
can=0;
}
}
else
{
num=num-3;
Send_Tacho(num*10);
j=num/5-10;
//TIMSK|=(1<<TOIE1); //T/C1 溢出中断允许
if (k<=10)
{
k++;
}
else
{
PWM_out(j);
k=0;
}
}
}
/*******************
if(rev==0)
{
if (j<=1500)
{
TIMSK|=(1<<TOIE1); //T/C1 溢出中断允许
j=j+2;
}
else
{
j=1500;
TIMSK|=(1<<TOIE1); //T/C1 溢出中断允许
}
}
else
{
if (j>=0)
{
TIMSK|=(1<<TOIE1); //T/C1 溢出中断允许
j=j-2;
}
else
{
j=0;
TIMSK|=(1<<TOIE1); //T/C1 溢出中断允许
}
}
/****************************/
if (can==1)
{
TIMSK|=(1<<TOIE0); //使能T0溢出中断
}
}
/*******************************************************************中断0配置*/
void timer0_init()
{
SREG = 0x80; //使能全局中断
//TIMSK|=(1<<TOIE0); //使能T0溢出中断
TCCR0|=(1<<CS02)|(0<<CS01)|(1<<CS00); // T/C0工作于普通模式,1024分频,
//定时器频率 = 8M/1024 =7812.5Hz
TCNT0 =146; //定时初值设置,定时时间 =(256-61)/7812.5=25ms
//6M/1024=5859.375 256-168=88/5859.375=0.015s
//256-139=117/5859.375=0.0199
//256-146=110/5859.375=0.0187
//256-81=175/5859.375=0.0298
}
//T1初始化程序
/*
void timer1_init(void)
{
TCCR1B = 0; //stop
TCNT1H = 0;
ICR1=0xFF00;
OCR1A=100;
OCR1B=100;
TCCR1A =(0<<WGM11)|(0<<WGM10)|(1<<COM1A1)|(0<<COM1A0);//|(1<<COM1B1)|(1<<COM1B0);
//升序记数时比较匹配将清零OC1A/OC1B,降序记数时比较匹配将置位OC1A/OC1B
TCCR1B =(1<<WGM13)|(0<<WGM12)|(0<<CS12)|(1<<CS11)|(1<<CS10);//(1<<WGM13)|(1<<WGM12)|(1<<CS10); //0x1A //start Timer
//相位与频率修正PWM,64分频
}
void PWM_out(unsigned int intFreq)
{
//if (intFreq<=0)
//TCCR1B = 0; //stop
ICR1=fosc/(intFreq*2*6.4);
OCR1A=ICR1/2;
}*/
//T1初始化程序
void timer1_init(void)
{
TCCR1B = 0; //stop
//TCNT1H = 0;
//ICR1=0xFFFF;
OCR1A=0x0FFF;
TCCR1A =(0<<WGM11)|(0<<WGM10)|(0<<COM1A1)|(1<<COM1A0);//WGM[3:0]=4;
TCCR1B =(0<<WGM13)|(1<<WGM12)|(1<<CS12)|(0<<CS11)|(1<<CS10);//N=1024,start Timer
TCNT1H = 0;
}
void PWM_out(unsigned int intFreq)
{
if (intFreq!=0)
{
OCR1A=2930/intFreq;
TCNT1H = 0;
TCNT1L = 0;
}
else
{OCR1A=0;
}
}
/*********************************************/
#pragma interrupt_handler timer1_ovf_isr:9
void timer1_ovf_isr(void)
{
//TIMSK&=~(1<<TOIE1); //T/C1 溢出中断关闭
//PWM_out(j);
}
void pwm(void)
{
PWM_out(1);
for(j=1;j<1500;j=j+15)
{TIMSK|=(1<<TOIE1); //T/C1 溢出中断允许
delay_ms(50);
}
for(j=1500;j>=30;j=j-15)
{TIMSK|=(1<<TOIE1); //T/C1 溢出中断允许
delay_ms(50);
}
delay_ms(200);
TIMSK&=~(1<<TOIE1); //T/C1 溢出中断关闭
}
//*************************************************************
//* 函数说明:MCU端口初始化 *
//* 输入: 无 *
//* 输出: 无 *
//* 调用函数: *
//*************************************************************
void port_init(void) //IO端口初始化
{
//DDRA|=(0Xfc); //PA output LCD data
//PORTA&=~(0Xff);
//DDRD=0xff; //can信号cs端口
//PORTD=0xff; //can信号cs端口
DDRDBIT3=0;
PORTDBIT3=1;
DDRBBIT0=1;
PORTBBIT0=1;
//DDRD &= ~(1 << PD2);
//PORTD |= (1 << PD2);
//MCUCR = 0X00; //低电平出发中断
//GICR = (1 << INT0); //INT0中断使能
DDRB=1<<1; //PWM输出端口为输出
PORTB=1<<1;
}
//call this routine to initialize all peripherals
void init_devices(void)
{
//stop errant interrupts until set up
CLI(); //disable all interrupts
port_init();
MCUCR = 0x00;
//EMCUCR = 0x00;
GICR = 0x00;
TIMSK = 0x00;
SEI(); //re-enable interrupts
//all peripherals are now initialized
}
//延时函数
void CAN_ID(unsigned long ID)
{
unsigned int IDH;
unsigned int IDL;
IDH= ID>>3;/右移3位
IDL=(ID & 7)<< 5;/取底3位左移5位
SPIByteWrite(TXB0SIDH,IDH);//设置发送缓冲器0的标准标识符,待修改***
SPIByteWrite(TXB0SIDL,IDL);//用到标准标识符
}
void Send_Tacho(unsigned long iTacho)//iTacho 0-7000
{
unsigned int ValH;
unsigned int ValL;
unsigned char b[8]={0x0,0x00,0x00,0x00,0x7D,0x00,0x00,0x7D};
ValL=iTacho*4 ;
ValH=iTacho*4 >>8;
b[2]=ValH;
b[3]=ValL;
CAN_ID(0x094);
CAN_Send(b);
}
/*****************************************************************************/
void Send_Temperature_full(void)//iTemperature 130
{
unsigned char b[8]={0xDF,0x02,0x00,0x50,0x00,0x00,0x00,0x00};
CAN_ID(0x288);
CAN_Send(b);
}
void Send_Temperature_zoo(void)//iTemperature 50
{
unsigned char b[8]={0x74,0x02,0x00,0x50,0x00,0x00,0x00,0x00};
CAN_ID(0x288);
CAN_Send(b);
}
/*****************************************************************************/
/*****************************************************************************/
void Send_ashen_background(void)//进入LED诊断环境
{
unsigned char b2[5]={0x04,0x31,0xFA,0x08,0xFF};
CAN_ID(0x7E3);
CAN_Send(b2);
}
void Send_allset(void)//LED全部亮
{
unsigned char b1[6]={0x05,0x31,0xFA,0x1C,0xE7,0xFF};
CAN_ID(0x7E3);
CAN_Send(b1);
}
void Send_allclr(void)//LED全部关
{
unsigned char b2[6]={0x05,0x31,0xFA,0x1C,0x00,0x00};
CAN_ID(0x7E3);
CAN_Send(b2);
}
/*****************************************************************************/
/*****************************************************************************/
void Send_door_ON(void)//四个车门-全亮
{
unsigned char b[3]={0xF0,0x23,0x00};
CAN_ID(0x4D4);
CAN_Send(b);
}
/*****************************************************************************/
void Send_Wakeup(void)//Wakeup msg
{
unsigned char b[5]={0x00,0x00,0x00,0x00,0x00};
CAN_ID(0x400);
CAN_Send(b);
}
/*****************************************************************************/
void Send_prndl_OFF(void)//档位的不同显示
{
unsigned char b[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
CAN_ID(0x115);
CAN_Send(b);
}
void Send_prndl_ON(long b)//
{
unsigned char b1[8]={0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00};
unsigned char b2[8]={0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00};
unsigned char b3[8]={0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00};
unsigned char b4[8]={0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00};
unsigned char b5[8]={0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x00};
unsigned char b6[8]={0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x00};
unsigned char br[8]={0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00};
unsigned char bp[8]={0x00,0x00,0x00,0xF0,0x00,0x00,0x00,0x00};
unsigned char bn[8]={0x00,0x00,0x00,0xF1,0x00,0x00,0x00,0x00};
unsigned char bd[8]={0x00,0x00,0x00,0xF2,0x00,0x00,0x00,0x00};
unsigned char bs[8]={0x00,0x00,0x00,0xF3,0x00,0x00,0x00,0x00};
unsigned char bl[8]={0x00,0x00,0x00,0xF4,0x00,0x00,0x00,0x00};
//unsigned char be[8]={0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00};
CAN_ID(0x115);
switch(b)
{
case 1:CAN_Send(b1);break;
case 2:CAN_Send(b2);break;
case 3:CAN_Send(b3);break;
case 4:CAN_Send(b4);break;
case 5:CAN_Send(b5);break;
case 6:CAN_Send(b6);break;
case 7:CAN_Send(br);break;
case 8:CAN_Send(bp);break;
case 9:CAN_Send(bn);break;
case 10:CAN_Send(bd);break;
case 11:CAN_Send(bs);break;
case 12:CAN_Send(bl);break;
//case 13:CAN_Send(be);break;
default:;break;
}
}
/*****************************************************************************
void Send_prndl_DSI(long b)//DSI Mode
{
unsigned char r[8]={0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00};
unsigned char p[8]={0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00};
unsigned char n[8]={0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00};
unsigned char d[8]={0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00};
CAN_ID(0x116);
switch(b)
{
case 8:CAN_Send(r);break;
case 9:CAN_Send(p);break;
case 10:CAN_Send(n);break;
case 11:CAN_Send(d);break;
default:;break;
}
}
/*****************************************************************************/
void Send_Sleep(void) //进入休眠状态
{
unsigned char b[5]={0x00,0x00,0x00,0x00,0x00};
CAN_ID(0x401);
CAN_Send(b);
}
/*****************************************************************************/
void Send_ON(void)//安全带,门,转向灯
{
unsigned char b0[3]={0xFF,0x23,0x00};
CAN_ID(0x4D4);
CAN_Send(b0);
}
/*****************************************************************************/
void Send_ESC()//电子稳定控制报警
{
unsigned char b[8]={0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
CAN_ID(0x068);
CAN_Send(b);
}
/*****************************************************************************/
void Send_Seatbelt()//驾驶座安全带开
{
unsigned char b[2]={0x07,0x00};
CAN_ID(0x268);
CAN_Send(b);
}
/*****************************************************************************/
void Send_Engine()//发动机故障
{
unsigned char b[7]={0x00,0x02,0x00,0x00,0x00,0x00,0x00};
CAN_ID(0x288);
CAN_Send(b);
}
/*****************************************************************************/
void Send_Cruise()//巡航
{
unsigned char b[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80};
CAN_ID(0x082);
CAN_Send(b);
}
/*****************************************************************************/
void stop(void) //停止函数
{
/****************************
Send_ashen_background();//进入led诊断环境
delay_ms(50);
Send_allclr();//led全部灭
/****************************/
TIMSK&=~(1<<TOIE0); //关闭T0溢出中断
TTH_CLR;//停止高电平
TTL_CLR;//停止低电平
RESI_CLR;//停止电阻
IGN_CLR;//停止点火
delay_ms(20);
BATT_CLR;//停止电池
delay_ms(500);
}
/****************************************************************************
*****************************************************************************/
void run(void)
{
can=1;
num=0;
num1=800;
rev=0;
TTH_CLR;//停止高电平
TTL_CLR;//停止低电平
IGN_CLR;//停止点火
delay_ms(20);
BATT_CLR;//停止电池
timer1_init(); //PWM使用定时器初始化
delay_ms(500);
/******************************/
if (i==0)
{
RESI_SET;//高电阻
}
else
{
RESI_CLR;//低电阻
}
/**********************************/
delay_ms(600);
BATT_SET;//给电池
delay_ms(20);
IGN_SET;//给点火
delay_ms(150);
Send_prndl_ON(1);
delay_ms(1500);
/******************************/
if (i==0)
{
Send_Temperature_full();//高温
}
else
{
Send_Temperature_zoo();//低温
}
delay_ms(20);
/**********************************
Send_door_ON();//四个车门-全亮
/***********************************/
Send_prndl_ON(1);
delay_ms(50);
/****************************
Send_ashen_background();//进入led诊断环境
delay_ms(50);
Send_allset();//led全部亮
/****************************/
Send_ON();//车门,转向灯
delay_ms(10);
Send_ESC();//ESC
delay_ms(10);
Send_Seatbelt();//安全带
delay_ms(10);
//Send_Engine();
delay_ms(10);
Send_Cruise();//巡航
delay_ms(20);
TTH_SET;//高电平
TTL_SET;//低电平
Send_prndl_ON(1);
delay_ms(100);
//转盘扫描程序
//TIMSK|=(1<<TOIE1); //T/C1 溢出中断允许
//j=10;
//DDRB=1<<1; //PWM输出端口为输出
//PORTB=1<<1;
TIMSK|=(1<<TOIE0); //使能T0溢出中断
while(can) //等待扫描结束
{
//PWM_out(j);
//delay_ms(200);
}
TIMSK&=~(1<<TOIE0); //关闭T0溢出中断
//DDRB=0<<1; //PWM输出端口为输入
if (i==0) //i为0或者为1代表单周或者双周
i=1;
else
i=0;
Init2515();
//timer1_init(); //PWM使用定时器初始化
//delay_ms(200);
}//end run
/******************************************************************************
******************************************************************************/
void main()
{
char m1=0,m2=0,m3=0; //模式编码变量
char before=000;//前次运行模式变量
port_init();
PORTD=0xff;
SPI_MasterInit();//SPI初始化,并启动
Init2515();
timer1_init(); //PWM使用定时器初始化
timer0_init();
//TIMSK&=~(1<<TOIE1); //T/C1 溢出中断关闭
//TIMSK|=(1<<TOIE1); //T/C1 溢出中断允许
delay_ms(2000);
while(0)
{
run();
}
while(1)
{
if(key_si1) //
{
delay_ms(20); //延时去抖,一般10-20ms
if(key_si1) //再次确认按键是否按下,没有按下则退出
{
m1=1;
}
}
if(!key_si1) //
{
delay_ms(20); //延时去抖,一般10-20ms
if(!key_si1) //再次确认按键是否按下,没有按下则退出
{
m1=0;
}
}
/********************************************************************/
if(key_si2) //
{
delay_ms(20); //延时去抖,一般10-20ms
if(key_si2) //再次确认按键是否按下,没有按下则退出
{
m2=1;
}
}
if(!key_si2) //
{
delay_ms(20); //延时去抖,一般10-20ms
if(!key_si2) //再次确认按键是否按下,没有按下则退出
{
m2=0;
}
}
/********************************************************************/
if(key_si3) //外部测试
{
delay_ms(500); //延时去抖,一般10-20ms
if(key_si3) //再次确认按键是否按下,没有按下则退出
{
m3=1;
}
}
if(!key_si3) //外部测试
{
delay_ms(20); //延时去抖,一般10-20ms
if(!key_si3) //再次确认按键是否按下,没有按下则退出
{
m3=0;
}
}
/********************************************************************/
runmodel=m3*100+m2*10+m1;//m1,m2,m3编码组合
//runmodel=000;
delay_ms(2);
switch(runmodel) //判断编码模式
{
case 100: //正常模式,驱动板停止工作
if (before==100)
{
stop();
before=100;
}
else
{
stop();
before=100;
}
break;
case 111: //正常模式,驱动板开始工作
if (before==111)
{
before=111;
run(); //调用正常运行函数
}
else
{
stop();
delay_ms(1000);
run(); //调用正常运行函数
before=111;
}
break;
case 11: //外部测试模式,仅给电池和点火信号
if (before==11)
{
before=11;
delay_ms(3000);
}
else
{
stop();
delay_ms(50);
BATT_SET;//给电池
delay_ms(10);
IGN_SET;//给点火
before=11;
}
break;
case 110: //m2有效,休眠模式,只给电池信号
if (before==110)
{
before=110;
delay_ms(1000);
}
else
{
stop();
delay_ms(100);
BATT_SET;//给电池
delay_ms(500);
Send_Sleep();//进入休眠
before=110;
}
break;
case 101: //m1有效,外控模式,类似正常启动模式
if (before==101)
{
before=101;
run(); //调用正常运行函数
}
else
{
stop();
delay_ms(1000);
run(); //调用正常运行函数
before=101;
}
break;
default:stop();break;
}//end switch
/******************************************************************/
}//end while
}//end main
复制代码
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1