查看: 1994|回复: 1

[求助] PDB中断时间问题

[复制链接]
  • TA的每日心情
    奋斗
    2019-8-2 21:20
  • 签到天数: 1 天

    连续签到: 1 天

    [LV.1]初来乍到

    4

    主题

    14

    帖子

    0

    注册会员

    Rank: 2

    积分
    101
    最后登录
    2020-12-8
    发表于 2019-8-2 20:49:29 | 显示全部楼层 |阅读模式
    我用的是拉普兰德K60的函数库,然后利用PDB触发ADC采样。后来发现采样速度上不去,于是在PDB中断里加了一个引脚电平翻转语句。发现是PDB的触发速度达不到,最快大概只有1ms一次。 感觉是它函数库里的初始化函数问题,现在把它的函数库贴出来,大家帮忙分析一下。它的PDB触发周期计算公式是对的吗?
    1. //PDB模块初始化结构体,用于配置PDB各项参数
    2. typedef struct
    3. {  
    4.   /*
    5.     描述:
    6.       设置PDBx计数器溢出周期,单位us
    7.     取值:
    8.       1~0xFFFFFFFF
    9.     初始化:
    10.       不必须初始化,PDB_CounterPeriodUs、PDB_CounterPeriodMs、PDB_CounterPeriodS至少一个初始化
    11.   */
    12.   uint32 PDB_CounterPeriodUs;
    13.   
    14.   /*
    15.     描述:
    16.       设置PDBx计数器溢出周期,单位ms
    17.     取值:
    18.       1~0xFFFFFFFF
    19.     初始化:
    20.       不必须初始化,PDB_CounterPeriodUs、PDB_CounterPeriodMs、PDB_CounterPeriodS至少一个初始化
    21.   */
    22.   uint32 PDB_CounterPeriodMs;
    23.   
    24.   /*
    25.     描述:
    26.       设置PDBx计数器溢出周期,单位s
    27.     取值:
    28.       1~0xFFFFFFFF
    29.     初始化:
    30.       不必须初始化,PDB_CounterPeriodUs、PDB_CounterPeriodMs、PDB_CounterPeriodS至少一个初始化
    31.   */
    32.   uint32 PDB_CounterPeriodS;
    33.   
    34.   /*
    35.     描述:
    36.       选择PDBx模块MOD、IDLY、CHnDLYm、INTx和POyDLY寄存器的加载模式选择
    37.     取值:
    38.       LOADMODE_0-模式0,当LDOK写1后立即加载数值到上述寄存器内
    39.       LOADMODE_1-模式1,当LDOK写1后且PDBx计数器值等于MOD寄存器值时加载数值到上述寄存器内
    40.       LOADMODE_2-模式2,当LDOK写1后且一个输入触发事件被检测到时加载数值到上述寄存器内
    41.       LOADMODE_3-模式3,当LDOK写1后且(PDBx计数器值等于MOD寄存器值 或 一个输入触发事件被检测到)时加载数值到上述寄存器内
    42.     初始化:
    43.       不必须初始化,默认LOADMODE_0
    44.   */
    45.   uint8 PDB_LoadModeSel;
    46.   
    47.   /*
    48.     描述:
    49.       设置PDBx计数器开始工作的输入触发源
    50.     取值:
    51.       TRIGGER_EXTERNAL        -外部触发
    52.       TRIGGER_CMP0            -CMP0模块触发
    53.       TRIGGER_CMP1            -CMP1模块触发
    54.       TRIGGER_CMP2            -CMP2模块触发
    55.       TRIGGER_PIT0            -PIT0模块触发
    56.       TRIGGER_PIT1            -PIT1模块触发
    57.       TRIGGER_PIT2            -PIT2模块触发
    58.       TRIGGER_PIT3            -PIT3模块触发
    59.       TRIGGER_FTM0            -FTM0模块触发
    60.       TRIGGER_FTM1            -FTM1模块触发
    61.       TRIGGER_FTM2            -FTM2模块触发
    62.       TRIGGER_RESERVED        -保留
    63.       TRIGGER_RTCALARM        -RTC Alarm触发
    64.       TRIGGER_RTCSECONDS      -RTC Seconds触发
    65.       TRIGGER_LPTMR           -LPTMR模块触发
    66.       TRIGGER_SOFTWARE        -软件触发
    67.     初始化:
    68.       不必须初始化,默认TRIGGER_EXTERNAL
    69.   */
    70.   uint8 PDB_TriggerInputSourceSel;
    71.   
    72.   /*
    73.     描述:
    74.       使能PDBx连续工作模式,使能后PDBx将在第一次触发后连续工作
    75.     取值:
    76.       TRUE-使能连续
    77.       FALSE-禁用连续
    78.     初始化:
    79.       不必须初始化,默认FALSE
    80.   */
    81.   boolean PDB_ContinuousModeEnable;
    82.   
    83.   /*
    84.     描述:
    85.       使能PDBx模块DMA请求
    86.     取值:
    87.       TRUE-使能
    88.       FALSE-禁用
    89.     初始化:
    90.       不必须初始化,默认FALSE
    91.   */
    92.   boolean PDB_DmaEnable;
    93.   
    94.   /*
    95.     描述:
    96.       使能PDBx模块中断,时能后当PDBx计数器计数时间等于PDB_Delay后触发中断
    97.     取值:
    98.       TRUE-使能
    99.       FALSE-禁用
    100.     初始化:
    101.       不必须初始化,默认FALSE
    102.   */
    103.   boolean PDB_IntEnable;
    104.    
    105.   /*
    106.     描述:
    107.       使能PDBx模块序列错误中断
    108.     取值:
    109.       TRUE-使能
    110.       FALSE-禁用
    111.     初始化:
    112.       不必须初始化,默认FALSE
    113.   */  
    114.   boolean PDB_SeqErrIntEnable;
    115.   
    116.   /*
    117.     描述:
    118.       设置PDBx延时寄存器溢出时间,单位us
    119.     取值:
    120.       1~0xFFFFFFFF
    121.     初始化:
    122.       不必须初始化
    123.   */
    124.   uint32 PDB_DelayUs;
    125.   
    126.   /*
    127.     描述:
    128.       设置PDBx延时寄存器溢出时间,单位ms
    129.     取值:
    130.       1~0xFFFFFFFF
    131.     初始化:
    132.       不必须初始化
    133.   */
    134.   uint32 PDB_DelayMs;
    135.   
    136.   /*
    137.     描述:
    138.       设置PDBx延时寄存器溢出时间,单位s
    139.     取值:
    140.       1~0xFFFFFFFF
    141.     初始化:
    142.       不必须初始化
    143.   */
    144.   uint32 PDB_DelayS;

    145.   /*
    146.     描述:
    147.       PDBx中断回调函数
    148.     取值:
    149.       函数必须为无返回值,无参数(eg. void isr(void);)
    150.     初始化:
    151.       不必须初始化、如未初始化则不会触发中断
    152.   */
    153.   PDB_ISR_CALLBACK PDB_Isr;

    154.   /*
    155.     描述:
    156.       PDBx序列错误中断回调函数
    157.     取值:
    158.       函数必须为无返回值,无参数(eg. void isr(void);)
    159.     初始化:
    160.       不必须初始化、如未初始化则不会触发中断
    161.   */
    162.   PDB_ISR_CALLBACK PDB_SeqErrIsr;
    163.   
    164. } PDB_InitTypeDef;


    165. uint8 LPLD_PDB_Init(PDB_InitTypeDef pdb_init_struct)
    166. {
    167.   uint32 us = pdb_init_struct.PDB_CounterPeriodUs
    168.             + pdb_init_struct.PDB_CounterPeriodMs*1000
    169.             + pdb_init_struct.PDB_CounterPeriodS*1000000;
    170.   uint32 delayus = pdb_init_struct.PDB_DelayUs
    171.             + pdb_init_struct.PDB_DelayMs*1000
    172.             + pdb_init_struct.PDB_DelayS*1000000;
    173.   uint8 loadmode = pdb_init_struct.PDB_LoadModeSel;
    174.   uint8 trriger = pdb_init_struct.PDB_TriggerInputSourceSel;
    175.   uint32 bus_clk = g_bus_clock/1000000;
    176.   uint8 prescaler, mult;
    177.   uint32 mod;
    178.   float32 temp;
    179.   
    180.   //参数检查
    181.   ASSERT( loadmode <= LOADMODE_3 );       //加载模式选择
    182.   ASSERT( trriger <= TRIGGER_SOFTWARE );  //触发输入源选择
    183.   
    184. /*
    185. *************************************************
    186.   【LPLD注解】PDB关键系数
    187.   prescaler(总线时钟预分频系数): 2^n(n:0~7)
    188.   mult(prescaler的倍数): 1、10、20、40
    189.   mod(计数器模数,影响计数器周期): 0~0xFFFF
    190.   计数器周期 = (prescaler*mult*mod)/bus_clk
    191. *************************************************
    192. */
    193.   
    194.   //根据期望的计数器周期自动设定prescaler、mult和mod的值
    195.   for(uint8 i=0; i<4; i++)
    196.   {
    197.     mult = i;
    198.     for(uint8 j=0; j<8; j++)
    199.     {
    200.       prescaler = j;
    201.       mod = (bus_clk*us)/((1<<j)*pdb_sc_mults[i]);
    202.       if(mod <= 0xFFFFu)
    203.         break;
    204.     }
    205.     if(mod <= 0xFFFFu)
    206.       break;
    207.     else if(i == 3)
    208.       return 0;         //PDB计数周期设置的过小,计算错误
    209.   }
    210.   
    211.   //使能PDB时钟
    212.   SIM->SCGC6 |= SIM_SCGC6_PDB_MASK;
    213.   
    214.   //初始化SC寄存器
    215.   PDB0->SC = 0x00;
    216.   //使能PDB
    217.   PDB0->SC |= PDB_SC_PDBEN_MASK;
    218.   PDB0->SC |= PDB_SC_MULT(mult);
    219.   PDB0->SC |= PDB_SC_PRESCALER(prescaler);
    220.   //配置MOD、IDLY、CHnDLYm、INTx和POyDLY寄存器的加载模式
    221.   PDB0->SC |= PDB_SC_LDMOD(loadmode);
    222.   //配置触发输入源
    223.   PDB0->SC |= PDB_SC_TRGSEL(trriger);
    224.   
    225.   //是否使能连续模式
    226.   if(pdb_init_struct.PDB_ContinuousModeEnable == TRUE)
    227.     PDB0->SC |= PDB_SC_CONT_MASK;
    228.   else
    229.     PDB0->SC &= ~(PDB_SC_CONT_MASK);
    230.   
    231.   //是否使能DMA
    232.   if(pdb_init_struct.PDB_DmaEnable == TRUE)
    233.     PDB0->SC |= PDB_SC_DMAEN_MASK;
    234.   else
    235.     PDB0->SC &= ~(PDB_SC_DMAEN_MASK);
    236.   
    237.   if(pdb_init_struct.PDB_Isr != NULL)
    238.   {
    239.     PDB_ISR[0] = pdb_init_struct.PDB_Isr;
    240.     //是否使能PDB中断
    241.     if(pdb_init_struct.PDB_IntEnable == TRUE)
    242.       PDB0->SC |= PDB_SC_PDBIE_MASK;
    243.     else
    244.       PDB0->SC &= ~(PDB_SC_PDBIE_MASK);
    245.   }
    246.   
    247.   if(pdb_init_struct.PDB_SeqErrIsr != NULL)
    248.   {
    249.     PDB_SE_ISR[0] = pdb_init_struct.PDB_SeqErrIsr;
    250.     //是否使能PDB序列错误中断
    251.     if(pdb_init_struct.PDB_SeqErrIntEnable == TRUE)
    252.       PDB0->SC |= PDB_SC_PDBEIE_MASK;
    253.     else
    254.       PDB0->SC &= ~(PDB_SC_PDBEIE_MASK);
    255.   }
    256.   
    257.   //设置PDB中断延时时间
    258.   if( delayus <= us )
    259.   {
    260.     temp = (float32)mod/(float32)us;
    261.     PDB0->IDLY = (uint32)(delayus*temp);
    262.   }
    263.   
    264.   //加载值
    265.   PDB0->SC |= PDB_SC_LDOK_MASK;
    266.   
    267.   return 1;
    268. }
    复制代码


    我知道答案 目前已有1人回答
    该会员没有填写今日想说内容.
    回复

    使用道具 举报

    该用户从未签到

    712

    主题

    6371

    帖子

    0

    超级版主

    Rank: 8Rank: 8

    积分
    24901
    最后登录
    2025-7-21
    发表于 2019-8-5 19:27:16 | 显示全部楼层
    楼主有没有试过NXP官方的库,是否有类似的问题?
    回复 支持 反对

    使用道具 举报

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

    本版积分规则

    关闭

    站长推荐上一条 /3 下一条

    Archiver|手机版|小黑屋|恩智浦技术社区

    GMT+8, 2025-7-22 13:21 , Processed in 0.078715 second(s), 21 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.

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