Introduction
Many controllers accept 0 to 20mA or 4 to 20mA currents from various instruments and make a 0-20mA signal generator that can help to calibrate and test many different instruments.
2. Overal Design
2.1. Target
2.2. Design
Taking STM32F030C8T6 for this experiment as it has 4 PWM output and great supports on opensource RT-Thread Real-Time Operating System. And I take a 0-96 inch OLED.
2.2.1.Hardware circuits
Figure 1 is a typical circuit of voltage-to-current. The single-chip outputs PWM, the control Vi voltage level is between 0-3V, and the current flowing through the RL is 0-20mA.
Figure 2 OLED display circuit
Because the MCU can be configured with pull-up resistors, the keys can be directly connected to the MCU.
Figure 3 Key circuit
2.2.2.Software Design
2.2.3. Key Point Code
/* key thread entry */
static void 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_NUM; i++)
{
key_state1[i] = rt_hw_key(i);
}
rt_thread_delay(RT_TICK_PER_SECOND / 20);
for (i=KEY1; i<KEY_NUM; i++)
{
key_state2[i] = rt_hw_key(i);
}
for (i=KEY1; i<KEY_NUM; 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 %d clicked\r\n", 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\r\n", 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 display code.
/* oled thread entry */
static void oled_thread_entry(void* parameter)
{
uint8_t i;
rt_base_t level;
char str_pwm[64];
OLED_Init();
OLED_Clear();
PWM_TIM1(999, 1); //48MHZ/(999+1)/(1+1) = 24KHZ
while(1)
{
//OLED_ShowString(0,...
Read more »
hello thanks for information.
how to download soource code?