snifer

【原创】基于MCP2510的Can总线在嵌入式系统中的应用

0
阅读(2029)

Can总线在嵌入式系统中的应用无处不在,今天就给大家全面解析CAN总线的结构原理及在嵌入式系统中的应用。

CAN 总线电路采用MCP2510 作为控制器,3.3V供电,TJA1050 作为驱动器。MCP2510 通过SPI 总线和CPU 连接,片选线占用S3C2410 的GPH0,中断占用S3C2410 的EINT4。CAN 总线接口用接线端子引出,同时对外提供5V 供电。

下图为其结构原理图:

blob.png

根据其原理设计得到的模块如下图:

blob.png

连接到ARM S3C6410中。

编译源程序

1、进入实验目录:

[sprife@localhost UP-Magic_Moudles]$ cd can/

[sprife@localhost can]$ ls

driver test UP-Magic-0202.pdf

[sprife@localhost can]$

2、编译驱动程序

[sprife@localhost can]$ cd driver/

[sprife@localhost driver]$ ls

Makefile mcp2510.h s3c-can-mcp2510.c spi_uptech.h up-can.h

[sprife@localhost driver]$

源程序:

/************************************************\

* by threewater<threewater@up-tech.com> *

* 2003.12.18 *

* *

\***********************************************/


#include <stdio.h>

#include <unistd.h>

#include <fcntl.h>

#include <time.h>

//#include <sys/types.h>

//#include <sys/ipc.h>

#include <sys/ioctl.h>

#include <pthread.h>


//#include "hardware.h"

#include "up-can.h"


#define CAN_DEV "/dev/can0"

static int can_fd = -1;


#define DEBUG

#ifdef DEBUG

#define DPRINTF(x...) printf(x)

#else

#define DPRINTF(x...)

#endif


static void* canRev(void* t)

{

CanData data;

int i;

DPRINTF("can recieve thread begin.\n");

for(;;){

read(can_fd, &data, sizeof(CanData));

for(i=0;i<data.dlc;i++)

putchar(data.data[i]);

fflush(stdout);

}

return NULL;

}


#define MAX_CANDATALEN 8

static void CanSendString(char *pstr)

{

CanData data;

int len=strlen(pstr);

memset(&data,0,sizeof(CanData));

data.id=0x123;

data.dlc=8;

for(;len>MAX_CANDATALEN;len-=MAX_CANDATALEN){

memcpy(data.data, pstr, 8);

//write(can_fd, pstr, MAX_CANDATALEN);

write(can_fd, &data, sizeof(data));

pstr+=8;

}

data.dlc=len;

memcpy(data.data, pstr, len);

//write(can_fd, pstr, len);

write(can_fd, &data, sizeof(CanData));

}


int main(int argc, char** argv)

{

int i;

pthread_t th_can;

static char str[256];

static const char quitcmd[]="\\q!";

void * retval;

int id=0x123;

char usrname[100]={0,};

 

       if((can_fd=open(CAN_DEV, O_RDWR))<0){

                printf("Error opening %s can device\n", CAN_DEV);

                return 1;

        }


ioctl(can_fd, UPCAN_IOCTRL_PRINTRIGISTER, 1);

ioctl(can_fd, UPCAN_IOCTRL_SETID, id);

#ifdef DEBUG

ioctl(can_fd, UPCAN_IOCTRL_SETLPBK, 1);

#endif

/* Create the threads */

pthread_create(&th_can, NULL, canRev, 0);


printf("\nPress \"%s\" to quit!\n", quitcmd);

printf("\nPress Enter to send!\n");


if(argc==2){ //Send user name

sprintf(usrname, "%s: ", argv[1]);

}

for(;;){

int len;

scanf("%s", str);

if(strcmp(quitcmd, str)==0){

break;

}

if(argc==2) //Send user name

CanSendString(usrname);

len=strlen(str);

str[len]='\n';

str[len+1]=0;

CanSendString(str);

}

/* Wait until producer and consumer finish. */

//pthread_join(th_com, &retval);


printf("\n");

close(can_fd);

return 0;

}

需要修改 Makfile 编译规则文件,在其中指定用户自己的内核源文件目录(产品光盘配套

linux2.6.21 内核,并保证该内核源码解压后至少编译过一次,才能正确编译内核驱动程序)

通过修改宏KERNELDIR ?变量来指定内核源码目录:

KERNELDIR ?= /home/sprife/UP-Magic/kernel/linux-2.6.21_magic/

使用make 命令编译红外驱动程序

[sprife@localhost driver]$ make

[sprife@localhost driver]$ ls

Makefile Module.symvers s3c-can-mcp2510.ko s3c-can-mcp2510.mod.o

spi_uptech.h

mcp2510.h s3c-can-mcp2510.c s3c-can-mcp2510.mod.c s3c-can-mcp2510.o

up-can.h

[sprife@localhost driver]$

当前目录下生成驱动程序 s3c-can-mcp2510.ko

2、编译应用程序

[sprife@localhost can]$ ls

driver test UP-Magic-0202.pdf

[sprife@localhost can]$ cd test/

[sprife@localhost test]$ ls

hardware.h install.sh main.c Makefile up-can.h

[sprife@localhost test]$ make

[sprife@localhost test]$ ls

canchat hardware.h install.sh main.c main.o Makefile up-can.h

[sprife@localhost test]$

当前目录下生成测试程序canchat

♦ NFS 挂载实验目录测试

3、启动UP-Magic 魔法师实训开发板,连好网线、串口线。将配套CAN 模块插入底板P7、P5

扩展端口(底板与模块插线端口一致)。通过串口终端挂载宿主机实验目录。

设置开发板IP : 192.168.1.199 ( 默认宿主机LINUX IP 192.168.1.43,NFS 共享目录

/home/sprife)

up-tech:~ #ifconfig eth0 192.168.1.199

up-tech:~ #mount -t nfs -o nolock,rsize=4096,wsize=4096 192.168.1.43:/home/sprife /mnt/nfs

4、进入串口终端的NFS 共享实验目录。

up-tech:~ #cd /mnt/nfs/UP-Magic/UP-Magic_Moudles/can/

up-tech:/mnt/nfs/UP-Magic/UP-Magic_Moudles/can #ls

UP-Magic-0202.pdf driver test

up-tech:/mnt/nfs/UP-Magic/UP-Magic_Moudles/can #

5、加载驱动程序

up-tech:/mnt/nfs/UP-Magic/UP-Magic_Moudles/can #insmod driver/s3c-can-mcp2510.ko

can device initialized

up-tech:/mnt/nfs/UP-Magic/UP-Magic_Moudles/can #

6、执行测试程序

up-tech:/mnt/nfs/UP-Magic/UP-Magic_Moudles/can #cd test/

up-tech:/mnt/nfs/UP-Magic/UP-Magic_Moudles/can/test #./canchat

can recieve thread begin.

Press "\q!"

一下午就干了这件事情,很忙,怎么破!