智能车制作

 找回密码
 注册

扫一扫,访问微社区

查看: 8192|回复: 7
打印 上一主题 下一主题

[讨论] K60 pdb预触发ADC,采用双通道触发,延时有点长

[复制链接]

7

主题

85

帖子

0

精华

高级会员

Rank: 4

积分
760
威望
347
贡献
199
兑换币
225
注册时间
2012-11-2
在线时间
107 小时
跳转到指定楼层
1#
发表于 2013-4-8 10:06:13 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
pdb预触发ADC时,等待adc转换完成后,adc模块产生中断。其中时间特别长,我用的是ADC016位精度,差分模式,ADC116位精度,单端模式。包括adc中断在内,用时达到20ms左右。请教adc被预触发后,等待adc转换完成是不是特别耗时,如果特别耗时有木有其他好的ad采集方式

32

主题

978

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2834
QQ
威望
1620
贡献
482
兑换币
1009
注册时间
2012-11-29
在线时间
366 小时
2#
发表于 2013-4-8 13:02:40 | 只看该作者
配置贴出来
回复 支持 反对

使用道具 举报

7

主题

85

帖子

0

精华

高级会员

Rank: 4

积分
760
威望
347
贡献
199
兑换币
225
注册时间
2012-11-2
在线时间
107 小时
3#
 楼主| 发表于 2013-4-14 12:54:19 | 只看该作者
void hw_pdb_init(void)
{
    //1.开PDB时钟
    SIM_SCGC6 |= (SIM_SCGC6_PDB_MASK);

    SIM_SOPT7 &= ~(SIM_SOPT7_ADC1ALTTRGEN_MASK | // 由于ADC1可以硬件触发,也可以软件触发,这里选择PDB(软件)触发
    SIM_SOPT7_ADC1PRETRGSEL_MASK | // 选择预触发器A
    SIM_SOPT7_ADC0ALTTRGEN_MASK | // selects PDB not ALT trigger
    SIM_SOPT7_ADC0PRETRGSEL_MASK) ;
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    SIM_SOPT7 |= SIM_SOPT7_ADC0TRGSEL(0); // 选择在PDB模式下,ADC的触发的输入命令源,这里是PDB的外部管脚;103或者111
    // PDB external pin input trigger for ADC
    SIM_SOPT7 |= SIM_SOPT7_ADC1TRGSEL(0); // same for both ADCs

    //2.初始化PDB状态与控制寄存器
    PDB0_SC = 0x00000000; //LDMOD = 0: 在设置完LDOK后立即加载
    // 必须在写缓冲区寄存器之前使能PDB,否则只是之前的值
    PDB0_SC |= PDB_SC_PDBEN_MASK;  //使能 PDB
    PDB0_SC |= PDB_SC_PRESCALER(0x1);           // 2
    PDB0_SC |= PDB_SC_MULT(0x1);                  //10
    PDB0_SC |= PDB_SC_TRGSEL(0xF); //软件触发器
    PDB0_SC |= PDB_SC_CONT_MASK;   //使能连续模式



    //3.初始化PDB通道1控制寄存器1
    PDB0_CH0C1 = PDB_C1_TOS(1)|PDB_C1_EN(1);   //使能预触发器输出到 ADC0
    PDB0_CH1C1 = PDB_C1_TOS(1)|PDB_C1_EN(1);   //使能预触发器输出到  ADC1
   
    //4.初始化PDB通道1延时寄存器
    PDB0_CH1DLY0 =3000;     //延时 = 1.5ms
    PDB0_CH1DLY1 = 30000;    // 延时 = 3ms
            
    //5.初始化PDB模寄存器
    PDB0_MOD = 62500;     //设置PDB_MOD时间=25ms,采集频率为40

    //6.初始化PDB中断延时寄存器
    PDB0_IDLY = 62500;    //设置中断延时值
   
   
   
    PDB0_SC |= PDB_SC_LDOK_MASK;//加载延时值
    PDB0_SC |= PDB_SC_PDBIE_MASK;//PDB中断使能
    PDB0_SC &= ~PDB_SC_DMAEN_MASK;//PDB不采用DMA
    PDB0_SC &= ~PDB_SC_PDBEIE_MASK; //使能PDB 序列错误中断

    PDB0_SC |= PDB_SC_SWTRIG_MASK;//设置成软件触发器
回复 支持 反对

使用道具 举报

7

主题

85

帖子

0

精华

高级会员

Rank: 4

积分
760
威望
347
贡献
199
兑换币
225
注册时间
2012-11-2
在线时间
107 小时
4#
 楼主| 发表于 2013-4-14 12:55:38 | 只看该作者
uint16 hw_adc_once_init(int MoudelNumber,int Channel,uint8 accuracy,uint8 diff)//采集某路模拟量的AD值
{
                uint8 ADCCfg1Mode = 0;
                ADC_MemMapPtr ADCMoudel;//保存ADC模块地址指针
                               
                switch(accuracy)
                {
                         case 8:
                           ADCCfg1Mode = 0x00;
                           break;
                         case 12:
                           ADCCfg1Mode = 0x01;
                           break;
                         case 10:
                           ADCCfg1Mode = 0x02;
                           break;
                         case 16:
                           ADCCfg1Mode = 0x03;
                           break;
                         default:
                           ADCCfg1Mode = 0x00;
                }
               
               
                if(MoudelNumber==0)//选择ADC模块0
                {
                   ADCMoudel = ADC0_BASE_PTR;
                }
                else               //选择ADC模块1
                {
                   ADCMoudel = ADC1_BASE_PTR;
                }
               
                //1  配置正常电源模式,总线时钟,总线时钟2分频,长采样时间使能,设置精度
                ADC_CFG1_REG(ADCMoudel) = ADLPC_NORMAL
                                                                 | ADC_CFG1_ADIV(ADIV_2)
                                                                 | ADLSMP_LONG
                                                                 | ADC_CFG1_MODE(ADCCfg1Mode)
                                                                 | ADC_CFG1_ADICLK(ADICLK_BUS);
                  
                //2  配置禁止异步时钟使能输出,ADxxat通道选择,高速配置,长采样时间   
                ADC_CFG2_REG(ADCMoudel)  =    MUXSEL_ADCA
                                                                 | ADACKEN_DISABLED
                                                                 | ADHSC_HISPEED
                                                                 | ADC_CFG2_ADLSTS(ADLSTS_20) ;
                                                               

               
               
                //4 设置为硬件触发,参考电压选择外部vref.
                ADC_SC2_REG(ADCMoudel) |= ADC_SC2_ADTRG_MASK;
                ADC_SC2_REG(ADCMoudel) |= ADC_SC2_REFSEL(0);
               
               
                //5 硬件平均滤波使能,32次滤波,单次转换开启
                ADC_SC3_REG(ADCMoudel) =  ADC_SC3_AVGE_MASK | ADC_SC3_AVGS(0x3);    //设置平均使能,8次硬件平均
                ADC_SC3_REG(ADCMoudel) &= ~ADC_SC3_ADCO_MASK;                        //开启单次模式               
               
                //3  设置通道号,设置差分
                if(diff)
                {
                         ADC_SC1_REG(ADCMoudel,A) = AIEN_ON | DIFF_DIFFERENTIAL | ADC_SC1_ADCH(Channel);  //设置差分
                }
                else
                {
                        ADC_SC1_REG(ADCMoudel,A) = AIEN_ON | DIFF_SINGLE | ADC_SC1_ADCH(Channel);         //设置单端输入
                }
                hw_uart_send_string(UART0,(uint8*)"adc_pdb is ok\n\r");
                return 1;
}
回复 支持 反对

使用道具 举报

7

主题

85

帖子

0

精华

高级会员

Rank: 4

积分
760
威望
347
贡献
199
兑换币
225
注册时间
2012-11-2
在线时间
107 小时
5#
 楼主| 发表于 2013-4-14 12:56:15 | 只看该作者
这上面两个函数是对PDB跟ADc的初始化
回复 支持 反对

使用道具 举报

7

主题

85

帖子

0

精华

高级会员

Rank: 4

积分
760
威望
347
贡献
199
兑换币
225
注册时间
2012-11-2
在线时间
107 小时
6#
 楼主| 发表于 2013-4-14 12:57:14 | 只看该作者
        hw_adc_once_init(0,1,16,1);        //adc0通道1,16位精度,差分
        hw_adc_init(1);                      //adc1初始化
    hw_adc_once_init(1,1,16,0);          //adc1,通道1,16位置精度,单个
    hw_pdb_init();          //pdb定时器初始化
       
        hw_enable_adc_int(ADC1_irq_no);    //ADC1中断使能
        hw_enable_adc_int(ADC0_irq_no);    //ADC0中断使能
        hw_enable_pdb_int();               //pdb中断使能
回复 支持 反对

使用道具 举报

7

主题

85

帖子

0

精华

高级会员

Rank: 4

积分
760
威望
347
贡献
199
兑换币
225
注册时间
2012-11-2
在线时间
107 小时
7#
 楼主| 发表于 2013-4-14 12:57:26 | 只看该作者
main函数里面的
回复 支持 反对

使用道具 举报

7

主题

85

帖子

0

精华

高级会员

Rank: 4

积分
760
威望
347
贡献
199
兑换币
225
注册时间
2012-11-2
在线时间
107 小时
8#
 楼主| 发表于 2013-4-14 12:58:13 | 只看该作者
下面是ADC中断:void adc0_irq(void)
{
         DisableInterrupts;           
          //读取转化结果
            ADvalue[0] = ADC0_RA;  
            diff_value = ADvalue[0];                      //差分信号值,用于显示
           // diff_value = ((float)diff_value/32768)*3300;  //差分信号值,用于舵机转速
            if(ADvalue[0]>>15)
              {
                                //采用补码运算
                       ADvalue[0] = ADvalue[0]-1;
                       ADvalue[0] = ~ADvalue[0];
                                  
          
              }
            ADvalue[0] = ((float)ADvalue[0]/32768)*3300;   //AD差分采集,最高位有符号位   
        if(pdb_counter ==5 )
        {  
                //设置串口输出,差分采集后采用判断时候有补码
              if(ADC0_RA>>15)
                       {               
                                 hw_uart_send_string(UART0,(uint8*)"-");//输出负号
                        }
   
                                hw_uart_send_number(UART0,ADvalue[0]);
                         hw_uart_send_string(UART0,(uint8*)"  ");
                         hw_uart_send_string(UART0,(uint8*)"adc0 irq is ok   ");
                         Led_flash(16);
                  
        }
             ADC0_SC1A &= ~ADC_SC1_COCO_MASK; //清中断标志
            
            EnableInterrupts;
}
void adc1_irq(void)
{
       
        DisableInterrupts;
        ADvalue[1] = ADC1_RA;  //读取转化结果
       
        ADvalue[1] = ((float)ADvalue[1]/65536)*3300;   //AD差分采集,最高位木有符号位
        single_value = ADvalue[1];                  //单个信号值,用于舵机转弯
          
         if(pdb_counter == 15)
            {         
                                       
                       hw_uart_send_number(UART0,ADvalue[1]);
                             
                
                hw_uart_send_string(UART0,(uint8*)"   adc1 irq is ok    ");
                ADC1_SC1A &= ~ADC_SC1_COCO_MASK;      //清中断标志
               // adc_flag=~adc_flag;
                Led_flash(15);
            }
         
          EnableInterrupts;
}
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

关于我们|联系我们|小黑屋|智能车制作 ( 黑ICP备2022002344号

GMT+8, 2024-12-25 14:47 , Processed in 0.050363 second(s), 28 queries , Gzip On.

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表