Chinaunix首页 | 论坛 | 博客
  • 博客访问: 629143
  • 博文数量: 112
  • 博客积分: 5011
  • 博客等级: 大校
  • 技术积分: 1406
  • 用 户 组: 普通用户
  • 注册时间: 2008-04-25 18:46
文章分类
文章存档

2011年(1)

2010年(5)

2009年(25)

2008年(81)

我的朋友

分类:

2008-04-26 17:11:29

来源:21ic 作者:qiubo_sohu 栏目:
请教关于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)我都试过了,都没有反应!!请各位指教,谢谢!!
阅读(3215) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~

chinaunix网友2010-07-20 17:38:48

差点被忽悠了,清中断貌似错了