【NiosII训练】第五篇、FPGA驱动DHT11

目录

第一部分、前言

1、闲话

第二部分、题目要求

1、图片

2、文字描述

3、dht11知识

第三部分、工程代码

1、软核的搭建

 2、顶层文件的代码

 3、Ecplise代码

 第四部分、总结

1、效果演示

2、感想

3、完整工程


第一部分、前言

1、闲话

还是一样,这个设计也是我们《SOPC技术及应用》课程结束的期末作业。我自己的是老师题库里的第题、驱动AD9854这个模块,题目要求在第一篇已经说到了,想回去看的铁子们可以回去看。

这一题是我室友的,报酬是给我买一杯奶茶(结果没给,我亏大发了😭😭😭),效果如下:

第二部分、题目要求

1、图片

2、文字描述

使用FPGA调通DHT11温湿度传感器,并能够将温度和湿度实时显示在lcd上,系统需要使用ucosii操作系统。

3、dht11知识

关于DHT11的知识,你到CSDN搜一下,出来一大把有些博主很详细的讲述了这个模块的工作原理,我这里就不做详述了。

第三部分、工程代码

1、软核的搭建

 2、顶层文件的代码

module AC620_GHRD(
	input  wire        clk,                           //                        clk.clk
	input  wire        reset_n,                     //                      reset.reset_n
	output wire        lcd_rst,                    //                    lcd_rst.export
	output wire        lcd_rd_n,                     //                     lcd_rd.export
	output wire        lcd_bl,                     //                     lcd_bl.export
	output wire        lcd_wr_n,                     //                     lcd_wr.export
	output wire        lcd_rs,                     //                     lcd_rs.export
	output wire        lcd_cs_n,                     //                     lcd_cs.export
	inout  wire [15:0] lcd_data,                     //                     lcd_db.export
	output wire        sdram_clk,                     //                  sdram_clk.clk
	output wire [11:0] sdram_addr,                        //                      sdram.addr
	output wire [1:0]  sdram_ba,                          //                           .ba
	output wire        sdram_cas_n,                       //                           .cas_n
	output wire        sdram_cke,                         //                           .cke
	output wire        sdram_cs_n,                        //                           .cs_n
	inout  wire [15:0] sdram_dq,                          //                           .dq
	output wire [1:0]  sdram_dqm,                         //                           .dqm
	output wire        sdram_ras_n,                       //                           .ras_n
	output wire        sdram_we_n,                         //                           .we_n
	input  wire        uart_0_rxd,                        //                     uart_0.rxd
	output wire        uart_0_txd,                        //                           .txd
	output wire        epcs_dclk,                         //                       epcs.dclk
	output wire        epcs_sce,                          //                           .sce
	output wire        epcs_sdo,                          //                           .sdo
	input  wire        epcs_data0,                         //                           .data0

	//对PIO端口进行定义
	inout  wire        dht11,
   output wire [3:0]  led

);

    mysystem u0 (
		.clk_clk                           (clk),                           //                        clk.clk
		.reset_reset_n                     (reset_n),                     //                      reset.reset_n
      .uart_0_rxd                        (uart_0_rxd),                        //                     uart_0.rxd
      .uart_0_txd                        (uart_0_txd),                        //                           .txd
      .epcs_dclk                         (epcs_dclk),                         //                       epcs.dclk
      .epcs_sce                          (epcs_sce),                          //                           .sce
      .epcs_sdo                          (epcs_sdo),                          //                           .sdo
      .epcs_data0                        (epcs_data0),                        //
		.lcd_rst_export                    (lcd_rst),                    //                    lcd_rst.export
		.lcd_bl_export                     (lcd_bl),                     //                     lcd_bl.export
		.lcd_wr_n                          (lcd_wr_n),                          //                        lcd.wr_n
		.lcd_rd_n                          (lcd_rd_n),                          //                           .rd_n
		.lcd_data                          (lcd_data),                          //                           .data
		.lcd_rs                            (lcd_rs),                            //                           .rs
		.lcd_cs_n                          (lcd_cs_n),                           //  
		.sdram_clk_clk                     (sdram_clk),                     //                  sdram_clk.clk
		.altpll_0_phasedone_conduit_export (), // altpll_0_phasedone_conduit.export
		.altpll_0_locked_conduit_export    (),    //    altpll_0_locked_conduit.export
		.altpll_0_areset_conduit_export    (),    //    altpll_0_areset_conduit.export
		.sdram_addr                        (sdram_addr),                        //                      sdram.addr
		.sdram_ba                          (sdram_ba),                          //                           .ba
		.sdram_cas_n                       (sdram_cas_n),                       //                           .cas_n
		.sdram_cke                         (sdram_cke),                         //                           .cke
		.sdram_cs_n                        (sdram_cs_n),                        //                           .cs_n
		.sdram_dq                          (sdram_dq),                          //                           .dq
		.sdram_dqm                         (sdram_dqm),                         //                           .dqm
		.sdram_ras_n                       (sdram_ras_n),                       //                           .ras_n
		.sdram_we_n                        (sdram_we_n),                        //                           .we_n
	   
		//添加的PIO端口
		.dht11_export                      (dht11),   //     dht11.export
      .led_export                        (led)      //       led.export
	
	);

endmodule

 3、Ecplise代码

dht11.c代码

#include "dht11.h"
//复位DHT11
void DHT11_Rst(void)
{
	IOWR_ALTERA_AVALON_PIO_DIRECTION(DHT11_BASE, 1);//方向为输出
	IOWR_ALTERA_AVALON_PIO_DATA(DHT11_BASE, 1);
	usleep(25);//初始25us为高电平

//	DHT11_IO_OUT(); 	//SET OUTPUT
//    DHT11_DQ_OUT=0; 	//拉低DQ
//    delay_ms(20);    	//拉低至少18ms
	IOWR_ALTERA_AVALON_PIO_DATA(DHT11_BASE, 0);
	usleep(18000);

//    DHT11_DQ_OUT=1; 	//DQ=1
//	delay_us(30);     	//主机拉高20~40us
	IOWR_ALTERA_AVALON_PIO_DATA(DHT11_BASE, 1);
	usleep(30);
}
//等待DHT11的回应
//返回1:未检测到DHT11的存在
//返回0:存在
alt_u8 DHT11_Check(void)
{
	alt_u8 retry=0;
	IOWR_ALTERA_AVALON_PIO_DIRECTION(DHT11_BASE, 0);//方向为输入
    while (IORD_ALTERA_AVALON_PIO_DATA(DHT11_BASE)&&retry<100)//DHT11会拉低40~80us
	{
		retry++;
		usleep(1);
	};
	if(retry>=100)return 1;
	else retry=0;
    while (!IORD_ALTERA_AVALON_PIO_DATA(DHT11_BASE)&&retry<100)//DHT11拉低后会再次拉高40~80us
	{
		retry++;
		usleep(1);
	};
	if(retry>=100)return 1;
	return 0;
}

//从DHT11读取一个位
//返回值:1/0
alt_u8 DHT11_Read_Bit(void)
{
	alt_u8 retry=0;
	IOWR_ALTERA_AVALON_PIO_DIRECTION(DHT11_BASE, 0);//方向为输入
	while(IORD_ALTERA_AVALON_PIO_DATA(DHT11_BASE)&&retry<100)//等待变为低电平
	{
		retry++;
//		delay_us(1);
		usleep(1);
	}
	retry=0;
	while(!IORD_ALTERA_AVALON_PIO_DATA(DHT11_BASE)&&retry<100)//等待变高电平
	{
		retry++;
//		delay_us(1);
		usleep(1);
	}
//	delay_us(40);//等待40us
	usleep(40);
	if(IORD_ALTERA_AVALON_PIO_DATA(DHT11_BASE))return 1;
	else return 0;
}

//从DHT11读取一个字节
//返回值:读到的数据
alt_u8 DHT11_Read_Byte(void)
{
	alt_u8 i,dat;
    dat=0;
	for (i=0;i<8;i++)
	{
   		dat<<=1;
	    dat|=DHT11_Read_Bit();
    }
    return dat;
}

//从DHT11读取一次数据
//temp:温度值(范围:0~50°)
//humi:湿度值(范围:20%~90%)
//返回值:0,正常;1,读取失败
alt_u8 DHT11_Read_Data(alt_u8 *temp,alt_u8 *humi)
{
	alt_u8 buf[5];
	alt_u8 i;
	DHT11_Rst();
	if(DHT11_Check()==0)
		{
			for(i=0;i<5;i++)//读取40位数据
			{
				buf[i]=DHT11_Read_Byte();
			}
			if((buf[0]+buf[1]+buf[2]+buf[3])==buf[4])
			{
				*humi=buf[0];
				*temp=buf[2];
			}
		}else return 1;
		return 0;
}

//初始化DHT11的IO口 DQ 同时检测DHT11的存在
//返回1:不存在
//返回0:存在
alt_u8 DHT11_Init(void)
{
	DHT11_Rst();  //复位DHT11
	return DHT11_Check();//等待DHT11的回应
}

 dht11.h代码

#ifndef DHT11_H_
#define DHT11_H_

#include "stdlib.h"
#include "stdint.h"
#include "system.h"
#include "alt_types.h"
#include <stdio.h>  //printf的头文件
#include "io.h"   //函数类型
#include "altera_avalon_pio_regs.h"
#include "unistd.h"		//延时函数的头文件

//复位DHT11
void DHT11_Rst(void);
alt_u8 DHT11_Read_Data(alt_u8 *temp,alt_u8 *humi);
alt_u8 DHT11_Read_Byte(void);
alt_u8 DHT11_Read_Bit(void);
alt_u8 DHT11_Init(void);
alt_u8 DHT11_Check(void) ;

#endif /* DHT11_H_ */

 主函数代码

#include "lcd9341.h"
#include "dht11.h"
#include <stdio.h>

alt_u8 temperature;
alt_u8 humidity;

int main()
{
	printf("I am 666!\n");
 	LCD9341_Init();
 	unsigned char a1[20],a2[20];
 	while(DHT11_Init())	//DHT11初始化
	{
		LCD_ShowString(30,130,"DHT11 Error");
		usleep(1000000);
	}
 	LCD_ShowString(30,130,"DHT11 OK    ");
	while(1)
	{
		DHT11_Read_Data(&temperature,&humidity);	//读取温湿度值
		printf("%d\n",temperature);
		printf("%d\n",humidity);
  		sprintf(a1,"Temp = %dC",temperature);
  		sprintf(a2,"Hum  = %d%%",humidity);
		LCD_ShowString(30,150,a1);
		LCD_ShowString(30,170,a2);
		usleep(1000000);
	}
}

 第四部分、总结

1、效果演示

DHT11的数据脚接FPGA的R1管脚。这里只展示图片,视频文件我已经上传到群文件,你也可以点击这里看一下演示效果(https://live.csdn.net/v/121263

 

2、感想

调试这个模块确实搞得我头都大了,虽然只用了两三个小时,但是搞得我心烦气燥。一开始是移植CSDN上面的51的时序,结果出问题,然后没法,我又重新移植32上驱动这个模块的时序,调试了好半天才搞好。(其实这两个时序都是一样的,第一次出的问题,我懒得回去看,大概是延时不准,导致时序出了问题)。

这个模块对时序的要求很严格,然后检测温度时温度值上升的很慢,但是检测湿度的值还是挺快的。

3、完整工程

嫖嫖怪时间,还是一样,扫码进群,我会放在群资料里面。或者让我你几个积分https://download.csdn.net/download/Learning1232/13695741)再或者留下邮箱,我看到了就发给你。当然有问题直接留言。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大屁桃

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值