目錄
一 項目背景
二 原理說明
三 設計實現(xiàn)——定時器初始化
四 設計實現(xiàn)——PWM捕獲
五 梳理總結
一 項目背景
? ? ? ? 目前使用了TI的ADC采樣芯片ADS1018實現(xiàn)模擬量4-20mA/0-20mA的采樣,原理是將外部輸入的模擬量信號4-20mA,經(jīng)由并聯(lián)的兩個100Ω電阻,轉(zhuǎn)換為0.2-1V的電壓信號傳遞到模數(shù)轉(zhuǎn)換芯片的入口,再由ADS1018(全量程設置為FS=±1.024V,對應碼為0x7FF)將0.2-1V電壓信號轉(zhuǎn)換為數(shù)據(jù)碼0x190-0x7D0(400-2000),即可以將外部輸入4-20mA與內(nèi)部采集數(shù)據(jù)400-2000對應上,如下圖所示:
? ? ? ? 但是限于成本和貨期的問題,考慮將該款ADC換成國產(chǎn)的其他方案。
? ? ? ? 又因為這邊AD采樣的是DCS或者PLC發(fā)出來的4-20mA/0-20mA信號,必須需要外加隔離,所以不能采用MCU自帶的ADC外設直接采樣的方案(MCU的ADC外設沒有隔離功能,必須外接隔離芯片才行),所以該方案舍棄。
? ? ? ? 找到一款客益電子(http://www.guestgood.com/)的APC/PAC芯片,可以將輸入的模擬信號轉(zhuǎn)化為PWM波的占空比輸出,這邊選用的APC芯片為GP9101。
二 原理說明
【1】APC/PAC芯片原理:
????????A=Analog,P=PWM,C=Convertor。
? ? ? ? APC=Analog to PWM Convertor 是一種模擬信號轉(zhuǎn)PWM信號的專用芯片,PAC=PWM to Analog Convertor是一種PWM信號轉(zhuǎn)模擬信號的專用芯片。
????????在信號調(diào)理領域,經(jīng)常需要面對模擬量信號的傳輸、采集、控制等問題,傳統(tǒng)的信號鏈芯片包括模數(shù)轉(zhuǎn)換器(ADC)、數(shù)模轉(zhuǎn)換器(DAC)、運算放大器(OpAmp)、比較器(Comparator)等等,它們扮演著模數(shù)混合信號處理的主要角色。信號鏈芯片的功能基礎而強大,經(jīng)過精心的設計后能形成多種多樣優(yōu)秀的信號處理電路。但即便如此,在很多應用領域,傳統(tǒng)的信號鏈芯片依然存在瓶頸和制約,無法達到理想的電路性能和技術指標,尤其在一些需要PWM信號的領域,傳統(tǒng)的方法遇到許多困難。
? ? ? ? 客益電子發(fā)明了一種新型的模擬信號處理的專用芯片,它實現(xiàn)了模擬信號與PWM信號間的高精度轉(zhuǎn)換功能,我們稱它為APC(Analog to PWM Convertor)和PAC(PWM to Analog Convertor)。?
【2】芯片特性:
? ? ? ? 這邊采用的芯片GP9101將輸入0-VCC的信號轉(zhuǎn)化為占空比0-100%,頻率默認為1KHz的PWM波輸出:
【3】采樣原理:
? ? ? ? 參考上面ADC采樣的思路,將外部輸入的模擬量信號4-20mA,經(jīng)由并聯(lián)的兩個400Ω電阻,轉(zhuǎn)換為0.8-4V的電壓信號傳遞到APC芯片的入口,再由GP9101(供電Vcc=5V)將0.8-4V電壓信號轉(zhuǎn)換為占空比為16-80%的PWM交由MCU進行捕獲,即可以將外部輸入4-20mA與內(nèi)部采集數(shù)據(jù)對應上,如下圖所示:
三 設計實現(xiàn)——定時器初始化
? ? ? ? 由上面的方案,首先需要實現(xiàn)的是定時器捕獲PWM功能的初始化,我這邊使用的主控芯片為小華的HC32F460,選用其高級控制定時器Timer6進行PWM捕獲,端口選用PB13,其功能是TIMER6_1_PWMB(Timer6的1單元B通道):
????????初始化程序如下:
/* TIMER6 unit and clock definition */
#define TIMER6_UNIT1 (M4_TMR61)
#define TIMER6_UNIT1_CLOCK (PWC_FCG2_PERIPH_TIM61)
/* TIMER6 channel B Port/Pin definition */
#define TIMER6_UNIT1_CHB (Timer6GenCompareB)
#define TIMER6_UNIT1_CHB_PORT (PortB)
#define TIMER6_UNIT1_CHB_PIN (Pin13)
#define TIMER6_UNIT1_CHB_FUNC (Func_Tim6)
void Timer6_APC_Config(void) //APC測試,采樣0.8V-4V電壓,APC輸出16%-80%占空比,經(jīng)過64分頻定時器捕獲,輸出比較值為420-2100(輸入K/B需要調(diào)整為2100/400)
{
stc_timer6_basecnt_cfg_t stcTIM6BaseCntCfg;
stc_timer6_port_input_cfg_t stcTIM6CapxCfg;
MEM_ZERO_STRUCT(stcTIM6BaseCntCfg);
MEM_ZERO_STRUCT(stcTIM6CapxCfg);
PWC_Fcg2PeriphClockCmd(TIMER6_UNIT1_CLOCK, Enable);
PORT_SetFunc(TIMER6_UNIT1_CHB_PORT, TIMER6_UNIT1_CHB_PIN, TIMER6_UNIT1_CHB_FUNC, Disable); //Timer61 PWMA
stcTIM6BaseCntCfg.enCntMode = Timer6CntSawtoothMode; //Sawtooth wave mode
stcTIM6BaseCntCfg.enCntDir = Timer6CntDirUp; //Counter counting up
stcTIM6BaseCntCfg.enCntClkDiv = Timer6PclkDiv64; //Count clock: pclk0/64(256分頻也可以試一試)
Timer6_Init(TIMER6_UNIT1, &stcTIM6BaseCntCfg); //timer6 PWM frequency, count mode and clk config
Timer6_SetPeriod(TIMER6_UNIT1, Timer6PeriodA, 0xFFFFu); //Period set
stcTIM6CapxCfg.enPortSel = Timer6xCHB; //Capture Input Port: PWM B port
stcTIM6CapxCfg.enPortMode = Timer6ModeCaptureInput; //Capture input function
stcTIM6CapxCfg.bFltEn = true; //Input filter enable
stcTIM6CapxCfg.enFltClk = Timer6FltClkPclk0Div16; //Filter clock
Timer6_PortInputConfig(TIMER6_UNIT1, &stcTIM6CapxCfg); //Input config
Timer6_ConfigHwCaptureB(TIMER6_UNIT1, Timer6HwTrigPWMBRise); //HW Capture: Timer6 PWMB port rise trig
Timer6_ConfigHwClear(TIMER6_UNIT1, Timer6HwTrigPWMBFall); //HW Clear: Timer6 PWMB port fall trig
Timer6_EnableHwClear(TIMER6_UNIT1);
/*start timer6*/
Timer6_StartCount(TIMER6_UNIT1);
}
【注】也可以使用中斷進行捕獲:
/* TIMER6 unit and clock definition */
#define TIMER6_UNIT1 (M4_TMR61)
#define TIMER6_UNIT1_CLOCK (PWC_FCG2_PERIPH_TIM61)
/* TIMER6 channel B Port/Pin definition */
#define TIMER6_UNIT1_CHB (Timer6GenCompareB)
#define TIMER6_UNIT1_CHB_PORT (PortB)
#define TIMER6_UNIT1_CHB_PIN (Pin13)
#define TIMER6_UNIT1_CHB_FUNC (Func_Tim6)
uint16_t u16CaptureA;
void Timer61_CapInputCallBack(void)
{
u16CaptureA = Timer6_GetGeneralCmpValue(TIMER6_UNIT1, TIMER6_UNIT1_CHB);
}
void Timer6_APC_Config(void) //APC測試,采樣0.8V-4V電壓,APC輸出16%-80%占空比,經(jīng)過64分頻定時器捕獲,輸出比較值為420-2100(輸入K/B需要調(diào)整為2100/400)
{
stc_timer6_basecnt_cfg_t stcTIM6BaseCntCfg;
stc_timer6_port_input_cfg_t stcTIM6CapxCfg;
stc_irq_regi_conf_t stcIrqRegiConf;
MEM_ZERO_STRUCT(stcTIM6BaseCntCfg);
MEM_ZERO_STRUCT(stcTIM6CapxCfg);
MEM_ZERO_STRUCT(stcIrqRegiConf);
PWC_Fcg2PeriphClockCmd(TIMER6_UNIT1_CLOCK, Enable);
PORT_SetFunc(TIMER6_UNIT1_CHB_PORT, TIMER6_UNIT1_CHB_PIN, TIMER6_UNIT1_CHB_FUNC, Disable); //Timer61 PWMA
stcTIM6BaseCntCfg.enCntMode = Timer6CntSawtoothMode; //Sawtooth wave mode
stcTIM6BaseCntCfg.enCntDir = Timer6CntDirUp; //Counter counting up
stcTIM6BaseCntCfg.enCntClkDiv = Timer6PclkDiv64; //Count clock: pclk0/64(256分頻也可以試一試)
Timer6_Init(TIMER6_UNIT1, &stcTIM6BaseCntCfg); //timer6 PWM frequency, count mode and clk config
Timer6_SetPeriod(TIMER6_UNIT1, Timer6PeriodA, 0xFFFFu); //Period set
stcTIM6CapxCfg.enPortSel = Timer6xCHB; //Capture Input Port: PWM B port
stcTIM6CapxCfg.enPortMode = Timer6ModeCaptureInput; //Capture input function
stcTIM6CapxCfg.bFltEn = true; //Input filter enable
stcTIM6CapxCfg.enFltClk = Timer6FltClkPclk0Div16; //Filter clock
Timer6_PortInputConfig(TIMER6_UNIT1, &stcTIM6CapxCfg); //Input config
Timer6_ConfigHwCaptureB(TIMER6_UNIT1, Timer6HwTrigPWMBRise); //HW Capture: Timer6 PWMB port rise trig
Timer6_ConfigHwClear(TIMER6_UNIT1, Timer6HwTrigPWMBFall); //HW Clear: Timer6 PWMB port fall trig
Timer6_EnableHwClear(TIMER6_UNIT1);
/*config interrupt*/
Timer6_ConfigIrq(TIMER6_UNIT1, Timer6INTENB, true);
stcIrqRegiConf.enIRQn = Int003_IRQn; //Register INT_TMR61_GUDF Int to Vect.No.002
stcIrqRegiConf.enIntSrc = INT_TMR61_GCMB; //Select Event interrupt function
stcIrqRegiConf.pfnCallback = &Timer61_CapInputCallBack; //Callback function
enIrqRegistration(&stcIrqRegiConf); //Registration IRQ
NVIC_ClearPendingIRQ(stcIrqRegiConf.enIRQn); //Clear Pending
NVIC_SetPriority(stcIrqRegiConf.enIRQn, DDL_IRQ_PRIORITY_04);//Set priority
NVIC_EnableIRQ(stcIrqRegiConf.enIRQn); //Enable NVIC
/*start timer6*/
Timer6_StartCount(TIMER6_UNIT1);
}
四 設計實現(xiàn)——PWM捕獲
????????因為輸入到MCU的PWM頻率為1KHz,所以捕獲定時器的周期值為:
? ? ? ? 捕獲到的PWM比較值即為:
? ? ? ? 所以由上面方案中采樣到的4-20mA對應的占空比16-80%,計算得到的比較值即為:
? ? ? ? 程序中的PWM捕獲采用Timer6_GetGeneralCmpValue接口:
/**************************************************************************
* 函數(shù)名稱: analogInputHandle
* 功能描述: 模擬量輸入處理
* 輸入?yún)?shù):
* 輸出參數(shù):
* 返 回 值:
* 其它說明:
**************************************************************************/
float analogInputHandle(STRU_ANALOG_IO_CTRL *p_analog_ctrl)
{
//...
//這邊捕獲到的比較值是根據(jù)輸入進來的PWM計算得到的
remote_ctrl.AI1_read = Timer6_GetGeneralCmpValue(TIMER6_UNIT1, TIMER6_UNIT1_CHB);
//...
}
? ? ? ? 采集得到的remote_ctrl.AI1_read再經(jīng)過公式(本例中,K=2100,B=420),對應得到4-20:
文章來源:http://www.zghlxwxcb.cn/news/detail-423815.html
五 梳理總結
? ? ? ? 這個APC替代ADC用于采樣模擬量輸入的方案,使用比較簡單方便,但是精度并沒有之前使用的ADS1018(12位精度)那么好,適用于對精度要求不高的場景。文章來源地址http://www.zghlxwxcb.cn/news/detail-423815.html
到了這里,關于【嵌入式】HC32F定時器PWM捕獲+APC芯片實現(xiàn)模擬AD采樣的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!