STM32串口实现1-wire(一)
来源:互联网 发布:Select as mssql 编辑:程序博客网 时间:2024/05/21 06:51
STM32串口实现1-wire(一)
接线
只需要将STM32的串口的TX线和18B20的DQ相连接,通过4.7K上拉电阻让TX线拉到3.3V即可(PS:就不贴图了)。
实现原理分析
- STM32支持单线半双工通信,看手册大概是说内部TX和RX相连接。也就是发出去的数据能够直接收到。在TX线上没有连接任何设备时发生什么就能接收到什么。
- 串口TTL起始位为低电平,空闲位高电平,这个和1-wire一样。
- 串口1btye数据包括1bit起始位(低电平)、8个数据位、1停止位(高电平)。可以通过串口1byte模拟出1-wire的1bit。
- 1-wire协议写信令,整个写需要60-120us,设备(18B20)在15-60us进行采样。如果将串口的波特率设置成115200,每个bit时间为1000000/115200=8.6us,串口1btye有9位数据组合成t=8.6*9=78us,刚好在1-wire协议范围内,并且采样时间在15-60us,8.6us(串口起始信号)还没有开始采样,通过控制串口发送的数据可以完成写0或者写1。如果串口发生0x00数据,就是1-wire写0信令,如果串口发生0xFF数据,就是1-wire写1信令。
- 1-wire协议读信令,串口发送0xFF,如果串口收到还是0xFF(单线半双工模式,TX和RX内部连接),那么就是读取1,或者就是读到0。
- 1-wire协议复位信令,由于复位的时序要求比较长,115200的波特率无法满足,复位时需要先将波特率设置成9600,复位完成后改成115200。发送0xF0进行复位(串口发生低位在前,发生5个连续的0),复位时长位1000000/9600 * 5us = 520us。如果收到0xF0说明设备没有应答,其他说明设备应答了。
代码实现
- 初始化代码
/**配置串口2*/void DS18B20_init(){ GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; GPIO_PinRemapConfig(GPIO_Remap_USART2, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2 , ENABLE); //USART2_TX PA.2 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD; GPIO_Init(GPIOA, &GPIO_InitStructure); //USART 初始化设置 USART_InitStructure.USART_BaudRate = 115200;//默认设置成115200 USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_StopBits = USART_StopBits_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(USART2, &USART_InitStructure); // USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);//开启中断 USART_Cmd(USART2, ENABLE); //使能串口 USART_HalfDuplexCmd(USART2, ENABLE);}
只配置了TX管脚,使能单线半双工模式(USART_HalfDuplexCmd函数)
- 复位操作
/**复位18B20,*返回0:找到设备,设备响应。*返回1:没有找到设备,设置无响应*/int DS18B20_Reset()//复位18B20{ unsigned char status ; USART_InitTypeDef USART_InitStructure; USART_InitStructure.USART_BaudRate = 9600;//一般设置为9600; USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_StopBits = USART_StopBits_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(USART2, &USART_InitStructure); USART_Cmd(USART2, ENABLE); USART_SendData(USART2,0xF0); //发送0xF0 低电平时长位 1/9600 * 1000 * 1000 * 5 us = 520us while (USART_GetFlagStatus(USART2, USART_FLAG_TC) == RESET) //等待传输完成 { } while (USART_GetFlagStatus(USART2, USART_FLAG_RXNE) == RESET) //等待发送完成 { } while(USART_GetFlagStatus(USART2, USART_FLAG_RXNE) != RESET)//等待收到数据,TX和RX内部连接,肯定能收到数据 { status = USART_ReceiveData(USART2); USART_ClearFlag(USART2,USART_FLAG_RXNE); } USART_InitStructure.USART_BaudRate = 115200;//将波特率改为115200 USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_StopBits = USART_StopBits_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(USART2, &USART_InitStructure); if(status == 0xF0) return 1; else return 0;}
- 写1Byte操作
void DS18B20_WriteBit(unsigned char bit){ if(bit) USART_SendData(USART2,0xFF); else USART_SendData(USART2,0x00); while (USART_GetFlagStatus(USART2, USART_FLAG_TC) == RESET) //等待传输完成 { } while (USART_GetFlagStatus(USART2, USART_FLAG_RXNE) == RESET) //等待收到数据 { } USART_ReceiveData(USART2); USART_ClearFlag(USART2,USART_FLAG_RXNE);}void DS18B20_WriteByte(unsigned char byte){ int i; for(i = 0 ; i < 8 ; i++)//8字节的数据组合成1字节 1-wire数据 { DS18B20_WriteBit((byte>>i) &0x01); }}
- 读1Byte操作
char DS18B20_ReadBit()//读取一位数据{ unsigned char status; USART_SendData(USART2,0xFF); while (USART_GetFlagStatus(USART2, USART_FLAG_TC) == RESET) //等待传输完成 { } while (USART_GetFlagStatus(USART2, USART_FLAG_RXNE) == RESET) //等待传输完成 { } status = USART_ReceiveData(USART2); USART_ClearFlag(USART2,USART_FLAG_RXNE); if(status == 0xFF) status = 1; else status = 0; return status;}char DS18B20_ReadByte(){ unsigned char status = 0; int i; for(i = 0 ; i < 8 ; i++) { status |= (DS18B20_ReadBit() << i); } return status;}
- 18B20启动转换
void DS18B20_Start(){ int i = 0xFFFF; DS18B20_reset(); DS18B20_WriteByte(0xCC);//跳过网络地址 DS18B20_WriteByte(0x44);//启动转换 while(i--);//等待转换完成}
- 读取18B20温度值
float DS18B20_GetTemp(){ unsigned char TL,TH ,t; short tem; float temp; DS18B20_Start(); DS18B20_reset(); DS18B20_WriteByte(0xCC);//跳过网络地址 DS18B20_WriteByte(0xBE);//读取温度值 TL=DS18B20_ReadByte(); // LSB TH=DS18B20_ReadByte(); // MSB if(TH>7) { TH=~TH; TL=~TL; t=0;//温度为负 }else t=1;//温度为正 tem=TH; //获得高八位 tem<<=8; tem+=TL;//获得底八位 temp = (float)tem*0.0625; if(t)return temp; //返回温度值 else return -temp; }
问题
- 在读取数据由于串口发送的是0xFF,将1-wire总线拉高,如果1-wire设备输出0时,此时会强制将1-wire总线拉低,即是TX线输出高电平,1-wire设备输出低电平,有可能将TX管脚烧掉(类似直接把TX线接到地上了),下一篇改进问题。
0 0
- STM32串口实现1-wire(一)
- STM32串口实现1-wire(二)
- STM32 串口DMA(一)
- stm32串口学习(一)
- STM32、串口、一键下载
- stm32串口-main实现发送
- stm32串口1收发
- stm32串口中断接收一帧数据
- STM32之USART 232串口通信<一>
- STM32串口一键下载电路
- STM32串口1发送,串口2接收
- stm32串口学习(二)
- STM32--USART(串口通信)
- STM32 uCOS下实现串口文件
- IAR +STM32实现printf()输出到串口
- STM32串口实现485双机通信原理
- 1-Wire搜索算法详解(1)
- 1-Wire搜索算法详解(2)
- Photoshop电商网页广告设计实战从入门到精通——互动出版网
- Android Touch事件传递机制
- uva 10420
- iOS开发 MPMoviePlayerController
- memset()的用法
- STM32串口实现1-wire(一)
- iOS9 learn Day-by-Day
- Unity3D之Foam浪花效果
- IOS开发-GCD详解
- vi操作
- JAVA三星题之Galton Box
- JS通过prototype实现继承的简单示例:
- Maven实战 第7章声明周期和插件
- iOS开发笔记--Objective-C实现多继承