【原创】基于MCP2510的Can总线在嵌入式系统中的应用
0赞Can总线在嵌入式系统中的应用无处不在,今天就给大家全面解析CAN总线的结构原理及在嵌入式系统中的应用。
CAN 总线电路采用MCP2510 作为控制器,3.3V供电,TJA1050 作为驱动器。MCP2510 通过SPI 总线和CPU 连接,片选线占用S3C2410 的GPH0,中断占用S3C2410 的EINT4。CAN 总线接口用接线端子引出,同时对外提供5V 供电。
下图为其结构原理图:
根据其原理设计得到的模块如下图:
连接到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!"
一下午就干了这件事情,很忙,怎么破!