📄 can_self.lst
字号:
C51 COMPILER V6.12 CAN_SELF 06/20/2008 08:56:27 PAGE 1
C51 COMPILER V6.12, COMPILATION OF MODULE CAN_SELF
OBJECT MODULE PLACED IN .\can_self.OBJ
COMPILER INVOKED BY: C:\Keil\C51\BIN\C51.EXE .\can_self.c DEBUG OBJECTEXTEND
stmt level source
1 /**************************************************************************************
2 项 目:基于CAN总线的自收发通信
3 说 明:主程序部分
4 功 能:外部按键每按下一次,计数值加一,同时计数值在数码管1、2上显示。
5 在计数值加一后,会使CAN总线上重新发送数据,此时接收端的计数值也同步更新显示
6 在数码管3、4上(为便于观察,接收显示的值比发送值大3)。
7 // CAN主要参数: PeliCAN模式,扩展帧EFF模式
8 // 29位标示码结构:
9 // 发送数据结构:计数结果,0x02,0x03,0x04,0x05,0x06,0x07,0x08
10 // 接收数据结构: 待显示数据+其它7个字节的数据
11 // 本节点的接收代码寄存器值: 0x11,0x22,0x33,0x44
12 // 本节点的屏蔽代码寄存器值:0x00,0x00,0x00,0x00;可以接收本节点的数据
13 // 目的节点地址:0x11,0x22,0x33,0x44;可以被本节点接收
14 模 块:can_self.c
15 作 者:特 权
16 时 间:08.6.17.
17 修 改:08.6.19.
18 **************************************************************************************/
19 /***感谢PIAE工作组提供的源码,这里特权根据自己的编程习惯做了一些修改并添加详细注释***/
20
21 #include <reg52.h>
22 #include <intrins.h>
23 #include "define.h"
24
25 ///////////////////////////////////////////////
26 //函数:inter0_key (外部中断INT0)
27 //说明:INT0按键为计数按键
28 // 每按下一次键,计数值加一
29 //入口:按键中断
30 //返回:按键加一
31 ///////////////////////////////////////////////
32 void inter0_key(void) interrupt 0
33 {
34 1 EA = 0; //关闭中断
35 1 Txd_data++; //计数结果增1,即待发送的数据增1
36 1 TXD_flag = 1; //发送数据标志位置位,即重新发送数据以更新数码管的显示数值
37 1 EA = 1; //重新开启中断
38 1 }
39
40 ///////////////////////////////////////////////
41 //函数:inter1_can_rxd (外部中断INT1)
42 //说明:接收数据函数,在中断服务程序中调用
43 //入口:无
44 //返回:无
45 ///////////////////////////////////////////////
46 void inter1_can_rxd( void ) interrupt 2
47 {
48 1 uchar state;
49 1
50 1 EA = 0; //关CPU中断
51 1 IE1 = 0; //由于是中断INT1是电平触发方式,所以需要软件将INT1的中断请求标志IE0清零
52 1
53 1 state = IR; //IR为SJA1000的中断寄存器
54 1 if( state & 0x01) //若IR.0=1--接收中断
55 1 { //接收数据帧
C51 COMPILER V6.12 CAN_SELF 06/20/2008 08:56:27 PAGE 2
56 2 RX_buffer[0] = RBSR;
57 2 RX_buffer[1] = RBSR1;
58 2 RX_buffer[2] = RBSR2;
59 2 RX_buffer[3] = RBSR3;
60 2 RX_buffer[4] = RBSR4;
61 2 RX_buffer[5] = RBSR5;
62 2 RX_buffer[6] = RBSR6;
63 2 RX_buffer[7] = RBSR7;
64 2 RX_buffer[8] = RBSR8;
65 2 RX_buffer[9] = RBSR9;
66 2 RX_buffer[10] = RBSR10;
67 2 RX_buffer[11] = RBSR11;
68 2 RX_buffer[12] = RBSR12;
69 2 RXD_flag = 1; //接收标志置位,以便进入接收处理程序
70 2 CMR = 0X04; //CMR.2=1--接收完毕,释放接收缓冲器
71 2 state = ALC; //释放仲裁随时捕捉寄存器(读该寄存器即可)
72 2 state = ECC; //释放错误代码捕捉寄存器(读该寄存器即可)
73 2 }
74 1
75 1 IER = 0x01; // IER.0=1--接收中断使能
76 1 EA = 1; //重新开启CPU中断
77 1 }
78
79 ///////////////////////////////////////////////
80 //函数:main
81 //说明:主函数
82 //入口:无
83 //返回:无
84 ///////////////////////////////////////////////
85 void main(void)
86 {
87 1 init_mcu();
88 1 init_sja1000();
89 1 while(1)
90 1 {
91 2 rxd_deal(); //接收处理程序
92 2 txd_deal(); //发送处理程序
93 2 led_show(0,Txd_data); //数码管1-2显示发送数据子程序
94 2 led_show(1,Rxd_data+3); //数码管3-4显示接收数据子程序
95 2 }
96 1 }
97
98 ///////////////////////////////////////////////
99 //函数:init_mcu
100 //说明:单片机I/O口初始化
101 // 主要是各中断寄存器的初始化
102 //入口:无
103 //返回:无
104 ///////////////////////////////////////////////
105 void init_mcu(void)
106 {
107 1 SJA_RST = 1; //CAN总线复位管脚复位无效
108 1 SJA_CS = 0; //CAN总线片选有效
109 1 EX1 = 1; //开MCU外部中断INT1
110 1 IT1 = 0; //MCU外部中断INT1设置为电平触发,该中断口连接CAN总线接收中断口
111 1 IT0 = 1; //MCU外部中断INT0设置为下降沿触发
112 1 EX0 = 1; //开MCU外部中断INT0
113 1 EA = 1; //开MCU总中断
114 1 SJA_CS = 1; //CAN总线片选无效,使得对数据总线的操作不会影响SJA1000。
115 1 }
116
117 ///////////////////////////////////////////////
C51 COMPILER V6.12 CAN_SELF 06/20/2008 08:56:27 PAGE 3
118 //函数:init_sja1000
119 //说明:独立CAN控制器SJA1000的初始化
120 //入口:无
121 //返回:无
122 ///////////////////////////////////////////////
123 void init_sja1000(void)
124 {
125 1 uchar state;
126 1 uchar ACRR[4];
127 1 uchar AMRR[4];
128 1
129 1 // 接收代码寄存器
130 1 ACRR[0] = 0x11;
131 1 ACRR[1] = 0x22;
132 1 ACRR[2] = 0x33;
133 1 ACRR[3] = 0x44;
134 1
135 1 // 接收屏蔽寄存器,只接收主机发送的信息
136 1 AMRR[0] = 0x00;
137 1 AMRR[1] = 0X00;
138 1 AMRR[2] = 0x00;
139 1 AMRR[3] = 0x00;
140 1
141 1 // 使用do--while语句确保进入复位模式
142 1 do
143 1 {
144 2 MODR = 0x09; // 设置MOD.0=1--进入复位模式,以便设置相应的寄存器
145 2 state = MODR;
146 2 }
147 1 while( !(state & 0x01) );
148 1
149 1 // 对SJA1000部分寄存器进行初始化设置
150 1 CDR = 0x88; // CDR为时钟分频器,CDR.3=1--时钟关闭, CDR.7=0---basic CAN, CDR.7=1---Peli CAN
151 1 BTR0 = 0x31; // 总线定时寄存器0 ;总线波特率设定
152 1 BTR1 = 0x1c; // 总线定时寄存器1 ;总线波特率设定
153 1 IER = 0x01; // IER.0=1--接收中断使能; IER.1=0--关闭发送中断使能
154 1 OCR = 0xaa; // 配置输出控制寄存器
155 1 CMR = 0x04; // 释放接收缓冲器
156 1
157 1 // 初始化接收代码寄存器
158 1 ACR0 = ACRR[0];
159 1 ACR1 = ACRR[1];
160 1 ACR2 = ACRR[2];
161 1 ACR3 = ACRR[3];
162 1
163 1 // 初始化接收屏蔽寄存器
164 1 AMR0 = AMRR[0];
165 1 AMR1 = AMRR[1];
166 1 AMR2 = AMRR[2];
167 1 AMR3 = AMRR[3];
168 1
169 1 // 使用do--while语句确保进入自接收模式
170 1 do
171 1 {
172 2 MODR = 0x04; //MOD.2=1--进入自接收模式,MOD.3=0--双滤波器模式
173 2 state = MODR;
174 2 }
175 1 while( !(state & 0x04) );
176 1 }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -