您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 信息化管理 > 第9课-PDB从了解到使用
[跟我学OSKinetis]第9课-PDB从了解到使用Postedon2013年11月25日bylpldcnPDB是什么意思,英文全称是ProgrammableDelayBlock,即可编程延时模块。从中文字面意思上看,每个字都那么熟悉,但是就是无法理解是什意思,很正常,但是再仔细看下技术文档中对该模块的简要介绍,应该就略知一二了吧。下面是文档中英文介绍的翻译:“可编程延时模块(PDB)为ADC输入的硬件触发或DAC生成的间隔触发提供可控制的内部或外部触发或可编程的间隔时间,以便能使ADC的转换或者DAC的更新达到精准定时。”上面的介绍是一整句话,但是已经阐释了PDB的整个功能。别看它这么长,说白了就是为ADC或DAC提供硬件触发的,再具体点就是提供什么触发呢,可以提供来自单片机内部模块的触发、外部的触发或者软件可编程的触发。来自单片机内部的模块的触发可以是CMP、PIT、FTM等等。也就是说PDB可以理解为一个桥梁,它接受不同来源的触发,转而再去触发ADC或DAC模块,相当于ADC、或DAC的管家一样。PDB工作原理之前的废话要讲清楚PDB的工作原理,真的不是一件简单的事情,如果按照技术文档的流程来看,你会越看越晕。技术文档的流程是先介绍特点、再介绍具体的寄存器最后进行功能描述。虽然符合书写原则,但是对于新手来讲确实如同天书一般。我是如何看的呢,如果我对这个模块不了解,那么我会先看一些关于该模块的简要介绍、特点,再去看章节最后一部分的功能描述(FunctionalDescription)。这些功能描述往往会捎带上寄存器的初始化流程、模块的运行流程等信息,这样我就对这个模块有了大体上的了解,最后再去逐一攻破细节。看懂PDB模块图说了这么多看技术文档的心得,其实是为我接下来的描述找后路,因为很可能你会看不懂我的描述,呵呵。如果真是这样,那就赶紧去啃技术文档吧。我接下来也只是说说PDB的重点需要描述的地方,告诉大家我对于PDB工作方式的理解。首先看下PDB的模块图解,改图描述了整个模块内部的关系机理。图中两个关键的部分分别是绿框和红框部分,没有这两部分,PDB的工作无从谈起。绿框部分是PDB的计数器部分,和大部分涉及到时间的外设模块一样,PDB也有计数器、MOD模寄存器等等。有了计数器,就有了基本的定时功能,也就可以控制触发的时间了。由“PDBCounter”框出来的引线,分别引向了橙色框“控制逻辑”部分、蓝色框“中断延时”部分和黄色框“ADC通道触发”部分。也就是说,PDB计数器分别会向这几部分提供计数支持。蓝框部分是PDB的中断延时功能,当PDB计数器“PDBCounter”的值等于蓝框中“PDBIDLY”寄存器的值时,PDB会根据TOEx位来判断是否产生PDB中断。有了这个功能,PDB就可以被当做一个普通的周期中断定时器来使用了。橙色框部分是控制逻辑模块,该模块可以理解为是用来控制PDB寄存器复位的。那么那些事件可以引起“PDBCounter”的复位呢?首先看绿框,当“PDBCNT”寄存器的值等于“PDBMOD”模寄存器的值时就会告诉“ControlLogic”模块计数器到达预设上限了。如果“CONT”位为1表示PDB为连续工作模式,则“ControlLogic”通知“PDBCounter”复位重新计数,如果果“CONT”位为0表示PDB为单次转换模式,则“ControlLogic”等待触发事件的到来,这个触发事件就是红框表示出来的部分。当触发事件发生,则“ControlLogic”通知“PDBCounter”复位重新计数。红框部分就是上面说的触发模块了,触发源由“TRIGSEL”位进行选择,触发源可以是Trigger-In0~14或“SWTRIG”软件触发中的任意一个。从图中还可以看出,触发源出来的引向不止用来控制PDB的复位,还引向了“DACintervaltriggerx”DAC间隔触发器,也就是说,触发源可以触发DAC间隔触发器产生DAC触发,当“DACIntervalCounterx”间隔计数器的值等于“DACINTx”的值的时候,就会输出DAC触发事件。另外触发源还引向了黄框的部分,即ADC。黄色框是通道n的预触发m模块,什么n呀m啊估计你已经荤菜了。简单理解就是n代表ADC的0或1模块,m为ADCx的A或B组通道。也就是说“Ch0pre-trigger0”用来触发ADC0的A组通道,同理“Ch0pre-trigger1”用来触发ADC0的B组通道。名字理解了,但是这个黄框内的复杂关系估计还是会让你晕菜,没关系,我们从已知的部分开始看。当触发源控制计数器复位开始计时后,“PDBCounter”的值就一直和“PDBCHnDLYm”的值进行对比,当相等后就会最终输出“Pre-triggerm”事件,这个就是ADC的硬件触发信号。图中的什么Ack、BB等等信号,是BacktoBack模式中需要用到的,这个我们会在以后讲到,今天大家能消化这些就不错了。什么是预触发可能有朋友会问了,触发就触发呗,怎么还搞个预触发,太复杂了。其实仔细想想就不难理解,从上图的模块图中不难看出,触发源只能选择一个,而相对来说ADC0模块有两组通道A和B,如果PDB在收到触发后就就立即触发A和B组是不可能的,因为ADCx的每组通道是不可能同时进行转换的,必定有一个先后顺序,有了先后顺序就必定需要有延时等待,因此就需要了上面讲到的“PDBCHnDLYm”通道延时寄存器,而这个延时计数的过程就是预触发过程,当“PDBCHnDLYm”的值等于“PDBCounter”的值时所导致的触发就是预触发。我们还可以从下面的示例图中看出这个过程:当PDB接收到了触发源的输入事件后(红色线开始),“PDBCounter”就会开始计数,持续“PDBCHnDLY0”的时间后,也就是黄色线的长度,会产生“Chnpre-trigger0”预触发信号,与此同时,对应产生“Chntrigger”通道n的触发事件。以此类推,当等待“PDBCHnDLYm”的时间后,产生“Chnpre-triggerm”预触发信号和对应的触发信号。PDB编程实践PDB周期定时中断说了这么多天书,还是来实践一下才是正道。首先我们做点简单的事情,让PDB先运行起来,不触发任何东西,就自己生成定时中断好了。打开例程“LPLD_PdbPeriodicInt”,这个例程实现的功能和PIT的功能类似,我们将在周期产生的中断函数中输出信息。具体先看初始化函数pdb_init()的代码:1pdb_init_struct.PDB_CounterPeriodMs=1000;//计数器溢出周期1000毫秒2pdb_init_struct.PDB_TriggerInputSourceSel=TRIGGER_SOFTWARE;//触发源为软件触发3pdb_init_struct.PDB_ContinuousModeEnable=TRUE;//连续工作模式4pdb_init_struct.PDB_DelayMs=200;//中断延时时间200毫秒5pdb_init_struct.PDB_IntEnable=TRUE;//使能延时中断6pdb_init_struct.PDB_Isr=pdb_isr;//中断函数设置7LPLD_PDB_Init(pdb_init_struct);8LPLD_PDB_EnableIrq();9LPLD_PDB_SoftwareTrigger();Line1:配置PDB计数器的溢出周期为1000毫秒,库函数会根据我们设置的时间,自动计算出MOD寄存器、MULT因子、PRESCALER分频的值。Line2:利用成员变量PDB_TriggerInputSourceSel配置PDB的触发源为软件触发,TRIGGER_SOFTWARE。Line3:配置PDB的工作模式为连续工作,即图中CONT位的值为1,PDB计数器会在等于MOD的值后立即复位并继续计数。Line4:配置中断延时时间为200毫秒,库函数会根据这个时间自动计算出“PDBIDLY”寄存器的值。Line5~6:使能PDB中断,配置中断函数。Line7:初始化PDB。Line8:使能中断请求。Line9:软件触发PDB开始工作。这个函数的作用就是让图中红框部分产生一个软件触发信号给“ControlLogic”。配置完PDB后,PDB的延时中断功能就会立即开始工作,不过程序会运行以下这句代码:1printf(Waitingfor200ms,andthen:\r\n);等待200ms后,第一次中断会发生,再等待1000ms后,第二次中断会发生。以后每个1000ms会发送一次中断。也就是说,初始化完成后,程序首先会延时200ms,才会触发第一次中断。这就是初始化时设置PDB_DelayMs为200ms的效果了。如果你不明白为什么,可以回头去看看第一幅PDB模块图。PDB触发ADC采集与前面几个例程不同,这是一个综合例程,我们要配合使用ADC+PDB+PIT这个3个模块来实现自动定时采集功能。打开例程“LPLD_PdbAnalogSample”,看main()函数中的初始化代码,首先初始化ADC的相关设置:1adc0_init_struct.ADC_Adcx=ADC0;//选择ADC02adc0_init_struct.ADC_BitMode=SE_12BIT;//配置转换精度3adc0_init_struct.ADC_CalEnable=TRUE;//使能初始化自动校准4adc0_init_struct.ADC_HwTrgCfg=HW_TRGA;//配置为硬件触发转换5adc0_init_struct.ADC_Isr=adc0_isr;//设置ADC中断函数6LPLD_ADC_Init(adc0_init_struct);7LPLD_ADC_Chn_Enable(ADC0,DAD1);8LPLD_ADC_EnableConversion(ADC0,DAD1,0,TRUE);9LPLD_ADC_EnableIrq(adc0_init_struct);Line4:前面几行没有要说的,主要是这里配置成员变量ADC_HwTrgCfg使ADC0为硬件触发转换模式。Line5:配置ADC中断函数,由于我们没有使用DMA功能,因此需要在中断里来获取转换结果。Line8:调用LPLD_ADC_EnableConversion()函数使能转换,该函数的前两个参数分别设置模块号和通道号,第3个参数设置转换通道为A组,第4个参数为使能转换结束中断。Line9:使能中断请求。接下来初始化PDB的相关设置:1pdb_init_struct.PDB_CounterPeriodMs=1000;//PDB计数器周期设置2pdb_init_struct.PDB_LoadModeSel=LOADMODE_0;//加载模式设置3pdb_init_struct.PDB_ContinuousModeEnable=FALSE;//禁用连续工作模式4pdb_init_struct.PDB_TriggerInputSourceSel=TRIGGER_PIT0;//配置触发源为PIT05LPLD_PDB_Init(pdb_init_struct);6LPLD_PDB_AdcTriggerCfg(ADC0,PRETRIG_EN_A,0);Line2:这是第1个例程没有配置过的参数,配置PDB_LoadModeSel加载模式,这里选择模式LOADMODE_0。加载模式指的是PDB寄存器中如CNT、MOD、DLY寄存器的加载模式,具体描述请参见PDB模块在线函数手册。(点击此处)Line3:禁用连续工作模式。Line4:配置PDB输入触发源为TRIGGER_PIT0,即PIT0模块。Line6:PDB对ADC的触发配置,调用函数LPLD_PDB_AdcTriggerCfg(),配置预触发ADC0模块,预触发A通道使能,预触发延时为0。最后配置PDB的触发源,PIT模块:1pit0_init_s
本文标题:第9课-PDB从了解到使用
链接地址:https://www.777doc.com/doc-2200162 .html