打印

使用STM32读取DS18B20温度传感器

[复制链接]
13500|14
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
puppyh|  楼主 | 2008-11-16 11:08 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
沙发
古道热肠| | 2008-11-16 11:14 | 只看该作者

这不是万利的STM32板吗,把程序贴上来大家看看吧

使用特权

评论回复
板凳
hotpower| | 2008-11-16 21:35 | 只看该作者

俺用了STM32的一个串口读取DS18B20温度传感器

虽然奢侈些但轻松太多了~~~

使用特权

评论回复
地板
winloop| | 2008-11-17 08:56 | 只看该作者

串口的什么模式?

使用特权

评论回复
5
yewuyi| | 2008-11-17 09:00 | 只看该作者

用UART ?

如果可能,那么肯定是省了读的麻烦,但多了数据纠正的麻烦。。。

使用特权

评论回复
6
puppyh|  楼主 | 2008-11-17 09:47 | 只看该作者

代码还有点乱

等到整理好了,就贴出来。

使用特权

评论回复
7
qjy_dali| | 2008-11-17 15:14 | 只看该作者

关于串口实现1-wire,美信有一篇应用笔记

  hotpower应该看了这个的吧,呵呵

使用特权

评论回复
8
BITiramisu| | 2008-11-17 20:26 | 只看该作者

哈哈

最近正准备使用1820来做个东西玩玩呢--可惜得从零开始。。。

看来可以像楼主学习不少东西~

使用特权

评论回复
9
渊深海阔| | 2010-8-31 12:51 | 只看该作者
给个例程吧

使用特权

评论回复
10
zhi620734442| | 2010-10-10 16:42 | 只看该作者
你放一个这样东西有什么用啊。。。。 要没有程序要不没有资料,发这个帖有意思不。。。。。

使用特权

评论回复
11
puppyh|  楼主 | 2010-10-10 20:29 | 只看该作者
不好意思,代码编写的不太好,一直没有时间去修改。既然有人有意见,我就先将老代码贴出来吧。

main.c:

/*==============================================================================
* File Name          : DS18B20.c
* Author             : Puppyh
* Version            : V0.1
* Date               : 10/15/2008
* Description        : Main program
==============================================================================*/

/* Includes */
#include "stm32f10x_lib.h"
#include "lib_bits.h"

#include "HW_Config.h"
#include "ds18b20.h"

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/

/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
ErrorStatus HSEStartUpStatus;

u8 Beep_Event;
u8 Beep_Flag;

unsigned char Timer_2ms_Flag;
unsigned char data[4];
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/*******************************************************************************
* Function Name  : Delay
* Description    : Inserts a delay time.
* Input          : nCount: specifies the delay time length.
* Output         : None
* Return         : None
*******************************************************************************/
void Delay(vu32 nCount)
{
        while (nCount--);
}
/*******************************************************************************
* Function Name : JoyState.
* Description   : Decodes the Joystick direction.
* Input         : None.
* Output        : None.
* Return value  : The direction value.
*******************************************************************************/
unsigned char Convert_Task(unsigned short c_Data)
{
        unsigned short temp;

        if (c_Data > 9999)
                return 1;

        for (temp = 0; temp < 4; temp ++)
                data[temp] = 0;

        temp = c_Data;
        while (temp >= 1000) {
                temp -= 1000;
                data[0] ++;
        }

        while (temp >= 100) {
                temp -= 100;
                data[1] ++;
        }

        while (temp >= 10) {
                temp -= 10;
                data[2] ++;
        }

        data[3] = temp;

        return 0;
}

/*******************************************************************************
* Function Name  : main
* Description    : Main program.
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
int main(void)
{
        unsigned long Show_Data;
        u8 Counter;
        u8 Flag;

        RCC_Configuration();                // System Clocks Configuration
        GPIO_Configuration();                // GPIO Configuration
        NVIC_Configuration();                // NVIC Configuration

        Initialize_DS18B20();
        NOP();

        while (1) {
                if (Timer_2ms_Flag) {
                        Timer_2ms_Flag = 0;
                        Counter ++;
                        if (Counter == 0) {
                                Flag ++;
                                if (ValBit(Flag, 0))
                                        Show_Data = Get_Temperature();
                                else
                                        Temperature_Convert();
                        }
                }
        }
}


STM32 中断处理程序:
/*******************************************************************************
* Function Name  : SysTickHandler
* Description    : This function handles SysTick Handler.
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void SysTickHandler(void)
{
        Timer_2ms_Flag = 1;

        GPIO_WriteBit(GPIOC, GPIO_Pin_6, (BitAction)(1 - GPIO_ReadOutputDataBit(GPIOC, GPIO_Pin_6)));
}

使用特权

评论回复
12
puppyh|  楼主 | 2010-10-10 20:30 | 只看该作者
与DS18B20有关的代码:


DS18B20.c

/*==============================================================================
* File Name          : DS18B20.c
* Author             : Puppyh
* Version            : V0.1
* Date               : 10/15/2008
* Description        :
==============================================================================*/
#include "stm32f10x_lib.h"
#include "ds18b20.h"

u8 Flag;

void us_Delay (u16 us)
{
        while(us--);
}

void ms_Delay(u16 count) //延时子函数
{
        u8 i;
        while(count) {
                i = 255;
                while(i --);
                count --;
        }
}


/*==============================================================================
名称: DS18B20_Reset
输入:无
输出:Flag --- 指示线上是否有DS18B20存在。
描述:
        发送一个复位脉冲(最少保持480μs的低电平信号),然后释放总线,MCU进入接收状态,DS1820
        在探测到引脚上的上升沿后,延时15~60μs后,DS1820发出存在脉冲(60~240μs的低电平信号)。
==============================================================================*/
u8 DS18B20_Reset(void)
{
        DS18B20_PIN = 1;
        us_Delay(10);
        DS18B20_PIN = 0;
        us_Delay(3500);                                        // 延时约480us,保持总线电平为低,总线上的器件将被复位。
        DS18B20_PIN = 1;                                // 发送复位脉冲后,释放总线,让总线处于空闲状态
        us_Delay(110);                                        // 释放总线后,以便从机DS18B20通过拉低总线来指示其是否在线,存在检测高电平时间:15~60us,
        us_Delay(110);                                        // 两段延时是为了保证延时精确
        if(DS18B20_PIN_IN == 0)
                Flag = TRUE;                                // 检测到DS18B20
        else
                Flag = FALSE;                                // 未检测到DS18B20

        us_Delay(1000);                                        // 存在检测低电平时间:60~240us,延时约140us
        DS18B20_PIN = 1;                                // 释放总线

        return Flag;
}

/*==============================================================================
读/写时间隙:
DS1820 的数据读写是通过时间隙处理位和命令字来确认信息交换。
        读一字节
==============================================================================*/
u8 DS18B20_Read_Byte(void )
{
        u8 c_value, i;
        u8 c_dat;

        value = 0;                                                // 设定初值为0
        for(i = 0; i < 8; i ++) {
                DS18B20_PIN = 0;                        // 将总线拉低
                us_Delay(10);                                // 延时1us~
                DS18B20_PIN = 1;                        // 拉低总线后再释放总线,让DS18B20能够控制总线,以便输出有效数据
                us_Delay(80);                                // MCU延时一段时间,读取DS18B20的数据,因为从DS18b20上输出的数据在读"时间隙"下降沿出现15us内有效
                c_dat = DS18B20_PIN_IN;                // 主机读从机18b20输出的数据,这些数据在读时隙的下降沿出现//15us内有效
                c_value = (u16)c_dat << 7) | (c_value >> 1);        //
                us_Delay(333);                                // 所有读"时间隙"必须60us,这里56us
                us_Delay(10);                                // 至少延时1us,才产生写"时间隙"
        }
        return value;                                        // 返回一个字节的数据
}

/*==============================================================================
读/写时间隙:
DS1820 的数据读写是通过时间隙处理位和命令字来确认信息交换。
        //写一个字节
==============================================================================*/
void DS18B20_Write_Byte(u8 cDat)
{
        u8 i, one_bit;

        for(i = 0; i < 8; i ++) {
                one_bit = cDat & 0x01;
                cDat = cDat >> 1;

                DS18B20_PIN = 0;
                if(one_bit) {                                //写 1
                        us_Delay(10);                        // 至少延时1us,才产生写"时间隙"
                        DS18B20_PIN = 1;                // 写时间隙开始后的15μs内允许数据线拉到高电平
                        us_Delay(445);                        // 所有写时间隙必须最少持续60us
                }
                else {                                                //写 0
                        us_Delay(460);                        // 必须把数据线拉到低电平并保持至少60μs,这里64us
                }
                DS18B20_PIN = 1;
                us_Delay(10);                                // 至少延时1us,才产生写"时间隙"
        }
}

/*==============================================================================
主机(单片机)控制18B20完成温度转换要经过三个步骤:
每一次读写之前都要18B20进行复位操作,复位成功后发送
一条ROM指令,最后发送RAM指令,这样才能对DS18b20进行
预定的操作。
复位要求主CPU将数据线下拉500us,然后释放,当DS18B20
受到信号后等待16~60us,后发出60~240us的存在低脉冲,
主CPU收到此信号表示复位成功
==============================================================================*/

/*==============================================================================
进行温度转换:
先初始化
然后跳过ROM:跳过64位ROM地址,直接向DS18B20发温度转换命令,适合单片工作
发送温度转换命令
==============================================================================*/
void Temperature_Convert(void)
{
        DS18B20_Reset();
        DS18B20_Write_Byte(0xCC);
        DS18B20_Write_Byte(0x44);
}

/*==============================================================================
获得温度:
==============================================================================*/
u16 Get_Temperature(void)
{
        u8 a, b;
        u16 temp;

        DS18B20_Reset();
        DS18B20_Write_Byte(0xCC);
        DS18B20_Write_Byte(0xBE);

        a = DS18B20_Read_Byte();
        b = DS18B20_Read_Byte();

        temp = (u16)b << 8 | a;

        return temp;
}
/*==============================================================================
读ROM   
==============================================================================*/
u16 DS18B20_Read_ROM(void)                        // 这里没有用到
{
        u8 a,b;
        u16 temp;

        DS18B20_Reset();
        us_Delay(30);
        DS18B20_Write_Byte(0x33);
        a = DS18B20_Read_Byte();
        b = DS18B20_Read_Byte();

        temp = b;
        temp <<= 8;
        temp = temp | a;

        return (u16)a << 8 | b;
}

/*==============================================================================
读ROM
==============================================================================*/
void Initialize_DS18B20(void)
{
        u8 temp;

        do {
                Temperature_Convert();
                ms_Delay(6180);
                temp = Get_Temperature();
        } while (temp == 85);
        Temperature_Convert();
}

DS18B20.h
/*==============================================================================
* File Name          : DS18B20.h
* Author             : Puppyh
* Version            : V0.1
* Date               : 10/15/2008
* Description        :
==============================================================================*/
#ifndef _DS18B20_H
#define _DS18B20_H

#define GPIOC_OFFSET                (GPIOC_BASE - PERIPH_BASE)                        // GPIOC offset

#define GPIOC_ODR_OFFSET        (GPIOC_OFFSET + 0x0C)                                // GPIOC ODR offset
#define GPIOC_IDR_OFFSET        (GPIOC_OFFSET + 0x08)                                // GPIOC IDR offset

#define GPIOx_ODR_OFFSET        GPIOC_ODR_OFFSET                                        // GPIOC ODR offset
#define GPIOx_IDR_OFFSET        GPIOC_IDR_OFFSET                                        // GPIOC IDR offset

#define GPIOx_PIN                        12

#define DS18B20_PIN                        *(vu32 *)(PERIPH_BB_BASE + (GPIOx_ODR_OFFSET * 32) + (GPIOx_PIN * 4))        // PC 12
#define DS18B20_PIN_IN                *(vu32 *)(PERIPH_BB_BASE + (GPIOx_IDR_OFFSET * 32) + (GPIOx_PIN * 4))        // PC 12

#define NOP()                                asm("nop");

void us_Delay(u16 us);
void ms_Delay(u16 count);                        //延时子函数
u8 DS18B20_Reset(void);
u8 DS18B20_Read_Byte(void);                        //读一字节
void DS18B20_Write_Byte(u8 dat);        //写一个字节
void Temperature_Convert(void);
u16 Get_Temperature(void);
u16 DS18B20_Read_ROM(void);                                //这里没有用到
void Initialize_DS18B20(void);

#endif

使用特权

评论回复
13
puppyh|  楼主 | 2010-10-10 20:35 | 只看该作者
其他有关代码:
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT_OD;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOC, &GPIO_InitStructure);                // Set PC.12 use for DS18B20

void RCC_Configuration(void)
{
        ErrorStatus HSEStartUpStatus;

        RCC_DeInit();                // RCC system reset(for debug purpose)
        RCC_HSEConfig(RCC_HSE_ON);                // Enable HSE
        HSEStartUpStatus = RCC_WaitForHSEStartUp();                // Wait till HSE is ready

        if(HSEStartUpStatus == SUCCESS) {
                FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);        // Enable Prefetch Buffer
                FLASH_SetLatency(FLASH_Latency_2);                // Flash 2 wait state

                RCC_HCLKConfig(RCC_SYSCLK_Div1);                // HCLK = SYSCLK
                RCC_PCLK2Config(RCC_HCLK_Div1);                // PCLK2 = HCLK
                RCC_PCLK1Config(RCC_HCLK_Div2);                // PCLK1 = HCLK/2
                RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);        // configure PLLCLK
                RCC_PLLCmd(ENABLE);        // Enable PLL
                while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET) {}        // Wait till PLL is ready

                RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);                // Select PLL as system clock source
                while(RCC_GetSYSCLKSource() != 0x08) {}        // Wait till PLL is used as system clock source
        }
        RCC_GetClocksFreq(&RCC_ClockFreq);                                                // This function fills a RCC_ClocksTypeDef structure with the current frequencies of different on chip clocks (for debug purpose)

        Peripheral_Clock_Enable();
}
#endif

使用特权

评论回复
14
zsz89757| | 2011-10-26 18:54 | 只看该作者
强大,好

使用特权

评论回复
15
yangge111| | 2013-4-25 20:26 | 只看该作者
群主,告诉我你的联系?

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

14

主题

208

帖子

0

粉丝