📄 can_mcu.c
字号:
/************关节五****************/
#include <reg51.h>
#include <absacc.h>
#define uchar unsigned char
#define uint unsigned int
#define CANMOD XBYTE[0x2000]/* 方式寄存器*/
#define CANCMR XBYTE[0x2001]/* 命令寄存器*/
#define CANSR XBYTE[0x2002]/* 状态寄存器*/
#define CANIER XBYTE[0x2003]/* 中断允许寄存器*/
#define CANACR XBYTE[0x2004]/* 接受代码寄存器*/
#define CANAMR XBYTE[0x2005]/* 接受屏蔽寄存器*/
#define CANBTR0 XBYTE[0x2006]/* BTR0,总线定时寄存器0*/
#define CANBTR1 XBYTE[0x2007]/* BTR1,总线定时寄存器1*/
#define CANOCR XBYTE[0x2008]/* OCR,输出控制寄存器*/
#define CANCDR XBYTE[0x201F]/* 时钟分频*/
#define CANSEN0 XBYTE[0x200A]/* 发送寄存器*/
#define CANSEN1 XBYTE[0x200B]/* 发送寄存器*/
#define CANSEN2 XBYTE[0x200C]/* 发送寄存器*/
#define CANSEN3 XBYTE[0x200D]/* 发送寄存器*/
#define CANSEN4 XBYTE[0x200E]/* 发送寄存器*/
#define CANSEN5 XBYTE[0x200F]/* 发送寄存器*/
#define CANSEN6 XBYTE[0x2010]/* 发送寄存器*/
#define CANSEN7 XBYTE[0x2011]/* 发送寄存器*/
#define CANSEN8 XBYTE[0x2012]/* 发送寄存器*/
#define CANSEN9 XBYTE[0x2013]/* 发送寄存器*/
#define CANREC0 XBYTE[0x2014]/* 接受寄存器0*/
#define CANREC1 XBYTE[0x2015]/* 接受寄存器1*/
#define CANREC2 XBYTE[0x2016]/* 接受寄存器2*/
#define CANREC3 XBYTE[0x2017]/* 接受寄存器3*/
#define CANREC4 XBYTE[0x2018]/* 接受寄存器4*/
#define CANREC5 XBYTE[0x2019]/* 接受寄存器5*/
#define CANREC6 XBYTE[0x201A]/* 接受寄存器6*/
#define CANREC7 XBYTE[0x201B]/* 接受寄存器7*/
#define CANREC8 XBYTE[0x201C]/* 接受寄存器8*/
#define CANREC9 XBYTE[0x201D]/* 接受寄存器9*/
#define ADSTART XBYTE[0x8000]
#define ADCH XBYTE[0x8000]
#define ADCL XBYTE[0x8001]
#define DACH XBYTE[0x4001]
#define DACL XBYTE[0x4000]
#define DACSEND XBYTE[0x6000]
sbit P1_1=P1^1; /*SJA1000片选信号*/
bit flag=0; /*设置标志位*/
/*-----------------延时程序25us(24MHz)-------------------------*/
void DelayTime(unsigned int times)
{
unsigned int i=0;
while(times--)
{
for(i=0;i<25;i++) {;}
}
}
/*-----------------CAN初试化-------------------------*/
void CanIni()
{
P1_1=0; /*片选信号,选择SJA1000芯片*/
DelayTime(30); /*复位延时*/
P1_1=1;
CANMOD=0x1; /*进入复位模式,对SJA000进行初始化,接收中断和复位请求*/
CANMOD=0x3;
CANCDR=0x8; /*选择BasicCAN模式,关闭时钟输出*/
CANAMR=0xef; /*11101111,接受屏蔽寄存器*/
CANACR=0x10; /*00010000,接受代码寄存器*/
CANBTR0=0x03; /*BTR0,总线定时寄存器0*/
CANBTR1=0x1c; /*BTR1,总线定时寄存器1*/
CANOCR=0xaa; /*OCR,输出控制寄存器*/
CANMOD=0x02; /*设置单滤波器接受方式,并返回工作状态*/
CANCMR=0x0e;
}
/*----------------外部中断0---------------------*/
void int0() interrupt 0 using 1
{
flag=(bit)(CANSR&0x01);
}
void main()
{
bit recsuc=0;/*接收成功标志*/
bit shijiao=0;
char states=4;/*工作状态:4--等待,1--复位,2---正常工作,3---示教*/
uchar fankuiH,fankuiL,sendH,sendL;
uint i,output,fankui;
char angel1,angel2,fankuiv1,fankuiv2;
float middata,backdata,angel,fankuiv;
IP=0x01; /*置INT0为高优先级中断*/
IE=0x81; /*1000,0001,允许外部0中断*/
CanIni();
angel=0.0;
angel1=1;
angel2=5;
recsuc=1;
for(;;)
{
if(flag==1){
EA=0;/*cpu关中断*/
do{;}while(CANSR&0x10);/*若正在接收数据则循环等待*/
angel1=CANREC2;/*整数部分*/
angel2=CANREC3;/*小数部分后两位*/
states=CANREC4;
CANCMR=4;/*释放接受缓冲器*/
flag=0;
if(states==1)
{ angel=0.0;
angel1=1;
angel2=1;
recsuc=1;
shijiao=0;
EX0=0;
}
if(states==2)
{
angel=(float)angel1+(float)angel2/100;/*将接受的数据赋给变量angel*/
recsuc=1;
shijiao=0;
EX0=0;
}
if(states==3)
{ shijiao=1;
angel1=1;
angel2=1;
recsuc=1;
EX0=0;
}
if(states==4)
{
recsuc=0;
shijiao=0;
EA=1;
EX0=1;
}
}/*if*/
if(recsuc==1){
EA=0;
ADSTART=0;
DelayTime(40);
fankuiH=ADCH;/*高四位*/
fankuiL=ADCL;/*低八位*/
fankui=ADCH*0x100+ADCL;/*采集电位计的12位数据*/
fankuiv=((float)(fankui))/19.5-(float)105.0;/*转换为角度值*/
fankuiv1=(char)fankuiv;
fankuiv2=(char)(((int)(fankuiv*100))%100);
if(!shijiao){
middata=angel-fankuiv;
backdata=middata*0.2;/*调用pid算法*/
if(backdata>=1)
backdata=2;
else
if(backdata<=-1)
backdata=-2;
output=(int)((backdata+5)*409.6);/*由0~10v电压转换为12位16进制数*/
if(output>=4095)
output=4095;
sendL=output&0xf;/*取低4位*/
sendL=sendL*0x10;/*低四位左移四位*/
sendH=output>>4;/*取高八位*/
/****************DA输出*****************/
DACH=sendH;
DACL=sendL;
DACSEND=0;
}/*** if(!shijiao)***/
/****************发送数据到上位机******************/
CANSEN0=0x01;/*id=8*/
CANSEN1=0xa8;/*length=8*/
CANSEN2=angel1;/*从上位机接收的角度值整数部分,对应smsg.data[0],rmsg.data[0]*/
CANSEN3=angel2;/*小数部分*/
CANSEN4=fankuiv1;/*电位计角度值整数部分*/
CANSEN5=fankuiv2;/*小数部分两位*/
CANSEN6=fankuiH;/*电位计高四位*/
CANSEN7=fankuiL;/*电位计低八位*/
CANSEN8=(char)middata;
CANSEN9=(char)states;
CANCMR=1;
if((middata>=-6)&(middata<=6)){EA=1;EX0=1;}
}/*if(recsuc==1)*/
}/*for*/
}/*main*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -