概述
一般儀器儀表的信號(hào)電流都為4-20mA,指最小電流為4mA,最大電流為20mA。傳輸信號(hào)時(shí)候,要考慮到導(dǎo)線上也有電阻,如果用電壓傳輸則會(huì)在導(dǎo)線的產(chǎn)生一定的壓降,那接收端的信號(hào)就會(huì)產(chǎn)生一定的誤差,所以使用電流信號(hào)作為變送器的標(biāo)準(zhǔn)傳輸。為什么選擇4-20mA而不是0-20mA呢?4ma而不是0ma是用來檢測(cè)線路開路的,如果0是最小,那么開路故障就檢測(cè)不到了。為了解決上述問題和避開相關(guān)噪聲的影響,我們用電流來傳輸信號(hào),因?yàn)殡娏鲗?duì)噪聲并不敏感。4~20mA的電流環(huán)便是用4mA表示零信號(hào),用20mA表示信號(hào)的滿刻度,而低于4mA高于20mA的信號(hào)用于各種故障的報(bào)警。
很多控制器接受來自各種檢測(cè)儀表的0~20mA或4~20mA電流,制作一個(gè)0-20mA的的信號(hào)發(fā)生器,可以給很多儀器儀表做校準(zhǔn)或測(cè)試。
2. 總體方案設(shè)計(jì)
2.1. 設(shè)計(jì)目標(biāo)
單片機(jī)控制4路PWM,輸出的PWM信號(hào)控制輸出電壓在0-3.0V之間,經(jīng)過電流電壓轉(zhuǎn)電流電路變成電流信號(hào),輸出電流在0-20mA之間。按鍵調(diào)節(jié)輸出電流,oled實(shí)時(shí)顯示4路電流值。
2.2. 設(shè)計(jì)思路
芯片選擇STM32F030C8T6,帶4路PWM輸出,性價(jià)比高,同時(shí)支持rt-thread操作系統(tǒng),這里我們選用2.1的版本。OLED選用中景園電子0-96寸OLED。
2.2.1.硬件電路原理
圖1是一個(gè)電壓轉(zhuǎn)電流的典型電路。單片機(jī)輸出PWM,控制Vi電壓電平在0-3V之間,RL流過的電流為0-20ma。
圖1 電壓轉(zhuǎn)電流電路
圖2 OLED顯示電路
由于MCU內(nèi)部可配置上拉電阻,所以可以直接將按鍵接到MCU上。
圖3 按鍵電路
2.2.2.軟件設(shè)計(jì)流圖
2.2.3.關(guān)鍵代碼
按鍵部分代碼。
/* key thread entry */
staticvoid key_thread_entry(void*parameter)
{
KEY_e i;
uint8_t key_state1[KEY_NUM];
uint8_t key_state2[KEY_NUM];
uint8_t key_counter[KEY_NUM];
rt_base_t level;
memset(key_counter, 0, sizeof(key_counter));
while(1)
{
for (i=KEY1; i
{
key_state1[i] = rt_hw_key(i);
}
rt_thread_delay(RT_TICK_PER_SECOND / 20);
for (i=KEY1; i
{
key_state2[i] = rt_hw_key(i);
}
for (i=KEY1; i
{
if (key_state1[i] == key_state2[i] &&
key_state1[i] == 0)
{
level =rt_hw_interrupt_disable();
if (key_counter[i] == 0)
{
switch(i)
{
case KEY2:
if (pwm_channel< 3)
{
pwm_channel++;
}
break;
case KEY1:
if (pwm_channel> 0)
pwm_channel--;
break;
case KEY3:
if(pwm_value[pwm_channel] < 20000)
pwm_value[pwm_channel]++;
break;
case KEY4:
if(pwm_value[pwm_channel] > 0)
pwm_value[pwm_channel]--;
break;
case KEY5:
if(pwm_value[pwm_channel] < 16000)
pwm_value[pwm_channel] += 4000;
else
pwm_value[pwm_channel] = 20000;
break;
case KEY6:
if(pwm_value[pwm_channel] >= 4000)
pwm_value[pwm_channel] -= 4000;
else
pwm_value[pwm_channel] = 0;
break;
}
rt_kprintf("key %dclicked ", i);
}
if (key_counter[i] >= 5)
{
switch(i)
{
case KEY2:
if (pwm_channel< 3)
{
pwm_channel++;
}
break;
case KEY1:
if (pwm_channel> 0)
pwm_channel--;
break;
case KEY3:
if(pwm_value[pwm_channel] < 20000)
pwm_value[pwm_channel]++;
break;
case KEY4:
if(pwm_value[pwm_channel] > 0)
pwm_value[pwm_channel]--;
break;
case KEY5:
if(pwm_value[pwm_channel] < 16000)
pwm_value[pwm_channel]+= 4000;
else
pwm_value[pwm_channel] = 20000;
break;
case KEY6:
if(pwm_value[pwm_channel] >= 4000)
pwm_value[pwm_channel] -= 4000;
else
pwm_value[pwm_channel] = 0;
break;
}
rt_kprintf("key%d pressed ", i);
}
if (key_counter[i] < 5)
{
key_counter[i]++;
}
rt_hw_interrupt_enable(level);
}
else
{
key_counter[i] = 0;
}
}
rt_thread_delay(RT_TICK_PER_SECOND / 100);
}
}
oled顯示部分代碼。
/* oled thread entry */
staticvoid oled_thread_entry(void*parameter)
{
uint8_t i;
rt_base_tlevel;
char str_pwm[64];
OLED_Init();
OLED_Clear();
PWM_TIM1(999, 1); //48MHZ/(999+1)/(1+1) = 24KHZ
while(1)
{
//OLED_ShowString(0, 3,"1.3' OLED TEST");
if ((memcmp(pwm_value_temp, pwm_value, sizeof(pwm_value)) != 0) ||
(pwm_channel_temp != pwm_channel))
{
level = rt_hw_interrupt_disable();
memcpy((char *)pwm_value_temp, (char *)pwm_value, sizeof(pwm_value));
pwm_channel_temp = pwm_channel;
rt_hw_interrupt_enable(level);
for (i=0; i<4; i++)
{
if (pwm_channel == i)
{
snprintf(str_pwm, 64,"* %2d.%03d ma", pwm_value[i]/1000, pwm_value[i]%1000);
}
else
{
snprintf(str_pwm, 64," %2d.%03d ma",pwm_value[i]/1000, pwm_value[i]%1000);
}
OLED_ShowString(0, i*2,(uint8_t *)str_pwm);
}
TIM_SetCompare1(TIM1, 0.915 *(pwm_value_temp[3] * 999) / 20000);
TIM_SetCompare2(TIM1, 0.915 *(pwm_value_temp[2] * 999) / 20000);
TIM_SetCompare3(TIM1, 0.915 *(pwm_value_temp[1] * 999) / 20000);
TIM_SetCompare4(TIM1, 0.915 *(pwm_value_temp[0] * 999) / 20000);
rt_thread_delay(RT_TICK_PER_SECOND / 10);
}
else
{
//OLED_ShowString(63,6,"CODE:");
rt_thread_delay(RT_TICK_PER_SECOND / 10);
}
}
}
2.2.4.RTT使用情況
按鍵的初始化函數(shù)可以不用再main函數(shù)中添加,而是在key.c中調(diào)用下面的函數(shù)就可以了INITDEVICEEXPORT(rthwkey_init),代碼看起來干凈整潔。通過scons來裁剪配置系統(tǒng),不需要人為刪減代碼,非常好用。Finsh組件,方便調(diào)試,方便自定義添加串口命令。代碼類linux編程風(fēng)格。提供POSIX 標(biāo)準(zhǔn)接口,上層代碼移植方便。
3. 實(shí)物展示
-
電流
+關(guān)注
關(guān)注
40文章
6942瀏覽量
132696 -
控制器
+關(guān)注
關(guān)注
112文章
16448瀏覽量
179482 -
發(fā)生器
+關(guān)注
關(guān)注
4文章
1368瀏覽量
61864
原文標(biāo)題:【周四RTOS專欄】一招教你設(shè)計(jì)RT-Thread的0-20mA電流發(fā)生器
文章出處:【微信號(hào):elecfans,微信公眾號(hào):電子發(fā)燒友網(wǎng)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
回收SMC100A信號(hào)發(fā)生器//二手儀器儀表回收
全新供應(yīng)Fluke 707普通回路校準(zhǔn)器 4-20毫安信號(hào)發(fā)生器 東莞市德佳儀器
圖像信號(hào)發(fā)生器_福祿克PM54200系列儀器儀表設(shè)備全新低價(jià)
4-20ma信號(hào)發(fā)生器電路(可自已制作)
![4-<b class='flag-5'>20ma</b><b class='flag-5'>信號(hào)</b><b class='flag-5'>發(fā)生器</b>電路(可自已<b class='flag-5'>制作</b>)](https://file1.elecfans.com//web2/M00/A4/57/wKgZomUMM8iANZK_AAD4tCutBzM695.jpg)
PWM轉(zhuǎn)0-20mA/4-20mA電流輸出模塊:GP8102-2
![PWM轉(zhuǎn)<b class='flag-5'>0-20mA</b>/4-<b class='flag-5'>20mA</b>電流輸出模塊:GP8102-2](https://file.elecfans.com/web1/M00/AF/93/o4YBAF3l8ViAHYSwAABxtPR3oVA790.jpg)
ISO的4-20mA電流環(huán)路信號(hào)隔離器
儀器儀表的標(biāo)定、檢定、校準(zhǔn)、校驗(yàn)的區(qū)別
0-20mA轉(zhuǎn)0-500Hz/1-5KHz/PLC頻率計(jì)采集轉(zhuǎn)換
![<b class='flag-5'>0-20mA</b>轉(zhuǎn)<b class='flag-5'>0</b>-500Hz/1-5KHz/PLC頻率計(jì)采集轉(zhuǎn)換](https://file.elecfans.com/web2/M00/A4/1D/poYBAGRbbuKAbUhWAAB5A0aC9Pw815.png)
無源型低成本、小體積兩線制4-20mA(0-20mA)電流環(huán)路模擬 信號(hào)隔離器
![無源型低成本、小體積兩線制4-<b class='flag-5'>20mA</b>(<b class='flag-5'>0-20mA</b>)電流環(huán)路模擬 <b class='flag-5'>信號(hào)</b>隔離<b class='flag-5'>器</b>](https://file.elecfans.com/web2/M00/23/5F/poYBAGGtbuOAAbrVAAAPJCI6SNw215.jpg)
評(píng)論