📄 main.c
字号:
/**********************************************************************************
工程名称: Can测试
CPU类型: LPC2148
晶振频率: 11.0592Mhz
作 者 : 武宪明
单 位 : 济南大学 控制科学与工程学院 自升0702
日 期 :
备 注 : AD0--------P0.4
AD1--------P0.5
AD2--------P0.6
AD3--------P0.7
AD4--------P0.8
AD5--------P0.9
AD6--------P0.10
AD7--------P0.11
RD/E-------P0.19
WR---------P0.20
ALE/AS-----P0.21
CS --------P0.22
************************************************************************************/
#include "config.h"
/* 定义CAN总线起始的GPIO,即D0对应的GPIO值(P0.4) */
#define CAN_BUS 4
#define RD 19
#define RD_1 IO0SET = 1<<RD
#define RD_0 IO0CLR = 1<<RD
#define WR 20
#define WR_1 IO0SET = 1<<WR
#define WR_0 IO0CLR = 1<<WR
#define ALE 21
#define ALE_1 IO0SET = 1<<ALE
#define ALE_0 IO0CLR = 1<<ALE
#define CS 22
#define CS_1 IO0SET = 1<<CS
#define CS_0 IO0CLR = 1<<CS
#define SJA_BTR0 0x01// 总线定时寄存器0
#define SJA_BTR1 0x1c// 总线定时寄存器1
#define SJA_ACR 0xaa// 验收代码寄存器
#define SJA_AMR 0x55// 验收屏蔽寄存器
#define SJA_OCR 0xaa// 输出控制寄存器
#define SJA_CDR 0x48// 时钟分频寄存器
#define LED 12
/* 输出CAN总线数据宏定义 */
#define OutData(dat) IO0CLR = 0xFF<<CAN_BUS; IO0SET = (dat&0xff)<<CAN_BUS
uint8 SJA_workmode=1; //0:为工作在复位模式 1:为工作在工作模式
uint8 connect_ok=0;
struct CAN_BUFstruct{ //定义CAN数据结构
uint8 CAN_ID_H; //8位---信息功能码2+节点号6
uint8 CAN_ID_L; //3位---数据场格式3
uint8 CAN_RTR; //1位---RTR
uint8 CAN_DLC; //4位---数据长度
uint8 CAN_Data[8];//8位---最多8字节数据
}receive_BUF,send_BUF;
/*************************************************************************************
函数名:void delay(uint8 data)
功 能:读取CAN总线数据
输 入:寄存器地址
返 回:8位数据
备 注:
**************************************************************************************/
void delay(uint32 data)
{
uint32 i;
for(;data>0;data--)
{ for(i=5;i>0;i--);
}
}
/*************************************************************************************
函数名:uint8 Read_Can(uint8 address)
功 能:读取CAN总线数据
输 入:寄存器地址
返 回:8位数据
备 注:
**************************************************************************************/
void GPIO_init(void)
{
PINSEL0=0x00000000;
IO0DIR|=(1<<RD)|(1<<WR)|(1<<ALE)|(1<<CS);
IO0DIR|=1<<LED;
}
/*************************************************************************************
函数名:uint8 Read_Can(uint8 address)
功 能:读取CAN总线数据
输 入:寄存器地址
返 回:8位数据
备 注:
**************************************************************************************/
uint8 Read_Can(uint8 address)
{
uint32 dat;
IO0DIR |=(0xff<<CAN_BUS); //设置为输出口
ALE_1;
CS_1;
RD_1;
WR_1;
OutData(address); //写入地址
delay(100);
ALE_0;
CS_0;
RD_0;
delay(1); //10ns
IO0DIR&=~(0xff<<CAN_BUS); //设置为输入口
dat=IO0PIN;
dat=dat>>CAN_BUS; //读取总线数据
CS_1;
RD_1;
return (uint8)dat;
}
/*************************************************************************************
函数名:void Write_Can(uint8 address,uint8 data)
功 能:写数据
输 入:address:待写入数据的地址
data:待写入的数据
返 回:无
备 注:
**************************************************************************************/
void Write_Can(uint8 address,uint8 data)
{
IO0DIR |=(0xff<<CAN_BUS); //设置为输出口
ALE_1;
CS_1;
WR_1;
RD_1;
OutData(address); //写入地址
ALE_0;
CS_0;
WR_0;
OutData(data); //写入数据
CS_1;
WR_1;
ALE_1;
delay(2);
}
/*************************************************************************************
函数名:void Can_Test(void)
功 能:测试寄存器
输 入:无
返 回:无
备 注:address:0x09 测试寄存器
data:0xaa 写入的数据
**************************************************************************************/
void Can_Test(void)
{
uint8 i;
Write_Can(0x09,0xaa);
i=Read_Can(0x09);
if(i==0xaa) connect_ok=1; //连接正常
else connect_ok=0; //连接失败
}
/*************************************************************************************
函数名:void setting_SJA_resetmode(void)
功 能:设置工作模式为复位模式
输 入:无
返 回:无
备 注:
**************************************************************************************/
void setting_SJA_resetmode(void)
{
uint8 resetdata=0,i;
resetdata=Read_Can(0x00);
resetdata|=0x01;
Write_Can(0x00,resetdata);
while(SJA_workmode)
{
i=Read_Can(0x00);
if((i&0x01)==1) SJA_workmode=0; //置复位模式成功
else SJA_workmode=1; //置复位模式失败
}
}
/*************************************************************************************
函数名:void setting_SJA_workmode(void)
功 能:设置工作模式为工作模式
输 入:无
返 回:无
备 注:
**************************************************************************************/
void setting_SJA_workmode(void)
{
uint8 workdata=0;
workdata=Read_Can(0x00);
workdata&=0xfe;
while(SJA_workmode==0)
{
Write_Can(0x00,workdata);
if((Read_Can(0x00)&0x01)==1) SJA_workmode=0; //置工作模式成功
else SJA_workmode=1; //置工作模式失败
}
}
/*************************************************************************************
函数名:void setting_SJA_rate(void)
功 能:设置数据传输速率
输 入:无
返 回:无
备 注:
**************************************************************************************/
uint8 setting_SJA_rate(void)
{
uint8 setting_success=0;
while(SJA_workmode) //工作模式
{
setting_SJA_resetmode(); //设置SJA工作在复位模式
}
Write_Can(0x06,SJA_BTR0);
Write_Can(0x07,SJA_BTR1);
if((Read_Can(0x06)==SJA_BTR0)&(Read_Can(0x07)==SJA_BTR1))
{
setting_success=1;
}
else setting_success=0;
return (setting_success);
}
/*************************************************************************************
函数名:void setting_SJA_dataselect(void)
功 能:设置接收数据类型
输 入:无
返 回:无
备 注:
**************************************************************************************/
uint8 setting_SJA_dataselect(void)
{
uint8 setting_success=0;
while(SJA_workmode) //工作模式
{
setting_SJA_resetmode(); //设置SJA工作在复位模式
}
Write_Can(0x04,SJA_ACR);
Write_Can(0x05,SJA_AMR);
if((Read_Can(0x04)==SJA_ACR)&(Read_Can(0x05)==SJA_AMR))
{
setting_success=1;
}
else setting_success=0;
return (setting_success);
}
/*************************************************************************************
函数名:void setting_SJA_CLK(void)
功 能:设置输出数据类型
输 入:无
返 回:无
备 注:
**************************************************************************************/
uint8 setting_SJA_CLK(void)
{
uint8 setting_success=0;
while(SJA_workmode) //工作模式
{
setting_SJA_resetmode(); //设置SJA工作在复位模式
}
Write_Can(0x08,SJA_OCR);
Write_Can(31,SJA_CDR);
if((Read_Can(0x08)==SJA_OCR)&(Read_Can(31)==SJA_CDR))
{
setting_success=1;
}
else setting_success=0;
return (setting_success);
}
/*************************************************************************************
函数名:void setting_SJA_CLK(void)
功 能:SJA1000初始化
输 入:无
返 回:无
备 注:
**************************************************************************************/
uint8 CAN_init(void)
{
while(connect_ok==0) //检测设备连接
{
Can_Test();
}
while(SJA_workmode) //置位复位模式
{
setting_SJA_resetmode();
}
while(setting_SJA_rate()==0) //设置数据传输速率
{
setting_SJA_rate();
}
while(setting_SJA_dataselect()==0) //设置接收数据格式
{
setting_SJA_dataselect();
}
while(setting_SJA_CLK()==0) //设置输出数据形式
{
setting_SJA_CLK();
}
}
/*************************************************************************************
函数名:uint8 send_CANBUF(void)
功 能:写发送缓存区
输 入:无
返 回:无
备 注:
**************************************************************************************/
uint8 send_CANBUF(void)
{
uint8 setting_success=0,i;
while(SJA_workmode) //置位工作模式
{
setting_SJA_workmode();
}
if((Read_Can(0x02)&0x20)==0) //发送状态为空
{
if((Read_Can(0x02)&0x04)!=0) //发送缓存器状态为释放
{
Write_Can(10,send_BUF.CAN_ID_H);
Write_Can(11,(send_BUF.CAN_ID_L<<5)|(send_BUF.CAN_RTR<<4)|(send_BUF.CAN_DLC));
if(send_BUF.CAN_RTR==0)
{
for(i=0;i<send_BUF.CAN_DLC;i++)
{
Write_Can(12+i,send_BUF.CAN_Data[i]);
}
}
setting_success=1;
}
}
return setting_success;
}
/*************************************************************************************
函数名:receive_CANBUF(void)
功 能:读接收缓存区
输 入:无
返 回:无
备 注: uint8 CAN_ID_H; //8位---信息功能码2+节点号6
uint8 CAN_ID_L; //3位---数据场格式3
uint8 CAN_RTR; //1位---RTR
uint8 CAN_DLC; //4位---数据长度
uint8 CAN_Data[8];//8位---最多8字节数据
**************************************************************************************/
uint8 receive_CANBUF(void)
{
uint8 setting_success=0,i;
while(SJA_workmode) //置位工作模式
{
setting_SJA_workmode();
}
if((Read_Can(0x02)&0x01)==0) //接收缓存器状态为空
{
if((Read_Can(0x02)&0x10)!=0) //接收状态为空闲
{
receive_BUF.CAN_ID_H=Read_Can(20);
receive_BUF.CAN_ID_L=((Read_Can(21)&0xe0)>>5);
receive_BUF.CAN_RTR =((Read_Can(21)&0x10)>>4);
receive_BUF.CAN_DLC =(Read_Can(21)&0x0f);
if(receive_BUF.CAN_RTR==0)
{
for(i=0;i<receive_BUF.CAN_DLC,i<8;i++)
{
receive_BUF.CAN_Data[i]=Read_Can(22+i);
}
}
setting_success=1;
}
}
return setting_success;
}
/*************************************************************************************
函数名:int main (void)
功 能:主函数
输 入:无
返 回:无
备 注: uint8 CAN_ID_H; //8位---信息功能码2+节点号6
uint8 CAN_ID_L; //3位---数据场格式3
uint8 CAN_RTR; //1位---RTR
uint8 CAN_DLC; //4位---数据长度
uint8 CAN_Data[8];//8位---最多8字节数据
**************************************************************************************/
int main (void)
{
uint8 Tab[8]={0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08};
uint8 i,j;
send_BUF.CAN_ID_H=0x01;
send_BUF.CAN_ID_L=0x00;
send_BUF.CAN_RTR=0x00;
send_BUF.CAN_DLC=0x08;
for(i=0;i<8;i++)
{
send_BUF.CAN_Data[i]= Tab[i];
}
GPIO_init();
CS_0;
// Can_Test();
// if(connect_ok==1) IO0SET=1<<LED;
// else IO0CLR=1<<LED;
CAN_init();
while(1)
{
send_CANBUF();
Write_Can(0x01,0x01);
}
return 0;
}
/*********************************************************************************************************
** End Of File
********************************************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -