在线时间10 小时
UID2085220
注册时间2014-11-22
NXP金币0
该用户从未签到
注册会员

- 积分
- 85
- 最后登录
- 2016-7-22
|
大家好!我正在学MSCAN模块,用的是MC9S12X128,可是作为接收结点的开发板始终没有接收到数据,应该是接收程序没有进入中断,可初始化CAN模块接收器中断使能打开了,是什么原因?急啊!搞了好几天了,有没有高手指教一番!小生在此不胜感激!
这是CAN模块的程序:
#include "derivative.h" /* include peripheral declarations */
#include "CAN.h"
/*************************************************************/
/* 初始化CAN0 */
/*************************************************************/
void INIT_CAN0(void)
{
if(CAN0CTL0_INITRQ==0) // 查询是否进入初始化状态
CAN0CTL0_INITRQ =1; // 进入初始化状态
while (CAN0CTL1_INITAK==0); //等待进入初始化状态
CAN0BTR0_SJW = 0; //设置同步
CAN0BTR0_BRP = 7; //设置波特率
CAN0BTR1 = 0x1c; //设置时段1和时段2的Tq个数 ,总线频率为250kb/s
// 关闭滤波器
CAN0IDMR0 = 0xFF;
CAN0IDMR1 = 0xFF;
CAN0IDMR2 = 0xFF;
CAN0IDMR3 = 0xFF;
CAN0IDMR4 = 0xFF;
CAN0IDMR5 = 0xFF;
CAN0IDMR6 = 0xFF;
CAN0IDMR7 = 0xFF;
CAN0CTL1 = 0xC0; //使能MSCAN模块,设置为一般运行模式、使用总线时钟源
CAN0CTL0 = 0x00; //返回一般模式运行
while(CAN0CTL1_INITAK); //等待回到一般运行模式
while(CAN0CTL0_SYNCH==0); //等待总线时钟同步
CAN0RIER_RXFIE = 1; //使能接收中断
}
/*************************************************************/
/* CAN0发送 */
/*************************************************************/
Bool MSCAN0SendMsg(struct can_msg msg)
{
unsigned char send_buf, sp;
// 检查数据长度
if(msg.len > 8)
return(FALSE);
// 检查总线时钟
if(CAN0CTL0_SYNCH==0)
return(FALSE);
send_buf = 0;
do
{
// 寻找空闲的缓冲器
CAN0TBSEL=CAN0TFLG;
send_buf=CAN0TBSEL;
}
while(!send_buf);
// 写入标识符
CAN0TXIDR0 = (unsigned char)(msg.id>>3);
CAN0TXIDR1 = (unsigned char)(msg.id<<5);
if(msg.RTR)
// RTR = 阴性
CAN0TXIDR1 |= 0x10;
// 写入数据
for(sp = 0; sp < msg.len; sp++)
*((&CAN0TXDSR0)+sp) = msg.data[sp];
// 写入数据长度
CAN0TXDLR = msg.len;
// 写入优先级
CAN0TXTBPR = msg.prty;
// 清 TXx 标志 (缓冲器准备发送)
CAN0TFLG = send_buf;
return(TRUE);
}
/*************************************************************/
/* CAN0接收 */
/*************************************************************/
Bool MSCAN0GetMsg(struct can_msg *msg)
{
unsigned char sp2;
// 检测接收标志
if(!(CAN0RFLG_RXF))
return(FALSE);
// 检测 CAN协议报文模式 (一般/扩展) 标识符
if(CAN0RXIDR1_IDE)
// IDE = Recessive (Extended Mode)
return(FALSE);
// 读标识符
msg->id = (unsigned int)(CAN0RXIDR0<<3) |
(unsigned char)(CAN0RXIDR1>>5);
if(CAN0RXIDR1&0x10)
msg->RTR = TRUE;
else
msg->RTR = FALSE;
// 读取数据长度
msg->len = CAN0RXDLR;
// 读取数据
for(sp2 = 0; sp2 < msg->len; sp2++)
msg->data[sp2] = *((&CAN0RXDSR0)+sp2);
// 清 RXF 标志位 (缓冲器准备接收)
CAN0RFLG = 0x01;
return(TRUE);
}
这是主程序
#include <hidef.h> /* common defines and macros */
#include "derivative.h" /* derivative-specific definitions */
#include "CAN.h"
#include "LCD.h"
#define LEDCPU PORTK_PK4
#define LEDCPU_dir DDRK_DDRK4
#define BUS_CLOCK 32000000 //总线频率
#define OSC_CLOCK 16000000 //晶振频率
char *xianshi[3] = {
"飞翔科技开发板",
"接收到的数据为:",
};
#define ID 0x0001 //发送标识符
#define data_len_TX 7 //发送数据长度
unsigned char k;
unsigned char senddata[8] = {'F','R','E','E','F','L','Y',0}; //发送的数据
struct can_msg msg_send, msg_get;
unsigned char datain=0;
/*************************************************************/
/* 初始化锁相环 */
/*************************************************************/
void INIT_PLL(void)
{
。。。。。。。。。。。。。。。。。。。。
}
/************************************************************/
/* 初始化ECT模块 */
/************************************************************/
void initialize_ect(void){
。。。。。。。。。。。。。。。。。。。。。
}
/************************************************************/
/* 在液晶上显示接收到的数据 */
/************************************************************/
void play_data(void)
{
。。。。。。。。。。。。。。。。。。。。。
}
/*************************************************************/
/* 中断接收函数 */
/*************************************************************/
#pragma CODE_SEG __NEAR_SEG NON_BANKED
void interrupt CAN_receive(void)
{
LEDCPU = ~LEDCPU;(在这里用指示灯检查是否进入中断,结果指示灯一直亮)
if(MSCAN0GetMsg(&msg_get))
{
// LEDCPU = ~LEDCPU;
// 接收新信息
if(msg_get.id == ID && (!msg_get.RTR))
{
// LEDCPU = ~LEDCPU;
datain=1;
}
}
else
{
for(;;);
}
}
#pragma CODE_SEG DEFAULT
/*************************************************************/
/* 主函数 */
/*************************************************************/
void main(void) {
DisableInterrupts;
INIT_PLL();
initialize_ect();
INIT_CAN0();
INIT_PORT();
LEDCPU_dir=1;
LEDCPU=0;
EnableInterrupts;
for(;;)
{
if(datain==1)
{
lcd_clear();
lcd_string(0,0,xianshi[0]);
lcd_string(1,0,xianshi[1]);
play_data();
datain=0;
}
}
}
|
|