具体代码:(参考了up江科大的代码)
ds18b20: GPIOA 4
①ds18b20.c:
#include "stm32f10x.h"
#include "delay.h"
#include "OLED.h"
void DS18B20_Mode_IN(void)//设置GPIO输入模式
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//上拉输入
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStructure);
}
void DS18B20_Mode_OUT(void)//设置GPIO输出模式
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStructure);
}
unsigned char DS18B20_Init(void)
{
Delay_Init();
//从机复位,检测从机给主机返回的脉冲
unsigned char ACK;
DS18B20_Mode_IN();//设置输入模式
GPIO_ResetBits(GPIOA,GPIO_Pin_4);//拉低总线(低电平)
DelayUs(500);
GPIO_SetBits(GPIOA,GPIO_Pin_4);//释放总线
DelayUs(70);
ACK = GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_4);
DelayUs(500);
return ACK;
}
void DS18B20_Send_Bit(unsigned char bit) //(主机:stm32)发送一位到(从机:ds18b20)
{
Delay_Init();
DS18B20_Mode_OUT();//设置输出模式
GPIO_ResetBits(GPIOA,GPIO_Pin_4);//拉低总线(低电平)
DelayUs(10);
if(bit)
{
GPIO_SetBits(GPIOA,GPIO_Pin_4);
DelayUs(50);
}
else
{
GPIO_ResetBits(GPIOA,GPIO_Pin_4);
DelayUs(50);
}
GPIO_SetBits(GPIOA,GPIO_Pin_4);
}
unsigned char DS18B20_Receive_Bit(void) //(从机:ds18b20)发送一位到(主机:stm32)
{
Delay_Init();
unsigned char Bit;
DS18B20_Mode_IN();//设置输入模式
GPIO_ResetBits(GPIOA,GPIO_Pin_4);//拉低总线(低电平)
DelayUs(5);
GPIO_SetBits(GPIOA,GPIO_Pin_4);//从机发0,主机拉高但是总线此时还是0
DelayUs(5);
Bit = GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_4);
DelayUs(50);
return Bit;
}
void DS18B20_Send_Byte(unsigned char Byte)//主机发送一个字节,从机接受
{
unsigned char i=0;
for(i=0;i<8;i++)
{
DS18B20_Send_Bit(Byte&(0x01<<i)); //依次取出二进制下对应的bit发送
}
}
unsigned char DS18B20_Receive_Byte(void)//从机发送一个字节,主机接受
{
unsigned char Byte =0x00;
unsigned char i=0;
for(i=0;i<8;i++)
{
if(DS18B20_Receive_Bit())
{
Byte|=(0x01<<i);
}
}
return Byte;
}
void DS18B20_ConvertTemperature(void)//温度变换
{
DS18B20_Init();
DS18B20_Send_Byte(0xCC); //SKIP_ROM
DS18B20_Send_Byte(0x44); //COVERT_T
}
float DS18B20_ReadTemperature(void)//温度读取
{
unsigned char TLSB,TMSB;
int Temp;
float T;
DS18B20_Init();
DS18B20_Send_Byte(0xCC); //SKIP_ROM
DS18B20_Send_Byte(0xBE); //READ_SCRATCHPAD
TLSB = DS18B20_Receive_Byte();
TMSB = DS18B20_Receive_Byte();
// OLED_ShowBinNum(1,1,TMSB,8);
// OLED_ShowBinNum(1,9,TLSB,8);
Temp=(TMSB<<8)|TLSB;
T = Temp/16.0;
return T;
}
②main.c
#include "stm32f10x.h"
#include "ds18b20.h"
#include "delay.h"
#include "OLED.h"
float T;
int main(void)
{
OLED_Init();
OLED_ShowString(1,1,"Temperature:");
// unsigned char ACK;
// ACK = DS18B20_Init();
// OLED_ShowNum(2,3,ACK,3); 检测从机是否应答
while(1)
{
DS18B20_ConvertTemperature();
DelayMs(10);
T = DS18B20_ReadTemperature();
if(T<0)
{
OLED_ShowChar(2,1,'-');
T=-T;
}
else
{
OLED_ShowChar(2,1,'+');
}
OLED_ShowNum(2,2,T,3);
OLED_ShowChar(2,5,'.');
OLED_ShowNum(2,6,(unsigned long)(T*10000)%10000,4);
}
}
附1:
oled代码直接复制up江科大;
delay代码:
//单片机头文件
#include "stm32f10x.h"
//delay头文件
#include "delay.h"
//延时系数
unsigned char UsCount = 0;
unsigned short MsCount = 0;
void Delay_Init(void)
{
SysTick->CTRL &= ~(1 << 2); //选择时钟为HCLK(72MHz)/8 103--9MHz
UsCount = 9; //微秒级延时系数
MsCount = UsCount * 1000; //毫秒级延时系数
}
void DelayUs(unsigned short us)
{
unsigned int ctrlResult = 0;
us &= 0x00FFFFFF; //取低24位
SysTick->LOAD = us * UsCount; //装载数据
SysTick->VAL = 0;
SysTick->CTRL = 1; //使能倒计数器
do
{
ctrlResult = SysTick->CTRL;
}
while((ctrlResult & 0x01) && !(ctrlResult & (1 << 16))); //保证在运行、检查是否倒计数到0
SysTick->CTRL = 0; //关闭倒计数器
SysTick->VAL = 0;
}
void DelayXms(unsigned short ms)
{
unsigned int ctrlResult = 0;
if(ms == 0)
return;
ms &= 0x00FFFFFF; //取低24位
SysTick->LOAD = ms * MsCount; //装载数据
SysTick->VAL = 0;
SysTick->CTRL = 1; //使能倒计数器
do
{
ctrlResult = SysTick->CTRL;
}
while((ctrlResult & 0x01) && !(ctrlResult & (1 << 16))); //保证在运行、检查是否倒计数到0
SysTick->CTRL = 0; //关闭倒计数器
SysTick->VAL = 0;
}
void DelayMs(unsigned short ms)
{
unsigned char repeat = 0;
unsigned short remain = 0;
repeat = ms / 500;
remain = ms % 500;
while(repeat)
{
DelayXms(500);
repeat--;
}
if(remain)
DelayXms(remain);
}
附2:
附3:
百度网盘分享的文件:stm32-ds…
链接:https://pan.baidu.com/s/12AutmQyw3QnOPi4hMxqWAw
提取码:a437