📄 car_3.c
字号:
//-----------------------变量定义-----------------------------------//
#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 + -