接着上次的freertos+串口通信,这次实现下freertos+adc利用热敏电阻实现温度传感器的制作。还是基于上次的工程,在任务1里面跑一个led灯,1秒闪一次。在任务2里面循环采集adc的值。
查询数据手册,使用PA2,对应ADC_IN2
添加adc的代码
void ADC_Function_Init(void)
{
ADC_InitTypeDef ADC_InitStructure={0};
GPIO_InitTypeDef GPIO_InitStructure={0};
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE );
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE );
RCC_ADCCLKConfig(RCC_PCLK2_Div8);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(GPIOA, &GPIO_InitStructure);
ADC_DeInit(ADC1);
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_InitStructure.ADC_ScanConvMode = DISABLE;
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigInjecConv_T1_CC4;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfChannel = 3;
ADC_Init(ADC1, &ADC_InitStructure);
ADC_InjectedSequencerLengthConfig(ADC1, 1);
ADC_InjectedChannelConfig(ADC1, ADC_Channel_2, 1, ADC_SampleTime_239Cycles5);
ADC_DiscModeChannelCountConfig( ADC1, 1);
ADC_InjectedDiscModeCmd(ADC1 , ENABLE);
ADC_ExternalTrigInjectedConvCmd(ADC1, ENABLE);
ADC_Cmd(ADC1, ENABLE);
ADC_BufferCmd(ADC1, DISABLE);
ADC_ResetCalibration(ADC1);
while(ADC_GetResetCalibrationStatus(ADC1));
ADC_StartCalibration(ADC1);
while(ADC_GetCalibrationStatus(ADC1));
Calibrattion_Val = Get_CalibrationValue(ADC1);
ADC_BufferCmd(ADC1, ENABLE);
}
void TIM1_PWM_In( u16 arr, u16 psc, u16 ccp )
{
GPIO_InitTypeDef GPIO_InitStructure={0};
TIM_OCInitTypeDef TIM_OCInitStructure={0};
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure={0};
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA | RCC_APB2Periph_TIM1, ENABLE );
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init( GPIOA, &GPIO_InitStructure);
TIM_TimeBaseInitStructure.TIM_Period = arr;
TIM_TimeBaseInitStructure.TIM_Prescaler = psc;
TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit( TIM1, &TIM_TimeBaseInitStructure);
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = ccp;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
TIM_OC4Init( TIM1, &TIM_OCInitStructure );
TIM_CtrlPWMOutputs(TIM1, ENABLE );
TIM_OC4PreloadConfig( TIM1, TIM_OCPreload_Disable );
TIM_ARRPreloadConfig( TIM1, ENABLE );
TIM_SelectOutputTrigger( TIM1, TIM_TRGOSource_Update );
TIM_Cmd( TIM1, ENABLE );
}
void task2_task(void *pvParameters)
{
while(1)
{
printf("task2 entry\r\n");
// GPIO_ResetBits(GPIOA, GPIO_Pin_2);
// vTaskDelay(500);
// GPIO_SetBits(GPIOA, GPIO_Pin_2);
// vTaskDelay(500);
while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));
ADC_ClearFlag( ADC1, ADC_FLAG_EOC);
while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_JEOC ));
ADC_ClearFlag( ADC1, ADC_FLAG_JEOC);
num=look_up_table(NTCTAB,0xF1,Get_ConversionVal(ADC1->IDATAR1));
printf("num =%d\r\n",num);
tempt=(float)num_to_temperature(num);
printf("temperature = %2d\r\n",tempt);
// printf("ADC Discontinuous injected group conversion...\r\n");
// printf( "%04d\r\n", Get_ConversionVal(ADC1->IDATAR1) );
}
}
将得到的adc的值查询对应的热敏电阻的阻值表,就可以得出温度值
static u16 NTCTAB[241]=
{
0xFED ,0xFE2 ,0xFD6 ,0xFCB ,0xFBF ,0xFB3 ,0xFA6 ,0xF9A ,0xF8D ,0xF80,
0xF73 ,0xF65 ,0xF58 ,0xF4A ,0xF3B ,0xF2D ,0xF1E ,0xF0F ,0xF00 ,0xEF1,
0xEE1 ,0xED1 ,0xEC1 ,0xEB1 ,0xEA0 ,0xE8F ,0xE7E ,0xE6C ,0xE5B ,0xE49,
0xE37 ,0xE24 ,0xE12 ,0xDFF ,0xDEC ,0xDD9 ,0xDC5 ,0xDB1 ,0xD9D ,0xD89,
0xD75 ,0xD60 ,0xD4B ,0xD36 ,0xD21 ,0xD0B ,0xCF6 ,0xCE0 ,0xCCA ,0xCB4,
0xC9D ,0xC87 ,0xC70 ,0xC59 ,0xC42 ,0xC2B ,0xC14 ,0xBFC ,0xBE4 ,0xBCD,
0xBB5 ,0xB9D ,0xB85 ,0xB6C ,0xB54 ,0xB3C ,0xB23 ,0xB0A ,0xAF2 ,0xAD9,
0xAC0 ,0xAA7 ,0xA8E ,0xA75 ,0xA5C ,0xA43 ,0xA2A ,0xA11 ,0x9F8 ,0x9DF,
0x9C6 ,0x9AD ,0x994 ,0x97B ,0x962 ,0x949 ,0x930 ,0x917 ,0x8FE ,0x8E5,
0x8CC ,0x8B4 ,0x89B ,0x882 ,0x86A ,0x852 ,0x839 ,0x821 ,0x809 ,0x7F1,
0x7D9 ,0x7C2 ,0x7AA ,0x793 ,0x77B ,0x764 ,0x74D ,0x736 ,0x720 ,0x709,
0x6F3 ,0x6DC ,0x6C6 ,0x6B0 ,0x69B ,0x685 ,0x670 ,0x65A ,0x645 ,0x630,
0x61C ,0x607 ,0x5F3 ,0x5DE ,0x5CB ,0x5B7 ,0x5A3 ,0x590 ,0x57D ,0x569,
0x557 ,0x544 ,0x532 ,0x51F ,0x50D ,0x4FB ,0x4EA ,0x4D8 ,0x4C7 ,0x4B6,
0x4A5 ,0x495 ,0x484 ,0x474 ,0x464 ,0x454 ,0x444 ,0x435 ,0x425 ,0x416,
0x407 ,0x3F9 ,0x3EA ,0x3DC ,0x3CD ,0x3BF ,0x3B2 ,0x3A4 ,0x397 ,0x389,
0x37C ,0x36F ,0x363 ,0x356 ,0x34A ,0x33D ,0x331 ,0x325 ,0x31A ,0x30E,
0x303 ,0x2F8 ,0x2EC ,0x2E2 ,0x2D7 ,0x2CC ,0x2C2 ,0x2B7 ,0x2AD ,0x2A3,
0x299 ,0x290 ,0x286 ,0x27D ,0x273 ,0x26A ,0x261 ,0x258 ,0x250 ,0x247,
0x23F ,0x236 ,0x22E ,0x226 ,0x21E ,0x216 ,0x20E ,0x206 ,0x1FF ,0x1F8,
0x1F0 ,0x1E9 ,0x1E2 ,0x1DB ,0x1D4 ,0x1CD ,0x1C7 ,0x1C0 ,0x1BA ,0x1B3,
0x1AD ,0x1A7 ,0x1A1 ,0x19B ,0x195 ,0x18F ,0x18A ,0x184 ,0x17E ,0x179,
0x174 ,0x16E ,0x169 ,0x164 ,0x15F ,0x15A ,0x155 ,0x150 ,0x14C ,0x147,
0x142 ,0x13E ,0x139 ,0x135 ,0x131 ,0x12C ,0x128 ,0x124 ,0x120 ,0x11C,
0x118
};
u8 look_up_table(u16 *a,u8 ArrayLong,u16 data)
{
u16 begin,end,middle ;
u8 i ;
begin = 0 ;
end = ArrayLong-1 ;
i = 0 ;
if(data >= a[begin]) return begin ;
else if(data <= a[end]) return end ;
while(begin < end)
{
middle = (begin+end)/2 ;
if(data == a[middle] ) break ;
if(data < a[middle] && data > a[middle+1]) break ;
if(data > a[middle]) end = middle ;
else begin = middle ;
if(i++ > ArrayLong) break ;
}
if(begin > end ) return 0 ;
return middle ;
}
//计算出温度值
u8 num_to_temperature(u8 num)
{
u8 data;
return data = 0.5*num-25;
}
以上只是截取了主要的代码,不是完整的,请选择性参考。附上打印温度效果图
顺便附上实物图,接线有点乱(目不忍视)