主题 : 采样点数不够,请求各位帮助 复制链接 | 浏览器收藏 | 打印
级别: 新手上路
UID: 4935
精华: 0
发帖: 32
金钱: 265 两
威望: 211 点
综合积分: 64 分
注册时间: 2009-04-04
最后登录: 2018-02-08
楼主  发表于: 2009-06-01 08:28

 采样点数不够,请求各位帮助

我使用mini2440做AD采样,输入信号是1KHz,预分频值是49,按理说一个周期应该是采样200个点,但是我现在一个周期只有将近40个点,请问下是什么原因?我的驱动程序是用自带的驱动修改的,部分代码如下:

#define PRESCALE_DIS        (0 << 14)
#define PRESCALE_EN         (1 << 14)
#define PRSCVL(x)           ((x) << 6)
#define ADC_INPUT(x)        ((x) << 3)
#define ADC_START           (1 << 0)
#define ADC_ENDCVT          (1 << 15)

#define START_ADC_AIN(ch, prescale) \
    do{ \
        ADCCON = PRESCALE_EN | PRSCVL(prescale) | ADC_INPUT((ch)) ; \
        ADCCON |= ADC_START; \
    }while(0)


static irqreturn_t adcdone_int_handler(int irq, void *dev_id)
{
    if (OwnADC) {
        adc_data = ADCDAT0 & 0x3ff;

        ev_adc = 1;
        wake_up_interruptible(&adcdev.wait);
    }

    return IRQ_HANDLED;
}

static ssize_t s3c2410_adc_read(struct file *filp, char *buffer, size_t count, loff_t *ppos)
{
    char str[20];
    int value;
    size_t len;
    
    unsigned short ad_buf[value_count];
    memset(ad_buf,0,sizeof(unsigned short) * value_count);
    
    if (down_trylock(&ADC_LOCK) == 0)
    {
        spin_lock_irq(&ADC_LOCK);
        int i = 0;    
        
        for (i = 0;i<1000;i++)
        {
            OwnADC = 1;
             START_ADC_AIN(adcdev.channel, adcdev.prescale);
            wait_event_interruptible(adcdev.wait, ev_adc);
            ev_adc = 0;

            ad_buf = adc_data;            
            OwnADC = 0;
        }
        spin_unlock_irq(&ADC_LOCK);
        up(&ADC_LOCK);
    }
    else
    {
        value = -1;
    }    

        copy_to_user(buffer,ad_buf, (sizeof(unsigned short))*value_count);

}
static int s3c2410_adc_open(struct inode *inode, struct file *filp)
{
    init_waitqueue_head(&(adcdev.wait));

    adcdev.channel=0;
    adcdev.prescale=0x31;

    DPRINTK( "adc opened\n");
    return 0;
}

测试的代码如下:
int main(void)
{
    fprintf(stderr, "press Ctrl-C to stop\n");
    int fd = open("/dev/adc", 0);
    FILE *fp;
    int i = 0;
    unsigned short buf[1000];
    char test[10];
    double AdData;
    if (fd < 0)
        {
        perror("open ADC device:");
        return 1;
    }

        for( i = 0;i<1000;i++)
        {       printf("ADC Value: %d\n", buf);
            AdData = (buf)*2.9/1024;
        printf("ADC Value: %10.9f\n",AdData);
    }

    close(fd);
    
    
}
级别: 新手上路
UID: 7039
精华: 0
发帖: 2
金钱: 20 两
威望: 20 点
综合积分: 4 分
注册时间: 2009-06-29
最后登录: 2017-09-13
1楼  发表于: 2009-06-29 15:40

 回 楼主(duancp) 的帖子

您好,我也是在用mini2440的AD采集外部输入电压,请问你用的AIN0、AIN1、AIN2、AIN3用的哪个管脚呢(看您的代码是用的AIN0,但是AIN0不是已经内部接了一个电阻吗,因此这个管脚应该不能为用户使用吧,只能作为测试用)?我现在是AIN读进来的数据不是我输入的电压大小,而且我启动板子后用电压表测得的AIN1、AIN2、AIN3与GND之间的电压始终是3.3V,我现在时用两根线接的,一根接到AIN,一根接到GND,但是就是读的不是我输入的电压,不知道我的接法是不是有问题,还是需要设置AIN为输入状态(如果要设置的话请问设置哪个寄存器呢),非常感谢!我郁闷了好几天了...呵呵...
级别: 新手上路
UID: 7039
精华: 0
发帖: 2
金钱: 20 两
威望: 20 点
综合积分: 4 分
注册时间: 2009-06-29
最后登录: 2017-09-13
2楼  发表于: 2009-06-29 15:57
另外,关于您的采样频率的问题,您贴出来的代码中我没有看到定时采样的代码呀!您好像是用的循环代码连续读取1000个数,我觉得您应该在驱动中加个定时器,而且ad_buf = adc_data; 这句话我没有看懂,您是定义了一个数组吗?ad_buf 是不是数组的名字呢?如果是数组的不应该是ad_buf [ i]= adc_data; 这样写吗?呵呵...我只是提一下我的看法...另外还是我上面向您请教的问题,我实在是搞不懂为啥我的信号采集不进去...郁闷了...