Author: Instructor Lu,Hua Qing vision embedded college lecturer.
Dht11 digital temperature and humidity sensor is a temperature and humidity composite sensor containing calibrated digital signal output. It uses special digital module acquisition technology and Temperature and Humidity Sensor Technology to ensure high reliability and excellent long-term stability of the product. The sensor includes a Resistance Type Humidity Sensor and an NTC temperature sensor, and is connected to a high-performance 8-bit microcontroller. It has the advantages of low cost, stable performance, and strong anti-interference ability.
The corresponding 2-int pin is the output pin and is connected to the 66-pin of the sam3s4b chip.
The dht11 device adopts simplified single-bus communication. A single bus has only one data line. Data Exchange and control in the system are completed by a single bus. A device (host or slave) connects to the data line through an open or tri-state port to allow the device to release the bus without sending data, and allow other devices to use the bus; A single bus usually requires an external pull resistance of about KB. In this way, when the bus is idle, its status is high. Because they are in a master-slave structure, only when the host calls the slave server can the slave server respond. Therefore, the access devices of the host must strictly follow the single-bus sequence. If the sequence is disordered, the device will not respond to the host.
Electrical connection Diagram
Th_data is connected to the F6 pin of sam3s4b:
Implementation Program
Main Program:
Int main (void)
{
Unsigned char ACC [3] = {0, 0 };
Unsigned char temp [2] = {0, 0}; // data comes from the tem-Hum Sensor
Unsigned char hum [2] = {0, 0}; // data comes from the tem-Hum Sensor
/* Initialize the SAM System */
Sysclk_init ();
Systick_config (sysclk_get_cpu_hz ()/1000); // interrupt in every MS
Wdt-> wdt_mr = wdt_mr_wddis;
/* Configure UART pins */
Gpio_configure_group (pins_uart0_pio, pins_uart0, pins_uart0_flags); // Add luyj 2013.5.8
Configure_console ();
Pmc_enable_periph_clk (id_pioa); // Add By luyj 2013.5.8
While (1)
{
Read_temp_hum (temp, hum );
Printf ("Temp [0] = % d temp [1] = % d hum [0] = % d, hum [1] = % d \ r ", temp [0], temp [1], hum [0], hum [1]);
Mdelay (1000 );
}
}
The above is the main program, mainly because the system clock is selected as an external crystal oscillator, the PLL frequency doubling cpu_hz is 64 MHz, the watchdog is disabled, and the serial port is configured to print the temperature and humidity values, enable the energy manager (PMC) of the Pa Port, and then read the temperature and humidity every second.
Void setteminttype (uint8_t type)
{
Switch (type)
{
Case 0:
Nvic_enableirq (irqn_type) id_pioa );
Pio_enable_interrupt (pioa, pio_f6 );
Pio_handler_set_priority (pioa, (irqn_type) id_pioa, irq_prior_pio );
Pio_handler_set (pioa, id_pioa, pio_f6, (pio_pullup | pio_debounce | irq_falling_edge), tum_handler); // interrupt on falling edge
Break;
Case 1:
Nvic_enableirq (irqn_type) id_pioa );
Pio_enable_interrupt (pioa, pio_f6 );
Pio_handler_set (pioa, id_pioa, pio_f6, (pio_pullup | pio_debounce | pio_it_rise_edge), tum_handler); // interrupt on rising edge
Pio_handler_set_priority (pioa, (irqn_type) id_pioa, irq_prior_pio );
Break;
Case 2:
Pio_disable_interrupt (pioa, pio_f6 );
Break;
Default:
Break;
}
}
The preceding subroutine setteminttype () is used to enable and cancel the interruption of the Temperature Collection pin of the PA66. When collecting specific data, you need to collect the IPv6 level holding time. Therefore, you must promptly respond to the rising and falling edges of IPv6. here, we use interruptions.
Data is used for communication and synchronization between the microprocessor and dht11. In a single bus data format, 40 bits of data are transmitted at a time, and the data is first transmitted at a high level.
Check BIT data definition:
"8bit humidity Integer Data + 8bit humidity fractional Data + 8bit temperature Integer Data + 8bit temperature fractional data" The 8bit check bit is equal to the last 8 digits of the result.
Example 1: The received 40-bit data is:
0011 0101 0000 0000 0001 1000 0000 0000 0100 1101
Humidity high 8-bit humidity low 8-bit temperature high 8-bit temperature low 8-bit check bit
Computing:
0011 0101 + 0000 0000 + 0001 1000 + 0000 0000 = 0100 1101
The received data is correct.
Humidity: 0011 0101 = 35 h = 53% RH
Temperature: 0001 1000 = 18 h = 24 ℃
Data Sequence diagram:
After the user's host (MCU) sends a start signal, the dht11 is switched from the low power mode to the high-speed mode. After the host's start signal ends, the dht11 sends a response signal to send 40-bit data, trigger a message collection. Signal transmission.
According to the chip time sequence diagram, we can see that this chip involves microsecond operations, so the M3 system tick recording time is quite accurate, and data can be read according to the time sequence,
Temperature and humidity reading steps:
Step 1: dht11 power-on, latency 1 s to be stable, test temperature and humidity, save data, dht11 data lines remain high, in the input state, detect external signals.
Step 2: Set the microprocessor I/O to an output low level, which is kept above 18 ms, and then enters the input state, waiting for dht11 to respond.
The program is as follows: (different versions have different pins)
Gpio_configure_pin (pio_pa6_idx, pio_output_1 | pio_pullup | pio_debounce | pio_it_rise_edge); // set F6 to output
Gpio_set_pin_low (pio_pa6_idx); // set to low
Mdelay (30 );
Gpio_configure_pin (pio_pa6_idx, pio_input | pio_pullup); // set Io to input
First set to high-level output, then delay 30 ms, then set this port as input.
Step 3: dht11's Data Detection ends with an external low level. It is set to output 80 microsecond low level as a response and 80 microsecond High Level notification peripherals to prepare to accept data, and the microprocessor waits for data to be accepted.
At this time, the program requires a delay of magnitude in microseconds, so the cortex-M3 system comes with the system tick.
Latency:
For (I = 0; I <3; I ++)
{
Setteminttype (I & 0x01 );//
While (pa6_counter = cnt_last );
Cnt_last = pa6_counter;
}
The above section of the program indicates: first judge whether it is a descent edge. When I = 0, the descent edge is triggered and continues to be executed. If not, then pa6_counter = cnt_last will always be true. It will always be blocked here. When the descent edge comes, it will trigger the 66-interrupt. The following figure shows how to handle this interrupt: tum_handler:
If (pin_pushbutton_1_id = ID & pin_pushbutton_1_mask = mask)
{Pa6_tc = running ick-> val;
Pa6_counter ++;
}
At this time, pa6_counter ++; pa6_counter and cnt_last are not equal, jump out of the interrupt, and then make them two equal, wait for I = 1, and re-enter the cycle. At this time, the rising edge is triggered. The principle is the same as above, then wait for I = 2, and the descent edge is triggered again. After the three trigger changes, data transmission starts.
Step 4: The DHT data outputs 40 bits of data, and the microprocessor receives 40 bits of data at high and low levels;
The BIT data "0" format is: 50 microseconds of low power and 26-28 microseconds of high level, BIT data "1" format is: 50 microsecond low level plus 70 microsecond high level. Bit Data "0", "1" format signal:
For (I = 0; I <40; I ++)
{
Setteminttype (1); // enable IRQ rising edge
While (pa6_counter = cnt_last );
Cnt_last = pa6_counter;
TC1 = pa6_tc; // record the remaining number in the countdown counter at this time. That is, the time when the position marked by Arrow 1 is left
Setteminttype (0); // enable IRQ falling edge
While (pa6_counter = cnt_last );
Cnt_last = pa6_counter;
The following if indicates that if the countdown has not been executed to 0, that is, the countdown has not been re-loaded, this time is the counter value of Arrow 1 minus the counter value of Arrow 2.
If (pa6_tc <TC1) // compare the current value of tick answer and the size of Interrupt generation
{
TC = TC1-pa6_tc; // record the number of tick answers
}
Otherwise, it means that when reading Arrow 2, the counter has been re-loaded, so this time is to use 64000 minus their absolute value.
Else
{
TC = 64000-(pa6_tc-TC1 );
}
The first eight bits are the 8 bits in temp height. If TC is greater than 3200 bits, the data format is 1. If TC is smaller than bits, the data is 0.
If (I <8)
{
Hum_10 <= 1;
If (TC> = 3200) // according to, our clock frequency is 64 MHz, that is, a pulse requires 1/64 us,
Hum_10 | = 0x01; // 3200 pulses are 3200 * (1/64) us, that is, 50us
}
Else if (I <16)
{
Hum_01 <= 1;
If (TC >= 3200)
Hum_01 | = 0x01;
}
Else if (I <24)
{
Temp_10 <= 1;
If (TC >= 3200)
Temp_10 | = 0x01;
}
Else if (I <32)
{
Temp_01 <= 1;
If (TC >= 3200)
Temp_01 | = 0x01;
}
Else
{
Chksum <= 1;
If (TC >= 3200)
Chksum | = 0x01;
}
}
Setteminttype (1); // enable IRQ rising edge
While (pa6_counter = cnt_last );
Setteminttype (2); // disable
* Temp = temp10;
* (Temp + 1) = temp01;
* Hum = hum10;
* (HUM + 1) = hum31;
Chk = temp10;
Chk + = temp01;
Chk + = hum10;
Chk + = hum31;
If (chk = chksum)
Return 1;
Else
Return 0;
Read the data for 40 times without stopping. Because one bit is read each time, the system judges the check bit. If it succeeds, the data is read successfully. Otherwise, the data is lost.
End signal:
After the dht11 is sent, continue to output the low level 50 microseconds to the input high level, check the temperature and humidity again, and wait for the external signal.
Current temperature for specific Printing
Source: Huaqing vision embedded Linux training network, the original article address: http://www.embedu.org/Column/Column688.htm
. (For more information, see the source)