one-wire(单总线)组件
Posted wangyanwen
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了one-wire(单总线)组件相关的知识,希望对你有一定的参考价值。
单总线:
单总线是美国DALLAS公司推出的外围串行扩展总线技术。与SPI、I²C串行数据通信方式不同.它采用单根信号线,既传输时钟又传输数据,而且数据传输是双向的,具有节省I/O口线、资源结构简单、成本低廉、便于总线扩展和维护等诸多优点。
原理
单总线器件内部设置有寄生供电电路(Parasite Power Circuit)。当单总线处于高电平时,一方面通过二极管VD向芯片供电,另方面对内部电容C(约800pF)充电;当单总线处于低电平时,二极管截止,内部电容c向芯片供电。由于电容c的容量有限,因此要求单总线能间隔地提供高电平以能不断地向内部电容C充电、维持器件的正常工作。这就是通过网络线路“窃取”电能的“寄生电源”的工作原理。要注意的是,为了确保总线上的某些器件在工作时(如温度传感器进行温度转换、E2PROM写人数据时)有足够的电流供给,除了上拉电阻之外,还需要在总线上使用MOSFET(场效应晶体管)提供强上拉供电。单总线的数据传输速率一般为16.3Kbit/s,最大可达142 Kbit/s,通常情况下采用100Kbit/s以下的速率传输数据。主设备I/O口可直接驱动200m范围内的从设备,经过扩展后可达1km范围。
结构
单总线主机或从机设备通过一个漏极开路或三态端口连接至该数据线,这样允许设备在不发送数据时释放数据总线,以允许设备在不发送数据时能够释放总线,而让其他设备使用总线,其内部等效电路如图9—20所示。
单总线要求外接一个约5 k的上拉电阻.这样,当单总线在闲置时,状态为高电平。如果传输过程需要暂时挂起,且要求传输过程还能够继续,则总线必须处于空闲状态。
传输之间的恢复时间没有限制,只要总线在恢复期间处于空闲状态(高电平)。如果总线保持低电平超过480 us,总线上的所有器件将复位。另外,在寄生方式供电时,为了保证单总线器件在某些工作状态下(如:温度转换器件、EEPROM写入等)具有足够的电源电流,必须在总线上提供强上拉。
命令序列
1一wire协议定义了复位脉冲、应答脉冲、写0、读0和读1时序等几种信号类型。所有的单总线命令序列(初始化ROM命令,功能命令)都是由这些基本的信号类型组成。在这些信号中,除了应答脉冲外,其他均由主机发出同步信号、命令和数据,都是字节的低位在前。典型的单总线命令序列如下:
第一步:初始化。
第二步:ROM命令.跟随需要交换的数据。
第三步:功能命令,跟随需要交换的数据。
每次访问单总线器件.都必须遵守这个命令序列.如果序列出现混乱,则单总线器件不会响应主机。但是这个准则对于搜索ROM命令和报警搜索命令例外,在执行两者中任何一条命令后,主机不能执行其他功能命令,必须返回至第一步。
(1)初始化
单总线上的所有传输都是从初始化开始的,初始化过程由主机发出的复位脉冲和从机响应的应答脉冲组成.应答脉冲使主机知道总线上有从机设备,且准备就绪。
(2)ROM命令
当主机检测到应答脉冲后,就发出ROM命令,这些命令与各个从机设备的唯一64位ROM代码相关,允许主机在单总线上连接多个从设备时,指定操作某个从设备。使得主机可以操作某个从机设备。这些命令能使主机检测到总线上有多少个从机设备以及设备类型,或者有没有设备处于报警状态。从机设备支持5种ROM命令,每种命令长度为8位。丰机在发出功能命今之前.必须发出ROM命今.
(3)功能命令
主机发出ROM命令,访问指定的从机,接着发出某个功能命令。这些命令允许主机写入或读出从机暂存器、启动工作以及判断从机的供电方式。
one_wire.c
1 /** 2 * @file one_wire.c 3 * @brief 4 * @version 0.1 5 * @date 2019-06-28 6 * 7 * !!!注意单总线GPIO脚必须有上拉,读写数据均为低位在前高位在后。 8 * 9 * @copyright Copyright (c) 2019 10 * 11 */ 12 /*----------------------------------------------------------------------------- 13 include 14 -----------------------------------------------------------------------------*/ 15 #include "one_wire.h" 16 #include "freertos\FreeRTOS.h" 17 #include "freertos\task.h" 18 #include "freertos\semphr.h" 19 20 /*----------------------------------------------------------------------------- 21 define 22 -----------------------------------------------------------------------------*/ 23 /* 用到的硬件TIMER定义 */ 24 #define ONE_WIRE_TIMER (TIMER0) 25 #define ONE_WIRE_TIMER_IRQ (TIMER0_IRQn) 26 #define ONE_WIRE_TIMER_US (get_apb_clk()/1000000) 27 /* 发送复位信号延时定义 */ 28 #define ONE_WIRE_SEND_RESET_TIMER_US (480)/* 发送复位时间 */ 29 #define ONE_WIRE_READ_RESPOND_TIMER_US (70)/* 读取响应时间 */ 30 #define ONE_WIRE_RESPOND_CONTINUE_TIMER_US (480)/* 响应持续时间 */ 31 /* 写数据信号延时定义 */ 32 #define ONE_WIRE_WRITE_PREPARE_TIMER_US (15)/* 写数据准备时间 */ 33 #define ONE_WIRE_WRITE_TIMER_US (30)/* 写数据时间 */ 34 #define ONE_WIRE_WRITE_CONTINUE_TIMER_US (65)/* 写数据持续时间 */ 35 /* 读数据信号延时定义 */ 36 #define ONE_WIRE_READ_PREPARE_TIMER_US (3)/* 读数据准备时间 */ 37 #define ONE_WIRE_READ_TIMER_US (13)/* 读数据时间 */ 38 #define ONE_WIRE_READ_CONTINUE_TIMER_US (63)/* 读数据持续时间 */ 39 40 /*----------------------------------------------------------------------------- 41 extern 42 -----------------------------------------------------------------------------*/ 43 44 /*----------------------------------------------------------------------------- 45 struct / enum / union 46 -----------------------------------------------------------------------------*/ 47 /* 整体状态类型 */ 48 typedef enum 49 50 ONE_WIRE_RESET_STATE = 0, 51 ONE_WIRE_WRITE_STATE = 1, 52 ONE_WIRE_READ_STATE = 2, 53 one_wire_state_t; 54 55 /* 复位状态类型 */ 56 typedef enum 57 58 ONE_WIRE_RESET_PREPARE_STATE = 0, 59 ONE_WIRE_RESET_TIME_STATE = 1, 60 ONE_WIRE_RESET_CONTINUE_STATE = 2, 61 ONE_WIRE_RESET_END_STATE = 3, 62 one_wire_reset_state_t; 63 64 /* 写状态类型 */ 65 typedef enum 66 67 ONE_WIRE_WRITE_PREPARE_STATE = 0, 68 ONE_WIRE_WRITE_TIME_STATE = 1, 69 ONE_WIRE_WRITE_CONTINUE_STATE = 2, 70 ONE_WIRE_WRITE_END_STATE = 3, 71 one_wire_write_state_t; 72 73 /* 读状态类型 */ 74 typedef enum 75 76 ONE_WIRE_READ_PREPARE_STATE = 0, 77 ONE_WIRE_READ_TIME_STATE = 1, 78 ONE_WIRE_READ_CONTINUE_STATE = 2, 79 ONE_WIRE_READ_END_STATE = 3, 80 one_wire_read_state_t; 81 82 /*----------------------------------------------------------------------------- 83 global 84 -----------------------------------------------------------------------------*/ 85 static one_wire_config one_wire = GPIO0, 86 gpio_pin_0, 87 UART1_TX_PAD, 88 THIRD_FUNCTION ;/*!< 默认GPIO配置 */ 89 90 static one_wire_state_t one_wire_state;/*!< 整体状态 */ 91 static one_wire_reset_state_t one_wire_reset_state;/*!< 复位状态 */ 92 static one_wire_write_state_t one_wire_write_state;/*!< 写数据状态 */ 93 static one_wire_read_state_t one_wire_read_state;/*!< 读数据状态 */ 94 95 SemaphoreHandle_t one_wire_lock;/*!< 互斥信号量 */ 96 97 static uint8_t one_wire_data;/*!< 读写数据临时变量 */ 98 99 /*----------------------------------------------------------------------------- 100 declare 101 -----------------------------------------------------------------------------*/ 102 103 /*----------------------------------------------------------------------------- 104 function 105 -----------------------------------------------------------------------------*/ 106 /** 107 * @brief 毫秒级延时 108 * 109 * @param us 毫秒数 110 */ 111 static void one_wire_delay_us(uint32_t us) 112 113 /* 毫秒级延时 */ 114 timer_set_count(ONE_WIRE_TIMER,us * ONE_WIRE_TIMER_US); 115 timer_start(ONE_WIRE_TIMER); 116 117 118 /** 119 * @brief 初始化 120 * 121 */ 122 int8_t one_wire_init(one_wire_config* config) 123 124 if(NULL != config) 125 126 /* 保存配置信息 */ 127 one_wire.one_wire_gpio_group = config->one_wire_gpio_group; 128 one_wire.one_wire_gpio_pin = config->one_wire_gpio_pin; 129 one_wire.one_wire_gpio_pad = config->one_wire_gpio_pad; 130 one_wire.one_wire_gpio_func = config->one_wire_gpio_func; 131 132 /* 初始化GPIO */ 133 Scu_SetDeviceGate((unsigned int)one_wire.one_wire_gpio_group,ENABLE); 134 Scu_Setdevice_Reset((unsigned int)one_wire.one_wire_gpio_group); 135 Scu_Setdevice_ResetRelease((unsigned int)one_wire.one_wire_gpio_group); 136 Scu_SetIOReuse(one_wire.one_wire_gpio_pad,one_wire.one_wire_gpio_func); 137 /* 初始化TIMER */ 138 Scu_SetDeviceGate(ONE_WIRE_TIMER,ENABLE); 139 Scu_Setdevice_Reset(ONE_WIRE_TIMER); 140 Scu_Setdevice_ResetRelease(ONE_WIRE_TIMER); 141 __NVIC_SetVector(ONE_WIRE_TIMER_IRQ,(uint32_t)one_wire_timer_handler); 142 NVIC_EnableIRQ(ONE_WIRE_TIMER_IRQ); 143 timer_init_t init; 144 init.mode = timer_count_mode_single; 145 init.div = timer_clk_div_0; 146 init.width = timer_iqr_width_2; 147 init.count = 0xFFFFFFFF; 148 timer_init(ONE_WIRE_TIMER,init); 149 one_wire_lock = xSemaphoreCreateCounting(1,0); 150 if(NULL == one_wire_lock) 151 152 return RETURN_ERR; 153 154 return RETURN_OK; 155 156 157 /** 158 * @brief 发送复位信号 159 * 160 */ 161 void one_wire_reset(void) 162 163 one_wire_state = ONE_WIRE_RESET_STATE; 164 one_wire_reset_state = ONE_WIRE_RESET_PREPARE_STATE; 165 one_wire_delay_us(1); 166 xSemaphoreTake(one_wire_lock,portMAX_DELAY); 167 168 169 /** 170 * @brief 写一个byte 171 * 172 * @param data 数据 173 */ 174 static void one_wire_write_byte(uint8_t data) 175 176 one_wire_state = ONE_WIRE_WRITE_STATE; 177 one_wire_write_state = ONE_WIRE_WRITE_PREPARE_STATE; 178 one_wire_data = data; 179 one_wire_delay_us(1); 180 xSemaphoreTake(one_wire_lock,portMAX_DELAY); 181 182 183 /** 184 * @brief 读一个byte 185 * 186 * @return uint8_t data 187 */ 188 static uint8_t one_wire_read_byte(void) 189 190 one_wire_state = ONE_WIRE_READ_STATE; 191 one_wire_read_state = ONE_WIRE_READ_PREPARE_STATE; 192 one_wire_delay_us(1); 193 xSemaphoreTake(one_wire_lock,portMAX_DELAY); 194 return one_wire_data; 195 196 197 /** 198 * @brief 写数据 199 * 200 * @param data 数据 201 * @param len 长度 202 */ 203 void one_wire_write(uint8_t *data,uint32_t len) 204 205 for (int i = 0; i < len; i++) 206 207 one_wire_write_byte(data[i]); 208 209 210 211 /** 212 * @brief 读数据 213 * 214 * @param data 数据 215 * @param len 长度 216 */ 217 void one_wire_read(uint8_t *data,uint32_t len) 218 219 memset(data,0,len); 220 for (int i = 0; i < len; i++) 221 222 data[i] = one_wire_read_byte(); 223 224 225 226 /** 227 * @brief TIMER中断处理函数 228 * 229 */ 230 void one_wire_timer_handler(void) 231 232 static uint8_t count = 0; 233 switch (one_wire_state) 234 235 /* 发送复位信号流程 */ 236 case ONE_WIRE_RESET_STATE: 237 switch (one_wire_reset_state) 238 239 case ONE_WIRE_RESET_PREPARE_STATE: 240 gpio_set_output_mode(one_wire.one_wire_gpio_group,one_wire.one_wire_gpio_pin); 241 gpio_set_output_low_level(one_wire.one_wire_gpio_group,one_wire.one_wire_gpio_pin); 242 one_wire_delay_us(ONE_WIRE_SEND_RESET_TIMER_US); 243 one_wire_reset_state = ONE_WIRE_RESET_TIME_STATE; 244 break; 245 case ONE_WIRE_RESET_TIME_STATE: 246 gpio_set_input_mode(one_wire.one_wire_gpio_group,one_wire.one_wire_gpio_pin); 247 one_wire_delay_us(ONE_WIRE_READ_RESPOND_TIMER_US); 248 one_wire_reset_state = ONE_WIRE_RESET_CONTINUE_STATE; 249 break; 250 case ONE_WIRE_RESET_CONTINUE_STATE: 251 if(gpio_get_input_level_single(one_wire.one_wire_gpio_group,one_wire.one_wire_gpio_pin)) 252 253 mprintf("从机未响应 %s %d\n",__FILE__,__LINE__); 254 return; 255 256 one_wire_delay_us(ONE_WIRE_RESPOND_CONTINUE_TIMER_US - ONE_WIRE_READ_RESPOND_TIMER_US); 257 one_wire_reset_state = ONE_WIRE_RESET_END_STATE; 258 break; 259 case ONE_WIRE_RESET_END_STATE: 260 xSemaphoreGiveFromISR(one_wire_lock,NULL); 261 break; 262 default: 263 break; 264 265 break; 266 /* 发送写数据信号流程 */ 267 case ONE_WIRE_WRITE_STATE: 268 switch (one_wire_write_state) 269 270 case ONE_WIRE_WRITE_PREPARE_STATE: 271 gpio_set_output_mode(one_wire.one_wire_gpio_group,one_wire.one_wire_gpio_pin); 272 gpio_set_output_low_level(one_wire.one_wire_gpio_group,one_wire.one_wire_gpio_pin); 273 one_wire_delay_us(ONE_WIRE_WRITE_PREPARE_TIMER_US); 274 one_wire_write_state = ONE_WIRE_WRITE_TIME_STATE; 275 break; 276 case ONE_WIRE_WRITE_TIME_STATE: 277 if(one_wire_data) 278 279 gpio_set_input_mode(one_wire.one_wire_gpio_group,one_wire.one_wire_gpio_pin); 280 281 one_wire_delay_us(ONE_WIRE_WRITE_TIMER_US - ONE_WIRE_WRITE_PREPARE_TIMER_US); 282 one_wire_write_state = ONE_WIRE_WRITE_CONTINUE_STATE; 283 break; 284 case ONE_WIRE_WRITE_CONTINUE_STATE: 285 one_wire_delay_us(ONE_WIRE_WRITE_CONTINUE_TIMER_US - ONE_WIRE_WRITE_TIMER_US - ONE_WIRE_WRITE_PREPARE_TIMER_US); 286 count++; 287 if(8 != count) 288 289 one_wire_write_state = ONE_WIRE_WRITE_PREPARE_STATE; 290 291 else 292 293 one_wire_write_state = ONE_WIRE_WRITE_END_STATE; 294 count = 0; 295 296 break; 297 case ONE_WIRE_WRITE_END_STATE: 298 xSemaphoreGiveFromISR(one_wire_lock,NULL); 299 break; 300 default: 301 break; 302 303 break; 304 /* 发送读数据信号流程 */ 305 case ONE_WIRE_READ_STATE: 306 switch (one_wire_read_state) 307 308 case ONE_WIRE_READ_PREPARE_STATE: 309 one_wire_data = 0; 310 gpio_set_output_mode(one_wire.one_wire_gpio_group,one_wire.one_wire_gpio_pin); 311 gpio_set_output_low_level(one_wire.one_wire_gpio_group,one_wire.one_wire_gpio_pin); 312 one_wire_delay_us(ONE_WIRE_READ_PREPARE_TIMER_US); 313 one_wire_read_state = ONE_WIRE_READ_TIME_STATE; 314 break; 315 case ONE_WIRE_READ_TIME_STATE: 316 one_wire_delay_us(ONE_WIRE_READ_TIMER_US - ONE_WIRE_READ_PREPARE_TIMER_US); 317 one_wire_read_state = ONE_WIRE_READ_CONTINUE_STATE; 318 break; 319 case ONE_WIRE_READ_CONTINUE_STATE: 320 one_wire_data |= gpio_get_input_level_single(one_wire.one_wire_gpio_group,one_wire.one_wire_gpio_pin) << count; 321 one_wire_delay_us(ONE_WIRE_READ_CONTINUE_TIMER_US - ONE_WIRE_READ_TIMER_US - ONE_WIRE_READ_PREPARE_TIMER_US); 322 count++; 323 if(8 != count) 324 325 one_wire_read_state = ONE_WIRE_READ_PREPARE_STATE; 326 327 else 328 329 one_wire_read_state = ONE_WIRE_READ_END_STATE; 330 count = 0; 331 332 break; 333 case ONE_WIRE_READ_END_STATE: 334 xSemaphoreGiveFromISR(one_wire_lock,NULL); 335 break; 336 default: 337 break; 338 339 break; 340 default: 341 break; 342 343
one_wire.h
/** * @file one_wire.h * @brief DHT11传感器的头文件 * @version 0.1 * @date 2019-07-02 * * @copyright Copyright (c) 2019 * */ #ifndef __ONE_WIRE_H__ #define __ONE_WIRE_H__ /** * @ingroup components * @defgroup one_wire 单总线 * @brief 单总线组件 * @ */ #ifdef __cplusplus extern "C" #endif /*----------------------------------------------------------------------------- include -----------------------------------------------------------------------------*/ #include "stdint.h" #include "string.h" #include "ci110x_timer.h" #include "ci110x_gpio.h" #include "ci110x_scu.h" #include "ci_log.h" /*----------------------------------------------------------------------------- define -----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------- extern -----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------- struct / enum / union -----------------------------------------------------------------------------*/ /* 单总线配置结构体 */ typedef struct gpio_base_t one_wire_gpio_group;/*!< GPIO组 */ gpio_pin_t one_wire_gpio_pin;/*!< GPIO_PINX */ PinPad_Name one_wire_gpio_pad;/*!< PAD名称 */ IOResue_FUNCTION one_wire_gpio_func;/*!< 第几功能是GPIO */ one_wire_config; /*----------------------------------------------------------------------------- global -----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------- function declare -----------------------------------------------------------------------------*/ int8_t one_wire_init(one_wire_config* config); void one_wire_reset(void); void one_wire_write(uint8_t *data,uint32_t len); void one_wire_read(uint8_t *data,uint32_t len); void one_wire_timer_handler(void); #ifdef __cplusplus #endif /** * @ */ #endif /*----------------------------------------------------------------------------- end of the file -----------------------------------------------------------------------------*/
脱命散人 2019.9.2 [记]
以上是关于one-wire(单总线)组件的主要内容,如果未能解决你的问题,请参考以下文章