qq_39148668 2021-11-24 18:26 采纳率: 0%
浏览 229
已结题

关于STM32F107基于HAL freertos 读取DS18B20延时问题

问题遇到的现象和发生背景

RTOS使用时sys不能使用发现 以前51的 最基础延时用起来也不行 查了一些资料实在难受

问题相关代码,请勿粘贴截图
void delayus(uint16_t us)

{

uint16_t differ=0xffff-us; //设定定时器计数器起始值

__HAL_TIM_SET_COUNTER(&htim7,differ);

HAL_TIM_Base_Start(&htim7); //启动定时器

  while(differ<0xffff-1) //补偿,判断

  {

    differ=__HAL_TIM_GET_COUNTER(&htim7); //查询计数器的计数值

  }

  HAL_TIM_Base_Stop(&htim7);

}


/* USER CODE BEGIN 0 */
#include "DS18B20.h"
#include "tim.h"
/* USER CODE END 0 */

/*----------------------------------------------------------------------------*/
/* Configure GPIO                                                             */
/*----------------------------------------------------------------------------*/
/* USER CODE BEGIN 1 */

void DS18B20_IO_OUT(void) {
    GPIO_InitTypeDef GPIO_InitStruct = { 0 };

    __HAL_RCC_GPIOA_CLK_ENABLE()
    ;

    GPIO_InitStruct.Pin = GPIO_PIN_0;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}


void DS18B20_IO_IN(void) {
    GPIO_InitTypeDef GPIO_InitStruct = { 0 };

    __HAL_RCC_GPIOA_CLK_ENABLE()
    ;

    GPIO_InitStruct.Pin =  GPIO_PIN_0;
    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}



unsigned char DS18B20_Reset() {
    unsigned char flag;
    DS18B20_IO_OUT();                       //DQ为输出
    HAL_GPIO_WritePin(GPIOA, DS18B20_Pin, GPIO_PIN_SET);
    delayus(8);                  //延时8微秒
    HAL_GPIO_WritePin(GPIOA, DS18B20_Pin, GPIO_PIN_RESET);                //拉低总线
    delayus(500);                //延时500微秒,产生复位脉冲,必须大于480微秒
    HAL_GPIO_WritePin(GPIOA, DS18B20_Pin, GPIO_PIN_SET);
    delayus(80);              //15~60us 后接收 60-240us的存在脉冲,必须大于60微秒
    DS18B20_IO_IN();
    if (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) == GPIO_PIN_SET)
        flag = 0;         //等待从机 DS18B20 应答(低电平有效):(DS18B20_IN&DS18B20_DQ),读DQ电平
    else
        flag = 1;
    DS18B20_IO_OUT();
    delayus(440);
    HAL_GPIO_WritePin(GPIOA, DS18B20_Pin, GPIO_PIN_SET);
    return (flag);
}
void DS18B20_Init() {
    DS18B20_Reset();
    DS18B20_WriteData(0xCC);  // 跳过ROM
    DS18B20_WriteData(0x4E);  // 写暂存器
    DS18B20_WriteData(0x64);  // 往暂存器的第三字节中写上限值100℃
    DS18B20_WriteData(0x00);  // 往暂存器的第四字节中写下限值0℃
    DS18B20_WriteData(0x7F);  // 将配置寄存器配置为12位精度
    DS18B20_Reset();
}
void DS18B20_WriteData(unsigned char wData) {
    unsigned char i;

    DS18B20_IO_OUT();
    for (i = 8; i > 0; i--) {
        HAL_GPIO_WritePin(GPIOA, DS18B20_Pin, GPIO_PIN_RESET);      //拉低总线,产生写信号
        delayus(15);                 //延时在15us~30us,手册上要求15微秒左右
        if (wData & 0x01)                //发送1位
                {
            HAL_GPIO_WritePin(GPIOA, DS18B20_Pin, GPIO_PIN_SET);
        } else {
            HAL_GPIO_WritePin(GPIOA, DS18B20_Pin, GPIO_PIN_RESET);
        }
        delayus(45);                 //延时15~60us
        HAL_GPIO_WritePin(GPIOA, DS18B20_Pin, GPIO_PIN_SET); //拉高总线电平,释放总线,等待总线恢复
        wData >>= 1;                    //准备下一位数据的传送
    }
    HAL_GPIO_WritePin(GPIOA, DS18B20_Pin, GPIO_PIN_SET);   //读写完成,将数据总线拉高,结束占用状态
}
unsigned char DS18B20_ReadData() {
    unsigned char i, TmepData = 0;    //温度变量定义为无符号字节型,读取传感器8位数据值

    for (i = 8; i > 0; i--) {
        TmepData >>= 1;             //数据右移
        DS18B20_IO_OUT();                   //DQ为输出
        HAL_GPIO_WritePin(GPIOA, DS18B20_Pin, GPIO_PIN_RESET);      //拉低总线,产生读信号
        delayus(6);               //总线拉低延时6微秒
        HAL_GPIO_WritePin(GPIOA, DS18B20_Pin, GPIO_PIN_SET);        //释放总线,准备读数据
        delayus(10);                //最初延时4微秒,延时6微秒
        DS18B20_IO_IN();                     //DQ数据口设置成数据输入状态,cpu读数据
        if (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) == GPIO_PIN_SET) //(DS18B20_IN & DS18B20_DQ),读DQ电平
                {
            TmepData |= 0x80;
        }
        delayus(65);             //!视频文件上要求延时45微秒,如果读取不当,做调整
    }
    return (TmepData);          //返回读到的数据
}
double DS18B20_Conert() {
    DS18B20_Init();
    unsigned int TempData1, TempData2;          //unsigned int定义16位两字节的数据类型
    double temp = 0;                     //中间变量,避免return表达式过于复杂
    DS18B20_Reset();
    DS18B20_WriteData(0xCC);       // 跳过ROM
    DS18B20_WriteData(0x44);       // 开始转换
    delayus(500);                 //延时一般在500us不能过小
    DS18B20_Reset();
    DS18B20_WriteData(0xCC);       // 跳过ROM
    DS18B20_WriteData(0xBE);       //读取 RAM
    TempData1 = DS18B20_ReadData();  //读低八位
    TempData2 = DS18B20_ReadData();  //读高八位
    //HAL_Delay(800);          //延时750~900ms,保证工作周期,转换温度对时间有较高的要求
    DS18B20_Reset();
    temp = ((TempData2 << 8) + TempData1); //8位左移8位,形成16位的二进制值;由温度传感器寄存器值储存意义进行换算
    return temp*0.0625; //输出温度位小数点后两位数据(四舍五入处理)
}

运行结果及报错内容

img

我的解答思路和尝试过的方法

这是下载使用的一些代码还是有问题

我想要达到的结果
  • 写回答

1条回答 默认 最新

  • Berte_Yu 2021-11-24 19:35
    关注

    遇到的问题是什么? 卡在了延时函数里?还是什么呢

    评论

报告相同问题?

问题事件

  • 系统已结题 12月2日
  • 创建了问题 11月24日

悬赏问题

  • ¥15 ads仿真结果在圆图上是怎么读数的
  • ¥20 Cotex M3的调试和程序执行方式是什么样的?
  • ¥20 java项目连接sqlserver时报ssl相关错误
  • ¥15 一道python难题3
  • ¥15 用matlab 设计一个不动点迭代法求解非线性方程组的代码
  • ¥15 牛顿斯科特系数表表示
  • ¥15 arduino 步进电机
  • ¥20 程序进入HardFault_Handler
  • ¥15 oracle集群安装出bug
  • ¥15 关于#python#的问题:自动化测试