打印
[STM8]

请教大神:有做过STM8控制SHT10的程序吗?

[复制链接]
1775|15
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
sjg142729|  楼主 | 2015-10-28 15:58 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
请教大神:有做过STM8控制SHT10的程序吗?
沙发
zhuotuzi| | 2015-10-28 16:50 | 只看该作者

使用特权

评论回复
板凳
zhuotuzi| | 2015-10-28 16:51 | 只看该作者

使用特权

评论回复
地板
zhuotuzi| | 2015-10-28 16:52 | 只看该作者

使用特权

评论回复
5
zhuotuzi| | 2015-10-28 16:52 | 只看该作者

使用特权

评论回复
6
zhuotuzi| | 2015-10-28 16:53 | 只看该作者

使用特权

评论回复
7
zhuotuzi| | 2015-10-28 16:53 | 只看该作者

使用特权

评论回复
8
zhuotuzi| | 2015-10-28 16:54 | 只看该作者
不好意思,人家是图片格式,下载需要积分,我只能截图发来了,防止排版乱了顺序,我就一楼一楼的帖了程序。

使用特权

评论回复
9
734774645| | 2015-10-28 17:31 | 只看该作者
楼上的发错了那个是SHT21,楼主要的是SHT11,我来发个例程。
----------------
/* Includes ------------------------------------------------------------------*/
#include "stm32f10x.h"
#include "usart1.h"
#include "stdio.h"
/* Private typedef -----------------------------------------------------------*/

/* Private define ------------------------------------------------------------*/
#define SDA_H()         GPIO_SetBits(GPIOB,GPIO_Pin_0)
#define SDA_L()         GPIO_ResetBits(GPIOB,GPIO_Pin_0)
#define SCK_H()         GPIO_SetBits(GPIOB,GPIO_Pin_1)
#define SCK_L()         GPIO_ResetBits(GPIOB,GPIO_Pin_1)
//读SDA数据
#define SDA_R()         GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_0)

/* Private macro -------------------------------------------------------------*/
#define noACK 0         //无应答
#define ACK   1         //应答

#define STATUS_REG_W    0x06   //000   0011    0
#define STATUS_REG_R    0x07   //000   0011    1
#define MEASURE_TEMP    0x03   //000   0001    1
#define MEASURE_HUMI    0x05   //000   0010    1
#define RESET           0x1e   //000   1111    0

/* Private variables ---------------------------------------------------------*/
enum {TEMP,HUMI};
uint8_t Test_Timetick = 0;
uint16_t Test_Counter = 0;
/* Private function prototypes -----------------------------------------------*/
void RCC_Config(void);
void USART1_Config(void);
void SHT10_Config(void);
void SHT10_SDAIn(void);
void SHT10_SDAOut(void);
void SHT10_Delay(void);
uint8_t SHT10_WriteByte(uint8_t value);
uint8_t SHT10_ReadByte(uint8_t Ack);
void SHT10_Start(void);
void SHT10_ConReset(void);
uint8_t SHT10_Measure(uint16_t* pValue, uint8_t* pCheckSum, uint8_t mode);
void SHT10_Cal(uint16_t Temp,uint16_t Hum, float* pTempValue,float* pHumValue);

/* Private functions ---------------------------------------------------------*/

/**
  * [url=home.php?mod=space&uid=247401]@brief[/url]  主程序
  * @param  无
  * @retval 无
  */
int main(void)
{
    //温度结果  16bit
    uint16_t TempValue;
    //湿度结果 16bit
    uint16_t HumValue;
    //温度转换结果
    float TempResult;
    //湿度转换结果
    float HumResult;
    //校验值
    uint8_t CheckValue = 0x00;
   
    //错误
    uint8_t error = 0x00;
   
    //初始化RCC
    RCC_Config();
    USART1_Config();
    SHT10_Config();
   
    printf("Start\n");
    while(1)
    {
        if(Test_Timetick)
        {
            Test_Timetick = 0;
            Test_Counter ++;
            
            //延时2000ms
            if(Test_Counter > 2000)
            {
                Test_Counter = 0;
               
                printf("启动转换!\n");
                //SHT10 连接
                SHT10_ConReset();
                //获得温度和湿度数据,16位格式
                error += SHT10_Measure(&TempValue,&CheckValue,TEMP);
                error += SHT10_Measure(&HumValue,&CheckValue,HUMI);
                //温度湿度计算,浮点数形式
                SHT10_Cal(TempValue ,HumValue,&TempResult,&HumResult);
                //通过串口输出,温度和湿度数据
                printf("温度 %2.1fC 湿度 %2.1f%%\n",TempResult,HumResult);

            }
        }
    }
}

/**
  * @brief  初始化Systick定时器
  * @param  None
  * @retval None
  */
void RCC_Config(void)
{        
    //Systick时钟每1ms触发一次
    if (SysTick_Config(SystemCoreClock / 1000))
    {
        //
        while (1);
    }
}

/**
  * @brief  初始化SHT10 IO口
  * @param  None
  * @retval None
  */
void SHT10_Config(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
   
    //使能GPIOA时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB ,ENABLE);
  
    //PB0 SDA 推挽输出
          GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
          GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
          GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
          GPIO_Init(GPIOB, &GPIO_InitStructure);
          //PB1 SCK 推挽输出
          GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
          GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;   
          GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
          GPIO_Init(GPIOB, &GPIO_InitStructure);
}

/**
  * @brief  配置为输入状态
  * @param  None
  * @retval None
  */
void SHT10_SDAIn(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
   
    //PB0 SDA 浮动输入,外部有上拉电阻
          GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
          GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
          GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
          GPIO_Init(GPIOB, &GPIO_InitStructure);   
}

/**
  * @brief  配置为输出状态
  * @param  None
  * @retval None
  */
void SHT10_SDAOut(void)
{
          GPIO_InitTypeDef GPIO_InitStructure;
   
    //PB0 SDA 推挽输出
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
          GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
          GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
          GPIO_Init(GPIOB, &GPIO_InitStructure);
}

/**
  * @brief  配置为输出状态
  * @param  写数据
  * @retval 应答
  */
uint8_t SHT10_WriteByte(uint8_t value)
{
    uint8_t i,error=0;  
    //SDA输出
    SHT10_SDAOut();
   
    for( i = 0x80 ; i>0 ; i/=2)            
    {
        if ( i & value)
            SDA_H();            
        else
            SDA_L();
        
        SHT10_Delay();                       
        SCK_H();                          
        SHT10_Delay();                       
        SCK_L();
        SHT10_Delay();                     
    }
   
    //SDA输入
    SHT10_SDAIn();
   
    SCK_H();                           
    error = SDA_R();   //读应答位                 
    SCK_L();
   
    return error;                 
}

/**
  * @brief  读数据
  * @param  应答
  * @retval 返回数据
  */
uint8_t SHT10_ReadByte(uint8_t Ack)
{
    uint8_t i,val=0;
    //输入状态
    SHT10_SDAIn();  
   
    for (i=0x80;i>0;i/=2)         
    {
        SHT10_Delay();  
        SCK_H();   
        SHT10_Delay();  
        if (SDA_R())
            val=(val | i);        //读数据
        SCK_L();                                          
    }
   
    //输出状态
    SHT10_SDAOut();  
    if(Ack)
        SDA_L();                //应答为低电平
    else
        SDA_H();

    SHT10_Delay();  
    SCK_H();                     
    SHT10_Delay();  
    SCK_L();
    SHT10_Delay();                                             
    return val;
}

/**
  * @brief  启动
  * @param  无
  * @retval 无
  */
void SHT10_Start(void)
{  
   //SDA输出
    SHT10_SDAOut();
   
    SCK_L();                  
    SHT10_Delay();         
    SCK_H();
    SHT10_Delay();         
    SDA_L();
    SHT10_Delay();         
    SCK_L();  
    SHT10_Delay();         
    SCK_H();
    SHT10_Delay();         
    SDA_H();                  
    SHT10_Delay();         
    SCK_L();                  
}

/**
  * @brief  重新连接
  * @param  无
  * @retval 无
  */
void SHT10_ConReset(void)
{
    uint8_t i;
    //输出
    SHT10_SDAOut();
   
    SDA_H();    //输出高电平
    SCK_L();
   
    for(i = 0 ; i < 9 ; i++)                  
    {
        SCK_H();
        SHT10_Delay();
        SCK_L();
        SHT10_Delay();
    }
   
    SHT10_Start();                  
}

/**
  * @brief  软件重启
  * @param  无
  * @retval 无
  */
uint8_t SHT10_SoftReset(void)
{
    uint8_t error=0;  
    SHT10_ConReset();              
    error += SHT10_WriteByte(RESET);      
    return error;                    
}

/**
  * @brief  温度或湿度测量
  * @param  温度或者湿度指针数据,校验值指针,模式
  * @retval 错误
  */
uint8_t SHT10_Measure(uint16_t* pValue, uint8_t* pCheckSum, uint8_t mode)
{
    uint8_t error=0;
   
    uint8_t Value_H = 0;
    uint8_t Value_L = 0;
   
    //启动
    SHT10_Start();               
    switch(mode)
    {                     
    case TEMP:
        error += SHT10_WriteByte(MEASURE_TEMP);
        break;
    case HUMI:
        error += SHT10_WriteByte(MEASURE_HUMI);
        break;
    default:
        break;         
    }
   
    //SDA读状态
    SHT10_SDAIn();
    //等待转换完成,代码有待优化
    while(SDA_R())
    {
        ;
    }

    Value_H = SHT10_ReadByte(ACK);    //读高位
    Value_L = SHT10_ReadByte(ACK);    //读低位
   
    *pCheckSum = SHT10_ReadByte(noACK);  //读校验结果
   
    //返回结果
    *pValue = (Value_H << 8) | Value_L;   
   
    return error;
}


/**
  * @brief  计算温度和湿度数据
  * @param  温度数据 湿度数据 温度结果 湿度结果
  * @retval 无
  */
void SHT10_Cal(uint16_t Temp,uint16_t Hum, float* pTempValue,float* pHumValue)
{
    const float d1 = -40.1;
    const float d2 = 0.01;
    float Temp_C;
    //温度结果,换算                 
    Temp_C = d1 + d2 * Temp;   
   
    const float C1 = -2.0468;           
    const float C2 = +0.0367;           
    const float C3 = -0.0000015955;     
    const float T1 = +0.01;            
    const float T2 = +0.00008;         
   
    //湿度线性值
    float RH_Lin;
    //湿度真实值
    float RH_True;  
   
    //RH线性结果
    RH_Lin = C1 + C2 * Hum + C3 * Hum *Hum;
    RH_True = (Temp_C - 25) * (T1 + T2 * Hum) + RH_Lin;
    //限定范围
    if( RH_True > 100 ) RH_True = 100;
    if( RH_True < 0.01) RH_True = 0.01;
   
    *pTempValue = Temp_C;
    *pHumValue = RH_True;
   
}


/**
  * @brief  延时函数
  * @param  无
  * @retval 无
  */
void SHT10_Delay(void)
{
    //延时函数,i有待修改
    for(uint16_t i = 500 ; i > 0 ; i--)
    {
        ;
    }
}


使用特权

评论回复
10
734774645| | 2015-10-28 17:32 | 只看该作者


在上传一个串口队列发送的代码,这个里面也使用到了!头文件部分




/* Includes ------------------------------------------------------------------*/
#include "stm32f10x.h"

//函数声明
void USART1_Config(void);
uint8_t Add_Tx1Item(uint8_t ch);
uint8_t Get_Tx1BufCounter(void);
uint8_t Get_Rx1Item(void);
uint8_t Get_Rx1BufCounter(void);
void Clear_Tx1Buf(void);
void Clear_Rx1Buf(void);
#endif

c文件部分
/**
  ******************************************************************************
  * [url=home.php?mod=space&uid=288409]@file[/url]   
  * [url=home.php?mod=space&uid=187600]@author[/url]  
  * [url=home.php?mod=space&uid=895143]@version[/url]
  * [url=home.php?mod=space&uid=212281]@date[/url]   
  * @brief   以队列的方式发送和接收数据
  ******************************************************************************
  */
/* Includes ------------------------------------------------------------------*/
#include "usart1.h"
#include "stdio.h"
#include "stm32f10x_it.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
//发送缓冲区长度
#define TX1_BUFFER_SIZE        128
//接收缓冲区长度
#define RX1_BUFFER_SIZE 128
/* Private variables ---------------------------------------------------------*/
//发送缓冲区
uint8_t Tx1_Buffer[TX1_BUFFER_SIZE];
uint8_t Tx1_WriteIndex = 0;
uint8_t Tx1_ReadIndex = 0;
uint8_t Tx1_Counter = 0;
//接收缓冲区
uint8_t Rx1_Buffer[RX1_BUFFER_SIZE];
uint8_t Rx1_WriteIndex = 0;
uint8_t Rx1_ReadIndex = 0;
uint8_t Rx1_Counter = 0;
uint8_t Rx1_BufOverflow = 0;
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/

/**
  * @brief  USART1_Config 初始化USART1
  *         第一步 使能GPIOA时钟
  *         第二步 配置IO口
  *         第三步 配置USART1
  *         第四步 配置中断优先级
  * @param  None
  * @retval None
  */
void USART1_Config(void)
{
    USART_InitTypeDef USART_InitStructure;
    GPIO_InitTypeDef GPIO_InitStructure;
   
    Clear_Tx1Buf();
    Clear_Rx1Buf();
   
    //使能GPIOA时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA \
                        | RCC_APB2Periph_USART1 ,ENABLE);
  
    //PA9 TX1 复用推挽输出
          GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
          GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
          GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
          GPIO_Init(GPIOA, &GPIO_InitStructure);
          //PA10 RX1 浮动输入
          GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
          GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;   
          GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
          GPIO_Init(GPIOA, &GPIO_InitStructure);
  
    USART_InitStructure.USART_BaudRate = 9600;
    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_Rx | USART_Mode_Tx;
    USART_Init(USART1, &USART_InitStructure);
    //使能接收中断
        USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);
    //使能USART1
        USART_Cmd(USART1, ENABLE);
   
    //配置USART1中断,最高优先级
    NVIC_InitTypeDef NVIC_InitStructure;
          //抢占优先级0  
          NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
          //从优先级1
          NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
          NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
          NVIC_Init(&NVIC_InitStructure);

}

/**
  * @brief  加入发送队列.
  * @param  待发送的数据
  * @retval 待发送的数据
  */
uint8_t Add_Tx1Item(uint8_t ch)
{
        //发送队列满。发送队列满
    while(Tx1_Counter == TX1_BUFFER_SIZE);        
        
    //压入数据
    Tx1_Buffer[Tx1_WriteIndex] = ch;
    //发送缓冲区写计数器移动
    Tx1_WriteIndex ++;
    if( Tx1_WriteIndex >= TX1_BUFFER_SIZE )
        {
            //写指针移动到队列头部        
                Tx1_WriteIndex = 0;                                
        }
    //数据总数增加
    Tx1_Counter++;
        
    //使能发送中断
        USART_ITConfig(USART1,USART_IT_TXE,ENABLE);
   
        return Tx1_WriteIndex;        
}
/**
  * @brief  返回发送队列中的字节数
  * @param  无
  * @retval 发送队列中的字节数
  */
uint8_t Get_Tx1BufCounter(void)
{
    return Tx1_Counter;
}

/**
  * @brief  从接收队列中取出数据.
  * @param  None
  * @retval 被取出数据
  */
uint8_t Get_Rx1Item(void)
{
        uint8_t Rx1_Data;
   
        //等待,需要修改
        while(Rx1_Counter == 0);
   
        //从队列中读取数据
        Rx1_Data = Rx1_Buffer[Rx1_ReadIndex];
    //接收缓冲区读指针移动
        Rx1_ReadIndex ++;
        if(Rx1_ReadIndex >= RX1_BUFFER_SIZE)
        {
                Rx1_ReadIndex = 0;
        }
    //
        Rx1_Counter --;

        return Rx1_Data;        
}

/**
  * @brief  返回接收队列中的字节数
  * @param  无
  * @retval 接收队列中的字节数
  */
uint8_t Get_Rx1BufCounter(void)
{
    return Rx1_Counter;
}

/**
  * @brief  清空发送队列
  * @param  无
  * @retval 无
  */
void Clear_Tx1Buf(void)
{
    for(uint8_t i = 0 ; i < TX1_BUFFER_SIZE ; i++)
    {
        Tx1_Buffer = 0;
    }
    Tx1_Counter = 0;
}
/**
  * @brief  清空接收队列
  * @param  无
  * @retval 无
  */
void Clear_Rx1Buf(void)
{
    for(uint8_t i = 0 ; i < RX1_BUFFER_SIZE ; i++)
    {
        Rx1_Buffer = 0;
    }
   
    Rx1_Counter = 0;
}

/**
  * @brief  USART1中断.
  * @param  None
  * @retval None
  */
void USART1_IRQHandler(void)
{
          uint8_t ch;
        
    //接收中断
        if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
          {
                //读取数据
                ch = USART_ReceiveData(USART1);               
        
        //清除接收中断标志位
        //USART_ClearFlag(USART1,USART_FLAG_RX1NE);
        //接收缓冲区数据个数递增
                Rx1_Counter++;        
        
                //数据填入接收队列
                Rx1_Buffer[Rx1_WriteIndex] = ch;
        
                Rx1_WriteIndex ++;
                if(Rx1_WriteIndex >= RX1_BUFFER_SIZE)
                {
                        Rx1_WriteIndex = 0;
                }

                //队列溢出
                if(Rx1_Counter >= RX1_BUFFER_SIZE)
                {
                        //数据作废,修改
                        //Rx1_Counter = 0;
                        //溢出标志置位
                        Rx1_BufOverflow = 1;
                }

          }
   
        //发送中断
        if(USART_GetITStatus(USART1, USART_IT_TXE) != RESET)
          {
                //清除接收中断标志位
                //USART_ClearFlag(USART1,USART_FLAG_TX1E);
                //存在未发送的数据
                if(Tx1_Counter > 0)
                {
                        //发送数据
                        USART_SendData(USART1, Tx1_Buffer[Tx1_ReadIndex]);
            //发送数据总数递减
                        Tx1_Counter --;
                        Tx1_ReadIndex++;
                        //回到缓冲区开头
                        if(Tx1_ReadIndex >= TX1_BUFFER_SIZE)
                        {
                                Tx1_ReadIndex = 0;
                        }
                }
        else
        {
            //无发送数据,关闭发送中断
            USART_ITConfig(USART1,USART_IT_TXE,DISABLE);;  
        }
          }
}


int fputc(int ch, FILE * f)
{
    //通过串口发送数据  
    Add_Tx1Item((uint8_t)ch);
   
    return ch;
}


使用特权

评论回复
11
sjg142729|  楼主 | 2015-10-29 09:07 | 只看该作者
非常感谢两位
但没有stm8采集sht10的程序吗

使用特权

评论回复
12
sun1238898| | 2015-10-29 10:03 | 只看该作者
SHT10和SHT11的时序是一样的,只是精度不一样而已。楼主不要迟疑。

使用特权

评论回复
13
september7| | 2015-10-29 19:28 | 只看该作者
734774645 发表于 2015-10-28 17:31
楼上的发错了那个是SHT21,楼主要的是SHT11,我来发个例程。
----------------

赞一个!

使用特权

评论回复
14
734774645| | 2015-10-29 19:48 | 只看该作者

举手之劳。

使用特权

评论回复
15
尤彼卡| | 2015-10-29 19:51 | 只看该作者
SHTxx系列单芯片传感器是一款含有已校准数字信号输出的温湿度复合传感器
有没有原理图呢

使用特权

评论回复
16
sjg142729|  楼主 | 2015-11-1 15:05 | 只看该作者
有没有寄存器版本的?

使用特权

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

本版积分规则

1

主题

3

帖子

0

粉丝