/////////////////////////////////////////////////////////
//CAN通信相关设置
//CAN初始化,接收函数,发送函数
/////////////////////////////////////////////////////////
#include<avr/interrupt.h>
#include<stdio.h>
#include "can.h"
#include "usart.h"
#define XBYTE ((unsigned char volatile *) 0)
uchar CAN_TXD_flag; //若TXD_flag=1,CAN要求发送处理
uchar CAN_RXD_flag = 0; //RXD_flag=0说明CAN无数据可以接收,RXD_flag=1说明CAN有数据可以接收
uchar RX_buffer[13] ;
/////////////////////////////////////////////////////////
//CAN初始化
void sja1000_init(void)
{
uchar state;
uchar ACRR[4];
uchar AMRR[4];
// 接收代码寄存器
ACRR[0] = 0x01;//相对于本节点的ID
ACRR[1] = 0x02;
ACRR[2] = 0x03;
ACRR[3] = 0x04;
// 接收屏蔽寄存器
AMRR[0] = 0xff;//相应的位为1的话,表示接收信息ID的本位置可以为任意数
AMRR[1] = 0Xff;
AMRR[2] = 0xff;
AMRR[3] = 0xff;
// 使用do--while语句确保进入复位模式
do
{
XBYTE[CAN_MOD]=0x09; // 设置MOD.0=1--进入复位模式,以便设置相应的寄存器
// MOD = 0x01;; // 设置MOD.0=1--进入复位模式,以便设置相应的寄存器
state = XBYTE[CAN_MOD];
}while( !(state & 0x09) );
// 对SJA1000部分寄存器进行初始化设置
XBYTE[CAN_CDR] =0x88; // CDR为时钟分频器,CDR.3=1--时钟关闭, CDR.7=0---basic CAN, CDR.7=1---Peli CAN
XBYTE[CAN_BTR0]=0x31; // 总线定时寄存器0 ;总线波特率设定
XBYTE[CAN_BTR1]=0x1c; // 总线定时寄存器1 ;总线波特率设定
XBYTE[CAN_IER] =0x01; // IER.0=1--接收中断使能; IER.1=0--关闭发送中断使能
XBYTE[CAN_OCR] =0xaa; // 配置输出控制寄存器
XBYTE[CAN_CMR] =0x04; // 释放接收缓冲器
// 初始化接收代码寄存器
XBYTE[ACR0]=ACRR[0];
XBYTE[ACR1]=ACRR[1];
XBYTE[ACR2]=ACRR[2];
XBYTE[ACR3]=ACRR[3];
// 初始化接收屏蔽寄存器
XBYTE[AMR0] = AMRR[0];
XBYTE[AMR1] = AMRR[1];
XBYTE[AMR2] = AMRR[2];
XBYTE[AMR3] = AMRR[3];
// 使用do--while语句确保退出复位模式
do
{
XBYTE[CAN_MOD]=0x08; //MOD.3=1--单滤波器模式
state = XBYTE[CAN_MOD];
}while( state & 0x01 );
printf("SJA1000初始化完成!!!\n\r");
}
/////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////
//CAN接收数据
void CAN_RXD( void )
{
uchar flag;
cli(); //disable all interrupts
flag = XBYTE[CAN_IR];
if( flag & 0x01) //IR.0 = 1 接收中断
{
RX_buffer[0] = XBYTE[RBSR0];
RX_buffer[1] = XBYTE[RBSR1];
RX_buffer[2] = XBYTE[RBSR2];
RX_buffer[3] = XBYTE[RBSR3];
RX_buffer[4] = XBYTE[RBSR4];
RX_buffer[5] = XBYTE[RBSR5];
RX_buffer[6] = XBYTE[RBSR6];
RX_buffer[7] = XBYTE[RBSR7];
RX_buffer[8] = XBYTE[RBSR8];
RX_buffer[9] = XBYTE[RBSR9];
RX_buffer[10] = XBYTE[RBSR10];
RX_buffer[11] = XBYTE[RBSR11];
RX_buffer[12] = XBYTE[RBSR12];
CAN_RXD_flag = 1;//置CAN通信有接收标志
XBYTE[CAN_CMR] = 0x04; //CMR.2=1释放接收缓冲器
flag = XBYTE[CAN_ALC]; //释放仲裁随时捕捉寄存器
flag = XBYTE[CAN_ECC]; //释放错误代码捕捉寄存器
}
XBYTE[CAN_IER] = 0x01; // IER.0=1--接收中断使能;
sei(); //re-enable interrupts
// printf("CAN接收接收正在进行!!!\n\r");
}
//////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////
//CAN接收处理函数
void can_rxd_deal(void)
{
uchar CAN_Rxd_data;
if( CAN_RXD_flag ==1) //CAN_RXD_flag=0说明无数据可以接收,CAN_RXD_flag=1说明有数据可以接收
{
cli(); //关闭全局中断
CAN_RXD_flag = 0; //CAN_RXD_flag清零,以便下次
if( RX_buffer[0] & 0x40 ) //接收到远程帧
{
CAN_TXD_flag = 1; //置位发送数据帧
}
else //接收到数据帧
{ //CAN总线要接收的数据,也是要在数码管3-4位置显示的数据
CAN_Rxd_data = RX_buffer[5];
}
sei(); //开启CPU中断
}
printf("接收缓冲器里的数据:\n\r");
// printf("%x\r\n",(RX_buffer[0]));
printf("%x\r\n",(RX_buffer[5]));
}
/////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////
//CAN发送函数
void can_txd(void)
{
uchar state;
uchar CAN_Txd_data=20;
uchar TX_buffer[ N_can ] ; //N_can=13,TX_buffer数组为待传送的数据帧
//初始化标示码头信息
TX_buffer[0] = 0x88; //.7=1--扩展帧;.6=0--数据帧; .0-.3=100--数据长度为8字节
TX_buffer[1] = 0x55; //本帧信息的ID
TX_buffer[2] = 0x22;
TX_buffer[3] = 0x33;
TX_buffer[4] = 0x44;
//初始化发送数据单元
TX_buffer[5] = CAN_Txd_data; //发送的第1个字节数据,也是数码管要显示的数据(计数结果)
TX_buffer[6] = 0x02; //2
TX_buffer[7] = 0x03; //3
TX_buffer[8] = 0x04; //4
TX_buffer[9] = 0x05; //5
TX_buffer[10] = 0x06; //6
TX_buffer[11] = 0x07; //7
TX_buffer[12] = 0x08; //8
//初始化数据信息
cli(); //关闭全局中断
//查询SJA1000是否处于接收状态,当SJA1000不处于接收状态时才可继续执行
do
{
state = XBYTE[CAN_SR]; ////SR为SJA1000的状态寄存器
printf("点亮LED1,正在接收\r\n");
printf("SR值是%x\r\n",(XBYTE[CAN_SR]));
printf("SR的地址是%x\r\n",(CAN_SR));
printf("state=XBYTE[CAN_SR]值是%x\r\n",state);
//LED_RED = 0; //点亮LED1
}while( state & 0x10 ); //SR.4=1 正在接收,等待
//---------查询SJA1000是否处于发送完毕状态----------//
do
{
state = XBYTE[CAN_SR];
// LED_RED = 0; //点亮LED1
printf("点亮LED2,发送请求未处理完\r\n");
printf("SR值是%x\r\n",state);
}while(!(state & 0x08)); //SR.3=0,发送请求未处理完,等待直到SR.3=1
//---------------查询发送缓冲器状态-----------------//
do
{
state = XBYTE[CAN_SR];
// LED_RED = 0; //点亮LED1
printf("点亮LED3,说明发送缓冲器被锁\r\n");
printf("SR值是%x\r\n",state);
}while(!(state & 0x04)); //SR.2=0,发送缓冲器被锁。等待直到SR.2=1
//LED_RED = !LED_RED; //熄灭LED1
//LED_GRE = !LED_GRE; //点亮LED2
//将待发送的一帧数据信息存入SJA1000的相应寄存器中
XBYTE[TBSR0] = TX_buffer[0];
XBYTE[TBSR1] = TX_buffer[1];
XBYTE[TBSR2] = TX_buffer[2];
XBYTE[TBSR3] = TX_buffer[3];
XBYTE[TBSR4] = TX_buffer[4];
XBYTE[TBSR5] = TX_buffer[5];
XBYTE[TBSR6] = TX_buffer[6];
XBYTE[TBSR7] = TX_buffer[7];
XBYTE[TBSR8] = TX_buffer[8];
XBYTE[TBSR9] = TX_buffer[9];
XBYTE[TBSR10] = TX_buffer[10];
XBYTE[TBSR11] = TX_buffer[11];
XBYTE[TBSR12] = TX_buffer[12];
XBYTE[CAN_CMR]=0x01; //置位发送请求
// printf("命令寄存器CMR值是%x\r\n",(*Can_cmr));
printf("命令寄存器CMR值是%x\r\n",(XBYTE[CAN_CMR]));
sei(); //开启CPU中断
printf("命令寄存器CMR值是是是%x\r\n",(XBYTE[CAN_CMR]));
printf("128外部存储器里的数据:\n\r");
printf("%x\r\n",(XBYTE[TBSR5]));
printf("%x\r\n",(XBYTE[RBSR5]));
printf("发送缓冲%x\r\n",(TX_buffer[5]));
printf("接收缓冲%x\r\n",(RX_buffer[5]));
printf("CAN发送结束!!\n\r");
}
/////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////
//CAN发送处理函数
void can_txd_deal(void)
{
if( CAN_TXD_flag == 1 ) //若CAN_TXD_flag=1,要求进行数据的发送处理
{
printf("CAN发送置位了吗吗吗!!\n\r");
CAN_TXD_flag = 0; //RXD_flag清零,以便下次查询
can_txd(); //发送数据帧
} //发送数据帧后,SJA1000将产生接收中断
}
/////////////////////////////////////////////////////////