第七次作业:
	
		#define  "ds18b20.h"
	
	
		#define "delay.h"
	
	
		#include "sys.h"
	
	
		#include "usart.h"
	
	
		#include "led.h"
	
	
		#include "lcd.h"
	
	
		void DS18B20_Rst(void)
	
	
		{
	
	
		DS18B20_IO_OUT(); //SET PG11 OUTPUT
	
	
		DS18B20_DQ_OUT=0;                       //拉低 DQ
	
	
		delay_us(750);                                    //拉低 750us
	
	
		DS18B20_DQ_OUT=1;                       //DQ=1
	
	
		delay_us(15); //15US
	
	
		}
	
	
		//等待 DS18B20 的回应
	
	
		//返回 1:未检测到 DS18B20 的存在
	
	
		//返回 0:存在
	
	
		u8 DS18B20_Check(void)
	
	
		{
	
	
		u8 retry=0;
	
	
		DS18B20_IO_IN();//SET PG11 INPUT
	
	
		while (DS18B20_DQ_IN&&retry<200) { retry++; delay_us(1); };
	
	
		if(retry>=200)return 1;
	
	
		else retry=0;
	
	
		while (!DS18B20_DQ_IN&&retry<240) {retry++; delay_us(1); };
	
	
		if(retry>=240)return 1;
	
	
		return 0;
	
	
		}
	
	
		//从 DS18B20 读取一个位
	
	
		//返回值:1/0
	
	
		u8 DS18B20_Read_Bit(void)
	
	
		{
	
	
		u8 data;
	
	
		DS18B20_IO_OUT();//SET PG11 OUTPUT
	
	
		DS18B20_DQ_OUT=0;
	
	
		delay_us(2);
	
	
		DS18B20_DQ_OUT=1;
	
	
		DS18B20_IO_IN();//SET PG11 INPUT
	
	
		delay_us(12);
	
	
		if(DS18B20_DQ_IN)data=1;
	
	
		else data=0;
	
	
		delay_us(50);
	
	
		return data;
	
	
		}
	
	
		//从 DS18B20 读取一个字节
	
	
		//返回值:读到的数据
	
	
		u8 DS18B20_Read_Byte(void)
	
	
		{
	
	
		u8 i,j,dat;
	
	
		dat=0;
	
	
		for (i=1;i<=8;i++)
	
	
		{
	
	
		j=DS18B20_Read_Bit();
	
	
		dat=(j<<7)|(dat>>1);
	
	
		}
	
	
		return dat;
	
	
		}
	
	
		//写一个字节到 DS18B20
	
	
		//dat:要写入的字节
	
	
		void DS18B20_Write_Byte(u8 dat)
	
	
		{
	
	
		u8 j;
	
	
		u8 testb;
	
	
		DS18B20_IO_OUT();//SET PG11 OUTPUT;
	
	
		for (j=1;j<=8;j++)
	
	
		{
	
	
		testb=dat&0x01;
	
	
		dat=dat>>1;
	
	
		if (testb)
	
	
		{
	
	
		DS18B20_DQ_OUT=0;// Write 1
	
	
		delay_us(2);
	
	
		DS18B20_DQ_OUT=1;
	
	
		delay_us(60);
	
	
		}
	
	
		else
	
	
		{
	
	
		DS18B20_DQ_OUT=0;// Write 0
	
	
		delay_us(60);
	
	
		DS18B20_DQ_OUT=1;
	
	
		delay_us(2);
	
	
		}
	
	
		}
	
	
		}
	
	
		//开始温度转换
	
	
		void DS18B20_Start(void)
	
	
		{
	
	
		DS18B20_Rst();
	
	
		DS18B20_Check();
	
	
		DS18B20_Write_Byte(0xcc);// skip rom
	
	
		DS18B20_Write_Byte(0x44);// convert
	
	
		}
	
	
		//初始化 DS18B20 的 IO 口 DQ 同时检测 DS 的存在
	
	
		//返回 1:不存在
	
	
		//返回 0:存在
	
	
		u8 DS18B20_Init(void)
	
	
		{
	
	
		GPIO_InitTypeDef GPIO_InitStructure;
	
	
		RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOG, ENABLE);  //使能 GPIOG 时钟
	
	
		//GPIOG9
	
	
		GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
	
	
		GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;                  //普通输出模式
	
	
		GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;                   //推挽输出
	
	
		GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;             //50MHz
	
	
		GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;                       //上拉
	
	
		GPIO_Init(GPIOG, &GPIO_InitStructure);                                     //初始化
	
	
		DS18B20_Rst();
	
	
		return DS18B20_Check();
	
	
		}
	
	
		//从 ds18b20 得到温度值
	
	
		//精度:0.1C
	
	
		//返回值:温度值 (-550~1250)
	
	
		short DS18B20_Get_Temp(void)
	
	
		{
	
	
		u8 temp;
	
	
		u8 TL,TH;
	
	
		short tem;
	
	
		DS18B20_Start();// ds1820 start convert
	
	
		DS18B20_Rst();
	
	
		DS18B20_Check();
	
	
		DS18B20_Write_Byte(0xcc);// skip rom
	
	
		DS18B20_Write_Byte(0xbe);// convert
	
	
		TL=DS18B20_Read_Byte(); // LSB
	
	
		TH=DS18B20_Read_Byte(); // MSB
	
	
		if(TH>7)
	
	
		{
	
	
		TH=~TH;
	
	
		TL=~TL;
	
	
		temp=0;                               //温度为负
	
	
		}else temp=1;                       //温度为正
	
	
		tem=TH;                              //获得高八位
	
	
		tem<<=8;
	
	
		tem+=TL;                             //获得底八位
	
	
		tem=(double)tem*0.625;      //转换
	
	
		if(temp)return tem;               //返回温度值
	
	
		else return -tem;
	
	
		}
	
	
		//ds18b20.h
	
	
		#ifndef__DS18B20_H
	
	
		#define__DS18B20_H
	
	
		#include"sys.h"
	
	
		#include"sys.h"
	
	
		//IO方向设置
	
	
		#define DS18B20_IO_IN() {GPIOG->MODERA=~(3<<(9*2));GPIOG->MODERA=~(0<<(9*2))} //PG9输入模式
	
	
		#define DS18B20_IO_OUT() {GPIOG->MODERA=~(3<<(9*2));GPIOG->MODERA=~(0<<(9*2))} //PG9输出模式
	
	
		//IO操作函数
	
	
		#define DS18B20_DQ_IN PGout(9)       //数据端口 PG9
	
	
		#define DS18B20_DQ_OUT PGout(9)    //数据端口PG9
	
	
		u8 DS18B20_Init(void);                          //初始化DS18B20
	
	
		short DS18B20_Get_Temp(void);            //获取温度
	
	
		void DS18B20_Start(void);              //开始温度转换
	
	
		void DS18B20_Write_Byte(u8 dat);  //写 入一个字节
	
	
		u8 DS18B20_Read_Byte(void);         //读出一个字节
	
	
		u8 DS18B20_Read_Bit(void);            //读出一个位
	
	
		u8 DS18B20_Check(void);                //检测是否存在DS18B20
	
	
		void DS18B20_Rst(void);                  //复位DS18B20
	
	
		
	
	
		int main(void)
	
	
		{
	
	
		u8 t=0;
	
	
		short temperature;
	
	
		NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);    //设置系统中断优先级分组2
	
	
		delay_init(168);                                                          //初始化延时函数
	
	
		uart_init(115200);                                                      //初始化串口波特率为115200
	
	
		
	
	
		LED_Init();                                                                             //初始化LED
	
	
		LCD_Init();
	
	
		POINT_COLOR=RED;                                                          //设置字体为红色
	
	
		LCD_ShowString(30,50,200,16,16,"Explorer STM32F4");
	
	
		LCD_ShowString(30,70,200,16,16,"DS18B20 TEST");
	
	
		LCD_ShowString(30,90,200,16,16,"ATOM@ALIENTEK");
	
	
		LCD_ShowString(30,110,200,16,16,"2014/5/7");
	
	
		while(DS18B20_Init())                                                           //DS18B20初始化
	
	
		{
	
	
		LCD_ShowString(30,130,200,16,16,"DS18B20 Error");
	
	
		delay_ms(200);
	
	
		LCD_Fill(30,130,239,130+16,WHITE);
	
	
		delay_ms(200);
	
	
		}
	
	
		LCD_ShowString(30,130,200,16,16,"DS18B20 OK");
	
	
		POINT_COLOR=BLUE;                                                        //设置字体为蓝色
	
	
		LCD_ShowString(30,150,200,16,16,"Temp:   . C");
	
	
		while(1)
	
	
		{
	
	
		if(t%10==0)//每100ms读取一次
	
	
		{
	
	
		temperature=DS18B20_Get_Temp();
	
	
		if(temperature<0)
	
	
		{
	
	
		LCD_ShowChar(30+40,150,'-',16,0);                                       //显示负号
	
	
		temperature=-temperature;                                                   //转为正数
	
	
		}else LCD_ShowChar(30+40,150,' ',16,0);                                //去掉负号
	
	
		LCD_ShowNum(30+40+8,150,temperature/10,2,16);            //显示正数部分
	
	
		LCD_ShowNum(30+40+32,150,temperature%10,1,16);     //显示小数部分
	
	
		}
	
	
		delay_ms(10);
	
	
		t++;
	
	
		if(t==20)
	
	
		{
	
	
		t=0;
	
	
		LED0=!LED0;
	
	
		}
	
	
		}
	
	
		}