The AM2302 temperature and humidity sensor uses a single bus to communicate with the MCU, which requires the MCU to have a certain processing speed in order to correctly parse the data sent by the AM2302.
How MCU processes AM2302 data
AM2302 transmits 40 bits of data to MCU at a time. Data bit 0 is composed of 50 microseconds of low level plus 26 microseconds of high level.
Data bit 1 consists of 50 microseconds of low level plus 70 microseconds of high level. This encoding method is a bit like NEC's infrared transmission protocol.
In addition, AM2302 needs to be started by the MCU. Therefore, for this single-wire protocol, although level change interrupt + counter or input capture can be used to parse 40 data bits, this requires switching the input and output configuration of the port and controlling the intervention timing of the corresponding peripherals.
The method introduced in this article uses a simple port read + delay operation to parse 40 bits of data.
if (data_port == 1)
delay_us(30);
if (data_port == 1)
//bit = 1
else
//bit = 0
The start signal is achieved by changing the port to output and then writing the port + delay.
//Change data_port to output
data_port = 0;
delay_us(1000);
data_port = 1;
delay_us(20);
//Change data_port to input
Data reading function implementation
According to the description of the above protocol, it is easy to abstract the following functions:
static unsigned char am2302_read_byte(void)
{
unsigned char i = 0;
unsigned char data = 0;
for (i = 0; i < 8; i++)
{
//50us low
while (0 == data_port)
{
}
delay_us(40);
if (0 == data_port)
{
continue;
}
else
{
data += (0x80U >> i);
while (1 == data_port)
{
}
}
}
return data;
}
By calling am2302_read_byte() 5 times, 40 bits of data are read out.
humidity_hign = am2302_read_byte();
humidity_low = am2302_read_byte();
temperature_high = am2302_read_byte();
temperature_low = am2302_read_byte();
checksum = am2302_read_byte();
Why can't the above function be used?
In some application scenarios, in order to reduce power consumption, the operating frequency of the MCU needs to be reduced to the lowest possible level.
If the system clock is very low, the instruction cycle becomes a key factor to be considered.
Here we take the PIC microcontroller as an example. If the system clock is 1 MHz, its instruction cycle is 4 microseconds.
(The instruction cycle is 4 times of the system clock).
At this time, if you use the function calling method mentioned above, you will not be able to get the correct data.
Because of the function call overhead, when am2302_read_byte() performs level judgment,
It is very likely that the start level has been missed, resulting in incorrect parsing. In addition, when it is judged that the data bit is 1,
data += (0x80U >> i);
while (1 == data_port)
{
}
Theoretically, the above operation should be completed in 40 to 50 microseconds, which is about 10 to 12 assembly instructions.
However, the above operations will currently be converted into many assembly instructions, which consumes too much time and causes incorrect parsing of subsequent data bits.
solution
A simple solution is to continue using the above function, but increase the system clock before calling it to shorten the instruction cycle.
It has some impact on power consumption, but the impact is not too big. The more fatal thing here is that when you improve the system, all peripherals that rely on the system clock, such as timers, need to be reset. When the temperature and humidity readings are completed, all have to be switched back.
Is it possible to optimize the above data reading function and reduce the generated assembly instructions so that it can
At 1 MHz system clock, data reading is completed?
How to improve the idea of using space to exchange time, cancel the function call, and expand the logic inside. This can be achieved using macro functions.
#define am2302_read_byte(data)
am2302_read_bit(data)
am2302_read_bit(data)
am2302_read_bit(data)
am2302_read_bit(data)
am2302_read_bit(data)
am2302_read_bit(data)
am2302_read_bit(data)
am2302_read_bit(data)
Optimize the implementation logic of data bit 1 and convert the shift operation into a fixed value assignment operation.
#define am2302_read_byte(data)
am2302_read_bit(data, 0x80)
am2302_read_bit(data, 0x40)
am2302_read_bit(data, 0x20)
am2302_read_bit(data, 0x10)
am2302_read_bit(data, 0x08)
am2302_read_bit(data, 0x04)
am2302_read_bit(data, 0x02)
am2302_read_bit(data, 0x01)
#define am2302_read_bit(data, bitmask)
while (0 == am2302_data_PORT)
{
}
__delay_us(26);
if (1 == am2302_data_PORT)
{
NOP();
NOP();
if (1 == am2302_data_PORT)
{
data += bitmask;
while (1 == am2302_data_PORT)
{
}
}
}
However, in the actual debugging process, it is found that sometimes the data cannot be completely parsed. Especially when there are a lot of data bits 1, it is often not possible to parse correctly. At this time, it is necessary to carefully analyze the generated assembly code of data bit 1.
movlb 0 ; select bank0
btfss 12,0 ;volatile //Judge I/O, equivalent to if (1 == am2302_data_PORT)
goto l435 //I/O is not 1, jump to the next data bit judgment logic
movlw 128 //I/O is 1, add 1 to the data, two instructions are used here
addwf _g_th,f
l435:
Use |= to replace += and turn the addition operation of two instructions into one instruction.
if (1 == am2302_data_PORT)
{
data |= bitmask;
while (1 == am2302_data_PORT)
{
}
}
The assembly code it generates becomes:
movlb 0 ; select bank0
btfss 12,0 ;volatile
goto l435
bsf _g_th,7
l435:
Finish
Using the above solution, the PIC microcontroller can communicate with the AM2302 in a single-line manner at a system clock of 1 MHz.
Previous article:How to connect a rotary encoder using a PIC microcontroller
Next article:Analysis of single chip computer key scanning program, display program and delay program
- Popular Resources
- Popular amplifiers
- Learn ARM development(16)
- Learn ARM development(17)
- Learn ARM development(18)
- Embedded system debugging simulation tool
- A small question that has been bothering me recently has finally been solved~~
- Learn ARM development (1)
- Learn ARM development (2)
- Learn ARM development (4)
- Learn ARM development (6)
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- LED chemical incompatibility test to see which chemicals LEDs can be used with
- Application of ARM9 hardware coprocessor on WinCE embedded motherboard
- What are the key points for selecting rotor flowmeter?
- LM317 high power charger circuit
- A brief analysis of Embest's application and development of embedded medical devices
- Single-phase RC protection circuit
- stm32 PVD programmable voltage monitor
- Introduction and measurement of edge trigger and level trigger of 51 single chip microcomputer
- Improved design of Linux system software shell protection technology
- What to do if the ABB robot protection device stops
- Wi-Fi 8 specification is on the way: 2.4/5/6GHz triple-band operation
- Wi-Fi 8 specification is on the way: 2.4/5/6GHz triple-band operation
- Vietnam's chip packaging and testing business is growing, and supply-side fragmentation is splitting the market
- Vietnam's chip packaging and testing business is growing, and supply-side fragmentation is splitting the market
- Three steps to govern hybrid multicloud environments
- Three steps to govern hybrid multicloud environments
- Microchip Accelerates Real-Time Edge AI Deployment with NVIDIA Holoscan Platform
- Microchip Accelerates Real-Time Edge AI Deployment with NVIDIA Holoscan Platform
- Melexis launches ultra-low power automotive contactless micro-power switch chip
- Melexis launches ultra-low power automotive contactless micro-power switch chip
- [GigaDevice GD32F310 Review] + Interactive Detection Device
- Unboxing record of the new IoT player mPower1203
- 4. Differential and Integral Circuits
- Is there a green, free-installation version of Excel for download?
- [CB5654 Intelligent Voice Development Board Review] Create a sample project and download the test
- GPIO3_28, why is it still shown as occupied?
- [ESP32-Audio-Kit Audio Development Board Review] 1. Unboxing and Doubts about the Factory Firmware
- Did you know? Tektronix MSO6 Series oscilloscopes make it easy to characterize jitter on GHz clocks and serial buses
- Optimizing DSP Power Budget by Adjusting Voltage Regulators
- Rapoo Multi-mode Bluetooth Mouse M600 Disassembly