1、can多机通信 Node1/&/描述:/ 本程序为第7章节点1的配套程序 &/功能描述:/ INT0按键程序+显示程序+CAN两点通信程序 &/ 数码管1-2(从右至左)显示(十进制)本节点计数结果,数码管3-4显示(十进制)接收到的数据 & &/CAN主要参数: / PeliCAN模式,扩展帧EFF模式 &/ 29位标示码结构: &/ 发送数据结构:计数结果 &/ 接收数据结构: 待显示数据 &/ 本节点的地址: 0x01(ACR03:0xff,0x01,0xff,0xff) &/ 验收屏蔽寄存器 :0xff,0x00,0xff,0xff;(AMR03)只接收发往本节点的报文 &/ 报文标识
2、符 :0x01,0x02,0x10,0x00; &/提示:如果CAN通讯不正常,会进入一个死循环,显示也不正常/&/【声明】 此程序仅用于学习与参考,引用请注明版权和作者信息! &/【声明】 作者: PIAE小组 include #include #include uchar jidian=0;void INT0_Counter( void ) interrupt 0 using 1/INT0按键为计数按键 EA = 0; Txd_data+; /存储计数结果,并为待发送的数据 TXD_flag = 1;/要发送数据标志位 jidian+; EA = 1;void CAN_RXD( voi
3、d ) interrupt 2/接收数据函数,在中断服务程序中调用 uchar data Judge; uchar data CanDataLength;/报文数据长度变量 unsigned char volatile xdata *p;/外部寄存器指针 uchar i; EA = 0;/关CPU中断 IE0 = 0; Judge = IR; if( Judge & 0x01) /IR.0 = 1 接收中断 CanDataLength = RBSR & 0x0f;/CAN数据报文的数据长度 p = &RBSR; for( i=0; i = (CanDataLength + 5); i+ ) R
4、X_bufferi = *p+; jidian=RX_buffer6; jidian=jidian; if(jidian) LED_GRE=1; if(!jidian)LED_GRE=0; RXD_flag = 1;/置有接收标志 CMR = 0X04; Judge = ALC;/释放仲裁随时捕捉寄存器 Judge = ECC;/释放错误代码捕捉寄存器 IER = 0x01;/ .0=1-接收中断使能; EA = 1;/打开CPU中断void main(void) CPU_init( ); /CPU初始化 CAN_init( ); /SJA1000初始化,对 SJA1000寄存器的读写是采用外
5、部寄存器寻址方式,所以不需要程序单独控制片选有效无效 _nop_(); _nop_(); while(1) _nop_(); _nop_(); Rxd_deal();/接收处理程序 Txd_deal();/发送处理程序 led_seg7(1,Txd_data); led_seg7(3,Rxd_data); /*处理函数*/*CPU初始化函数*void CPU_init(void)/初始化CPU SJA_RST = 0;/CAN总线复位管脚有效 Delay( 20 ); SJA_RST = 1;/CAN总线复位管脚无效 SJA_CS = 0;/CAN总线片选有效 EX1 = 1; IT1 = 0
6、;/CAN总线接收中断 IT0 = 1;/外部中断0负边沿触发 EX0 = 1;/打开外部中断0 EA = 1; /打开总中断 SJA_CS = 1;/CAN总线片选无效,使对数据总线的操作不会影响SJA1000。void Rxd_deal(void)/ 接收处理程序/ if( RXD_flag ) EA = 0;/关闭CPU中断 RXD_flag = 0; if( RX_buffer3 = 0x10 )/如果该报文传输的为按键计数 Rxd_data = RX_buffer5; EA = 1; / 接收处理程序/void Txd_deal(void)/发送处理函数,主要是准备数据,并且调用发送
7、函数 if( TXD_flag = 1 ) _nop_(); TXD_flag = 0; if(Txd_data & 0x01) /将奇数计数值发往节点2. /初始化标示码头信息 TX_buffer0 = 0x82;/.7=0扩展帧;.6=0数据帧; .30=1数据长度 TX_buffer1 = 0x01;/本节点地址 TX_buffer2 = 0x02;/ TX_buffer3 = 0x10;/ TX_buffer4 = 0x00;/ TX_buffer5 = Txd_data;/ jidian+; TX_buffer6=jidian; else if(!(Txd_data & 0x01)
8、/将偶数计数值发往节点3. /初始化标示码头信息 TX_buffer0 = 0x82;/.7=0扩展帧;.6=0数据帧; .30=1数据长度 TX_buffer1 = 0x01;/本节点地址 TX_buffer2 = 0x03;/ TX_buffer3 = 0x10;/ TX_buffer4 = 0x00;/ TX_buffer5 = Txd_data;/ jidian+; TX_buffer6=jidian; CAN_TXD(); _nop_(); _nop_(); /*处理函数*/*CAN子函数*void CAN_init( void )/SJA1000 的初始化 uchar bdata
9、Judge; uchar ACRR4; uchar AMRR4; ACRR0 = 0xff; ACRR1 = 0x01; ACRR2 = 0xff; ACRR3 = 0xff;/接收代码寄存器 AMRR0 = 0xff; AMRR1 = 0xff; AMRR2 = 0xff; AMRR3 = 0xff;/接收屏蔽寄存器,只接收发往本节点的报文 do / .0=1-reset MODR,进入复位模式,以便设置相应的寄存器 /防止未进入复位模式,重复写入 MODR = 0x09; Judge = MODR ; while( !(Judge & 0x01) ); CDR = 0x88;/ CDR.3
10、=1-时钟关闭, .7=0-basic CAN, .7=1-Peli CAN BTR0 = 0x31; BTR1 = 0x1c;/总线波特率设定 IER = 0x01;/ .0=1-接收中断使能; .1=0-关闭发送中断使能 OCR = 0xaa;/ 配置输出控制寄存器 CMR = 0x04;/释放接收缓冲器 ACR = ACRR0; ACR1 = ACRR1; ACR2 = ACRR2; ACR3 = ACRR3;/初始化标示码 AMR = AMRR0; AMR1 = AMRR1; AMR2 = AMRR2; AMR3 = AMRR3;/初始化掩码 do /确保退出复位模式 MODR = 0
11、x08; Judge = MODR ; while( Judge & 0x01 );/SJA1000 的初始化void CAN_TXD( void ) uchar data Judge;/初始化数据信息 EA = 0; /关中断 do Judge = SR; LED_RED = 0;/ while( Judge & 0x10 ); /SR.4=1 正在接收,等待 do Judge = SR; LED_RED = 0;/ while(!(Judge & 0x08); /SR.3=0,发送请求未处理完,等待 do Judge = SR; LED_RED = 0;/ while(!(Judge &
12、0x04); /SR.2=0,发送缓冲器被锁。等待 LED_RED = !LED_RED; / LED_GRE = !LED_GRE;/灯闪烁 TBSR = TX_buffer0; TBSR1 = TX_buffer1; TBSR2 = TX_buffer2; TBSR3 = TX_buffer3; TBSR4 = TX_buffer4; TBSR5 = TX_buffer5; TBSR6=TX_buffer6; CMR = 0x01;/置位发送请求 EA = 1;void Delay(uchar delay_time)/延时程序 while(delay_time-) /*CAN子函数*/*显
13、示子函数*void led_seg7(uchar from,uchar number) /from(1_4):数码管显示起始位置(从右到左),number:显示的数(数码管上采用10进制显示) uchar digit,temp_l; uchar temp_h=0x7f; temp_h = _cror_(temp_h,from-1); /确定从哪一位开始显示,即确定高四位 temp_h = temp_h & 0xf0; /取高四位 temp_l = P2 & 0x0f; /取P2的低四位 P2 = temp_h | temp_l; /设定P2口 if(number=0) P0 = led0; D
14、elay(10); P0 = 0xff; else while(number) digit = number%10 ; number /= 10; P0 = leddigit ; Delay(10); temp_h = P2 & 0xf0; /取P2的高四位 temp_h = temp_h | 0x0f; /拼装 temp_h,进行位选 temp_h = _cror_(temp_h,1); temp_h = temp_h & 0xf0; /取高四位 temp_l = P2 & 0x0f; /取P2的低四位 P0 = 0xff; P2 = temp_h | temp_l; /设定P2口 Node
15、2/&/描述:/ 本程序为第7章节点2的配套程序 &/功能描述:/ INT0按键程序+显示程序+CAN两点通信程序 &/ 数码管1-2(从右至左)显示(十进制)本节点计数结果,数码管3-4显示(十进制)接收到的数据 & &/CAN主要参数: / PeliCAN模式,扩展帧EFF模式 &/ 29位标示码结构: &/ 发送数据结构:计数结果 &/ 接收数据结构: 待显示数据 &/ 本节点的地址: 0x02(ACR03:0xff,0x02,0xff,0xff) &/ 验收屏蔽寄存器 :0xff,0x00,0xff,0xff;(AMR03)只接收发往本节点的报文 &/ 报文标识符 :0x02,0x01
16、,0x10,0x00; &/提示:如果CAN通讯不正常,会进入一个死循环,显示也不正常/&/【声明】 此程序仅用于学习与参考,引用请注明版权和作者信息! &/【声明】 作者: PIAE小组 include #include #include uchar jidian=0;void INT0_Counter( void ) interrupt 0 using 1/INT0按键为计数按键 EA = 0; Txd_data+; /存储计数结果,并为待发送的数据 TXD_flag = 1;/要发送数据标志位 jidian+; EA = 1;void CAN_RXD( void ) interrup
17、t 2/接收数据函数,在中断服务程序中调用 uchar data Judge; uchar data CanDataLength;/报文数据长度变量 unsigned char volatile xdata *p;/外部寄存器指针 uchar i; EA = 0;/关CPU中断 IE0 = 0; Judge = IR; if( Judge & 0x01) /IR.0 = 1 接收中断 CanDataLength = RBSR & 0x0f;/CAN数据报文的数据长度 p = &RBSR; for( i=0; i = (CanDataLength + 5); i+ ) RX_bufferi =
18、*p+; jidian= RX_buffer6 ; jidian=jidian; if(jidian) LED_GRE=1; if(!jidian)LED_GRE=0; RXD_flag = 1;/置有接收标志 CMR = 0X04; Judge = ALC;/释放仲裁随时捕捉寄存器 Judge = ECC;/释放错误代码捕捉寄存器 IER = 0x01;/ .0=1-接收中断使能; EA = 1;/打开CPU中断void main(void) CPU_init(); /CPU初始化 CAN_init( ); /SJA1000初始化,对 SJA1000寄存器的读写是采用外部寄存器寻址方式,所以
19、不需要程序单独控制片选有效无效 _nop_(); _nop_(); while(1) _nop_(); _nop_(); Rxd_deal();/接收处理程序 Txd_deal();/发送处理程序 led_seg7(1,Txd_data); led_seg7(3,Rxd_data); /*处理函数*/*CPU初始化函数*void CPU_init(void)/初始化CPU SJA_RST = 0;/CAN总线复位管脚有效 Delay( 20 ); SJA_RST = 1;/CAN总线复位管脚无效 SJA_CS = 0;/CAN总线片选有效 EX1 = 1; IT1 = 0;/CAN总线接收中断
20、 IT0 = 1;/外部中断0负边沿触发 EX0 = 1;/打开外部中断0 EA = 1; /打开总中断 SJA_CS = 1;/CAN总线片选无效,使对数据总线的操作不会影响SJA1000。void Rxd_deal(void)/ 接收处理程序/ if( RXD_flag ) EA = 0;/关闭CPU中断 RXD_flag = 0; if( RX_buffer3 = 0x10 )/如果该报文传输的为按键计数 Rxd_data = RX_buffer5; EA = 1; / 接收处理程序/void Txd_deal(void)/发送处理函数,主要是准备数据,并且调用发送函数 if( TXD_
21、flag = 1 ) _nop_(); TXD_flag = 0; TX_buffer5 = Txd_data;/ TX_buffer6=jidian; CAN_TXD(); _nop_(); _nop_(); /*处理函数*/*CAN子函数*void CAN_init( void )/SJA1000 的初始化 uchar bdata Judge; uchar ACRR4; uchar AMRR4; ACRR0 = 0xff; ACRR1 = 0x02; ACRR2 = 0xff; ACRR3 = 0xff;/接收代码寄存器 AMRR0 = 0xff; AMRR1 = 0X00; AMRR2
22、= 0xff; AMRR3 = 0xff;/接收屏蔽寄存器,只接收发往本节点的报文 do / .0=1-reset MODRe,进入复位模式,以便设置相应的寄存器 /防止未进入复位模式,重复写入 MODR = 0x09; Judge = MODR ; while( !(Judge & 0x01) ); CDR = 0x88;/ CDR.3=1-时钟关闭, .7=0-basic CAN, .7=1-Peli CAN BTR0 = 0x31; BTR1 = 0x1c;/总线波特率设定 IER = 0x01;/ .0=1-接收中断使能; .1=0-关闭发送中断使能 OCR = 0xaa;/ 配置输出
23、控制寄存器 CMR = 0x04;/释放接收缓冲器 ACR = ACRR0; ACR1 = ACRR1; ACR2 = ACRR2; ACR3 = ACRR3;/初始化标示码 AMR = AMRR0; AMR1 = AMRR1; AMR2 = AMRR2; AMR3 = AMRR3;/初始化掩码 do /确保退出复位模式 MODR = 0x08; Judge = MODR ; while( Judge & 0x01 );/SJA1000 的初始化void CAN_TXD( void ) uchar data Judge;/初始化标示码头信息 TX_buffer0 = 0x82;/.7=0扩展帧
24、;.6=0数据帧; .30=1数据长度 TX_buffer1 = 0x02;/本节点地址 TX_buffer2 = 0x01;/ TX_buffer3 = 0x10;/ TX_buffer4 = 0x00;/初始化标示码头信息/初始化发送数据单元 TX_buffer5 = Txd_data; TX_buffer6=jidian;/初始化数据信息 EA = 0; /关中断 do Judge = SR; LED_RED = 0;/ while( Judge & 0x10 ); /SR.4=1 正在接收,等待 do Judge = SR; LED_RED = 0;/ while(!(Judge & 0x08); /SR.3=0,发送请求未处理完,等待 do Judge = SR; LED_RED = 0;/ while(!(Judge & 0
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1