1、程序设计
三个线程,一个消息队列(大小是1,长度是12)
线程1:LED 500ms闪烁一次;
线程2:adc采样;
线程3:oled显示;
在线程2中,采样到数据后,通过消息队列发送到线程3,线程3收到消息后,更新oled显示。
2、RT-Thread配置 默认是没有使能消息队列的,需要使能消息队列;
3、代码实现
(1)Led初始化及led线程 static rt_thread_t led_thread = RT_NULL;
void LedInit(void)
{
gpio_init_type gpio_init_struct;
/* enable the led clock */
crm_periph_clock_enable(CRM_GPIOC_PERIPH_CLOCK, TRUE);
/* set default parameter */
gpio_default_para_init(&gpio_init_struct);
/* configure the led gpio */
gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
gpio_init_struct.gpio_mode = GPIO_MODE_OUTPUT;
gpio_init_struct.gpio_pins = GPIO_PINS_2|GPIO_PINS_3|GPIO_PINS_5;
gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
gpio_init(GPIOC, &gpio_init_struct);
}
static void led_thread_entry(void *parameter)
{
while (1)
{
gpio_bits_write(GPIOC, GPIO_PINS_2|GPIO_PINS_3|GPIO_PINS_5, (confirm_state)!gpio_output_data_bit_read(GPIOC, GPIO_PINS_2|GPIO_PINS_3|GPIO_PINS_5));
rt_thread_mdelay(1000);
rt_kprintf("led blink\r\n");
}
}
void LedThreadStart(void)
{
led_thread = rt_thread_create( "led", /*线程名字*/
led_thread_entry,/*线程入口函数*/
RT_NULL,/*线程入口函数参数*/
256, /*线程栈大小*/
4 , /*线程优先级*/
20); /*线程时间片*/
rt_thread_startup (led_thread);
}
(2)adc初始化以及adc线程 static rt_thread_t adc_thread = RT_NULL;
static uint8_t adc_data[12];
void AdcGpioInit(void)
{
/* enable the clock */
crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK, TRUE);
gpio_init_type gpio_init_struct;
/* set default parameter */
gpio_default_para_init(&gpio_init_struct);
/* configure the led gpio */
gpio_init_struct.gpio_mode = GPIO_MODE_ANALOG;
gpio_init_struct.gpio_pins = GPIO_PINS_1 ;
gpio_init(GPIOA, &gpio_init_struct);
}
void AdcConfig(void)
{
adc_base_config_type adc_base_struct;
crm_periph_clock_enable(CRM_ADC1_PERIPH_CLOCK, TRUE);
crm_adc_clock_div_set(CRM_ADC_DIV_6);
adc_base_default_para_init(&adc_base_struct);
adc_base_struct.sequence_mode = FALSE;
adc_base_struct.repeat_mode = FALSE;
adc_base_struct.data_align = ADC_RIGHT_ALIGNMENT;
adc_base_struct.ordinary_channel_length = 1;
adc_base_config(ADC1, &adc_base_struct);
adc_ordinary_conversion_trigger_set(ADC1, ADC12_ORDINARY_TRIG_SOFTWARE, TRUE);
adc_tempersensor_vintrv_enable(TRUE);
adc_enable(ADC1, TRUE);
adc_calibration_init(ADC1);
while(adc_calibration_init_status_get(ADC1));
adc_calibration_start(ADC1);
while(adc_calibration_status_get(ADC1));
}
uint16_t AdcSample(uint8_t channel)
{
adc_ordinary_channel_set(ADC1, (adc_channel_select_type)channel, 1, ADC_SAMPLETIME_239_5);
adc_ordinary_software_trigger_enable(ADC1,TRUE);
while(!adc_flag_get(ADC1, ADC_CCE_FLAG));
adc_flag_clear(ADC1, ADC_CCE_FLAG);
return adc_ordinary_conversion_data_get(ADC1);
}
void AdcInit(void)
{
AdcGpioInit();
AdcConfig();
}
static void adc_thread_entry(void *parameter)
{
uint16_t ref=0;
float vdd=0;
float ch16=0;
float ch1=0;
uint16_t part1=0,part2=0;
int result;
uint8_t *p=(uint8_t *)parameter;
while(1)
{
ref=AdcSample(ADC_CHANNEL_17);
vdd=1.2/(float)ref*4095;
part1=(uint32_t)vdd;
part2=vdd*1000-part1*1000;
rt_kprintf("\r\nVdd=%d.%d V\r\n",part1,part2);
rt_memcpy(&p[0],(uint8_t *)&part1,2);
rt_memcpy(&p[2],(uint8_t *)&part2,2);
ch1=AdcSample(ADC_CHANNEL_1)*vdd / 4095;
part1=(uint32_t)ch1;
part2=ch1*1000-part1*1000;
rt_kprintf("Channel 1=%d.%d V\r\n",part1,part2);
rt_memcpy(&p[4],(uint8_t *)&part1,2);
rt_memcpy(&p[6],(uint8_t *)&part2,2);
ch16=AdcSample(ADC_CHANNEL_16)*vdd / 4095;
part1=(uint32_t)ch16;
part2=ch16*1000-part1*1000;
rt_kprintf("Channel 16=%d.%d V\r\n",part1,part2);
rt_memcpy(&p[8],(uint8_t *)&part1,2);
rt_memcpy(&p[10],(uint8_t *)&part2,2);
extern rt_mq_t adc_to_oled_mq;
result = rt_mq_send(adc_to_oled_mq, p,12);
if (result != RT_EOK)
{
rt_kprintf("%s,send mq err\r\n",adc_thread->name);
}
else
{
rt_kprintf("%s,send mq success\r\n",adc_thread->name);
}
rt_memset(p,'\0',12);
rt_thread_mdelay(2000);
}
}
void AdcThreadStart(void)
{
adc_thread = rt_thread_create("adc",
adc_thread_entry,
&adc_data,
512,
5,
20);
rt_thread_startup (adc_thread);
}
(3)oled初始化、oled线程、消息队列创建 static rt_thread_t oled_thread=RT_NULL;
rt_mq_t adc_to_oled_mq=RT_NULL;
static uint8_t oled_data[12];
static char temp[16];
static void oled_thread_entry(void *parameter)
{
uint8_t *p =(uint8_t *)parameter;
while(1)
{
if(rt_mq_recv(adc_to_oled_mq,p,12,RT_WAITING_FOREVER)==RT_EOK)
{
rt_kprintf("%s,recv message queue \r\n",oled_thread->name);
rt_memset(temp,' ',sizeof(temp));
rt_sprintf(temp,"Vdd=%d.%d V",*(uint16_t*)(&p[0]),*(uint16_t*)(&p[2]));
OledShowString(10,0,temp,16);
rt_kprintf("%s\r\n",temp);
rt_memset(temp,' ',sizeof(temp));
rt_sprintf(temp,"Ch1=%d.%d V",*(uint16_t*)(&p[4]),*(uint16_t*)(&p[6]));
OledShowString(10,2,temp,16);
rt_kprintf("%s\r\n",temp);
rt_memset(temp,' ',sizeof(temp));
rt_sprintf(temp,"Ch16=%d.%d V",*(uint16_t*)(&p[8]),*(uint16_t*)(&p[10]));
OledShowString(10,4,temp,16);
rt_kprintf("%s\r\n",temp);
}
}
}
void OledThreadStart(void)
{
adc_to_oled_mq=rt_mq_create("adc_oled", 12,1, RT_IPC_FLAG_PRIO);
oled_thread= rt_thread_create("oled",oled_thread_entry,oled_data,512,7,20);
rt_thread_startup(oled_thread);
}
4、现象
|
|