- DS18B20的温度转换需要时间等待,这在一个实时控制里面是很浪费资源的,所以在单片机没有上系统的时候,使用定时器中断后台处理DS18B20的温度转换时序就很有必要。
DS18B20的时序是以微秒为单位的,使用寄存器操作响应快,在定时器中断里面要把DS18B20的时序写出来很麻烦,需要运行的语句和算法很多,为了节省一点点的资源,用寄存器操作比较好。
程序把时序都写出来了,但是没有做过多的优化,等以后有时间了再慢慢优化,仅以此作记录。
typedef enum
{
init=0,
check=1,
write1=2,
write2=3,
write3=4,
write4=5,
read=6,
result=7
}STEP;
typedef enum
{
S1=0,
S2=1,
S3=2,
}_STEP;
typedef struct
{
u16 TEMPL[4];
u16 TEMPH[4];
}DS_TEMP;
typedef struct
{
STEP step;
_STEP sp;
u8 retry;
u16 delay_us[10];
u8 ds_flag[4];
u16 data[8];
u8 cal;
u16 dat[4];
u32 ds;
}DS_STRUCT;
DS_STRUCT DS_STATE;
DS_TEMP DS_TEMP_STRUCT;
void DS_CONFIG(u16 arr , u16 psc)
{
NVIC_InitTypeDef NVIC_InitStructure;
DS_STATE.ds_flag[3]=0;
DS_STATE.delay_us[0]=114;
DS_STATE.delay_us[1]=20;
DS_STATE.delay_us[2]=50;
DS_STATE.data[4]=0xCC;
DS_STATE.data[5]=0x44;
DS_STATE.data[6]=0xCC;
DS_STATE.data[7]=0xBE;
RCC->APB2ENR|=1<<7;
RCC->APB1ENR|=1<<2;
DS_TIM->ARR=arr-1;
DS_TIM->PSC=psc-1;
DS_TIM->CR1|=1<<7;
DS_TIM->SR=0;
DS_TIM->CNT=0;
DS_TIM->EGR=1;
DS_TIM->DIER=1;
NVIC_InitStructure.NVIC_IRQChannel=TIM4_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority=2;
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
void DS_18B20_GPIO(GPIOMode_TypeDef GPIO_MODE)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9 ;
GPIO_InitStructure.GPIO_Mode=GPIO_MODE;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOF, &GPIO_InitStructure);
}
void DS18B20_Write(u8 _data)
{
DS_18B20_GPIO(GPIO_Mode_Out_PP);
if(DS_STATE.ds_flag[1]==0)
{
DS_STATE.cal