问题遇到的现象和发生背景
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; //输出温度位小数点后两位数据(四舍五入处理)
}
运行结果及报错内容
我的解答思路和尝试过的方法
这是下载使用的一些代码还是有问题