博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
STM32 f407 温湿度采集报警
阅读量:5265 次
发布时间:2019-06-14

本文共 43026 字,大约阅读时间需要 143 分钟。

软件

keil5

实现

1.使用stm32f407中的DS18B20传感器采集空气温度

2.使用stm32f407中的DHT11传感器采集空气的温度和湿度
3.显示到stm32f407的LCD液晶显示器上
4.当温度超过30℃时,led灯 和 电磁继电器控制的灯闪烁,蜂鸣器持续响
5.当温度低于30℃时,一切恢复

效果

效果

源码

main.c

#include "led.h"#include "button.h"#include "buzzer.h"#include "delay.h"#include "lcd.h"#include "ds18b20.h"#include "dht11.h"#define WAR_T 30int main(void)    {     int yan;    char buf[10];    char dht[5];    delay_init();    LCD_Init();    buzzer_init();    //320 * 240    DS18B20_Init();    dht_init();    LCD_Clear(0x01CF);    BRUSH_COLOR = WHITE;    BACK_COLOR = 0x1f << 11;    //BACK_COLOR = BLACK;    //LCD_DisplayString(30, 50, 24, (u8 *)" 0.0 ");    LCD_DisplayMyname(10,200);      //Ãû×Ö    LCD_Draw_Rectangle(1, 1, 318, 238);    LCD_Draw_Line( 110,1 ,110 ,160 );    LCD_Draw_Line( 220,1 ,220 ,160 );    LCD_Draw_Line( 1,120 ,220 ,120 );    LCD_Draw_Line( 1,160 ,318 ,160 );        LCD_DisplayString(10, 70, 16, (u8 *)"PM2.5 ug/m3");    LCD_DisplayString(125, 70, 16, (u8 *)"HCHO mg/m3");    LCD_DisplayString(260, 170, 24, (u8 *)"TIME");    LCD_DisplayString(220, 200, 24, (u8 *)"12 : 00");    LCD_DisplayString(30, 175, 24, (u8 *)"WELCOME !");        LCD_DisplayTu1(225,20);    LCD_DisplayTu2(225,100);        //for(yan=0xF800;yan<=0xFFE0;yan++);    LCD_Draw_Rectangle(10, 90, 90, 100);    LCD_Draw_Rectangle(125, 90, 210, 100);    LCD_Fill_onecolor(10, 95, 90, 100,yan);    LCD_Fill_onecolor(125, 95, 210, 100,yan);        while(1)    {        int i;        get_temperature(buf);        LCD_DisplayString(225, 50, 24, (u8 *)buf);        LCD_DisplayOTherChar(295,50,0,24);//温度符号        dht_get_data(dht);        LCD_DisplayNum(285, 100, dht[0], 2, 24, 0);        LCD_DisplayNum(285, 20, dht[2], 2, 24, 0);        //if( buf[1] >= '0'+2 && buf[2] >= 9+'0')        delay_ms(500);    }}

led.h

#ifndef __LED_H#define __LED_H#include "stm32f4xx_conf.h"/*    LED0    PE3    LED1    PE4    LED2    PG9    GPIO管脚输出高电压时灯灭 低电压时亮    1.对于GPIO管脚打开时钟*/#define GPIOE_MODER     (*(volatile unsigned int *)(GPIOE_BASE + 0x00))#define GPIOE_OTYPER    (*(volatile unsigned int *)(GPIOE_BASE + 0x04))#define GPIOE_OSPEEDR   (*(volatile unsigned int *)(GPIOE_BASE + 0x08))#define GPIOE_PUPDR     (*(volatile unsigned int *)(GPIOE_BASE + 0x0C))#define GPIOE_ODR       (*(volatile unsigned int *)(GPIOE_BASE + 0x14))#define GPIOG_MODER (*(volatile unsigned int *)(GPIOG_BASE + 0x00))#define GPIOG_OTYPER    (*(volatile unsigned int *)(GPIOG_BASE + 0x04))#define GPIOG_OSPEEDR   (*(volatile unsigned int *)(GPIOG_BASE + 0x08))#define GPIOG_PUPDR     (*(volatile unsigned int *)(GPIOG_BASE + 0x0C))#define GPIOG_ODR       (*(volatile unsigned int *)(GPIOG_BASE + 0x14))extern void led_init(void);extern void led_on(int no);extern void led_off(int no);#endif

led.c

#include "led.h"#include "bitband.h"void led_init(void)    {    GPIO_InitTypeDef LED;    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE | RCC_AHB1Periph_GPIOG, ENABLE);        LED.GPIO_Mode = GPIO_Mode_OUT;    LED.GPIO_OType = GPIO_OType_PP;    LED.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_4;    LED.GPIO_PuPd = GPIO_PuPd_NOPULL;    LED.GPIO_Speed = GPIO_Fast_Speed;        GPIO_Init(GPIOE, &LED);    LED.GPIO_Pin = GPIO_Pin_9;    GPIO_Init(GPIOG, &LED);    GPIO_SetBits(GPIOE, GPIO_Pin_3 | GPIO_Pin_4);    GPIO_SetBits(GPIOG, GPIO_Pin_9);}void led_on(int no)    {    switch(no)  {        case 0 :            PGOut(9) = 0;            break;        case 1 :            PEOut(4) = 0;            break;        case 2 :            PEOut(3) = 0;            break;        default:            break;    }}void led_off(int no)    {    switch(no)  {        case 0 :            PGOut(9) = 1;            break;        case 1 :            PEOut(4) = 1;            break;        case 2 :            PEOut(3) = 1;            break;        default:            break;    }}

button.h

#ifndef __BUTTON_H#define __BUTTON_H#include "stm32f4xx_conf.h"extern void button_init(void);extern int button_state(int);#endif

button.c

#include "button.h"#include "bitband.h"// PF9 PF8 PF7 PE6//按键按下是1 抬起是0void button_init(void)    {    GPIO_InitTypeDef BUTTON;        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE | RCC_AHB1Periph_GPIOF, ENABLE);        BUTTON.GPIO_Mode = GPIO_Mode_IN;    BUTTON.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9;    BUTTON.GPIO_PuPd = GPIO_PuPd_NOPULL;        GPIO_Init(GPIOF, &BUTTON);        BUTTON.GPIO_Pin = GPIO_Pin_6;    GPIO_Init(GPIOE, &BUTTON);}int button_state(int no)    {    int ret;        switch(no)  {        case 0 :             ret = PFIn(9);            break;        case 1 :            ret = PFIn(8);            break;        case 2 :            ret = PFIn(7);            break;        case 3 :            ret = PEIn(6);            break;        default:            ret = 1;            break;    }   return !ret;}

buzzer.h

#ifndef __BUZZER_H#define __BUZZER_H#include "stm32f4xx_conf.h"extern void buzzer_init(void);extern void buzzer_on(void);extern void buzzer_off(void);#endif

buzzer.c

#include "buzzer.h"#include "bitband.h"//pd7void buzzer_init(void)    {    GPIO_InitTypeDef BUZZER;    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);        BUZZER.GPIO_Mode = GPIO_Mode_OUT;    BUZZER.GPIO_OType = GPIO_OType_PP;    BUZZER.GPIO_Pin = GPIO_Pin_7;    BUZZER.GPIO_PuPd = GPIO_PuPd_NOPULL;    BUZZER.GPIO_Speed = GPIO_Fast_Speed;        GPIO_Init(GPIOD, &BUZZER);    GPIO_ResetBits(GPIOD, GPIO_Pin_7);}void buzzer_on(void)    {    PDOut(7) = 1;}void buzzer_off(void)    {    PDOut(7) = 0;}

delay.h

#ifndef __DELAY_H#define __DELAY_H              #include "stm32f4xx.h" typedef uint32_t  u32;typedef uint16_t  u16;typedef uint8_t   u8;#define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr &0xFFFFF)<<5)+(bitnum<<2)) #define MEM_ADDR(addr)  *((volatile unsigned long  *)(addr)) #define BIT_ADDR(addr, bitnum)   MEM_ADDR(BITBAND(addr, bitnum)) //GPIO#define GPIOA_ODR_Addr    (GPIOA_BASE+20) //0x40020014#define GPIOB_ODR_Addr    (GPIOB_BASE+20) //0x40020414 #define GPIOC_ODR_Addr    (GPIOC_BASE+20) //0x40020814 #define GPIOD_ODR_Addr    (GPIOD_BASE+20) //0x40020C14 #define GPIOE_ODR_Addr    (GPIOE_BASE+20) //0x40021014 #define GPIOF_ODR_Addr    (GPIOF_BASE+20) //0x40021414    #define GPIOG_ODR_Addr    (GPIOG_BASE+20) //0x40021814   #define GPIOH_ODR_Addr    (GPIOH_BASE+20) //0x40021C14    #define GPIOI_ODR_Addr    (GPIOI_BASE+20) //0x40022014     //GPIO#define GPIOA_IDR_Addr    (GPIOA_BASE+16) //0x40020010 #define GPIOB_IDR_Addr    (GPIOB_BASE+16) //0x40020410 #define GPIOC_IDR_Addr    (GPIOC_BASE+16) //0x40020810 #define GPIOD_IDR_Addr    (GPIOD_BASE+16) //0x40020C10 #define GPIOE_IDR_Addr    (GPIOE_BASE+16) //0x40021010 #define GPIOF_IDR_Addr    (GPIOF_BASE+16) //0x40021410 #define GPIOG_IDR_Addr    (GPIOG_BASE+16) //0x40021810 #define GPIOH_IDR_Addr    (GPIOH_BASE+16) //0x40021C10 #define GPIOI_IDR_Addr    (GPIOI_BASE+16) //0x40022010  #define PAOut(n)   BIT_ADDR(GPIOA_ODR_Addr,n)#define PAIn(n)    BIT_ADDR(GPIOA_IDR_Addr,n) #define PBOut(n)   BIT_ADDR(GPIOB_ODR_Addr,n) #define PBIn(n)    BIT_ADDR(GPIOB_IDR_Addr,n) #define PCOut(n)   BIT_ADDR(GPIOC_ODR_Addr,n)  #define PCIn(n)    BIT_ADDR(GPIOC_IDR_Addr,n) #define PDOut(n)   BIT_ADDR(GPIOD_ODR_Addr,n) #define PDIn(n)    BIT_ADDR(GPIOD_IDR_Addr,n) #define PEOut(n)   BIT_ADDR(GPIOE_ODR_Addr,n) #define PEIn(n)    BIT_ADDR(GPIOE_IDR_Addr,n) #define PFOut(n)   BIT_ADDR(GPIOF_ODR_Addr,n) #define PFIn(n)    BIT_ADDR(GPIOF_IDR_Addr,n)  #define PGOut(n)   BIT_ADDR(GPIOG_ODR_Addr,n) #define PGIn(n)    BIT_ADDR(GPIOG_IDR_Addr,n)  #define PHOut(n)   BIT_ADDR(GPIOH_ODR_Addr,n) #define PHIn(n)    BIT_ADDR(GPIOH_IDR_Addr,n) #define PIOut(n)   BIT_ADDR(GPIOI_ODR_Addr,n)  #define PIIn(n)    BIT_ADDR(GPIOI_IDR_Addr,n)  #define SYSCLK 168    //调用系统时钟    void delay_init(void);void delay_ms(u16 nms);void delay_us(u32 nus);#endif

delay.c

#include "delay.h"//利用系统定时,编写的延时函数static u8  fac_us=0; //us延时倍乘数             static u16 fac_ms=0; //ms延时倍乘数,在ucos下,代表每个街拍的ms数/***************************************************************************** 名称: delay_init()*功能:延时函数初始化* 入口参数:无* 返回参数:无****************************************************************************/void delay_init()    {    SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);    fac_us=SYSCLK/8;    fac_ms=(u16)fac_us*1000; //每个ms需要的systick时钟数}                                   /***************************************************************************** 名称: void delay_us(u32 nus)* 功能:延时nus* 入口参数:要延时的微秒数* 返回参数:无* 说明:nus的值 不要大于798915us****************************************************************************/void delay_us(u32 nus)    {         u32 midtime;                 SysTick->LOAD=nus*fac_us; //时间加载             SysTick->VAL=0x00;        //清空计数器    SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ;          //开始倒数    do  {        midtime=SysTick->CTRL;    }    while((midtime&0x01)&&!(midtime&(1<<16)));//等待时间到达     SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk;       //关闭计数器    SysTick->VAL =0X00;       //清空计数器 }/***************************************************************************** 名称: void delay_xms(u16 nms)* 功能:延时nms* 入口参数:要延时的毫秒数* 返回参数:无* 说明:SysTick->LOAD为24位寄存器,所以,最大延时为:nms<=0xffffff*8*1000/SYSCLK            对168M条件下nms<=798ms ****************************************************************************/void delay_xms(u16 nms)    {                      u32 midtime;               SysTick->LOAD=(u32)nms*fac_ms;//时间加载(SysTick->LOAD为24bit)    SysTick->VAL =0x00;           //清空计数器    SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ;          //开始倒数     do  {        midtime=SysTick->CTRL;    }    while((midtime&0x01)&&!(midtime&(1<<16)));//等待时间到达     SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk;       //关闭计数器    SysTick->VAL =0X00;       //清空计数器       } /***************************************************************************** 名称: void delay_ms(u16 nms)* 功能:延时nms* 入口参数:要延时的毫秒数* 返回参数:无* 说明:nms:0~65535****************************************************************************/void delay_ms(u16 nms)    {          u8 repeat=nms/540;  //这里用540,是考虑到某些地方可能超频使用                            //比如超频到248M的时候,delay_xms最大智能延时541ms左右了    u16 remain=nms%540;    while(repeat)   {        delay_xms(540);        repeat--;    }    if(remain)delay_xms(remain);}

lcd.h

#ifndef __LCD_H#define __LCD_H     #include "delay.h"   #include "stdlib.h"  //LCD驱动重要参数集extern  u16  lcd_id;         //LCD IDextern  u8   dir_flag;       //横屏还是竖屏控制:0,竖屏;1,横屏   extern  u16  lcd_width;      //LCD宽度extern  u16  lcd_height;     //LCD高度extern  u16  write_gramcmd;  //写gram指令extern  u16  setxcmd;            //设置x坐标指令extern  u16  setycmd;            //设置y坐标指令   //LCD的画笔颜色和背景色  extern u16  BRUSH_COLOR;//默认红色extern u16  BACK_COLOR; //背景颜色 默认为白色 //-----------------LCD背光端口定义---------------- #define LCD_BACK PDOut(3)//PFout(10)  //LCD背光       PF10        //根据硬件电路图可以看靠我们使用NOR/SRAM的Bank1.sector4,地址位 HADDR[27,26]=11//A12作为数据命令区分线//因为我们使用的是16位的数据高度,所以要注意设置时STM32内部会右移一位对齐       #define  CMD_BASE        ((u32)(0x6C000000 | 0x00000000))#define  DATA_BASE       ((u32)(0x6C000000 | 0x00002000))#define LCD_CMD       ( * (volatile u16 *) CMD_BASE )#define LCD_DATA      ( * (volatile u16 *) DATA_BASE)     //扫描方向定义#define L2R_U2D  0 //从左到右 从上到下#define L2R_D2U  1 //从左到右 从下到上#define R2L_U2D  2 //从右到左 从上到下#define R2L_D2U  3 //从右到左 从下到上#define U2D_L2R  4 //从上到下 从左到右#define U2D_R2L  5 //从上到下 从右到左#define D2U_L2R  6 //从下到上 从左到右#define D2U_R2L  7 //从下到上 从右到左#define INIT_SCAN_DIR  R2L_U2D   //设置初始化扫描方向//颜色值定义#define WHITE        0xFFFF#define BLACK        0x0000   #define BLUE         0x001F #define GREEN        0x07E0#define BRED         0XF81F#define GRED               0XFFE0#define GBLUE              0X07FF#define BROWN            0XBC40  #define BRRED            0XFC07  #define GRAY             0X8430  #define RED          0xF800#define MAGENTA      0xF81F#define CYAN         0x7FFF#define YELLOW       0xFFE0#define DARKBLUE         0X01CF //深蓝#define LIGHTBLUE        0X7D7C //浅蓝#define GRAYBLUE         0X5458 //灰蓝#define JBS        for(JBS=RED;JBS<=DARKBLUE;JBS++)void LCD_WriteReg(u16 LCD_Reg, u16 LCD_Value);u16 LCD_ReadReg(u16 LCD_Reg);void LCD_WriteRAM_Prepare(void);void LCD_Init(void);//初始化void LCD_DisplayOn(void);//开显示void LCD_DisplayOff(void);//关显示void LCD_Clear(u16 Color);//清屏void LCD_SetCursor(u16 Xpos, u16 Ypos);                     //设置光标void LCD_DrawPoint(u16 x,u16 y);                                    //画点void LCD_Color_DrawPoint(u16 x,u16 y,u16 color);    //颜色画点u16  LCD_GetPoint(u16 x,u16 y);                                   //读点void LCD_AUTOScan_Dir(u8 dir);                   void LCD_Display_Dir(u8 dir);                        void LCD_Set_Window(u16 sx,u16 sy,u16 width,u16 height);    void LCD_Draw_Circle(u16 x0,u16 y0,u8 r);   //画图void LCD_Draw_Line(u16 x1, u16 y1, u16 x2, u16 y2);//画线void LCD_Draw_Rectangle(u16 x1, u16 y1, u16 x2, u16 y2);            //画矩形void LCD_Fill_onecolor(u16 sx,u16 sy,u16 ex,u16 ey,u16 color);      //填充单个颜色void LCD_Draw_Picture(u16 sx,u16 sy,u16 ex,u16 ey,u16 *color);      //填充指定颜色void LCD_DisplayChar(u16 x,u16 y,u8 word,u8 size);                            //显示一个字符void LCD_DisplayOTherChar(u16 x,u16 y,u8 word,u8 size);                         //显示除ASCII之外的字符void LCD_DisplayNum(u16 x,u16 y,u32 num,u8 len,u8 size,u8 mode);                //显示 数字void LCD_DisplayNum_color(u16 x,u16 y,u32 num,u8 len,u8 size,u8 mode,u16 brushcolor,u16 backcolor); //显示自定义数字void LCD_DisplayString(u16 x,u16 y,u8 size,u8 *p);                 //显示一个12/16/24字体字符串void LCD_DisplayString_color(u16 x,u16 y,u8 size,u8 *p,u16 brushcolor,u16 backcolor); //显示一个12/16/24字体自定义颜色的字符串                                    void LCD_DisplayMyname(u16 x,u16 y);void LCD_DisplayTu1(u16 x,u16 y);void LCD_DisplayTu2(u16 x,u16 y);#endif

lcd.c

#include "lcd.h"#include "cfont.h"                        //初始化LCD的画笔颜色和背景色      u16 BRUSH_COLOR=BLACK;  //画笔颜色u16 BACK_COLOR=WHITE;  //背景色//管理LCD驱动重要参数  u16  lcd_id;          //LCD ID  u16  lcd_width;       //LCD的宽度  u16  lcd_height;      //LCD的高度  u16 write_gramcmd=0X2C;  u16 read_gramcmd = 0x2E;  u16 setxcmd=0X2A;  u16 setycmd=0X2B;      /***************************************************************************** 名称: void LCD_WriteReg(u16 LCD_Reg, u16 LCD_Value)* 功能:LCD写寄存器* 入口参数:LCD_Reg: 寄存器地址*              LCD_RegValue: 要写入的数据****************************************************************************/                  void LCD_WriteReg(u16 LCD_Reg, u16 LCD_Value)    {      LCD_CMD = LCD_Reg;       //写入要写的寄存器序号    LCD_DATA = LCD_Value;  //向寄存器写入的数据               }/***************************************************************************** 名称: u16 LCD_ReadReg(u16 LCD_Reg)* 功能:LCD读寄存器* 入口参数:LCD Reg:寄存器地址* 返回参数:督导该寄存器序号里的值     ****************************************************************************/   u16 LCD_ReadReg(u16 LCD_Reg)    {                                              LCD_CMD=LCD_Reg;        //写入要读的寄存器序号    delay_us(5);              return LCD_DATA;        //返回读到的值}   //开始写GRAMvoid LCD_WriteRAM_Prepare(void)    {    LCD_CMD=write_gramcmd;    }//lcd延时函数void lcdm_delay(u8 i)    {    while(i--);}//LCD开启显示void LCD_DisplayOn(void)    {                                 LCD_CMD=0x29;}   //LCD关闭显示void LCD_DisplayOff(void)    {             LCD_CMD=0x28;}   /*****************************************************************************名称: void LCD_SetCursor(u16 Xaddr, u16 Yaddr)* 功能:设置光标位置* 入口参数:x:x坐标      y:y坐标    ****************************************************************************/void LCD_SetCursor(u16 Xaddr, u16 Yaddr)    {                LCD_CMD=setxcmd;         LCD_DATA=(Xaddr>>8);         LCD_DATA=(Xaddr&0XFF);           LCD_CMD=setycmd;         LCD_DATA=(Yaddr>>8);         LCD_DATA=(Yaddr&0XFF);} /***************************************************************************** 名称: void LCD_AUTOScan_Dir(u8 dir)* 功能:设置LCD的自动扫描方向* 入口参数:dir:扫描方向  ****************************************************************************/      void LCD_AUTOScan_Dir(u8 dir)    {    u16 regval=0;    u16 dirreg=0;     switch(dir)    {        case L2R_U2D://从左到右 从上到下             regval|=(0<<7)|(0<<6)|(0<<5); break;        case L2R_D2U://从左到右 从下到上            regval|=(1<<7)|(0<<6)|(0<<5); break;        case R2L_U2D://从右到左 从上到下            regval|=(0<<7)|(1<<6)|(0<<5); break;        case R2L_D2U://从右到左 从下到上            regval|=(1<<7)|(1<<6)|(0<<5); break;             case U2D_L2R://从上到下 从左到右            regval|=(0<<7)|(0<<6)|(1<<5); break;        case U2D_R2L://从上到下 从右到左            regval|=(0<<7)|(1<<6)|(1<<5); break;        case D2U_L2R://从下到上 从左到右            regval|=(1<<7)|(0<<6)|(1<<5);break;        case D2U_R2L://从下到上 从右到左            regval|=(1<<7)|(1<<6)|(1<<5); break;         }    //设置扫描方法    dirreg=0X36;      regval|=0X08;           LCD_WriteReg(dirreg,regval);        LCD_CMD=setxcmd; //x的最小值    LCD_DATA=0;    LCD_DATA=0;//x的最大值    LCD_DATA=(lcd_width-1)>>8;    LCD_DATA=(lcd_width-1)&0XFF;    LCD_CMD=setycmd; //y的最小值    LCD_DATA=0;    LCD_DATA=0;//y的最大值    LCD_DATA=(lcd_height-1)>>8;    LCD_DATA=(lcd_height-1)&0XFF;  }/***************************************************************************** 名称: void LCD_Display_Dir(u8 dir)* 功能:这只LCD显示方向* 入口参数:dir: 0,竖屏  1,横屏****************************************************************************/void LCD_Display_Dir(u8 dir)    {     switch (dir) {        case L2R_U2D:        case L2R_D2U:        case R2L_U2D:        case R2L_D2U:            //先左右后上下的是竖屏            lcd_width=240;            lcd_height=320;             break;        default:            //先上下后左右的是横屏显示            lcd_width=320;            lcd_height=240;            break;    }        LCD_AUTOScan_Dir(dir);  //设置扫描方向}   /***************************************************************************** 名称: u16 LCD_GetPoint(u16 x,u16 y)* 读取某点的颜色值* 入口参数:x:x坐标   y:y坐标* 返回参数:此点的颜色****************************************************************************/u16 LCD_GetPoint(u16 x,u16 y)    {    vu16 r=0,g=0,b=0;    if(x>=lcd_width||y>=lcd_height)        return 0;    //超过了范围 直接返回          LCD_SetCursor(x,y);         LCD_CMD = read_gramcmd;   //9341 发送读GRAM指令                       if(LCD_DATA)        r=0;                            lcdm_delay(2);        r=LCD_DATA;                                  //实际坐标颜色        lcdm_delay(2);        b=LCD_DATA;     g=r&0XFF;        //对于9341第一次读取的是RG的值 R在前 G在后 个占8位    g<<=8;    return (((r>>11)<<11)|((g>>10)<<5)|(b>>11)); //ILI9341需要公式转换一下} /***************************************************************************** 名称: void LCD_DrawPoint(u16 x,u16 y)* 功能:画点(在该点写入画笔的颜色)* 入口参数:x:x坐标   y:y坐标* 返回参数:无* 说明 RUSH_COLOR:此点的颜色值****************************************************************************/void LCD_DrawPoint(u16 x,u16 y)    {    LCD_SetCursor(x,y);         //设置光标位置     LCD_WriteRAM_Prepare();   //开始写入GRAM    LCD_DATA=BRUSH_COLOR; }/***************************************************************************** 名称: void LCD_Color_DrawPoint(u16 x,u16 y,u16 color)* 功能:在设置的坐标除画相应颜色(在该点写入自定义颜色)* 入口参数:x:x坐标  y:y坐标            color 此点的颜色值*说明:color:写入此点的颜色值   UCGUI调用该函数****************************************************************************/void LCD_Color_DrawPoint(u16 x,u16 y,u16 color)    {                   LCD_CMD=setxcmd;         LCD_DATA=(x>>8);         LCD_DATA=(x&0XFF);           LCD_CMD=setycmd;         LCD_DATA=(y>>8);         LCD_DATA=(y&0XFF);              LCD_CMD=write_gramcmd;       LCD_DATA=color; }    /***************************************************************************** 名称: void LCD_Set_Window(u16 sx,u16 sy,u16 width,u16 height)* 功能:设置窗口,最后并设置画点坐标到窗口左上角(sx,sy)*入口参数:sx,sy:窗口起始坐标(左上角)     width,height:窗口宽度和高度*说明:窗口大小width*height.****************************************************************************/void LCD_Set_Window(u16 sx,u16 sy,u16 width,u16 height)    {       width=sx+width-1;    height=sy+height-1;    LCD_CMD=setxcmd;     LCD_DATA=(sx>>8);     LCD_DATA=(sx&0XFF);      LCD_DATA=(width>>8);     LCD_DATA=(width&0XFF);      LCD_CMD=setycmd;     LCD_DATA=(sy>>8);     LCD_DATA=(sy&0XFF);     LCD_DATA=(height>>8);     LCD_DATA=(height&0XFF); } /***************************************************************************** 名称: void LCD_Clear(u16 color)* 功能:清屏函数* 入口参数:color: 要清屏的填充色****************************************************************************/void LCD_Clear(u16 color)    {    u32 i=0;          u32 pointnum=0;        pointnum=lcd_width*lcd_height;   //得到LCD总点数    LCD_SetCursor(0x00,0x00);          //设置光标位置    LCD_WriteRAM_Prepare();              //开始写入GRAM           for(i=0;i
0)mcx=1; else if(model_x==0)mcx=0; //垂直线 else {mcx=-1;model_x=-model_x;} if(model_y>0)mcy=1; else if(model_y==0)mcy=0; //水平线 else{mcy=-1;model_y=-model_y;} if( model_x>model_y)model=model_x; else model=model_y; for(i=0;i<=model+1;i++ ) //画线输出 { LCD_DrawPoint(mRow,mCol); xm1+=model_x ; ym2+=model_y ; if(xm1>model) { xm1-=model; mRow+=mcx; } if(ym2>model) { ym2-=model; mCol+=mcy; } } }/***************************************************************************** 名称: void LCD_Draw_Rectangle(u16 x1, u16 y1, u16 x2, u16 y2)* 功能:画矩形 * 入口参数:(x1,y1),(x2,y2):矩形的对角坐标****************************************************************************/void LCD_Draw_Rectangle(u16 x1, u16 y1, u16 x2, u16 y2) { LCD_Draw_Line(x1,y1,x2,y1); LCD_Draw_Line(x1,y1,x1,y2); LCD_Draw_Line(x1,y2,x2,y2); LCD_Draw_Line(x2,y1,x2,y2);}/***************************************************************************** 名称: void LCD_Draw_Circle(u16 x0,u16 y0,u8 r)*功能:字指定位置画一个指定大小的圆* 入口参数:(x,y):中心点 r :半径****************************************************************************/void LCD_Draw_Circle(u16 x0,u16 y0,u8 r) { int a,b; int di; a=0;b=r; di=3-(r<<1); //判断下个点位置的标志 while(a<=b) { LCD_DrawPoint(x0+a,y0-b); LCD_DrawPoint(x0+b,y0-a); LCD_DrawPoint(x0+b,y0+a); LCD_DrawPoint(x0+a,y0+b); LCD_DrawPoint(x0-a,y0+b); LCD_DrawPoint(x0-b,y0+a); LCD_DrawPoint(x0-a,y0-b); LCD_DrawPoint(x0-b,y0-a); a++; if(di<0)di +=4*a+6; //使用Bresenham算法画圆 else { di+=10+4*(a-b); b--; } }} /***************************************************************************** 名称: void LCD_DisplayChar(u16 x,u16 y,u8 num,u8 size)* 功能:在指定位置显示一个字符* 入口参数:x,y:起始坐标 word:要显示的字符:abcdefg1234567890... size:字体大小 12/16/24*说明:取字模参考网上取字模方式,改字模取模方向为先从上到下,再从左到右****************************************************************************/void LCD_DisplayChar(u16 x,u16 y,u8 word,u8 size) { u8 bytenum,bytedata, a,b; u16 ymid=y; if(size==12) bytenum=12; // 判断各个字体子啊字库数组中占的字节数 else if(size==16) bytenum=16; else if(size==24) bytenum=36; else return; word=word-' '; //得到偏移后的值 因为空格之前的字符没在font.h中的数组里面 for(b=0;b
=lcd_height)return; //超区域 退出函数 if((y-ymid)==size) { y=ymid; x++; if(x>=lcd_width)return; //超区域 退出函数 break; } } } } /***************************************************************************** 名称: void LCD_DisplayOtherChar(u16 x,u16 y,u8 num,u8 size)* 功能:在指定位置显示一个除ASCII之外的字符* 入口参数:x,y:起始坐标 word:要显示的字符 0:摄氏度标志 size:字体大小 12/16/24* 说明:取字模参考网上 该字模取模方向为先从上到下 再从左到右****************************************************************************/void LCD_DisplayOTherChar(u16 x,u16 y,u8 word,u8 size) { u8 bytenum,bytedata, a,b; u16 ymid=y; if(size==12) bytenum=24; // 判断各个字体子啊字库数组中占的字节数 else if(size==16) bytenum=32; else if(size==24) bytenum=72; else return; for(b=0;b
=lcd_height)return; //超区域 退出函数 if((y-ymid)==size) { y=ymid; x++; if(x>=lcd_width)return; //超区域 退出函数 break; } } } } //m^n函数//返回值:m^n次方u32 LCD_Pow(u8 m,u8 n) { u32 mid=1; while(n--)mid*=m; return mid;}/***************************************************************************** 名称: : void LCD_DisplayNum(u16 x,u16 y,u32 num,u8 len,u8 size,u8 mode)* 功能: 在指定位置显示一串数字* 入口参数:x,y:起始坐标 num:数值(0~999999999); len:长度(即要显示的位数) size:字体大小 mode: 0:高位为0 不显示 1:高位为0显示0****************************************************************************/void LCD_DisplayNum(u16 x,u16 y,u32 num,u8 len,u8 size,u8 mode) { u8 t,numtemp; u8 end0=0; for(t=0;t
=' ')) //判断是不是非法字符! { LCD_DisplayChar(x,y,*p,size); x+=size/2; if(x>=lcd_width) break; p++; } }/*****************************************************************************名称: : void LCD_DisplayString(u16 x,u16 y,u8 size,u8 *p)* 功能: 显示自定义字符串* 入口参数:x,y:起始坐标* width,height:区域大小* size:字体大小* *p:字符串起始地址 * brushcolor:自定义画笔颜色* backcolor:自定义背景颜色****************************************************************************/ void LCD_DisplayString_color(u16 x,u16 y,u8 size,u8 *p,u16 brushcolor,u16 backcolor) { u16 bh_color,bk_color; bh_color=BRUSH_COLOR; //暂存画笔颜色 bk_color=BACK_COLOR; //暂存背景颜色 BRUSH_COLOR=brushcolor; BACK_COLOR=backcolor; LCD_DisplayString(x,y,size,p); BRUSH_COLOR=bh_color; //不改变系统颜色 BACK_COLOR=bk_color;}//配置FSMC可变静态存储控制器void LCD_FSMC_Config() { GPIO_InitTypeDef GPIO_InitStructure; FSMC_NORSRAMInitTypeDef FSMC_NORSRAMInitStructure; FSMC_NORSRAMTimingInitTypeDef readWriteTiming; FSMC_NORSRAMTimingInitTypeDef writeTiming; RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD|RCC_AHB1Periph_GPIOE|RCC_AHB1Periph_GPIOF|RCC_AHB1Periph_GPIOG, ENABLE);//使能PD PE PF PG时钟 RCC_AHB3PeriphClockCmd(RCC_AHB3Periph_FSMC,ENABLE);//使能FSMC时钟 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; //PF10 推挽输出 控制背光 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; //普通输出模式 GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //100MHz GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉 GPIO_Init(GPIOD, &GPIO_InitStructure); //初始化 // GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_14 | GPIO_Pin_15; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; //复用输出 GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉 GPIO_Init(GPIOD, &GPIO_InitStructure); //初始化 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; //复用输出 GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉­ GPIO_Init(GPIOE, &GPIO_InitStructure); //初始化 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //PG2,FSMC_A12 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; //¸´ÓÃÊä³ö GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //ÍÆÍìÊä³ö GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //ÉÏÀ­ GPIO_Init(GPIOG, &GPIO_InitStructure); //³õʼ»¯ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12; //PG12 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; //复用输出 GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉­­ GPIO_Init(GPIOG, &GPIO_InitStructure); //初始化 GPIO_PinAFConfig(GPIOD,GPIO_PinSource0,GPIO_AF_FSMC);//PD0,AF12 GPIO_PinAFConfig(GPIOD,GPIO_PinSource1,GPIO_AF_FSMC);//PD1,AF12 GPIO_PinAFConfig(GPIOD,GPIO_PinSource4,GPIO_AF_FSMC); GPIO_PinAFConfig(GPIOD,GPIO_PinSource5,GPIO_AF_FSMC); GPIO_PinAFConfig(GPIOD,GPIO_PinSource8,GPIO_AF_FSMC); GPIO_PinAFConfig(GPIOD,GPIO_PinSource9,GPIO_AF_FSMC); GPIO_PinAFConfig(GPIOD,GPIO_PinSource10,GPIO_AF_FSMC); GPIO_PinAFConfig(GPIOD,GPIO_PinSource14,GPIO_AF_FSMC); GPIO_PinAFConfig(GPIOD,GPIO_PinSource15,GPIO_AF_FSMC);//PD15,AF12 GPIO_PinAFConfig(GPIOE,GPIO_PinSource7,GPIO_AF_FSMC); //PE7,AF12 GPIO_PinAFConfig(GPIOE,GPIO_PinSource8,GPIO_AF_FSMC); GPIO_PinAFConfig(GPIOE,GPIO_PinSource9,GPIO_AF_FSMC); GPIO_PinAFConfig(GPIOE,GPIO_PinSource10,GPIO_AF_FSMC); GPIO_PinAFConfig(GPIOE,GPIO_PinSource11,GPIO_AF_FSMC); GPIO_PinAFConfig(GPIOE,GPIO_PinSource12,GPIO_AF_FSMC); GPIO_PinAFConfig(GPIOE,GPIO_PinSource13,GPIO_AF_FSMC); GPIO_PinAFConfig(GPIOE,GPIO_PinSource14,GPIO_AF_FSMC); GPIO_PinAFConfig(GPIOE,GPIO_PinSource15,GPIO_AF_FSMC);//PE15,AF12 GPIO_PinAFConfig(GPIOG,GPIO_PinSource2,GPIO_AF_FSMC);//PF12,AF12 GPIO_PinAFConfig(GPIOG,GPIO_PinSource12,GPIO_AF_FSMC); readWriteTiming.FSMC_AddressSetupTime = 0XF; //地址建立时间(ADDSET)为16个HCLK 1/168M=6ns*16=96ns > 90 readWriteTiming.FSMC_AddressHoldTime = 0x00; //地址保持时间(ADDHLD)模式A未用到 readWriteTiming.FSMC_DataSetupTime = 60; //数据存储时间为60个HCLK =6*60=360ns > 255 readWriteTiming.FSMC_BusTurnAroundDuration = 0x00; readWriteTiming.FSMC_CLKDivision = 0x00; readWriteTiming.FSMC_DataLatency = 0x00; readWriteTiming.FSMC_AccessMode = FSMC_AccessMode_A; //模式A writeTiming.FSMC_AddressSetupTime = 3; //地址建立时间(ADDSET)为3个HCLK =18ns > 15 writeTiming.FSMC_AddressHoldTime = 0x00; //地址保持时间(ADDHLD) 模式A不使用 writeTiming.FSMC_DataSetupTime = 2; //数据保存时间为6ns*3个HCLK=18ns > 15 writeTiming.FSMC_BusTurnAroundDuration = 0x00; writeTiming.FSMC_CLKDivision = 0x00; writeTiming.FSMC_DataLatency = 0x00; writeTiming.FSMC_AccessMode = FSMC_AccessMode_A; //模式A FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM4;// 使用E4,也就对应BTCR[6],[7] FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable; // 不复用数据地址 FSMC_NORSRAMInitStructure.FSMC_MemoryType =FSMC_MemoryType_SRAM;// FSMC_MemoryType_SRAM; //SRAM FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b;//存储器数据宽度为16bit FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode =FSMC_BurstAccessMode_Disable;// FSMC_BurstAccessMode_Disable; FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low; FSMC_NORSRAMInitStructure.FSMC_AsynchronousWait=FSMC_AsynchronousWait_Disable; FSMC_NORSRAMInitStructure.FSMC_WrapMode = FSMC_WrapMode_Disable; FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState; FSMC_NORSRAMInitStructure.FSMC_WriteOperation = FSMC_WriteOperation_Enable; //存储器写使能 FSMC_NORSRAMInitStructure.FSMC_WaitSignal = FSMC_WaitSignal_Disable; FSMC_NORSRAMInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Enable; // 读写使用不同的时序 FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable; FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &readWriteTiming; //读写时序 FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &writeTiming; //写时序 FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure); //初始化FSMC配置 FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM4, ENABLE); // 使能BANK1 delay_ms(50); // delay 50 ms }//初始化lcdvoid LCD_Init(void) { LCD_FSMC_Config(); //尝试9341 ID的读取 LCD_CMD=0XD3; lcd_id=LCD_DATA; //dummy read lcd_id=LCD_DATA; //读到0X00 lcd_id=LCD_DATA; //读取93 lcd_id<<=8; lcd_id|=LCD_DATA; //读取41 LCD_CMD=0xCF; LCD_DATA=0x00; LCD_DATA=0xC1; LCD_DATA=0X30; LCD_CMD=0xED; LCD_DATA=0x64; LCD_DATA=0x03; LCD_DATA=0X12; LCD_DATA=0X81; LCD_CMD=0xE8; LCD_DATA=0x85; LCD_DATA=0x10; LCD_DATA=0x7A; LCD_CMD=0xCB; LCD_DATA=0x39; LCD_DATA=0x2C; LCD_DATA=0x00; LCD_DATA=0x34; LCD_DATA=0x02; LCD_CMD=0xF7; LCD_DATA=0x20; LCD_CMD=0xEA; LCD_DATA=0x00; LCD_DATA=0x00; LCD_CMD=0xC0; //Power control LCD_DATA=0x1B; //VRH[5:0] LCD_CMD=0xC1; //Power control LCD_DATA=0x01; //SAP[2:0];BT[3:0] LCD_CMD=0xC5; //VCM control LCD_DATA=0x30; //3F LCD_DATA=0x30; //3C LCD_CMD=0xC7; //VCM control2 LCD_DATA=0XB7; LCD_CMD=0x36; // Memory Access Control LCD_DATA=0x48; LCD_CMD=0x3A; LCD_DATA=0x55; LCD_CMD=0xB1; LCD_DATA=0x00; LCD_DATA=0x1A; LCD_CMD=0xB6; // Display Function Control LCD_DATA=0x0A; LCD_DATA=0xA2; LCD_CMD=0xF2; // 3Gamma Function Disable LCD_DATA=0x00; LCD_CMD=0x26; //Gamma curve selected LCD_DATA=0x01; LCD_CMD=0xE0; //Set Gamma LCD_DATA=0x0F; LCD_DATA=0x2A; LCD_DATA=0x28; LCD_DATA=0x08; LCD_DATA=0x0E; LCD_DATA=0x08; LCD_DATA=0x54; LCD_DATA=0XA9; LCD_DATA=0x43; LCD_DATA=0x0A; LCD_DATA=0x0F; LCD_DATA=0x00; LCD_DATA=0x00; LCD_DATA=0x00; LCD_DATA=0x00; LCD_CMD=0XE1; //Set Gamma LCD_DATA=0x00; LCD_DATA=0x15; LCD_DATA=0x17; LCD_DATA=0x07; LCD_DATA=0x11; LCD_DATA=0x06; LCD_DATA=0x2B; LCD_DATA=0x56; LCD_DATA=0x3C; LCD_DATA=0x05; LCD_DATA=0x10; LCD_DATA=0x0F; LCD_DATA=0x3F; LCD_DATA=0x3F; LCD_DATA=0x0F; LCD_CMD=0x2B; LCD_DATA=0x00; LCD_DATA=0x00; LCD_DATA=0x01; LCD_DATA=0x3f; LCD_CMD=0x2A; LCD_DATA=0x00; LCD_DATA=0x00; LCD_DATA=0x00; LCD_DATA=0xef; LCD_CMD=0x11; //Exit Sleep delay_ms(120); LCD_CMD=0x29; //display on LCD_Display_Dir(U2D_R2L); //初始化为 横屏 LCD_BACK=1; //点亮背光 LCD_Clear(WHITE);}void LCD_DisplayMyname(u16 x,u16 y) { u8 bytenum,bytedata, a,b; u16 ymid=y; bytenum = sizeof(gao);// for(b=0;b
=lcd_height)return; //超区域 退出函数 if((y-ymid)==32) { y=ymid; x++; if(x>=lcd_width)return; //超区域 退出函数 break; } } }} void LCD_DisplayTu1(u16 x,u16 y) { u8 bytenum,bytedata, a,b; u16 ymid=y; bytenum = sizeof(biao1);// for(b=0;b
=lcd_height)return; //超区域 退出函数 if((y-ymid)==32) { y=ymid; x++; if(x>=lcd_width)return; //超区域 退出函数 break; } } }}void LCD_DisplayTu2(u16 x,u16 y) { u8 bytenum,bytedata, a,b; u16 ymid=y; bytenum = sizeof(biao2);// for(b=0;b
=lcd_height)return; //超区域 退出函数 if((y-ymid)==32) { y=ymid; x++; if(x>=lcd_width)return; //超区域 退出函数 break; } } } }

cfont.h

#ifndef __CFONT_H#define __CFONT_H //字库均来源于网络工具生成  此处略//摄氏度符号const unsigned char otherChar_1212[1][24] = {
{0x00,0x00,0x60,0x00,0x60,0x00,0x00,0x00,0x1F,0x80,0x20,0x40,0x20,0x40,0x20,0x40,0x20,0x40,0x20,0xC0,0x11,0x80,0x00,0x00}};const unsigned char otherChar_1616[1][32] = {
{0x00,0x00,0x30,0x00,0x48,0x00,0x30,0x00,0x00,0x00,0x03,0xF0,0x0E,0x18,0x08,0x0C,0x10,0x04,0x10,0x04,0x10,0x04,0x10,0x04,0x08,0x0C,0x0C,0x38,0x00,0x00,0x00,0x00}};

ds18b20.h

#ifndef S3C_DS_H#define S3C_DS_Hextern void DS18B20_Init(void);extern void get_temperature(char *buf);#endif

ds18b20.c

#include "stm32f4xx.h"#include "ds18b20.h"#include "delay.h"extern void gpio_out_state(int);extern int gpio_input_state(void);int  DS1820_Reset(void);                //DS1820 复位 void DS1820_WriteData(char wData);      //写数据到 DS1820 /**********************************************************  *DS1820 复位及存在检测(通过存在脉冲可以判断 DS1820 是否损坏)  *函数名称:DS1820_Reset()  *说明:函数返回一个位标量(0 或 1)flag=0 存在,反之 flag=1 不存在  **********************************************************/ int DS1820_Reset(void)     {     int flag;             gpio_out_state(0);    //延时 480 微秒,产生复位脉冲     delay_us(480);    gpio_out_state(1);    //延时 80 微秒对总线采样     delay_us(80);    flag = gpio_input_state();       //对数据脚采样     delay_us(400);    //延时 400 微秒等待总线恢复     return flag;                //根据 flag 的值可知 DS1820 是否存在或损坏  ,可加声音告警提示 DS1820 故障 } /**********************************************************  *写数据到 DS1820  *函数名称:DS1820_WriteData()  **********************************************************/ void DS1820_WriteData(char wData)     {     char i;     for(i = 8; i > 0; i--)    {        gpio_out_state(0);                  //拉低总线,产生写信号         delay_us(4);                    //延时 4us         gpio_out_state(wData & 0x01);   //发送 1 位         delay_us(60);               //延时 60us,写时序至少要 60us         gpio_out_state(1);                  //释放总线,等待总线恢复         wData >>= 1;                    //准备下一位数据的传送     } } /**********************************************************  *DS18B20 初始化  *函数名称:DS1820_WriteData()  *说明:本初始化程序可以不要,因为 18B20 在出厂时就被配置为 12 位精度了  **********************************************************/ void DS18B20_Init(void)  {     DS1820_Reset();     DS1820_WriteData(0xCC);    //  跳过 ROM     DS1820_WriteData(0x4E);    //  写暂存器     DS1820_WriteData(0x20);    //  往暂存器的第三字节中写上限值     DS1820_WriteData(0x00);    //  往暂存器的第四字节中写下限值     DS1820_WriteData(0x7F);    //  将配置寄存器配置为 12 位精度     DS1820_Reset(); } /**********************************************************  *从 DS1820 中读出数据  *函数名称:DS1820_ReadData()  **********************************************************/ char DS1820_ReadData(void)     {     char i,TmepData = 0;     for(i = 8; i > 0; i--)    {        TmepData >>= 1;         gpio_out_state(0);          //拉低总线,产生读信号         delay_us(4);                //延时 4us         gpio_out_state(1);          //释放总线,准备读数据         delay_us(8);                //延时 8 微秒读数据         if(gpio_input_state())            TmepData |= 0x80;         delay_us(60);                   //延时 60us         gpio_out_state(1);                  //拉高总线,准备下一位数据的读取.     }     return TmepData;            //返回读到的数据 } /**********************************************************  *转换子程序  **********************************************************/ void tem_to_string(char *buf, char temperature[])    {     unsigned char temp_data,temp_data_2;     unsigned short TempDec;         //用来存放 4 位小数     temp_data = temperature[1];     temp_data &= 0xf8;              //取高 4 位     if(temp_data == 0xf8)    {          //判断是正温度还是负温度读数                        //负温度读数求补,取反加 1,判断低 8 位是否有进位         if(temperature[0]==0)    {      //有进位,高 8 位取反加 1             temperature[0]=~temperature[0]+1;             temperature[1]=~temperature[1]+1;         }else    {              //没进位,高 8 位不加 1             temperature[0]=~temperature[0]+1;             temperature[1]=~temperature[1];         }     }     //温度格式  temperature[1]:[xxxxAAAA] AAAA 温度的高4位    //温度格式  temperature[0]:[BBBBCCCC] BBBB 温度的低4位 CCCC小数(乘以0.0625得到的是温度)    temp_data = temperature[1]<<4;                              //取高字节低 4 位(温度读数高 4 位),注意此时是 12 位精度     temp_data_2 = temperature[0]>>4;                        //取低字节高 4 位(温度读数低 4 位),注意此时是 12 位精度     temp_data = temp_data | temp_data_2;                    //组合成完整数据         buf[0] = temp_data / 100 + 0x30;                        //取百位转换为 ASCII 码     buf[1] = (temp_data % 100) / 10 + 0x30;             //取十位转换为 ASCII 码     buf[2] = (temp_data % 100 ) % 10 + 0x30;            //取个位转换为 ASCII 码     buf[3] = '.';#if 0    1111    = 15;    2 ^ 3 + 2 ^ 2 + 2 ^ 1 + 2 ^ 0 = 15     1111    = (2 ^ 3 + 2 ^ 2 + 2 ^ 1 + 2 ^ 0) * 0.0625  = 15 * 0.0625    #endif    temperature[0] &= 0x0f;                         //取小数位转换为 ASCII 码     TempDec = temperature[0] * 625;                 //625=0.0625*10000,表示小数部分,扩大 1 万倍  ,方便显示     buf[4] = TempDec / 1000 + 0x30;                 //取小数十分位转换为 ASCII 码     buf[5] = (TempDec % 1000) / 100 + 0x30;             //取小数百分位转换为 ASCII 码     buf[6] = ((TempDec % 1000) % 100) / 10 + 0x30;  //取小数千分位转换为 ASCII 码     buf[7] = ((TempDec % 1000) % 100) % 10 + 0x30;  //取小数万分位转换为 ASCII 码     buf[8] = '\0';}void get_temperature(char *buf)     {     int i;     char temperature[2]; //存放温度数据     DS1820_Reset();                  //复位     DS1820_WriteData(0xcc); //跳过 ROM 命令     DS1820_WriteData(0x44); //温度转换命令     DS1820_Reset();         //复位     DS1820_WriteData(0xcc); //跳过 ROM 命令     DS1820_WriteData(0xbe); //读 DS1820 温度暂存器命令     for (i=0;i<2;i++){         temperature[i] = DS1820_ReadData();    //采集温度     }     DS1820_Reset();              //复位,结束读数据     tem_to_string(buf, temperature);    delay_us(50);}

dht11.h

#ifndef __DHT_H#define __DHT_H#include "stm32f4xx_conf.h"extern void dht_init(void);extern void dht_get_data(char *buf);#endif

dht11.c

#include "dht11.h"#include "delay.h"#include "bitband.h"void dht_init(void)    {    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);}void dht_gpio_out(void)    {    GPIO_InitTypeDef Gpio_Value;    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);        Gpio_Value.GPIO_Mode = GPIO_Mode_OUT;    Gpio_Value.GPIO_OType = GPIO_OType_PP;    Gpio_Value.GPIO_Pin = GPIO_Pin_4;    Gpio_Value.GPIO_PuPd = GPIO_PuPd_NOPULL;    Gpio_Value.GPIO_Speed = GPIO_Fast_Speed;        GPIO_Init(GPIOA, &Gpio_Value);  }void dht_gpio_in(void)    {    GPIO_InitTypeDef Gpio_Value;    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);        Gpio_Value.GPIO_Mode = GPIO_Mode_IN;    Gpio_Value.GPIO_Pin = GPIO_Pin_4;    Gpio_Value.GPIO_PuPd = GPIO_PuPd_NOPULL;    Gpio_Value.GPIO_Speed = GPIO_Fast_Speed;        GPIO_Init(GPIOA, &Gpio_Value);  }void dht_output_state(int state)    {    dht_gpio_out();    if(state)        PAOut(4) = 1;    else        PAOut(4) = 0;}int dht_input_state(void)    {    dht_gpio_in();    return PAIn(4);}void dht_get_data(char *buf)    {    char i;    char tmp = 0;    dht_output_state(0);    delay_ms(20);    dht_output_state(1);        while(dht_input_state());    while(!dht_input_state());        for(i = 0; i < 40; i++)     {        while(dht_input_state());        while(!dht_input_state());        delay_us(40);        tmp <<= 1;        if(dht_input_state())            tmp |= 1;        if((i + 1) % 8 == 0)// 7 15 23 31   {            buf[i / 8] = tmp;            tmp = 0;        }    }    dht_output_state(1);}

转载于:https://www.cnblogs.com/OceanF/p/9150998.html

你可能感兴趣的文章
内核链表使用--删除链表节点
查看>>
eclipse启动无响应,停留在Loading workbench状态
查看>>
How exactly does Google AdWords work?
查看>>
多线程系列(4)使用多线程的安全问题
查看>>
C# 你可能没这样用过(逗逼方式) return
查看>>
387. First Unique Character in a String
查看>>
JSP、Servlet乱码终极解决方案
查看>>
libcurl教程(转)
查看>>
旅途上看的电影和观后感
查看>>
SpringMVC 拦截器 异常
查看>>
C语言版的16进制与字符串互转函数
查看>>
qt实现类似QQ伸缩窗口--鼠标事件应用
查看>>
Ztree异步树加载
查看>>
复杂问题的简单抽象:魔兽世界中的兔子们
查看>>
UVA 10529-Dumb Bones(概率dp)
查看>>
Hibernate4的注解 (持续更新范例中)
查看>>
关于IE和火狐,谷歌,Safari对Html标签Object和Embed的支持问题
查看>>
消息中间件收录集
查看>>
MyEclipse DB Browser使用图文全攻略
查看>>
poj3320 Jessica's Reading Problem(尺取思路+STL)
查看>>