首页 在ARM9(S3C2440)上实现ZigBee协议--基于CC2420芯片

在ARM9(S3C2440)上实现ZigBee协议--基于CC2420芯片

举报
开通vip

在ARM9(S3C2440)上实现ZigBee协议--基于CC2420芯片在ARM9(S3C2440)上实现ZigBee协议--基于CC2420芯片 在ARM9(S3C2440)上实现ZigBee协议--基于CC2420芯片 ZigBee是一种基于IEEE802.15.4规范的无线技术。它在短距离的低速率的数据通信有很大的优势,它的控制范围大概是200m-500m,传输速率也是250Kb/s左右。ZigBee依据802.15.4标准,在数千个微小的传感器之间相互协调实现通信,这些传感器只需要很少的能量,以接力的方式通过无线电波将数据从一个传感器传到另一个传感器,所以它们的通信效率非常高...

在ARM9(S3C2440)上实现ZigBee协议--基于CC2420芯片
在ARM9(S3C2440)上实现ZigBee 协议 离婚协议模板下载合伙人协议 下载渠道分销协议免费下载敬业协议下载授课协议下载 --基于CC2420芯片 在ARM9(S3C2440)上实现ZigBee协议--基于CC2420芯片 ZigBee是一种基于IEEE802.15.4规范的无线技术。它在短距离的低速率的数据通信有很大的优势,它的控制范围大概是200m-500m,传输速率也是250Kb/s左右。ZigBee依据802.15.4标准,在数千个微小的传感器之间相互协调实现通信,这些传感器只需要很少的能量,以接力的方式通过无线电波将数据从一个传感器传到另一个传感器,所以它们的通信效率非常高。采用ZigBee有几个好处:一是采用该技术的设备可以工作在无需获得许可的频带上;第二是它对的功耗达到了最低的限度,基于ZigBee的设备能用单个电池运行长达5年的时间;最后就是基于ZigBee协议组建的网络具有极大的可伸缩性,采用星型拓扑结构的网络的主设备可以支持4万多个节点。因此ZigBeed在短距离的无线控制及传感器网络中向到广泛的应用,本系统 设计 领导形象设计圆作业设计ao工艺污水处理厂设计附属工程施工组织设计清扫机器人结构设计 的时候采用了基于ZigBee协议的CC2420射频收发器。 外围接口电路 CC2420的应用电路 CC2420模块引脚 S3C2440与CC2420连接电路 2. 驱动程序设计 CC2420与S3C2440的接口主要是SPI的四线接口,如上图,其实用到就是三个 在编写CC2420的驱动程序前,先写一个驱动程序的框架,接着就可以在后面的开发过程中添加有关CC2420操作的代码了。下面是我最先写的一个框架: struct file_operations这个数据结构提供文件系统的入口点函数,也就是访问设备驱动的函数,包括设备的读写操作,初始化操作等等。file_operations在定义。 static struct file_operations spi_fops = { .owner = THIS_MODULE, .open = spi_open, .read = spi_read, .write = spi_write, }; 下面是对设备的打开操作,设备文件被打开后,应用程序就会得到一个对应于些设备的句柄。 static int spi_open(struct inode *inode, struct file *filp) { printk(KERN_ALERT "spi open"); return 0; } 下面的两个函数是应用程序对设备进行读写操作时会调用的。由于这里涉及到数据在内核空间与数据空间的数据交换,因此在这里不能直接使用从用户空间传递进来的数据,也不能直接将内核空间的数据缓冲区直接给用户空间引用。Linux内核提供了两个函数可以实现用户空间与内核空间之间的数据拷贝,它们分别为copy_from_user ,copy_to_user。 static ssize_t spi_write(struct file *filp,const char *buf,size_t count,loff_t *f_ops) { char pTXBuffer[30]; copy_from_user(pTxBuffer, buf, count); } static ssize_t spi_read(struct file *filp, const char *buff, size_t count, loff_t *offp) { copy_to_user(buff, pRxBuffer, count); return count; } Spi_init函数是在驱动模块加载时调用的,它是最先被执行的一个函数。在这里一般会进行一些设备的初始化工作,例如注册设备,端口映射。 Static int spi_init(void) { printk(KERN_ALERT "mscl_spi_bus initialization\n"); if(SPI_MAJOR) { SPI_DEV = MKDEV(SPI_MAJOR, SPI_MINOR); reval = register_chrdev_region(SPI_DEV, 0, SPI_NAME); } else { reval = alloc_chrdev_region( &SPI_DEV, 0, 1, SPI_NAME); SPI_MAJOR = MAJOR(SPI_DEV); } if (reval == -1) { printk(KERN_ERR "mscl_register device failed\n"); return -1; } SPI_CDEV = cdev_alloc(); if (SPI_CDEV != NULL) { cdev_init(SPI_CDEV, &spi_fops); SPI_CDEV->ops = &spi_fops; SPI_CDEV->owner = THIS_MODULE; if (cdev_add(SPI_CDEV, SPI_DEV, 1)) { printk(KERN_ALERT "Something wrong accors when register device\n"); } else { printk(KERN_ALERT "mscl_Successfully adding the device\n"); } } } spi_exit在驱动模块被卸载时会被调用,例如我们用rmmod命令时。在这里一般会进行一些资源的释放操作,例如释放之前注册的中断,端口内存等等。 static void __exit spi_exit(void) { } module_init(spi_init); module_exit(spi_exit); module_init是要告诉内核spi_init是驱动的初始化函数,这样在加载驱动模块时该函数就会被执行去完成设备的初始化工作。 module_exit是要告诉内核spi_exit是驱动模块的清除函数,在移除驱动模块时这个函数就会被执行。 module_init,module_exit都只是一个宏,其实就是告诉编译器将它们放到代码段的init节中。 3. 完善驱动 在具备了驱动程序的基本框架后,下面就可以逐渐完善它,增强它的功能。 l I/O端口映射 I/O端口空间非常有限,所有的总线设备都以内在映射方式来映射它的I/O端口和外设内存。但是驱动程序并不能直接通过物理地址访问I/O内存资源,而必须将它们映射到核心虚地址空间内,然后才能根据映射所得到的核心虚地址范围,通过访内指令访问这些I/O内存资源。Linux内核提供了ioremap()函数将I/O内存资源的物理地址映射到核心虚地址空间中。 下面的几个函数提供了映射后SPI0的相关寄存器,外部中断控制寄存器。 rSPCON0 = ioremap(S3C2410_SPCON0, 1); rSPSTA0 = ioremap(S3C2410_SPSTA0, 1); rSPPIN0 = ioremap(S3C2410_SPPIN0, 1); rSPPRE0 = ioremap(S3C2410_SPPRE0, 1); rSPTDAT0 = ioremap(S3C2410_SPTDAT0, 1); rSPRDAT0 = ioremap(S3C2410_SPRDAT0, 1); rEXINT0 = ioremap(EXINT0, 4); rEXINT1 = ioremap(EXINT1, 4); rEXINT2 = ioremap(EXINT2, 4); 这里利用ioremap函数进行端口的映射后就会得到这些寄存器的虚地址,在后面对这些寄存器进行读写操作时,都是利用这些返回的虚地址,不能利用它们的物理地址去进行寄存器的读写。 l SPI端口设置 为了能够使S3C2440能够与CC2420进行数据传输,S3C2440的SPI必须正确地配置其传输格式。 (1) 将GPE11-13脚设置成SPI0的I/O口。 s3c2410_gpio_cfgpin(S3C2410_GPE11, S3C2440_PIN_MISO0); s3c2410_gpio_cfgpin(S3C2410_GPE12, S3C2440_PIN_MOSI0); s3c2410_gpio_cfgpin(S3C2410_GPE13, S3C2440_PIN_SCLK0); 这里将GPIO的E端口的三个引脚映射成SPI的通道0的三个功能脚(MISO,MOSI,SCLK),注意程序中其它的地方要将它们映射成其它其它功能的I/O口时必须之后将其它还原,以免影响后面对CC2420的操作。 (2) 设置SPI的数据传输格式 Spivalue=S3C2410_SPCON_SMOD_POLL|S3C2410_SPCON_ENSCK|S3C2410_SPCON_MSTR|S3C2410_SPCON_CPOL_LOW|S3C2410_SPCON_CPHA_FMTA|0<<0; iowrite8(spivalue, rSPCON0); iowrite8是Linux内核提供的一个读写外部IO口的函数,一般用它来设置外部设备的一个寄存器。上面的操作是设置SPI的控制寄存器的相关的控制位:上升沿收发数据,主模式,正常模式。 (3) I/O口设置 根据硬件接口电路,S3C2440与CC2420的其它控制口也必须正确地配置,因些必须将相关的I/O口映射到接口电路设计时的功能口。下面的配置请参照硬件接口设计一章关于CC2420接口设置一节。 s3c2410_gpio_cfgpin(S3C2410_GPG2, S3C2440_PIN_REST); s3c2410_gpio_cfgpin(S3C2410_GPG3, S3C2440_PIN_CS); s3c2410_gpio_cfgpin(S3C2410_GPG5, S3C2440_PIN_VREG); s3c2410_gpio_cfgpin(S3C2410_GPG6, S3C2440_PIN_FIFOP); s3c2410_gpio_cfgpin(S3C2410_GPG7, S3C2440_PIN_FIFO); s3c2410_gpio_cfgpin(S3C2410_GPG9, S3C2440_PIN_SFD); s3c2410_gpio_cfgpin(S3C2410_GPG10, S3C2440_PIN_CCA); s3c2410_gpio_cfgpin这个函数是将CC2440的某一个I/O口设置成参数2指定的功能,其中参数2是一个宏,例如每一条语句就将GPIO的G2引脚设置成REST脚的功能,即是输入脚。基本上每一个宏都对应着CC2420上的某一个引脚上的一个功能,如输入/输出/中断,具体的请参见程序及原理图。 l 中断设置 为了方便驱动的开发,CC2420的一些引脚接到S3C2440的中断脚上,如SFD,FIFO,FIFOP,它们为驱动的调试提供了相关的信息。中断的设置包括了外部中断的中断模式,中断触发方式等的设置。软件的配置如下,硬件的接口详细细节请参考硬件接口一章。 (1) 外部中断模式为IRQ gpiovalue = (~(EINT8_23)) & ioread32(S3C2410_INTMOD); iowrite32(gpiovalue, S3C2410_INTMOD); (2) 允许外部中断14,15,17 gpiovalue = ioread32(S3C2410_INTMSK); gpiovalue &= (~(EINT8_23)); iowrite32(gpiovalue, S3C2410_INTMSK); // 允许FIFOP,FIFO,SFD的中断 gpiovalue = ioread32(S3C2410_EINTMASK); gpiovalue &= (~((1<<14)|(1<<15)|(1<<17))); iowrite32(gpiovalue, S3C2410_EINTMASK); 其中S3C2440的中断模块是这样的,其中有6个外部中断,其中的第4个中断又对应有4个子中断(EINT4-7),第5个外部中断源又对应有16个子中断(EINT8-23),这些中断在S3C2440的处理器的外部引脚上都有唯一的一个引脚与之想对应的,因此S3C2440具有非常丰富的外部中断源,与外设的交互性是很强大的,在接口设计时也是非常的方便,我们可以用中断的方式同步再者之间的工作,提高处理器的CPU利用率。 (3) 外部中断的触发方式选择 gpiovalue = ioread32(rEXINT1)&(~(0xFF00F000)); gpiovalue |= INTTRI_FIFOP | INTTRI_FIFO; iowrite32(gpiovalue,rEXINT1); gpiovalue = ioread32(rEXINT2)&(~(0xF0)); gpiovalue |= INTTRI_SFD; iowrite32(gpiovalue,rEXINT2); l 中断注册 前面设置好了外部中断,现在就要向内核注册了,将相关的中断服务程序关联起来,这样当发生了外部中断就会进入到 先前定义的中断服务程序了。 request_irq(IRQ_EINT14, basicRfRecvPacket, SA_INTERRUPT, SPI_NAME, NULL); request_irq(IRQ_EINT17, SFD_Interrupt, SA_INTERRUPT, "SFD", NULL); request_irq(IRQ_EINT15, FIFO_Interrupt, SA_INTERRUPT, "FIFO", NULL); basicRfRecvPacket,SFD_Interrupt,FIFO_Interrupt这三个中断服务程序分别是CC2420的FIFOP,SFD,FIFO的中断服务程序。 l CC2420的操作 在前面的几个步骤中,一个CC2420的驱动程序已经基本完成了,但是还没有涉及到对CC2420的操作。其实对它的读写操作也就是针对SPI的读写操作,只是在收发数据时还要结合在前面介绍的关于CC2420的读写时序,数据传输格式等。 下面简要地介绍一下CC2420的读写操作。首先要先实现对CC2420的读写操作必须要先实现对SPI数据的正确读写。下面的两个宏是两个对SPI数据寄存器的读写的最基本操作: #define FASTSPI_TX(x) \ do { \ FASTSPI_WAIT(); \ iowrite8(x, rSPTDAT0);\ FASTSPI_WAIT(); \ } while (0) #define FASTSPI_RX(x) \ do { \ FASTSPI_RX_GARBAGE();\ x = ioread8(rSPRDAT0); \ } while (0) 有了这两个基本的操作宏,则对 CC2420的操作就可以完成了,例如我们要读取CC2420的状态字节,就可以先用FASTSPI_TX向CC2420发送一个命令脉冲,等待发送完毕后就可以再用FASTSPI_RX读取到CC2420的状态字了。其它的例如RAM,寄存器等的读写操作也是相似的,只要在设计的时候参照CC2420的读写时序及数据传输格式就可以了,读写时序图可以参照CC2420的技术手册
本文档为【在ARM9(S3C2440)上实现ZigBee协议--基于CC2420芯片】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
下载需要: 免费 已有0 人下载
最新资料
资料动态
专题动态
is_742547
暂无简介~
格式:doc
大小:53KB
软件:Word
页数:10
分类:互联网
上传时间:2012-01-10
浏览量:47