Chinaunix首页 | 论坛 | 博客
  • 博客访问: 952263
  • 博文数量: 214
  • 博客积分: 10173
  • 博客等级: 上将
  • 技术积分: 1867
  • 用 户 组: 普通用户
  • 注册时间: 2007-06-18 13:48
文章分类

全部博文(214)

文章存档

2012年(1)

2010年(13)

2009年(5)

2008年(98)

2007年(97)

分类: LINUX

2008-11-12 22:37:23

为ARM9加485接口

  近来有一个项目要在ARM9上用到一个485总线,这开始想来不太好做,可是做起来也很容易,这就把我的做法在这里做个记录,要是有兴趣的朋友可以看看;

  先把一个串口的R,D分别接到MAX485的R,D接口,然后接一根不用的引脚到485的控制脚,只要在发送数据时把该引脚置高,接收时置低就好

下面是该引脚的GPIO驱动:

//GPIO_drv.h

#ifndef _GPIO_H_
#define _GPIO_H_

#include /* needed for the _IOW etc stuff used later */

#define GPIO_IOC_MAGIC 'k'

#define IOCLR _IO(GPIO_IOC_MAGIC,  11)
#define IOSET _IO(GPIO_IOC_MAGIC,  12)
#define IOGET _IO(GPIO_IOC_MAGIC,  13)

#define GPC14 (1<<14)
#define GPC15 (1<<15)
#define GPC22 (1<<22)

#endif /* _GPIO_H_ */

//gpio_drv.c


#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include

#define TEST

#include "gpio_driv.h"

#define IOPORT_MAJOR 220

typedef char ioport_device_t;
long port_addr;
static ioport_device_t gpio_devices[257];

int gpio_open(struct inode*,struct file *);
int gpio_release(struct inode*,struct file *);
int gpio_ctl_ioctl(struct inode*,struct file *, unsigned int, unsigned long);

static struct file_operations gpio_ctl_fops= {
 ioctl:gpio_ctl_ioctl,
 open:gpio_open,
 release:gpio_release,
};

int __init gpio_init(void){
 int ret;

 ret = register_chrdev(IOPORT_MAJOR, "gpio_driv", &gpio_ctl_fops);
 if (ret < 0) {
  printk(KERN_WARNING "gpio: can't get major %d\n", IOPORT_MAJOR);
  return ret;
 }

 return 0;
}

void gpio_exit(void)
{
 unregister_chrdev(IOPORT_MAJOR, "gpio_driv");
}

module_init(gpio_init);
module_exit(gpio_exit);

AT91PS_SYS AT91_SYS = (AT91PS_SYS) AT91C_VA_BASE_SYS;

int gpio_open(struct inode*inode,struct file *file)
{
 int minor;
 
 minor = MINOR(inode->i_rdev);

#ifdef TEST
 //test
 //PB0&1,PB0 out,PB1 in
 AT91_SYS->PMC_PCER |= 1< AT91_SYS->PIOB_PER |= 3<<0;
 AT91_SYS->PIOB_OER |= 1<<0;
  AT91_SYS->PIOB_ODR |= 2<<0;
  
  AT91_SYS->PIOB_PER |= 3<<22;
 AT91_SYS->PIOB_OER |= 1<<22;
  AT91_SYS->PIOB_ODR |= 2<<22;
  
#endif

 AT91_SYS->PMC_PCER |= (1< AT91_SYS->PIOC_PER |= (0x3<<14);
 AT91_SYS->PIOC_OER |= (0x3<<14); 

 gpio_devices[minor]++;
 return 0;
}

int gpio_release(struct inode *inode,struct file *file)
{
 int minor;
 minor = MINOR(inode->i_rdev);
 
 if (gpio_devices[minor])
  gpio_devices[minor]--;
 
 return 0;
}

int gpio_ctl_ioctl(struct inode *inode, struct file *file,
 unsigned int cmd, unsigned long arg)
{
 //int minor = MINOR(inode->i_rdev);
 int ret = 0;
 int local;

 switch (cmd) {
 case IOSET:
  if (arg == GPC14) {
  #ifdef TEST
   AT91_SYS->PIOB_SODR |= ( 1<<0 );
  #endif
   AT91_SYS->PIOC_SODR |= (1<<14);
  }
  else if (arg == GPC15) {
   AT91_SYS->PIOC_SODR |= (1<<15);
  }
  else if (arg==GPC22){
   AT91_SYS->PIOB_SODR |= (1<<22);
  }
  break;
 case IOCLR:
  if (arg == GPC14) {
  #ifdef TEST 
                        AT91_SYS->PIOB_CODR |= ( 1<<0 );
  #endif
                        AT91_SYS->PIOC_CODR |= (1<<14);
                }
                else if (arg == GPC15) {
                        AT91_SYS->PIOC_CODR |= (1<<15);
                }
        else if (arg==GPC22){
                        AT91_SYS->PIOB_CODR |= (1<<22);
        }
                break;
 case IOGET:
 #ifdef TEST
  local = AT91_SYS->PIOB_PDSR;
 #else 
  local = AT91_SYS->PIOC_PDSR;
 #endif
  ret = put_user(local,  ((unsigned int *)arg));
  break;
 }

 return ret;
}
我用的是PB22脚,这你们可以根据自已的要求改,

下面是该驱动的测试程序

 

#include
#include
#include
#include
#include
#include
#include

#define DEVICE_GPIODRIV "/dev/gpio_driv"

#include "gpio_driv.h"

int main(void)
{
 int fd;
 int val=-1;
 int c;

 if((fd=open(DEVICE_GPIODRIV,O_RDWR | O_NONBLOCK))<0)
 {
  perror("can not open device");
  exit(1);
 }

 while(1) {
  
  printf("gpio test select:\n");
  printf("0-get 1-set/clr 2-GPC22Low 3-GPC22High 4-exit");
  scanf("%d", &c);
  if(c==0) {
   // GET test
   for(;;)
   {
    int t;
    ioctl(fd,IOSET, GPC14);
    ioctl(fd,IOGET, (unsigned long)(&t));
    printf("%d",(t&0x2)?1:0);
    ioctl(fd,IOCLR, GPC14);
           ioctl(fd,IOGET, (unsigned long)(&t));
           printf("%d",(t&0x2)?1:0);
   }
  }
  else if (c==1) {
   // SET & CLR test
   for(;;) {
    ioctl(fd, IOSET, GPC14);
    usleep(100000);
    ioctl(fd, IOCLR, GPC14);
    usleep(100000);
    ioctl(fd, IOSET, GPC15);
    usleep(100000);
    ioctl(fd, IOCLR, GPC15);
    usleep(100000);
   }
  }
  else if(c==2){
   ioctl(fd, IOCLR, GPC22);
  }
  else if(c==3){
   ioctl(fd, IOSET, GPC22);
  }
  else if (c==4) {
   for(;;) {
    ioctl(fd, IOSET, GPC22);
    usleep(100000);
    ioctl(fd, IOCLR, GPC22);
    usleep(100000);
   }
  }
  else if (c==5) {
   close(fd);
   exit(0);
  }
 }
 
 close(fd); 
}

阅读(1704) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~