CANrs232完整程序经典.docx
- 文档编号:17586201
- 上传时间:2023-07-26
- 格式:DOCX
- 页数:16
- 大小:19.15KB
CANrs232完整程序经典.docx
《CANrs232完整程序经典.docx》由会员分享,可在线阅读,更多相关《CANrs232完整程序经典.docx(16页珍藏版)》请在冰点文库上搜索。
CANrs232完整程序经典
CAN-RS232完成程序
转载请注明出处
设计:
陈仲库
main.c
/****************************************************************************/
#include
#include
#include
#include
#include
#include
sbitp35=P3^5;
longMM=0;//记录收发次数
///////////////////////////////////////////////
//函数:
main
voidmain(void)
{
Init_MCU();
COM_Init();
Init_SJA1000();
while
(1)
{
RXD_deal();//接收处理并转发至串口
LED_GRE=!
LED_GRE;
delay(100);
LED_RED=!
LED_RED;
TXD_deal();//接收来自串口的数据发送处理程序到CAN
}
}
////////接收来自串口的数据并转发到CAN-BUS/////////////////////////////
/*功能
如果串口有数据请求即MCU_RXD_FLG=1,且数据是以AA开头和55结尾
数据转发只转发8个有效值,即只能接收包括AA55在内10个字节的数据,如果多余10个字节,则只取10个
如果不够10个,则以0补齐8个
例如发送0XAA,0X11,0X22,0X33,0X44,0X55,0X66,0X77,0X88,0X99,0X55,此时只能接收0X11,0X22,0X33,0X44,0X55,0X66,0X77,0X88并转发到CAN-BUS上
如果发送0XAA,0X11,0X22,0X33,0X44,0X55则转发0X22,0X33,0X44,0000
*///////////////////////////////
voidTXD_deal(void)
{
chari;intch;
if(MCU_RXD_FLG)//&&!
RXD_flag)//若MCU_RXD_FLG=1,要求进行数据的发送处理
{
EA=0;
if(TX_dat[0]==0xAA&&TX_dat[num-1]==0x55)
{
printf("\n\n\n");
printf("sendNo.=%ld\n",MM++);
if(num<10)for(i=num-1;i<9;i++)TX_dat[i]=0;////处理来自串口的数据小于10个,即有效位小于8个,此时只处理有效位,后面用0补齐
for(i=0;i<8;i++)TX_buffer[5+i]=TX_dat[i+1];//提取有效位8字节
CAN_TXD();//发送数据帧到CAN-Bus
for(i=5;i<13;i++){ch=TX_buffer[i];printf("%0x",ch);}
//for(i=0;i<19;i++)TX_dat[i]=0;
}
num=0;
MCU_RXD_FLG=0;//RXD_flag清零,以便下次查询
EA=1;
}
//测试用
elseif(!
p35)//如果p35短接后,发送别的数据
{
TX_buffer[5]=0xFF;//.7=0--扩展帧;.6=0--数据帧;.0-.3=100--数据长度为8字节
TX_buffer[6]=0xFF;//本帧信息的ID
TX_buffer[7]=0xFF;
TX_buffer[8]=0xFF;
TX_buffer[9]=0xEE;
TX_buffer[10]=0xEE;//.7=0--扩展帧;.6=0--数据帧;.0-.3=100--数据长度为8字节
TX_buffer[11]=0xEE;//本帧信息的ID
TX_buffer[12]=0xEE;
TX_buffer[13]=0xDD;
CAN_TXD();//发送数据帧
delay(1000);delay(1000);
printf("\n\n");
for(i=5;i<13;i++){ch=TX_buffer[i];printf("%0x",ch);}
}
}
///////////////////////////////////////////////**
/*************************************************/
/*功能
只要CAN线上有数据,便转发到串口
*///////////////////////////////
voidRXD_deal(void)
{
inttmp,i;
if(RXD_flag)//RXD_flag=0说明无数据可以接收,RXD_flag=1说明有数据可以接收
{
EA=0;//关闭CPU中断
printf("\n");
//printf("\nstartreceiveNo.=%ld:
\n",N++);
RXD_flag=0;//RXD_flag清零,以便下次查询
for(i=5;i<13;i++){tmp=RX_buffer[i];printf("%0x",tmp);}//往串口发送数据MCU_TXD(RX_buffer[i]);//
//ES=1;
EA=1;//重新开启CPU中断
}
}
Com-CTRL.H
bitMCU_RXD_FLG=0;//串口接收标志,=1串口接收到数据,=0
unsignedcharTX_dat[20];//串口接收到的数据缓冲区
unsignedcharnum=0;//接收来自串口数据计数
//*********串口初始化*************//
voidCOM_Init(void)
{
SCON=0x50;
TMOD|=0x20;
TH1=0xFE;//1440011.0592
IE|=0x90;
TR1=1;
TI=1;
TH0=0xDC;//T0定义初始值
TL0=0x66;
TR0=0;
ET0=1;
}////////////END//////////
//*******串口接收中断函数***************//
voidserial()interrupt4//using3
{
intt=10;
EA=0;
if(RI)
{
TR0=0;RI=0;
TX_dat[num++]=SBUF;
TH0=0xDC;TL0=0x66;
TR0=1;while(t--);
}
EA=1;
}////////////END//////////
//*******定时器***********//
voidtimer0()interrupt1
{
EA=0;
//if(TX_dat[0]==0xAA&&TX_dat[num-1]==0x55)//必须以AA开头和55结尾的数组
{
MCU_RXD_FLG=1;RI=0;
}
TR0=0;
EA=1;
}////////////END//////////
/**/
/*
//向串口发送一个字符
voidMCU_TXD(unsignedcharch)
{
SBUF=ch;
while(TI==0);
TI=0;
}
*/
Sja1000.h
/**************************************************************************************
项目:
基于CAN总线的自收发通信(节点1)
**************************************************************************************/
#defineucharunsignedchar//宏定义
#defineuintunsignedint//宏定义
bitTXD_flag=0;//若TXD_flag=1,要求发送处理,说明串口已接到数据可以往can上发送
bitRXD_flag=0;//RXD_flag=0说明无数据可以接收,RXD_flag=1说明有数据可以接收
ucharTX_buffer[13];//接收的13个字节数据(//发送的数据)
ucharRX_buffer[13];//接收的13个字节数据
/*P2口的管脚定义
sbitLED_RED=P2^1;//该I/0口接红LED
sbitLED_GRE=P2^2;//该I/0口接绿LED
sbitSJA_RST=P2^3;//SJA1000复位管脚,低电平有效
sbitSJA_CS=P2^0;//SJA1000片选管脚,低电平有效
sbitLED_0=P2^7;//数码管0
sbitLED_1=P2^6;//数码管1
sbitLED_2=P2^5;//数码管2
sbitLED_3=P2^4;//数码管3
*/
sbitLED_RED=P2^4;//该I/0口接红LED
sbitLED_GRE=P2^5;//该I/0口接绿LED
sbitSJA_RST=P1^4;//P2^3;//SJA1000复位管脚,低电平有效
sbitSJA_CS=P2^0;//SJA1000片选管脚,低电平有效
/*CAN总线SJA1000寄存器地址定义(用的是PeliCAN模式,扩展帧EFF模式)*/
//xdata---->可寻址片外ram(64k地址范围:
0000H-FFFFH)
ucharxdataMODR_at_0xFE00;//模式寄存器
ucharxdataCMR_at_0xFE01;//命令寄存器
ucharxdataSR_at_0xFE02;//状态寄存器
ucharxdataIR_at_0xFE03;//中断寄存器
ucharxdataIER_at_0xFE04;//中断使能寄存器
ucharxdataBTR0_at_0xFE06;//总线定时寄存器0;总线波特率的选择
ucharxdataBTR1_at_0xFE07;//总线定时寄存器1;总线波特率的选择
ucharxdataOCR_at_0xFE08;//输出控制寄存器
//验收代码寄存器(16-19)
ucharxdataACR0_at_0xFE10;//16;
ucharxdataACR1_at_0xFE11;//17;
ucharxdataACR2_at_0xFE12;//18;
ucharxdataACR3_at_0xFE13;//19;
//验收屏蔽寄存器(20-23)
ucharxdataAMR0_at_0xFE14;//20;
ucharxdataAMR1_at_0xFE15;//21;
ucharxdataAMR2_at_0xFE16;//22;
ucharxdataAMR3_at_0xFE17;//23;
ucharxdataCDR_at_0xFE1F;//31;//时钟分频器
ucharxdataALC_at_0xFE0B;//11;//仲裁丢失捕捉寄存器
ucharxdataECC_at_0xFE0C;//12;//误码捕捉寄存器
//发送缓冲器地址(16-28)
ucharxdataTBSR0_at_0xFE10;//16;//TX帧信息
ucharxdataTBSR1_at_0xFE11;//17;//TX识别码1(ID.21-ID.28)
ucharxdataTBSR2_at_0xFE12;//18;//TX识别码2(ID.13-ID.20)
ucharxdataTBSR3_at_0xFE13;//19;//TX识别码3(ID.5-ID.12)
ucharxdataTBSR4_at_0xFE14;//20;//TX识别码4(高5位是ID.0-ID.4)
ucharxdataTBSR5_at_0xFE15;//21;//数据1
ucharxdataTBSR6_at_0xFE16;//22;//数据2
ucharxdataTBSR7_at_0xFE17;//23;//数据3
ucharxdataTBSR8_at_0xFE18;//24;//数据4
ucharxdataTBSR9_at_0xFE19;//25;//数据5
ucharxdataTBSR10_at_0xFE1A;//26;//数据6
ucharxdataTBSR11_at_0xFE1B;//27;//数据7
ucharxdataTBSR12_at_0xFE1C;//28;//数据8
//接收缓冲器地址(16-28)
ucharxdataRBSR0_at_0xFE10;//16;
ucharxdataRBSR1_at_0xFE11;//17;
ucharxdataRBSR2_at_0xFE12;//18;
ucharxdataRBSR3_at_0xFE13;//19;
ucharxdataRBSR4_at_0xFE14;//20;
ucharxdataRBSR5_at_0xFE15;//21;
ucharxdataRBSR6_at_0xFE16;//22;
ucharxdataRBSR7_at_0xFE17;//23;
ucharxdataRBSR8_at_0xFE18;//24;
ucharxdataRBSR9_at_0xFE19;//25;
ucharxdataRBSR10_at_0xFE1A;//26;
ucharxdataRBSR11_at_0xFE1B;//27;
ucharxdataRBSR12_at_0xFE1C;//28;
/*子函数申明*/
voidInit_MCU(void);
voidInit_SJA1000(void);
voidRXD_deal(void);
voidTXD_deal(void);
//voidcan_txd(void);
voiddelay(inttime);
//voidled_show(uchar,uchar);
CAN-CTRL.H
///////////////////初始化////////////////
//**********单片机I/O口初始化***********//
voidInit_MCU(void)
{
SJA_RST=1;//CAN总线复位管脚复位无效
SJA_CS=0;//CAN总线片选有效
EX0=1;//开MCU外部中断INT1
IT0=0;//MCU外部中断INT1设置为电平触发,该中断口连接CAN总线接收中断口
EA=1;//开MCU总中断
SJA_CS=1;//CAN总线片选无效,使得对数据总线的操作不会影响SJA1000。
////串口初始化
SCON=0x50;
TMOD&=0x0F;
TMOD|=0x20;
TH1=0xfE;//Baud:
fosc=11.0592MHz,9600FD;FE14400
TR1=1;//启动timer1run
TI=1;
}//////////////////////////////////////
//**********SJA1000初始化***********//
voidInit_SJA1000(void)
{
ucharstate;
ucharACRR[4]={0X44,0X33,0X22,0X10};//接收代码寄存器
ucharAMRR[4]={0xff,0xff,0xff,0xff};//接收屏蔽寄存器
do//使用do--while语句确保进入复位模式
{
MODR=0x09;//设置MOD.0=1--进入复位模式,以便设置相应的寄存器
state=MODR;
}
while(!
(state&0x01));
//对SJA1000部分寄存器进行初始化设置
CDR=0x88;//CDR为时钟分频器,CDR.3=1--时钟关闭,CDR.7=0---basicCAN,CDR.7=1---PeliCAN
BTR0=0x04;//0x31;//总线定时寄存器0;总线波特率设定
BTR1=0x1c;//0x1c;//总线定时寄存器1;总线波特率设定
IER=0x01;//IER.0=1--接收中断使能;IER.1=0--关闭发送中断使能
OCR=0xaa;//配置输出控制寄存器
CMR=0x04;//释放接收缓冲器
ACR0=ACRR[0];//初始化接收代码寄存器
ACR1=ACRR[1];
ACR2=ACRR[2];
ACR3=ACRR[3];
AMR0=AMRR[0];//初始化接收屏蔽寄存器
AMR1=AMRR[1];
AMR2=AMRR[2];
AMR3=AMRR[3];
do//使用do--while语句确保退出复位模式
{
MODR=0x08;//MOD.3=0--双滤波器模式
state=MODR;
}
while(state&0x01);
}//////////////////////////////////////
//**********CAN发送数据到CAN-Bus***********//
voidCAN_TXD(void)
{
ucharstate;
//初始化标示码头信息
TX_buffer[0]=0x88;//.7=0--扩展帧;.6=0--数据帧;.0-.3=100--数据长度为8字节
TX_buffer[1]=0xFF;//本帧信息的ID
TX_buffer[2]=0xFF;
TX_buffer[3]=0xFF;
TX_buffer[4]=0xFF;
do//查询SJA1000是否处于接收状态,当SJA1000不处于接收状态时才可继续执行
{
state=SR;//SR为SJA1000的状态寄存器
}
while(state&0x10);//SR.4=1正在接收,等待
do//查询SJA1000是否处于发送完毕状态
{
state=SR;
}
while(!
(state&0x08));//SR.3=0,发送请求未处理完,等待直到SR.3=1
do//查询发送缓冲器状态
{
state=SR;
}
while(!
(state&0x04));//SR.2=0,发送缓冲器被锁。
等待直到SR.2=1
//将待发送的一帧数据信息存入SJA1000的相应寄存器中
TBSR0=TX_buffer[0];
TBSR1=TX_buffer[1];
TBSR2=TX_buffer[2];
TBSR3=TX_buffer[3];
TBSR4=TX_buffer[4];
TBSR5=TX_buffer[5];
TBSR6=TX_buffer[6];
TBSR7=TX_buffer[7];
TBSR8=TX_buffer[8];
TBSR9=TX_buffer[9];
TBSR10=TX_buffer[10];
TBSR11=TX_buffer[11];
TBSR12=TX_buffer[12];
CMR=0x01;//置位发送请求
}//////////////////////////////////////
//**********延时子程序***********//
voiddelay(inttime)
{
while(time--);
}
////////////////中断///////////////////////
//**********中断接收来自CAN-Bus数据***********//
voidinter1_can_rxd(void)interrupt0
{
ucharstate;
EA=0;//关CPU中断
IE0=0;//由于是中断INT1是电平触发方式,所以需要软件将INT1的中断请求标志IE0清零
state=IR;//IR为SJA1000的中断寄存器
if(state&0x01)//若IR.0=1--接收中断
{
RX_buffer[0]=RBSR0;
RX_buffer[1]=RBSR1;
RX_buffer[2]=RBSR2;
RX_buffer[3]=RBSR3;
RX_buffer[4]=RBSR4;
RX_buffer[5]=RBSR5;
RX_buffer[6]=RBSR6;
RX_buffer[7]=RBSR7;
RX_buffer[8]=RBSR8;
RX_buffer[9]=RBSR9;
RX_buffer[10]=RBSR10;
RX_buffer[11]=RBSR11;
RX_buffer[12]=RBSR12;
RXD_flag=1;//接收标志置位,以便进入接收处理程序
CMR=0x04;//CMR.2=1--接收完毕,释放接收缓冲器
state=ALC;//释放仲裁随时捕捉寄存器(读该寄存器即可)
state=ECC;//释放错误代码捕捉寄存器(读该寄存器即可)
}
IER=0x01;//IER.0=1--接收中断使能
EA
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- CANrs232 完整 程序 经典
![提示](https://static.bingdoc.com/images/bang_tan.gif)