标签:推出 流程 send 其他 电源 start span mode str
单总线是美国DALLAS公司推出的外围串行扩展总线技术。与SPI、I²C串行数据通信方式不同.它采用单根信号线,既传输时钟又传输数据,而且数据传输是双向的,具有节省I/O口线、资源结构简单、成本低廉、便于总线扩展和维护等诸多优点。
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 }
/** * @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 [记]
标签:推出 流程 send 其他 电源 start span mode str
原文地址:https://www.cnblogs.com/wangyanwen/p/11445326.html