打印
[STM32F1]

STM32+DHT11温湿度应用

[复制链接]
3354|28
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
hanzhen654|  楼主 | 2017-10-26 21:20 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
下载程序后D1指示灯闪烁表示程序正常运行,如果DHT11未插上,初始化Error,否则Success将检测的温湿度显示在LCD上,同时也可以在串口助手上显示,波特率设定9600DHT11数据口接在开发板的PG11接口。
沙发
hanzhen654|  楼主 | 2017-10-26 21:23 | 只看该作者
主函数:包含LCD初始化显示和数据处理函数


int main(void)
{       
        u8 i=0;
        delay_init();
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
        uart_init(9600);
        TFT_Init();       
        led_init();
        lcd_display();
        while(DHT11_Init())        //检测DS18B20是否纯在
        {
                GUI_Show12ASCII(130,50,"Error   ",RED,BLACK);       
                delay_ms(500);               
        }
        GUI_Show12ASCII(130,50,"Success",RED,BLACK);
        while(1)
        {                               
                i++;
                if(i==15)
                {
                        i=0;
                        data_pros();           //读取一次DHT11数据最少要大于100ms
                        led0=~led0;
                }
                delay_ms(10);                                       
        }       
}

使用特权

评论回复
板凳
hanzhen654|  楼主 | 2017-10-26 21:29 | 只看该作者
LCD初始化显示
void lcd_display()         
{
        TFT_ClearScreen(BLACK);
        GUI_Show12ASCII(10,10,"PRECHIN",GREEN,BLACK);
        GUI_Show12ASCII(10,30,"www.prechin.com",GREEN,BLACK);
        GUI_Show12ASCII(10,50,"DHT11 Test!",GREEN,BLACK);       
        GUI_Show12ASCII(10,70,"2015-11-12",GREEN,BLACK);
        GUI_Show12ASCII(10,100,"Temp:   C",GREEN,BLACK);
        GUI_Show12ASCII(10,130,"Humi:   %RH",GREEN,BLACK);


}

使用特权

评论回复
地板
hanzhen654|  楼主 | 2017-10-26 21:32 | 只看该作者
数据处理函数
void data_pros()       
{
        u8 temp;              
        u8 humi;
        u8 temp_buf[3],humi_buf[3];
        DHT11_Read_Data(&temp,&humi);
        temp_buf[0]=temp/10+0x30;       
        temp_buf[1]=temp%10+0x30;
        temp_buf[2]='\0';
        GUI_Show12ASCII(55,100,temp_buf,RED,BLACK);
               
        humi_buf[0]=humi/10+0x30;       
        humi_buf[1]=humi%10+0x30;
        humi_buf[2]='\0';
        GUI_Show12ASCII(55,130,humi_buf,RED,BLACK);               
}

使用特权

评论回复
5
hanzhen654|  楼主 | 2017-10-26 21:34 | 只看该作者
需要的头文件
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "lcd_driver.h"
#include "gui.h"
#include "dht11.h"

使用特权

评论回复
6
hanzhen654|  楼主 | 2017-10-26 21:39 | 只看该作者
在延时函数部分包括了以下函数
01.延时US级别的
void delay_us(u32 i)
{
        u32 temp;
        SysTick->LOAD=9*i;                 //设置重装数值, 72MHZ时
        SysTick->CTRL=0X01;                 //使能,减到零是无动作,采用外部时钟源
        SysTick->VAL=0;                            //清零计数器
        do
        {
                temp=SysTick->CTRL;                   //读取当前倒计数值
        }
        while((temp&0x01)&&(!(temp&(1<<16))));         //等待时间到达
        SysTick->CTRL=0;        //关闭计数器
        SysTick->VAL=0;                //清空计数器
}
02.延时毫秒级别的。
void delay_ms(u32 i)
{
        u32 temp;
        SysTick->LOAD=9000*i;          //设置重装数值, 72MHZ时
        SysTick->CTRL=0X01;                //使能,减到零是无动作,采用外部时钟源
        SysTick->VAL=0;                        //清零计数器
        do
        {
                temp=SysTick->CTRL;           //读取当前倒计数值
        }
        while((temp&0x01)&&(!(temp&(1<<16))));        //等待时间到达
        SysTick->CTRL=0;        //关闭计数器
        SysTick->VAL=0;                //清空计数器
}



使用特权

评论回复
7
hanzhen654|  楼主 | 2017-10-26 21:46 | 只看该作者
在USART串口里面我们可以看到   串口1的配置   中断优先级的设置
void usart_init()
{
        GPIO_InitTypeDef GPIO_InitStructure;                  //声明一个结构体变量,用来初始化GPIO
        USART_InitTypeDef  USART_InitStructure;          //串口结构体定义
        NVIC_InitTypeDef NVIC_InitStructure;//中断结构体定义
       
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);         //打开时钟
       
        /*  配置GPIO的模式和IO口 */
        GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;//TX                           //串口输出PA9
        GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;            //复用推挽输出
        GPIO_Init(GPIOA,&GPIO_InitStructure);  /* 初始化串口输入IO */
        GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10;//RX                         //串口输入PA10
        GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;                  //模拟输入
        GPIO_Init(GPIOA,&GPIO_InitStructure); /* 初始化GPIO */


        USART_InitStructure.USART_BaudRate=9600;   //波特率设置为9600        //波特率
        USART_InitStructure.USART_WordLength=USART_WordLength_8b;                //数据长8位
        USART_InitStructure.USART_StopBits=USART_StopBits_1;                        //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);        /* 初始化USART1 */
        USART_Cmd(USART1, ENABLE);                   /* 使能USART1 */
        USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//使能或者失能指定的USART中断 接收中断
        USART_ClearFlag(USART1,USART_FLAG_TC);//清除USARTx的待处理标志位

        /* 设置NVIC参数 */
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);   
        NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;            //打开USART1的全局中断
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;          //抢占优先级为0
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;                         //响应优先级为0
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                          //使能
        NVIC_Init(&NVIC_InitStructure);

}

使用特权

评论回复
8
hanzhen654|  楼主 | 2017-10-26 21:51 | 只看该作者
led部分    端口初始化   LED闪烁
void LED_Init()         
{
        GPIO_InitTypeDef GPIO_InitStructure;        //声明一个结构体变量,用来初始化GPIO

        SystemInit();        //系统时钟初始化

        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE); /* 开启GPIO时钟 */

        /*  配置GPIO的模式和IO口 */
        GPIO_InitStructure.GPIO_Pin=LED;         //选择你要设置的IO口
        GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;          //设置推挽输出模式
        GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;          //设置传输速率
        GPIO_Init(GPIOC,&GPIO_InitStructure); /* 初始化GPIO */       
}
void led_display()       
{
        GPIO_SetBits(GPIOC,LED);         //IO口输出高电平
        delay(6000000);//延时约为1s
        GPIO_ResetBits(GPIOC,LED); //IO口输出低电平
        delay(6000000);
}



使用特权

评论回复
9
hanzhen654|  楼主 | 2017-10-27 09:09 | 只看该作者
LCD TFT GPIO的初始化
void TFT_GPIO_Config(void)
{
        GPIO_InitTypeDef GPIO_InitStructure;
       
        /* 打开时钟使能 */
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE  
                              | RCC_APB2Periph_GPIOG, ENABLE);


        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_12;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
        /* FSMC_A10(G12) 和RS(G0)*/
        GPIO_Init(GPIOG, &GPIO_InitStructure);


        GPIO_InitStructure.GPIO_Pin = (GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_4
                                      | GPIO_Pin_5 | GPIO_Pin_8 | 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_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_Init(GPIOE, &GPIO_InitStructure);
}



使用特权

评论回复
10
hanzhen654|  楼主 | 2017-10-27 09:10 | 只看该作者
初始化FSMC
void TFT_FSMC_Config(void)
{
        /* 初始化函数 */
        FSMC_NORSRAMInitTypeDef        FSMC_NORSRAMInitStructure;
        FSMC_NORSRAMTimingInitTypeDef  FSMC_NORSRAMTiming;


        /* 设置读写时序,给FSMC_NORSRAMInitStructure调用 */
        /* 地址建立时间,3个HCLK周期 */
        FSMC_NORSRAMTiming.FSMC_AddressSetupTime = 0x02;


        /* 地址保持时间,1个HCLK周期 */
        FSMC_NORSRAMTiming.FSMC_AddressHoldTime = 0x00;


        /* 数据建立时间,6个HCLK周期 */
        FSMC_NORSRAMTiming.FSMC_DataSetupTime = 0x05;


        /* 数据保持时间,1个HCLK周期 */
        FSMC_NORSRAMTiming.FSMC_DataLatency = 0x00;


        /* 总线恢复时间设置 */
        FSMC_NORSRAMTiming.FSMC_BusTurnAroundDuration = 0x00;
       
        /* 时钟分频设置 */
        FSMC_NORSRAMTiming.FSMC_CLKDivision = 0x01;


        /* 设置模式,如果在地址/数据不复用时,ABCD模式都区别不大 */
        FSMC_NORSRAMTiming.FSMC_AccessMode = FSMC_AccessMode_B;


        /*设置FSMC_NORSRAMInitStructure的数据*/
        /* FSMC有四个存储块(bank),我们使用第一个(bank1) */
        /* 同时我们使用的是bank里面的第 4个RAM区 */
        FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM4;


        /* 这里我们使用SRAM模式 */
        FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_SRAM;


        /* 使用的数据宽度为16位 */
        FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b;


        /* 设置写使能打开 */
        FSMC_NORSRAMInitStructure.FSMC_WriteOperation = FSMC_WriteOperation_Enable;


        /* 选择拓展模式使能,即设置读和写用不同的时序 */
        FSMC_NORSRAMInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Enable;
       
        /* 设置地址和数据复用使能不打开 */
        FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable;
       
        /* 设置读写时序 */
        FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &FSMC_NORSRAMTiming;
       
        /* 设置写时序 */
        FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &FSMC_NORSRAMTiming;


        /* 打开FSMC的时钟 */
        RCC_AHBPeriphClockCmd(RCC_AHBPeriph_FSMC, ENABLE);
         
        FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure);


        /*!< Enable FSMC Bank1_SRAM Bank */
        FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM4, ENABLE);       
}

使用特权

评论回复
11
hanzhen654|  楼主 | 2017-10-27 09:13 | 只看该作者
LCD写入命令 写入的16位命令
void TFT_WriteCmd(uint16_t cmd)
{
        TFT->TFT_CMD = cmd<<8 ;
}
LCD写入数据 写入的16位数据
void TFT_WriteData(u16 dat)
{
        TFT->TFT_DATA = dat<<8;
}
void TFT_WriteData_Color(u16 color)
{
        TFT->TFT_DATA = color&0xff00;
        TFT->TFT_DATA = color<<8;
}

使用特权

评论回复
12
hanzhen654|  楼主 | 2017-10-27 09:15 | 只看该作者
初始化LCD屏
void TFT_Init(void)
{
        uint16_t i;


        TFT_GPIO_Config();
        TFT_FSMC_Config();


        //************* Start Initial Sequence **********//       
        TFT_WriteCmd(0xCB);  
        TFT_WriteData(0x39);
        TFT_WriteData(0x2C);
        TFT_WriteData(0x00);
        TFT_WriteData(0x34);  
        TFT_WriteData(0x02);   


        TFT_WriteCmd(0xCF);  
        TFT_WriteData (0x00);
        TFT_WriteData (0xa2); //c1
        TFT_WriteData (0Xf0);  //30
         
        TFT_WriteCmd(0xE8);  
        TFT_WriteData (0x84);          //85
        TFT_WriteData (0x11);          //00
        TFT_WriteData (0x7a);          //79
       
       
        TFT_WriteCmd(0xEA);  
        TFT_WriteData (0x66);  //00
        TFT_WriteData (0x00);
       
        TFT_WriteCmd(0xED);  
        TFT_WriteData (0x55);         //64
        TFT_WriteData (0x01);         //03
        TFT_WriteData (0X23);         //12
        TFT_WriteData (0X01);         //81
         
        TFT_WriteCmd(0xF7);  
        TFT_WriteData (0x20);         //20
       
       
        TFT_WriteCmd(0xC0);    //Power control
        TFT_WriteData (0x1c);   //VRH[5:0]         //1c
         
        TFT_WriteCmd(0xC1);    //Power control
        TFT_WriteData (0x13);   //SAP[2:0];BT[3:0]         //13
         
        TFT_WriteCmd(0xC5);    //VCM control
        TFT_WriteData (0x23);
        TFT_WriteData (0x3F);
         
        TFT_WriteCmd(0xC7);    //VCM control2
        TFT_WriteData(0xA5);
       
        TFT_WriteCmd(0xB1);  
        TFT_WriteData (0x00);
        TFT_WriteData (0x17);
       
        TFT_WriteCmd(0x3A);  
        TFT_WriteData (0x55);
       
        TFT_WriteCmd(0xB6);  
        TFT_WriteData (0x0A);
        TFT_WriteData (0xa2);  //a2
        TFT_WriteData (0x27);
        TFT_WriteData (0x00);
         
        TFT_WriteCmd(0x36);    // Memory Access Control
        TFT_WriteData (0x08);           //08        BGR
         
        TFT_WriteCmd(0xF2);    // 3Gamma Function Disable
        TFT_WriteData (0x02);         //00
         
        TFT_WriteCmd(0x26);    //Gamma curve selected
        TFT_WriteData (0x01);
         
        TFT_WriteCmd(0xE0);    //Set Gamma
        TFT_WriteData (0x0F);
        TFT_WriteData (0x14);
        TFT_WriteData (0x13);
        TFT_WriteData (0x0C);
        TFT_WriteData (0x0E);
        TFT_WriteData (0x05);
        TFT_WriteData (0x45);
        TFT_WriteData (0x85);
        TFT_WriteData (0x36);
        TFT_WriteData (0x09);
        TFT_WriteData (0x14);
        TFT_WriteData (0x05);
        TFT_WriteData (0x09);
        TFT_WriteData (0x03);
        TFT_WriteData (0x00);
         
        TFT_WriteCmd(0XE1);    //Set Gamma
        TFT_WriteData (0x00);
        TFT_WriteData (0x24);
        TFT_WriteData (0x26);
        TFT_WriteData (0x03);
        TFT_WriteData (0x0F);
        TFT_WriteData (0x04);
        TFT_WriteData (0x3F);
        TFT_WriteData (0x14);
        TFT_WriteData (0x52);
        TFT_WriteData (0x04);
        TFT_WriteData (0x10);
        TFT_WriteData (0x0E);
        TFT_WriteData (0x38);
        TFT_WriteData (0x39);
        TFT_WriteData (0x0F);


        TFT_WriteCmd(0x2A );
        TFT_WriteData(0x00);
        TFT_WriteData(0x00);
        TFT_WriteData(0x00);
        TFT_WriteData(0xEF);


        TFT_WriteCmd(0x2B );
        TFT_WriteData(0x00);
        TFT_WriteData(0x00);
        TFT_WriteData(0x01);
        TFT_WriteData(0x3F);
         
        TFT_WriteCmd(0x11);    //Exit Sleep
        for(i=50000; i>0; i--);         //延时
        for(i=50000; i>0; i--);
        for(i=50000; i>0; i--);
        for(i=50000; i>0; i--);
        for(i=50000; i>0; i--);
        for(i=50000; i>0; i--);
        TFT_WriteCmd(0x29);    //Display on


}

使用特权

评论回复
13
hanzhen654|  楼主 | 2017-10-27 09:22 | 只看该作者

设置要操作的窗口范围
xStart:窗口起始X坐标
yStart:窗口起始Y坐标
xEnd:窗口结束X坐标
yEnd:窗口结束Y坐标
void TFT_SetWindow(uint16_t xStart, uint16_t yStart, uint16_t xEnd, uint16_t yEnd)
{
        TFT_WriteCmd(0x2A);


    TFT_WriteData(xStart/256);
    TFT_WriteData(xStart%256);
    TFT_WriteData(xEnd/256);
    TFT_WriteData(xEnd%256);


    TFT_WriteCmd(0x2b);
    TFT_WriteData(yStart/256);
    TFT_WriteData(yStart%256);
    TFT_WriteData(yEnd/256);
    TFT_WriteData(yEnd%256);
    TFT_WriteCmd(0x2c);
}

使用特权

评论回复
14
hanzhen654|  楼主 | 2017-10-27 09:40 | 只看该作者
将LCD清屏成相应的颜色
void TFT_ClearScreen(uint16_t color)
{
        uint16_t i, j ;


        TFT_SetWindow(0, 0, TFT_XMAX, TFT_YMAX);         //作用区域
          for(i=0; i<TFT_XMAX+1; i++)
        {
                for (j=0; j<TFT_YMAX+1; j++)
                {
                        TFT_WriteData_Color(color);
                }
        }
}

使用特权

评论回复
15
hanzhen654|  楼主 | 2017-10-27 11:53 | 只看该作者
在GUI函数部分 在彩屏上面画一点
        x:点的X坐标
        y:点的Y坐标
        color:点的颜色
void GUI_Dot(uint16_t x, uint16_t y, uint16_t color)
{  
        TFT_SetWindow(x, y, x, y);  //设置点的位置
        TFT_WriteData_Color(color);       //画点       
}

使用特权

评论回复
16
hanzhen654|  楼主 | 2017-10-27 11:54 | 只看该作者
给一个区域涂上颜色
sx:起始X坐标, sy:起始Y坐标,
ex:终止X坐标, ey:终止Y坐标,

color:方框的颜色
void GUI_Box(uint16_t xState, uint16_t yState, uint16_t xEnd, uint16_t yEnd, uint16_t color)
{
        uint16_t temp;


    if((xState > xEnd) || (yState > yEnd))
    {
        return;
    }   
        TFT_SetWindow(xState, yState, xEnd, yEnd);
    xState = xEnd - xState + 1;
        yState = yEnd - yState + 1;


        while(xState--)
        {
                 temp = yState;
                while (temp--)
                 {       
                        TFT_WriteData_Color(color);
                }
        }
}


使用特权

评论回复
17
hanzhen654|  楼主 | 2017-10-27 11:56 | 只看该作者

画一个十字的标记
x:标记的X坐标;
y:标记的Y坐标
color:标记的颜色
void GUI_DrowSign(uint16_t x, uint16_t y, uint16_t color)
{
    uint8_t i;


    /* 画点 */
    TFT_SetWindow(x-1, y-1, x+1, y+1);
    for(i=0; i<9; i++)
    {
        TFT_WriteData_Color(color);   
    }


    /* 画竖 */
    TFT_SetWindow(x-4, y, x+4, y);
    for(i=0; i<9; i++)
    {
        TFT_WriteData_Color(color);   
    }


    /* 画横 */
    TFT_SetWindow(x, y-4, x, y+4);
    for(i=0; i<9; i++)
    {
        TFT_WriteData_Color(color);   
    }
}

使用特权

评论回复
18
stm32jy| | 2017-10-27 12:06 | 只看该作者
不错,很详细,DHT11总线不是很难,TFT就厉害了。

使用特权

评论回复
19
捉虫天师| | 2017-10-27 15:49 | 只看该作者
32的这种例子太少了,保存下来参考。

使用特权

评论回复
20
hanzhen654|  楼主 | 2017-10-27 20:38 | 只看该作者
捉虫天师 发表于 2017-10-27 15:49
32的这种例子太少了,保存下来参考。

相互学习,不用客气。

使用特权

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

本版积分规则

73

主题

1766

帖子

2

粉丝