ARM-LINUX-based Temperature Sensor driving

Source: Internet
Author: User

Temperature Sensor driving based on ARM-LINUX (1)

Author: Feng Jian,Hua Qing vision embedded college lecturer.

DS18B20 digital temperature sensor wiring is convenient, encapsulated into can be used in a variety of occasions, such as pipe type, threaded type, magnet Adsorption Type, stainless steel encapsulation type, a variety of models, LTM8877, LTM8874 and so on. It mainly changes its appearance based on different application scenarios. The encapsulated DS18B20 can be used for non-extreme temperature scenarios, such as cable trench temperature measurement, blast furnace water circulation temperature measurement, boiler temperature measurement, data center temperature measurement, Agricultural Greenhouse temperature measurement, clean room temperature measurement, and ammunition library temperature measurement. It is suitable for digital temperature measurement and control of various small-space devices.

Technical Performance description

1. Unique single-line interface. When DS18B20 is connected to a microprocessor, only one port line is required to implement two-way communication between the microprocessor and DS18B20.
2. Temperature Measurement Range:-55 ℃ ~ + 125 ℃, inherent temperature resolution 0.5 ℃.
3. Supports multi-point networking. Multiple DS18B20 can be connected to a unique three-line network.
4. Working Power Supply: 3 ~ 5 V/DC
5. No peripheral components are required during use.
6. the measurement result is 9 ~ 12-digit serial transmission


DS18b20 Encapsulation

DS18B20 pin function: GND voltage ground • DQ Single Data Bus • VDD power supply voltage • NC empty pin


Connection between DS18b20 and processor

Operating Principle and Application of DS18B20

The Temperature Detection of DS18B20 is fully integrated with the digital data output on a single chip to improve anti-interference. A working cycle can be divided into two parts: Temperature Detection and data processing. Before explaining the workflow, we need to understand the internal memory resources of 18b20. 18b20 has three types of storage resources. They are:

Rom read-only memory:

It is used to store the DS18B20 encoding. the first 8 digits are single-line series encoding (the DS18B20 encoding is 19 h), and the last 48 digits are the unique serial number of the chip, the last 8 bits are the CRC codes of the 56 bits (redundancy verification ). Data cannot be changed during production. A total of 64-bit DS18B20 Rom.

Ram Data Storage:

It is used for internal computing and data access. Data is lost after power loss. A total of 9 bytes of RAM are DS18B20, each of which is 8 bits. 1st and 2 bytes are the data value information after temperature conversion, and 3rd and 4 bytes are the image of the user's EEPROM (commonly used for storing temperature alarm values. The value will be refreshed when the power-on is reset. The first byte is the user's 5th EEPROM image. 6th, 7, and 8 bytes are counting registers designed to provide users with a higher temperature resolution. They are also temporary storage units for internal temperature conversion and calculation. The 9th bytes are the CRC code of the first 8 bytes. EEPROM non-volatile memory, used to store data that needs to be stored for a long time, the upper and lower temperature alarm value and verification data,
DS18B20 has a total of 3-bit EEPROM and images exist in Ram to facilitate user operations.

The procedure for the Controller to operate on 18b20 is as follows:

1. Reset: first, we must reset the DS18B20 chip. Reset is a low-level signal from the Controller (single-chip microcomputer) to at least us on the single-bus DS18B20. When 18b20 receives this reset signal, it will be in the range of 15 ~ After 60 us, a chip pulse is sent back.

2. Pulse: After the reset level ends, the Controller should increase the data single bus so that ~ There is a pulse after receiving 60 us, and the existing pulse is a 60 ~ US low-level signal. Now, the communication parties have reached a basic agreement, and the next step will be the data communication between the Controller and 18b20. If the reset time is low or the circuit breaking of a single bus is not connected to an existing pulse, you should pay attention to the handling of unexpected situations during design.

3. The controller sends the ROM command. After the two parties have finished greeting each other, they will exchange the ROM command. There are five Rom commands and only one Rom command can be sent in each work cycle, rom Commands include read Rom data, specified matching chip, skip Rom, chip search, and alarm chip search. The Rom instruction is 8-bit in length, which is used to operate the 64-bit optical print Rom in the chip. The main purpose is to identify and process multiple devices attached to a bus. It is true that multiple devices can be mounted on a single bus at the same time and are differentiated by the unique ID number of each device. Generally, Rom commands can be skipped only when a single 18b20 chip is mounted (note: the Rom skipping command does not mean that the Rom is not sent.
Command, but with a unique "Skip command ")

4. The controller sends memory operation commands: After the ROM command is sent to 18b20, the memory operation commands are sent continuously. The operation commands are also 8-bit, with 6 in total, memory Operation commands are used to write Ram data, read Ram data, copy Ram data to EEPROM, temperature conversion, copy the alarm values in EEPROM to ram, and switch the working mode. The function of memory operation commands is what the 18b20 command does, and is the key to Chip Control.

5. execution or data read/write: After a memory operation command is completed, the command execution or data read/write will be performed. This operation depends on the Memory Operation Command. If the temperature conversion command is executed, the Controller (single-chip microcomputer) must wait for 18b20 to execute its command. Generally, the conversion time is us. For example, to execute the data read/write command, you must strictly follow the read/write sequence of 18b20.

To read the current temperature data, we need to execute two work cycles. The first cycle is reset, skip the ROM command, execute the temperature conversion Memory Operation Command, and wait for the temperature conversion time of us. Then, the second cycle is reset, the ROM instruction is skipped, the memory operation instruction for reading Ram is executed, and the data is read (up to 9 bytes, can be stopped in the middle, read-only simple temperature values read the first two bytes ). Other operation procedures are similar, so we will not discuss them here.

On the DS18B20 Data Manual Online resources are more abundant, here is not detailed introduction, the following is based on the ARM-LINUX driver, in the arm-GCC compiled after testing. (The source of the original vision of Hua Qing is reprinted)

# Include <Linux/module. h>
# Include <Linux/moduleparam. h>
# Include <Linux/fs. h>
# Include <Linux/proc_fs.h>
# Include <Linux/errno. h>
# Include <Linux/cdev. h>
# Include <Linux/IOCTL. h>
# Include <linux/fcntl. h>
# Include <linux/sched. h>
# Include <linux/poll. h>
# Include <linux/version. h>
# Include <linux/kernel. h>
# Include <linux/init. h>
# Include <linux/device. h>
# Include <linux/mm. h>
# Include <linux/spinlock. h>
# Include <plat/map. h>
# Include <asm/io. h>
# Include <asm/delay. h>
# Include <asm/memory. h>
# Include <asm/uaccess. h>
# Include <asm/mach/map. h>
# Include <asm/uaccess. h>
# Include <mach/regs-gpio.h>
# Include <mach/map. h>
MODULE_LICENSE ("GPL ");

# Define GPHCON (* (volatile unsigned int *) S3C2410_GPHCON)
# Define gphdat (* (volatile unsigned int *) s3c2410_gphdat)
# Define gphup (* (volatile unsigned int *) s3c2410_gphup)

Static int DS18B20 _ major = 230;/* apply for a device number statically */

Struct cdev;
Struct class * my_class;

Spinlock_t lock;

Dev_t Dev = 0;
Int number_of_devices = 1;

/* Set to input mode */
Void set_conin (void)
{
Gphcon & = ~ (1 <19 );
Gphcon & = ~ (1 <18 );
}

/* Set to output mode */
Void set_conout (void)
{
Gphcon | = (1 <18 );
Gphcon & = ~ (1 <19 );
}

/* Pin position */
Void set_data (int I)
{
If (I = 0 ){
Gphdat & = ~ (1 <9 );
} Else if (I = 1 ){
Gphdat | = (1 <9 );
}
}

/* Reset DS18B20 */
Unsigned int reset_ds18b20 (void)
{
Unsigned int retValue;
Set_conOUT ();

Set_data (1 );
_ Udelay (1 );
Set_data (0 );
_ Udelay (600 );
Set_data (1 );
_ Udelay (20 );
Set_conin ();
_ Udelay (100 );
/* Initialization is successful if x = 0 after a slight delay
X = 1 indicates initialization failure */
Retvalue = (gphdat> 9) & 0x01;
Printk ("init is % d \ n", retvalue );
Return retvalue;
}

/* Read the temperature of one digit */
Unsigned int read_bit (void)
{
Spin_lock (& lock );
Set_conout ();
// Set_data (1 );
// _ Udelay (2 );
Set_data (0 );
_ Udelay (2 );
Set_conIN ();
_ Udelay (1 );
Spin_unlock (& lock );
Return (GPHDAT> 9) & 0x01 );
}

/* Write a command */
Void write_bit (char bitValue)
{
Spin_lock (& lock );
Set_conout ();
Set_data (0 );
_ Udelay (15 );
If (bitvalue = 1 ){
Set_data (1 );
} Else {
Set_data (0 );
}
Spin_unlock (& lock );
_ Udelay (45 );
Set_conin ();
_ Udelay (2 );
}

/* Write command */
Void write_cmd (char cmd)
{
Unsigned char I;
Unsigned char temp;

For (I = 0; I <8; I ++ ){
Temp = cmd> I;
Temp & = 0x01;
Write_bit (temp );
}
// _ Udelay (10 );
}
/* Open the device */
Static int DS18B20 b20_open (struct inode * inode, struct file * filp)
{
Printk (KERN_INFO "HEY! Device opened \ n ");
// GPHUP & = ~ (1 <9 );
Gphup | = (1 <9 );
Spin_lock_init (& lock );
Return 0;
}
/* Read data */
Static int DS18B20 (struct file * filp, char * buffer, size_t count, loff_t * PPOs)
{
Char lowvalue = 0, highvalue = 0;
Unsigned int I;
// Float value;

If (reset_ds18b20 ()){
Printk ("init error \ n ");
}
_ Udelay (400 );
Set_conOUT ();
Set_data (1 );
Write_cmd (0xcc );
Write_cmd (0x44 );
_ Udelay (100000 );

If (reset_ds18b20 ()){
Printk ("init error \ n ");
}
_ Udelay (400 );
Set_conout ();
Set_data (1 );
Write_cmd (0xcc );
Write_cmd (0xbe );
/* Read the temperature conversion value */

For (I = 0; I <8; I ++ ){
If (read_bit ()){
Lowvalue | = (0x01 <I );
}
_ Udelay (62 );
}
Printk ("lowvalue is % d \ n", lowvalue );
For (I = 0; I <8; I ++ ){
If (read_bit ()){
Highvalue | = (0x01 <I );
}
_ Udelay (62 );
}
Printk ("highvalue is % d \ n", highvalue );
# If 0
I = highvalue;
I <= 8;
I = I | lowvalue;
Value = I * 0.0625;
Printk ("kernel is % d \ n", value );
# Endif

Highvalue <= 4;
Highvalue | = (lowvalue & 0xf0)> 4 );

/* Copy the kernel data to the user space */
Copy_to_user (buffer, & highvalue, sizeof (highvalue ));
Return 0;
}
/* Write the command. Leave it empty here */
Static int DS18B20 (struct file * file, const char * buffer, size_t count, loff_t * ppos)
{
Return 0;
}

Static int DS18B20 _ release (struct inode * inode, struct file * filp)
{
Printk (kern_info "device closed \ n ");
Return 0;
}

Static int DS18B20 (struct inode * inode, struct file * file, unsigned int cmd, unsigned long Arg)
{
Return 0;
}

Struct file_operations DS18B20 _fops = {
. Owner = this_module,
. Open = maid,
. Read = maid,
. Write = maid,
. Ioctl = maid,
. Release = DS18B20 _ release,
};
Static void DS18B20 b20_setup_cdev (void)
{
Int error, devno = mkdev (DS18B20 b20_major, 0 );
Cdev_init (& cdev, & DS18B20 b20_fops );
Cdev. Owner = this_module;
Cdev. Ops = & DS18B20 b20_fops;
Error = cdev_add (& cdev, devno, 1 );
If (error)
Printk (kern_info "error % d adding DS18B20 % d \ n", error, 0 );
My_class = class_create (this_module, "my_class ");
If (is_err (my_class ))
{
Printk ("Err: failed in creating class. \ n ");
Return;
}
Device_create (my_class, NULL, devno, NULL, "ds18b20 ");
}
/* Register the device */

Static int DS18B20 (void)
{
Int result;

Dev = MKDEV (DS18B20 b20_major, 0 );
If (DS18B20 _ major)
Result = register_chrdev_region (Dev, 1, "DS18B20 ");
Else {
Result = alloc_chrdev_region (& Dev, 0, 1, "DS18B20 ");
DS18B20 b20_major = major (Dev );
}
If (result <0 ){
Printk (kern_warning "DS18B20: Unable to get Major % d \ n", DS18B20 _ major );
Return result;
}
If (DS18B20 _ major = 0)
DS18B20 b20_major = result;

DS18B20 b20_setup_cdev ();
Printk ("DS18B20 initialized. \ n ");
Return 0;
}

Static void _ exit DS18B20 b20_exit (void)
{
Dev_t devno = mkdev (DS18B20 b20_major, 0 );
Device_destroy (my_class, devno );
Class_destroy (my_class );
Cdev_del (& cdev );
Unregister_chrdev_region (devno, number_of_devices );

Printk ("DS18B20 _ major = % d \ n", DS18B20 _ major );
Printk ("DS18B20 device uninstalled \ n ");
}

Module_init (DS18B20 b20_init );
Module_exit (DS18B20 b20_exit );

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.