zoukankan      html  css  js  c++  java
  • DS18B20实验:神舟IV

    DS18B20是由DALLAS半导体公司推出的一种的“一线总线”接口的温度传感器

    移植了正点原子的驱动,单总线时序,在神舟IV进行验证,只改动了读取函数,之前返回short类型,我改成了float,正点原子在小数显示时用了/10,我没用液晶直接串口输出,printf %f  原子地址:http://openedv.com/posts/list/13366.htm

    神舟板子上使用PE1作为DS18B20的DQ

    另:DS18B20可以总线挂很多传感器,ROM指令也有四五个,可以查询,操作特定的某个器件,我这里只用了一颗DS18B20,所以用了最简单的初始化,读取温度值流程。

    .h
    1 //PE1作为DS18B20的DQ pin
    2 #define DS18B20_OUT_High  GPIO_SetBits(GPIOE, GPIO_Pin_1) 
    3 #define DS18B20_OUT_Low   GPIO_ResetBits(GPIOE, GPIO_Pin_1)
    4 #define    DS18B20_DQ_IN      GPIO_ReadInputDataBit(GPIOE, GPIO_Pin_1)
    DS18B20_IO
     1 //PE1作为DS18B20的DQ pin
     2 void DS18B20_IO_OUT(void)
     3 {
     4     GPIO_InitTypeDef GPIO_InitStructure;
     5     //推挽输出
     6     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
     7     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;    
     8     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;    
     9     GPIO_Init(GPIOE, &GPIO_InitStructure);
    10 }
    11 
    12 void DS18B20_IO_IN(void)
    13 {
    14     GPIO_InitTypeDef GPIO_InitStructure;
    15   //上拉输入
    16     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
    17     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;        
    18     GPIO_Init(GPIOE, &GPIO_InitStructure);
    19 }
    DS18B20_Rst
    1 //复位DS18B20
    2 void DS18B20_Rst(void)       
    3 {                 
    4     DS18B20_IO_OUT(); //SET PA0 OUTPUT
    5     DS18B20_OUT_Low; //拉低DQ
    6     delay_us(750);    //拉低750us
    7     DS18B20_OUT_High; //DQ=1 
    8     delay_us(15);     //15US
    9 }
    DS18B20_Check
     1 //等待DS18B20的回应
     2 //返回1:未检测到DS18B20的存在
     3 //返回0:存在
     4 u8 DS18B20_Check(void)        
     5 {   
     6     u8 retry=0;
     7     DS18B20_IO_IN();//SET PA0 INPUT     
     8     while (DS18B20_DQ_IN&&retry<200)
     9     {
    10         retry++;
    11         delay_us(1);
    12     };     
    13     if(retry>=200)return 1;
    14     else retry=0;
    15     while (!DS18B20_DQ_IN&&retry<240)
    16     {
    17         retry++;
    18         delay_us(1);
    19     };
    20     if(retry>=240)return 1;        
    21     return 0;
    22 }
    DS18B20_Init
     1 //初始化DS18B20的IO口 DQ 同时检测DS的存在
     2 //返回1:不存在
     3 //返回0:存在         
     4 u8 DS18B20_Init(void)
     5 {
     6      GPIO_InitTypeDef  GPIO_InitStructure;
     7      
     8      RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE);     //使能PORTG口时钟 
     9     
    10      GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;                //PORTG.11 推挽输出
    11      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;           
    12      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    13      GPIO_Init(GPIOG, &GPIO_InitStructure);
    14 
    15      GPIO_SetBits(GPIOE,GPIO_Pin_1);    //输出1
    16 
    17     DS18B20_Rst();
    18 
    19     return DS18B20_Check();
    20 } 
    DS18B20_Read_Bit
     1 //从DS18B20读取一个位
     2 //返回值:1/0
     3 u8 DS18B20_Read_Bit(void)              // read one bit
     4 {
     5     u8 data;
     6     DS18B20_IO_OUT();//SET PA0 OUTPUT
     7     DS18B20_OUT_Low; 
     8     delay_us(2);
     9     DS18B20_OUT_High; 
    10     DS18B20_IO_IN();//SET PA0 INPUT
    11     delay_us(12);
    12     if(DS18B20_DQ_IN)data=1;
    13     else data=0;     
    14     delay_us(50);           
    15     return data;
    16 }
    DS18B20_Read_Byte
     1 //从DS18B20读取一个字节
     2 //返回值:读到的数据
     3 u8 DS18B20_Read_Byte(void)    // read one byte
     4 {        
     5     u8 i,j,dat;
     6     dat=0;
     7     for (i=1;i<=8;i++) 
     8     {
     9         j=DS18B20_Read_Bit();
    10         dat=(j<<7)|(dat>>1);
    11     }                            
    12     return dat;
    13 }
    DS18B20_Write_Byte
     1 //写一个字节到DS18B20
     2 //dat:要写入的字节
     3 void DS18B20_Write_Byte(u8 dat)     
     4  {             
     5     u8 j;
     6     u8 testb;
     7     DS18B20_IO_OUT();//SET PA0 OUTPUT;
     8     for (j=1;j<=8;j++) 
     9     {
    10         testb=dat&0x01;
    11         dat=dat>>1;
    12         if (testb) 
    13         {
    14             DS18B20_OUT_Low;// Write 1
    15             delay_us(2);                            
    16             DS18B20_OUT_High;
    17             delay_us(60);             
    18         }
    19         else 
    20         {
    21             DS18B20_OUT_Low;// Write 0
    22             delay_us(60);             
    23             DS18B20_OUT_High;
    24             delay_us(2);                          
    25         }
    26     }
    27 }
    DS18B20_Start
    1 //开始温度转换
    2 void DS18B20_Start(void)// ds1820 start convert
    3 {                                          
    4     DS18B20_Rst();       
    5     DS18B20_Check();     
    6     DS18B20_Write_Byte(0xcc);// skip rom
    7     DS18B20_Write_Byte(0x44);// convert
    8 } 
    DS18B20_Get_Temp
     1 //从ds18b20得到温度值
     2 //精度:0.1C
     3 //返回值:温度值 (-550~1250) 
     4 float DS18B20_Get_Temp(void)
     5 {
     6     float result;
     7     u8 temp;
     8     u8 TL,TH;
     9     short tem;
    10     DS18B20_Start ();                    // ds1820 start convert
    11     DS18B20_Rst();
    12     DS18B20_Check();     
    13     DS18B20_Write_Byte(0xcc);// skip rom
    14     DS18B20_Write_Byte(0xbe);// convert        
    15     TL=DS18B20_Read_Byte(); // LSB   
    16     TH=DS18B20_Read_Byte(); // MSB  
    17               
    18     if(TH>7)
    19     {
    20         TH=~TH;
    21         TL=~TL; 
    22         temp=0;//温度为负  
    23     }else temp=1;//温度为正            
    24     tem=TH; //获得高八位
    25     tem<<=8;    
    26     tem+=TL;//获得底八位
    27 //  tem=(float)tem*0.0625;//转换 
    28 //    if(temp)return tem; //返回温度值
    29 //    else return -tem;  
    30     
    31     result=tem*0.0625;//转换
    32     if(temp)return result; //返回温度值
    33     else return -result;  
    34       
    35 } 

    我们只需用两个函数DS18B20_Get_Temp和DS18B20_Init

    main中调用DS18B20_Init()

    之后我在按键2中断中读取温度输出

    key2
     1 extern u8 DS18B20Init_Flag;
     2 void EXTI15_10_IRQHandler(void)
     3 {
     4   /* key2 */
     5   //以下代码实现按键2按下后在串口打印出当前时间
     6   if(EXTI_GetITStatus(EXTI_Line10) != RESET)
     7   {
     8     Led_Turn_off_all();
     9     Led_Turn_on_2();
    10     printf("\n\r Key 2 interrupt \n\r");
    11     printf("\n\r Now is %d年 %d月 %d日 %d点 %d分 %d秒 ,星期%d\n\r",calendar.w_year,calendar.w_month,calendar.w_date,calendar.hour,calendar.min,calendar.sec,calendar.week);
    12     
    13     if(DS18B20Init_Flag)     printf("\r\n 当前温度值:%3.2f° \n\r",DS18B20_Get_Temp());
    14     else printf("\r\n 温度传感器DS18B20初始化失败 \n\r");
    15     /* Clear the EXTI Line 10 */  
    16     EXTI_ClearITPendingBit(EXTI_Line10);
    17   }
    18   

    效果还不错

  • 相关阅读:
    微信小程序 --- 获取当前坐标
    微信小程序 --- 缓存数据
    微信小程序 --- 音乐的播放和控制
    微信小程序 --- webSocket
    微信小程序 --- 文件的上传和下载
    微信小程序 --- 选择图片和拍照
    微信小程序 --- loading提示框
    微信小程序 --- toast消息提示框
    Atitit.attilax软件研发与项目管理之道
    Atitit.attilax软件研发与项目管理之道
  • 原文地址:https://www.cnblogs.com/wwjdwy/p/3019832.html
Copyright © 2011-2022 走看看