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

全部博文(214)

文章存档

2012年(1)

2010年(13)

2009年(5)

2008年(98)

2007年(97)

分类: LINUX

2008-11-12 22:39:34

请教关于SPI口ADC驱动问题!
本人基于AT91RM9200芯片和14位SPI接口模数转换芯片AD7467写了一个基于LINUX系统的简单的驱动.编写驱动不规范,但用来测试应该没有问题,在LINUX系统下加载模块程序便开始运行.程序如下:(头文件省略)
#define SPI_SPCK_BAUD 3400000  //3.4MHz
#define SPI_CSR0_SCBR AT91C_MASTER_CLOCK/(2*SPI_SPCK_BAUD)
#define SPI_CSR0_DLYBS 4

static AT91PS_SYS sys=(AT91PS_SYS)AT91C_VA_BASE_SYS;
static AT91PS_SPI spi=(AT91PS_SPI)AT91C_VA_BASE_SPI;
static unsigned int rec;

DECLARE_COMPLETION(interrupt_completion);

static void spi_write(void)
{
    spi->SPI_TDR = 0x2AAA;  往发送寄存器写14位数据,立即开始传输
}


static void spi_interrupt(int irq,void *dev_id,struct pt_regs *regs)
{
    unsigned int result;
    sys->AIC_ICCR = (1<    rec = sys->AIC_ISR & sys->AIC_IMR & spi->SPI_SR & spi->SPI_IMR;//读中断状态寄存器
    result = spi->SPI_RDR ;   //从接收寄存器取值
    printk("the result is %i .\n",result);
    complete(&interrupt_completion);
    sys->AIC_EOICR = 1;             //中断处理结束
}

static int __init spi_spck_init(void)
{   
free_irq(AT91C_ID_SPI,NULL);   //释放内核中SPI驱动所占用的中断注册
if(request_irq(AT91C_ID_SPI,spi_interrupt,SA_INTERRUPT,"spi",NULL))
        return -EBUSY;              
   
    AT91_CfgPIO_SPI();
    AT91_CfgPIO_SPI_CS0(); //配置引脚外设控制       
    sys->PIOA_ASR = 0x0F;     // 配置PIO口由SPI控制
    sys->PMC_PCER = 1<    spi->SPI_CR = AT91C_SPI_SWRST; //软复位SPI
    
    spi->SPI_MR = AT91C_SPI_MSTR|AT91C_SPI_MODFDIS|((unsigned int)(14<<16)); //设置SPI模式寄存器,使能CS0
    spi->SPI_CSR0 = AT91C_SPI_CPOL|AT91C_SPI_NCPHA|AT91C_SPI_BITS_14|(SPI_CSR0_SCBR<<8)|(SPI_CSR0_DLYBS<<16); //配置CS0寄存器
    
    sys->AIC_SMR[AT91C_ID_SPI] = AT91C_AIC_PRIOR_HIGHEST;//设置高级中断控制中SPI中断优先级为最高
    sys->AIC_IECR = (1<    
    spi->SPI_IER = AT91C_SPI_RDRF;//使能SPI中断控制器中接收寄存器满中断
    spi->SPI_CR = AT91C_SPI_SPIEN;//使能SPI
    
    spi_write(); //执行写程序
    wait_for_completion(&interrupt_completion);
printk("it works ok\n");
}

static void __exit spi_spck_exit(void)
{
    spi->SPI_CR=AT91C_SPI_SPIDIS;//disable spi
    free_irq(AT91C_ID_SPI,NULL);
}
module_init(spi_spck_init);
module_exit(spi_spck_exit);
若将MISO和MOSI两根线直连,加载该驱动模块时能正确读出写入的十四位数据.用示波器检测,SCLK信号的频率也正确,CS信号和MOSI也有输出波形.如果这四根线不外接任何器件时(MISO和MOSI也不短接),加载该模块居然也能输出14位数据,只是每一位都为1,这就奇怪了,MISO引脚没有任何外界数据输入居然也能输出数据??并且用示波器测信号输入脚MISO居然也有波形,这是怎么回事??当接上AD7467时,症状跟没接任何芯片一样,而且四种时钟模式(CPOL和NCPHA)我都试过了,都没有反应!!请各位指教,谢谢!!
阅读(1808) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~

xizuopeng2012-10-09 09:27:10

请问一下
AT91_CfgPIO_SPI();
    AT91_CfgPIO_SPI_CS0(); //配置引脚外设控制
这2个函数是哪个头文件里的?