CAN单节点的自通信程序
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
/****************************************************************************** ********
项目:基于CAN总线的自收发通信
说明:主程序部分
功能:外部按键每按下一次,计数值加一,同时计数值在数码管1、2上显示。
在计数值加一后,会使CAN总线上重新发送数据,此时接收端的计数值也同步更新显示
在数码管3、4上(为便于观察,接收显示的值比发送值大3)。
// CAN主要参数: PeliCAN模式,扩展帧EFF模式
// 29位标示码结构:
// 发送数据结构:计数结果,0x02,0x03,0x04,0x05,0x06,0x07,0x08
// 接收数据结构: 待显示数据+其它7个字节的数据
// 本节点的接收代码寄存器值: 0x11,0x22,0x33,0x44
// 本节点的屏蔽代码寄存器值:0x00,0x00,0x00,0x00;可以接收本节点的数据
// 目的节点地址:0x11,0x22,0x33,0x44;可以被本节点接收
模块:can_self.c
作者:PIAE GROUP
注释修改者:特权
修改时间:08.6.17.
******************************************************************************* *******/
/***感谢PIAE工作组提供的源码,这里特权根据自己的编程习惯做了一些修改并添加详细注释***/
#include
#include
#include "define.h"
///////////////////////////////////////////////
//函数:inter0_key (外部中断INT0)
//说明:INT0按键为计数按键
// 每按下一次键,计数值加一
//入口:按键中断
//返回:按键加一
///////////////////////////////////////////////
void inter0_key(void) interrupt 0
{
EA = 0; //关闭中断
Txd_data++; //计数结果增1,即待发送的数据增1
TXD_flag = 1; //发送数据标志位置位,即重新发送数据以更新数码管的显示数值
EA = 1; //重新开启中断
}
///////////////////////////////////////////////
//函数:inter1_can_rxd (外部中断INT1)
//说明:接收数据函数,在中断服务程序中调用
//入口:无
//返回:无
///////////////////////////////////////////////
void inter1_can_rxd( void ) interrupt 2
{
uchar state;
EA = 0; //关CPU中断
IE1 = 0; //由于是中断INT1是电平触发方式,所以需要软件将INT1的中断请求标志IE0清零
state = IR; //IR为SJA1000的中断寄存器
if( state & 0x01) //若IR.0=1--接收中断
{ //接收数据帧
RX_buffer[0] = RBSR;
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 = 1; //重新开启CPU中断
}
///////////////////////////////////////////////
//函数:main
//说明:主函数
//入口:无
//返回:无
///////////////////////////////////////////////
void main(void)
{
init_mcu();
init_sja1000();
while(1)
{
rxd_deal(); //接收处理程序
txd_deal(); //发送处理程序
led_show(0,Txd_data); //数码管1-2显示发送数据子程序
led_show(1,Rxd_data+3); //数码管3-4显示接收数据子程序
}
}
///////////////////////////////////////////////
//函数:init_mcu
//说明:单片机I/O口初始化
// 主要是各中断寄存器的初始化
//入口:无
//返回:无
///////////////////////////////////////////////
void init_mcu(void)
{
SJA_RST = 1; //CAN总线复位管脚复位无效
SJA_CS = 0; //CAN总线片选有效
EX1 = 1; //开MCU外部中断INT1
IT1 = 0; //MCU外部中断INT1设置为电平触发,该中断口连接CAN总线接收中断口IT0 = 1; //MCU外部中断INT0设置为下降沿触发
EX0 = 1; //开MCU外部中断INT0
EA = 1; //开MCU总中断
SJA_CS = 1; //CAN总线片选无效,使得对数据总线的操作不会影响SJA1000。}
///////////////////////////////////////////////
//函数:init_sja1000
//说明:独立CAN控制器SJA1000的初始化
//入口:无
//返回:无
///////////////////////////////////////////////
void init_sja1000(void)
{
uchar state;
uchar ACRR[4];