搜索
bottom↓
回复: 4

stm32f103在RT-Thread上使用one-wire总线操作DS18B20求助!

[复制链接]

出0入8汤圆

发表于 2014-11-3 10:53:02 | 显示全部楼层 |阅读模式
本帖最后由 qqtfh 于 2014-11-3 10:58 编辑








如题,参考了http://www.amobbs.com/forum.php? ... ght=STM32%2BDS18B20
贴子上的STM32F407使用one-wire总线操作DS18B20的方法移植到STM32F103上来。
代码如下:
#ifndef __DS18B20_H__
#define __DS18B20_H__

#include <rtthread.h>
#include <stm32f10x.h>

#define DS18B20_GIVE_TICK_RTOS                                                 //此定义可让线程放弃时间片
#define DS18B20_OK                                                                                                 0 //操作成功
#define DS18B20_ERROR                                                                                 1 //操作失败
#define DS18B20_NO_DEVICE                                                                 2 //总线上无设备
#define DS18B20_INVALID_BUF                                                         3 //缓冲地址非法
#define DS18B20_USART                                                                                 USART2 //操作的USART
#define DS18B20_DMA_CH_RX                                                                 DMA1_Channel6
#define DS18B20_DMA_CH_TX                                                                 DMA1_Channel7
#define DS18B20_DMA_FLAG_RX                                                         DMA1_FLAG_TC6 //RX DMA完成标志
#define DS18B20_DMA_FLAG_TX                                                         DMA1_FLAG_TC7 //TX DMA完成标志
#define DS18B20_BIT_0                                                                                 0x00 //读写位为0
#define DS18B20_BIT_1                                                                                 0xff        //读写位为1

void ds18b20_uartInit(uint32_t baudRate);
void ds18b20_dmaInit(void);
void ds18b20_init(void);
uint8_t ds18b20_reset(void);
void ds18b20_toBits(uint8_t ds18b20_byte, uint8_t *ds18b20_bits);
uint8_t ds18b20_toByte(uint8_t *ds18b20_bits);
void ds18b20_busXfer(void);
void ds18b20_writeByte(uint8_t data);
void ds18b20_writeBuf(uint8_t *buf, uint8_t length);
uint8_t ds18b20_readByte(void);
void ds18b20_readBuf(uint8_t *buf, uint8_t length);
void ds18b20_id(void);
void ds18b20_get(void);


#endif



#include <rtthread.h>
#include <stm32f10x.h>

#include "ds18b20.h"

static uint8_t ds18b20_buf[8];        //设备私有缓冲

void ds18b20_uartInit(uint32_t baudRate)
{
        USART_InitTypeDef USART_InitStructure;
        USART_InitStructure.USART_BaudRate = baudRate;
        USART_InitStructure.USART_WordLength = USART_WordLength_8b;
        USART_InitStructure.USART_StopBits = USART_StopBits_1;
        USART_InitStructure.USART_Parity = USART_Parity_No;
        USART_InitStructure.USART_HardwareFlowControl =
        USART_HardwareFlowControl_None;
        USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
        USART_Init(DS18B20_USART, & USART_InitStructure);
}

void ds18b20_dmaInit(void)
{
        DMA_InitTypeDef DMA_InitStructure;

  DMA_DeInit(DS18B20_DMA_CH_RX);
  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t) &(DS18B20_USART->DR);
  DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t) ds18b20_buf;
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
  DMA_InitStructure.DMA_BufferSize = sizeof(ds18b20_buf);
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
  DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
  DMA_InitStructure.DMA_Priority = DMA_Priority_Low;
  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
  DMA_Init(DS18B20_DMA_CH_RX, &DMA_InitStructure);

  DMA_DeInit(DS18B20_DMA_CH_TX);
  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t) &(DS18B20_USART->DR);
  DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t) ds18b20_buf;
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
  DMA_InitStructure.DMA_BufferSize = sizeof(ds18b20_buf);
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
  DMA_InitStructure.DMA_PeripheralDataSize =
                        DMA_PeripheralDataSize_Byte;
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
  DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
  DMA_InitStructure.DMA_Priority = DMA_Priority_Low;
  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
  DMA_Init(DS18B20_DMA_CH_TX, &DMA_InitStructure);
}

void ds18b20_init(void)
{
        GPIO_InitTypeDef GPIO_InitStruct;

  if (DS18B20_USART == USART2)
        {
                RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);

                GPIO_InitStruct.GPIO_Pin = GPIO_Pin_2;
                GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
                GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;

                GPIO_Init(GPIOA, &GPIO_InitStruct);

                GPIO_InitStruct.GPIO_Pin = GPIO_Pin_3;
                GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
                GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;

                GPIO_Init(GPIOA, &GPIO_InitStruct);

                RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
  }
       
        ds18b20_uartInit(115200);
        USART_Cmd(DS18B20_USART, ENABLE);
        ds18b20_dmaInit();
        RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
}

uint8_t ds18b20_reset(void)
{
        uint8_t ds18b20_presence;
        ds18b20_uartInit(9600);
        // Send the 0xf0 at 9600
        USART_ClearFlag(DS18B20_USART, USART_FLAG_TC);
        USART_SendData(DS18B20_USART, 0xF0);
        while (USART_GetFlagStatus(DS18B20_USART, USART_FLAG_TC) == RESET)
        {
                #ifdef ds18b20_GIVE_TICK_RTOS
                rt_thread_yield();
                #else
                __NOP();
                #endif
        }
        ds18b20_presence = USART_ReceiveData(DS18B20_USART);
        ds18b20_uartInit(115200);
        return(ds18b20_presence != 0xF0)? DS18B20_OK : DS18B20_NO_DEVICE;
}

void ds18b20_toBits(uint8_t ds18b20_byte, uint8_t *ds18b20_bits)
{
        uint8_t i;
        for (i=0; i<8; i++)
        {
                *ds18b20_bits =(ds18b20_byte & 0x01)? DS18B20_BIT_1 : DS18B20_BIT_0;
                ds18b20_bits ++;
                ds18b20_byte = ds18b20_byte >> 1;
        }
}

uint8_t ds18b20_toByte(uint8_t *ds18b20_bits)
{
        uint8_t i;
        uint8_t ds18b20_byte =0;
        for (i=0; i<8; i++)
        {
                ds18b20_byte = ds18b20_byte >> 1;
                if (*ds18b20_bits == DS18B20_BIT_1)
                {
                        ds18b20_byte |= 0x80;
                }
                ds18b20_bits ++;
        }
        return ds18b20_byte;
}

void ds18b20_busXfer(void)
{
        USART_DMACmd(DS18B20_USART, USART_DMAReq_Tx | USART_DMAReq_Rx, ENABLE);
        DMA_ClearFlag(DS18B20_DMA_FLAG_RX);
        DMA_ClearFlag(DS18B20_DMA_FLAG_TX);
        USART_DMACmd(DS18B20_USART, USART_DMAReq_Tx | USART_DMAReq_Rx, ENABLE);
  DMA_Cmd(DS18B20_DMA_CH_RX, ENABLE);
  DMA_Cmd(DS18B20_DMA_CH_TX, ENABLE);
        while (DMA_GetFlagStatus(DS18B20_DMA_FLAG_RX) == RESET) //等待传输完成
        {
                #ifdef ds18b20_GIVE_TICK_RTOS
                rt_thread_yield();
                #else
                __NOP();
                #endif
        }
        DMA_Cmd(DS18B20_DMA_CH_RX, DISABLE); //顺序1:RX DMA
        DMA_Cmd(DS18B20_DMA_CH_TX, DISABLE); //顺序2:TX DMA
        USART_DMACmd(DS18B20_USART, USART_DMAReq_Tx | USART_DMAReq_Rx, DISABLE);
        //顺序3:UART DMAUART DMAUART DMAUART
}

void ds18b20_writeByte(uint8_t data)
{
        ds18b20_toBits(data, ds18b20_buf);
        ds18b20_busXfer();
}

void ds18b20_writeBuf(uint8_t *buf, uint8_t length)
{
        while (length> 0)
        {
                ds18b20_writeByte(*buf);
                buf ++;
                length --;
        }
}

uint8_t ds18b20_readByte(void)
{
        ds18b20_toBits(0xFF, ds18b20_buf);
        ds18b20_busXfer();
        return ds18b20_toByte(ds18b20_buf);
}

void ds18b20_readBuf(uint8_t *buf, uint8_t length)
{
        while (length> 0)
        {
                *buf = ds18b20_readByte();
                buf ++;
                length --;
        }
}

void ds18b20_id(void)
{
        uint32_t i;
        uint8_t buf[8];
        ds18b20_init();
        ds18b20_reset(); //总线复位
        ds18b20_writeByte(0x33); //发送命令0x33,读取ROM
        ds18b20_readBuf(buf, 8); //读取8byte(64bit)
        rt_kprintf("Type= %02X ID= ", buf[0]); //byte[0]:设备类别ID
        for (i=6;i>0;i--)
        rt_kprintf("%02X",buf); //byte[6]-[1]:设备序列号
        rt_kprintf(" CRC= %02X", buf[7]); //byte[7]byte[7]:CRC值
        rt_kprintf("\n");
}

void ds18b20_get(void)
{
        uint8_t buf[2];
        int16_t* buf16 = (int16_t*)&buf[0];
        ds18b20_init();
        while(1)
        {
                rt_kprintf("ds18b20_get");
                ds18b20_reset(); //总线复位
                ds18b20_writeBuf("\xCC\x44", 2); //发送命令XCC跳过ROM,X44转换温度
                /*max convert time = 750ms, here we set delay = 800ms*/
                rt_thread_delay((rt_tick_t)(RT_TICK_PER_SECOND *4/5)); //最高精度转换时间<=750ms<=750ms<=750ms
                ds18b20_reset(); //总线复位
                ds18b20_writeBuf("\xCC\xBE", 2); //发送命令XCC跳过ROM,X44转换温?
                ds18b20_readBuf(buf, 2); //读取RAM最开始两个字节的温度数据
                rt_kprintf("data = %d temp = %d\n", //转换工式temp=data*0.625
                (*buf16), ((int32_t)(*buf16))*125/2); //此处温度值*1000
        }
}

但是调用ds18b20_get();代码一直停在while (USART_GetFlagStatus(DS18B20_USART, USART_FLAG_TC) == RESET)。
应该是设置有问题,初学STM32,求指点。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

阿莫论坛20周年了!感谢大家的支持与爱护!!

曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……

出0入8汤圆

 楼主| 发表于 2014-11-3 16:26:23 | 显示全部楼层
沉得好快!

出0入8汤圆

 楼主| 发表于 2014-11-6 09:54:47 | 显示全部楼层
问题已经解决,自问自答好了。void ds18b20_busXfer(void)里关闭DMA后需要重新配置一下DMA_InitStructure.DMA_BufferSize = Size;再打开DMA,否则DMA只能传输一次。在度娘找到的答案,不明所以,望高手解答。

出0入0汤圆

发表于 2015-1-30 18:17:52 | 显示全部楼层
我用楼主的程序可以读温度,但是读ID函数ds18b20_id(void),要复位两次才能读到id
”ds18b20_reset(); //总线复位
ds18b20_reset(); //总线复位"
要两次才能读ID,为啥?

出0入8汤圆

 楼主| 发表于 2015-1-30 20:31:06 | 显示全部楼层
bbglx 发表于 2015-1-30 18:17
我用楼主的程序可以读温度,但是读ID函数ds18b20_id(void),要复位两次才能读到id
”ds18b20_reset(); //总 ...

我也读DS18B20的ID作为设备的唯一ID,但木有出现这种情况。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-8-25 19:58

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表