之前一直在做驱动方面的整理工作,对驱动的高效性有一些自己的理解这里和大家分享一下。并奉驱动程序,本程序覆盖uart1-8。
串口驱动,这是在每个单片机中可以说是必备接口。可以说大部分产品中都会使用,更有甚者一个产品中用到8个串口。这样一个高效的驱动是决定您产品优劣的关键因素。本文主要针对STM32F4XX系列芯片做的一个驱动接口层。以减少您在开发项目时驱动方面所花费时间,以及为程序达到高效的处理为目的。
从51,pic到现在的STM32,个人感觉STM32这方面做的非常突出,丰富的使用模式,强大的引脚映射功能,强大的处理能力等,给我留下的深刻的印象。
关于串口的使用方式,个人总结出以下三种:
1) 中断接收,状态查询发送:这种方式在单片机时代用的比较多,那时候大部分芯片的处理速度不够快,工业控制接口中大部分使用的是9600波特率,程序简单也就对串口发送数据所用时间要求不高。
2) 中断接收,中断发送:这种方式一般会在对高效性要求较高,或软件实时性高的产品中使用。这种方式的好外在于完全释放了CPU在发送开始到结束这一时间CPU控制权。
3) 中断接口,DMA发送:这种方式的使用场合和模式2相同,效率也相差不多。但这种方式确实比模式2CPU的占用时间会更少。
举个例子来说明以上三种模式。假如要把一堆物品从A点运到B点通过传送带,在这个传送过程中传送带上一次只能运一个物品,模式一:把物品放到传送带A点上,然后等待物品由A点被传到B点,这时再放一个物品到传送带上,以此往复所有物品传送过去。模式二:把物品放到A点的传送带上然后就去忙别的事情,看到物品快被传到B点,马上回来再放一个物品到传送带上。很明显这种方式比模式一多了很多空余时间。模式三:这种模式就牛了,在把物品放到A点之前,直接去找了一个“闲杂人等”过来,把物品交给他由他去发,我们需要再发送时,先问下她是否以发完,如果发完了就把新的物品交给他,如果没发完就等一小回再来找他。哈哈,这样咱们就有更多的时间去忙更多的事情了,也不用一回跑来一回跑去。把跑路的时间给节约出来了。
以上三种模式,很明显得出那种模式发送数据效率最高。我们下面说提供的程序就是使用模式三。
说完发送,再说说接收方式。大家一定发现数据接收都是采用中断方式,是的 本人使用过DMA方式进行过多次测试,在使用方面确实没有中断接收灵活。主要有以下两种情况,1,DMA接收数据的主要判断依据1是接收器满中断,这种情况在实际中很少用,除非您的数据是定长。这种方式同时还会存在一些安全隐患,假如噪声原因多接收到一个字节,那之后数据时序就会错位。2,DMA总线空闲中断,这种方式除非是半双工情况下使用。在全双工时被受到发送完成总线空闲的干扰。所以在数据接收方式上主要使用中断。
在数据接收中断方面还分二种方式,
方式1:顺序接收,在接收到第一个数据时就触发超时定时器,每接收到一个字节时就清一次定时器,都到一组数据接收完毕,定时器会因为触发超时中断。在超时中断中来判断一组数据被接收。这种方式一般会用到实时性的一些协议中,比如MODBUS。
方式2:队列接收,申请一个缓冲区收尾相接,接收到数据时载入队列之中,用户只要定时的去队列中读数据,来使用这些数据。这种方式是window,linux的驱动主要接收方式。他的优点就在于在使用数据时无需关闭中断。也就不用怛心在处理上一组数据时了来新的数据会破坏上组数据内容。在方式1中需要考虑在处理数据时暂时性的关下中断。
以下程序则主要是使用到接收使用方式2,发送数据使用模式3的DMA发送,本驱动程序为可裁切,覆盖串口1-8,通过宏裁切。下面提供了一些接口,这里对接口做一个大概的说明。
打开串口
void BSP_UartOpen(uint8_t COM, uint32_t baud, uint8_t data, uint8_t stop, uint8_t parity);
关闭串口
void BSP_UartClose(uint8_t COM);
向串口中写数据
uint32_t BSP_UartWrite(uint8_t COM, uint8_t *buffter, uint32_t len);
从串口中读数据
uint32_t BSP_UartRead(uint8_t COM, uint8_t *buffter, uint32_t len);
查询串口发送忙碌状态
uint32_t BSP_UartTxIdleState(uint8_t COM);
这个接口主要用在,向串口写数据后,在进行下一次写数据之前需要进行查询。
具体接口的使用方法,函数都有详细的说明。
1 /* 2 ******************************************************************************** 3 * 4 * BSP_Uart.c 5 * 6 * File : BSP_Uart.c 7 * Version : V1.0 8 * Author : whq 9 * Mode : Thumb2 10 * Toolchain : 11 * Description : 串口驱动程序 12 * 13 * History : 14 * Date : 2013.08.12 15 *******************************************************************************/ 16 #include <string.h> 17 18 #include "misc.h" 19 #include "stm32f4xx_gpio.h" 20 #include "stm32f4xx_rcc.h" 21 #include "stm32f4xx_usart.h" 22 #include "stm32f4xx_dma.h" 23 24 25 #include "Queue.h" 26 #include "BSP_Uart.h" 27 28 29 #if COM1_EN 30 static uint8_t COM1_TX_BUFF[BSP_COM1_Tx_BUFF_SIZE] = {0}; 31 static uint8_t COM1_RX_BUFF[BSP_COM1_Rx_BUFF_SIZE] = {0}; 32 static QUEUE8_TYPE COM1_RX_QUEUE = {0}; 33 #endif 34 35 #if COM2_EN 36 static uint8_t COM2_TX_BUFF[BSP_COM2_Tx_BUFF_SIZE] = {0}; 37 static uint8_t COM2_RX_BUFF[BSP_COM2_Rx_BUFF_SIZE] = {0}; 38 static QUEUE8_TYPE COM2_RX_QUEUE = {0}; 39 #endif 40 41 #if COM3_EN 42 static uint8_t COM3_TX_BUFF[BSP_COM3_Tx_BUFF_SIZE] = {0}; 43 static uint8_t COM3_RX_BUFF[BSP_COM3_Rx_BUFF_SIZE] = {0}; 44 static QUEUE8_TYPE COM3_RX_QUEUE = {0}; 45 #endif 46 47 #if COM4_EN 48 static uint8_t COM4_TX_BUFF[BSP_COM4_Tx_BUFF_SIZE] = {0}; 49 static uint8_t COM4_RX_BUFF[BSP_COM4_Rx_BUFF_SIZE] = {0}; 50 static QUEUE8_TYPE COM4_RX_QUEUE = {0}; 51 #endif 52 53 #if COM5_EN 54 static uint8_t COM5_TX_BUFF[BSP_COM5_Tx_BUFF_SIZE] = {0}; 55 static uint8_t COM5_RX_BUFF[BSP_COM5_Rx_BUFF_SIZE] = {0}; 56 static QUEUE8_TYPE COM5_RX_QUEUE = {0}; 57 #endif 58 59 #if COM6_EN 60 static uint8_t COM6_TX_BUFF[BSP_COM6_Tx_BUFF_SIZE] = {0}; 61 static uint8_t COM6_RX_BUFF[BSP_COM6_Rx_BUFF_SIZE] = {0}; 62 static QUEUE8_TYPE COM6_RX_QUEUE = {0}; 63 #endif 64 65 #if COM7_EN 66 static uint8_t COM7_TX_BUFF[BSP_COM7_Tx_BUFF_SIZE] = {0}; 67 static uint8_t COM7_RX_BUFF[BSP_COM7_Rx_BUFF_SIZE] = {0}; 68 static QUEUE8_TYPE COM7_RX_QUEUE = {0}; 69 #endif 70 71 #if COM8_EN 72 static uint8_t COM8_TX_BUFF[BSP_COM8_Tx_BUFF_SIZE] = {0}; 73 static uint8_t COM8_RX_BUFF[BSP_COM8_Rx_BUFF_SIZE] = {0}; 74 static QUEUE8_TYPE COM8_RX_QUEUE = {0}; 75 #endif 76 77 78 79 static USART_TypeDef* const COM_USART[COMn] = { 80 #if COM1_EN 81 BSP_COM1, 82 #endif 83 #if COM2_EN 84 BSP_COM2, 85 #endif 86 #if COM3_EN 87 BSP_COM3, 88 #endif 89 #if COM4_EN 90 BSP_COM4, 91 #endif 92 #if COM5_EN 93 BSP_COM5, 94 #endif 95 #if COM6_EN 96 BSP_COM6, 97 #endif 98 #if COM7_EN 99 BSP_COM7, 100 #endif 101 #if COM8_EN 102 BSP_COM8, 103 #endif 104 }; 105 106 static const uint8_t COM_AF[COMn] = { 107 #if COM1_EN 108 BSP_COM1_AF, 109 #endif 110 #if COM2_EN 111 BSP_COM2_AF, 112 #endif 113 #if COM3_EN 114 BSP_COM3_AF, 115 #endif 116 #if COM4_EN 117 BSP_COM4_AF, 118 #endif 119 #if COM5_EN 120 BSP_COM5_AF, 121 #endif 122 #if COM6_EN 123 BSP_COM6_AF, 124 #endif 125 #if COM7_EN 126 BSP_COM7_AF, 127 #endif 128 #if COM8_EN 129 BSP_COM8_AF, 130 #endif 131 }; 132 133 static const uint8_t COM_TX_AF_PIN[COMn] = { 134 #if COM1_EN 135 BSP_COM1_TX_AF_PIN, 136 #endif 137 #if COM2_EN 138 BSP_COM2_TX_AF_PIN, 139 #endif 140 #if COM3_EN 141 BSP_COM3_TX_AF_PIN, 142 #endif 143 #if COM4_EN 144 BSP_COM4_TX_AF_PIN, 145 #endif 146 #if COM5_EN 147 BSP_COM5_TX_AF_PIN, 148 #endif 149 #if COM6_EN 150 BSP_COM6_TX_AF_PIN, 151 #endif 152 #if COM7_EN 153 BSP_COM7_TX_AF_PIN, 154 #endif 155 #if COM8_EN 156 BSP_COM8_TX_AF_PIN, 157 #endif 158 }; 159 160 static const uint8_t COM_RX_AF_PIN[COMn] = { 161 #if COM1_EN 162 BSP_COM1_RX_AF_PIN, 163 #endif 164 #if COM2_EN 165 BSP_COM2_RX_AF_PIN, 166 #endif 167 #if COM3_EN 168 BSP_COM3_RX_AF_PIN, 169 #endif 170 #if COM4_EN 171 BSP_COM4_RX_AF_PIN, 172 #endif 173 #if COM5_EN 174 BSP_COM5_RX_AF_PIN, 175 #endif 176 #if COM6_EN 177 BSP_COM6_RX_AF_PIN, 178 #endif 179 #if COM7_EN 180 BSP_COM7_RX_AF_PIN, 181 #endif 182 #if COM8_EN 183 BSP_COM8_RX_AF_PIN, 184 #endif 185 }; 186 187 static GPIO_TypeDef* const COM_TX_PORT[COMn] = { 188 #if COM1_EN 189 BSP_COM1_TX_GPIO_PORT, 190 #endif 191 #if COM2_EN 192 BSP_COM2_TX_GPIO_PORT, 193 #endif 194 #if COM3_EN 195 BSP_COM3_TX_GPIO_PORT, 196 #endif 197 #if COM4_EN 198 BSP_COM4_TX_GPIO_PORT, 199 #endif 200 #if COM5_EN 201 BSP_COM5_TX_GPIO_PORT, 202 #endif 203 #if COM6_EN 204 BSP_COM6_TX_GPIO_PORT, 205 #endif 206 #if COM7_EN 207 BSP_COM7_TX_GPIO_PORT, 208 #endif 209 #if COM8_EN 210 BSP_COM8_TX_GPIO_PORT, 211 #endif 212 }; 213 214 static GPIO_TypeDef* const COM_RX_PORT[COMn] = { 215 #if COM1_EN 216 BSP_COM1_RX_GPIO_PORT, 217 #endif 218 #if COM2_EN 219 BSP_COM2_RX_GPIO_PORT, 220 #endif 221 #if COM3_EN 222 BSP_COM3_RX_GPIO_PORT, 223 #endif 224 #if COM4_EN 225 BSP_COM4_RX_GPIO_PORT, 226 #endif 227 #if COM5_EN 228 BSP_COM5_RX_GPIO_PORT, 229 #endif 230 #if COM6_EN 231 BSP_COM6_RX_GPIO_PORT, 232 #endif 233 #if COM7_EN 234 BSP_COM7_RX_GPIO_PORT, 235 #endif 236 #if COM8_EN 237 BSP_COM8_RX_GPIO_PORT, 238 #endif 239 }; 240 241 static const uint32_t COM_USART_CLK[COMn] = { 242 #if COM1_EN 243 BSP_COM1_CLK, 244 #endif 245 #if COM2_EN 246 BSP_COM2_CLK, 247 #endif 248 #if COM3_EN 249 BSP_COM3_CLK, 250 #endif 251 #if COM4_EN 252 BSP_COM4_CLK, 253 #endif 254 #if COM5_EN 255 BSP_COM5_CLK, 256 #endif 257 #if COM6_EN 258 BSP_COM6_CLK, 259 #endif 260 #if COM7_EN 261 BSP_COM7_CLK, 262 #endif 263 #if COM8_EN 264 BSP_COM8_CLK, 265 #endif 266 }; 267 268 static const uint32_t COM_TX_PORT_CLK[COMn] = { 269 #if COM1_EN 270 BSP_COM1_TX_GPIO_CLK, 271 #endif 272 #if COM2_EN 273 BSP_COM2_TX_GPIO_CLK, 274 #endif 275 #if COM3_EN 276 BSP_COM3_TX_GPIO_CLK, 277 #endif 278 #if COM4_EN 279 BSP_COM4_TX_GPIO_CLK, 280 #endif 281 #if COM5_EN 282 BSP_COM5_TX_GPIO_CLK, 283 #endif 284 #if COM6_EN 285 BSP_COM6_TX_GPIO_CLK, 286 #endif 287 #if COM7_EN 288 BSP_COM7_TX_GPIO_CLK, 289 #endif 290 #if COM8_EN 291 BSP_COM8_TX_GPIO_CLK, 292 #endif 293 }; 294 295 static const uint32_t COM_RX_PORT_CLK[COMn] = { 296 #if COM1_EN 297 BSP_COM1_RX_GPIO_CLK, 298 #endif 299 #if COM2_EN 300 BSP_COM2_RX_GPIO_CLK, 301 #endif 302 #if COM3_EN 303 BSP_COM3_RX_GPIO_CLK, 304 #endif 305 #if COM4_EN 306 BSP_COM4_RX_GPIO_CLK, 307 #endif 308 #if COM5_EN 309 BSP_COM5_RX_GPIO_CLK, 310 #endif 311 #if COM6_EN 312 BSP_COM6_RX_GPIO_CLK, 313 #endif 314 #if COM7_EN 315 BSP_COM7_RX_GPIO_CLK, 316 #endif 317 #if COM8_EN 318 BSP_COM8_RX_GPIO_CLK, 319 #endif 320 }; 321 322 static const uint16_t COM_TX_PIN[COMn] = { 323 #if COM1_EN 324 BSP_COM1_TX_PIN, 325 #endif 326 #if COM2_EN 327 BSP_COM2_TX_PIN, 328 #endif 329 #if COM3_EN 330 BSP_COM3_TX_PIN, 331 #endif 332 #if COM4_EN 333 BSP_COM4_TX_PIN, 334 #endif 335 #if COM5_EN 336 BSP_COM5_TX_PIN, 337 #endif 338 #if COM6_EN 339 BSP_COM6_TX_PIN, 340 #endif 341 #if COM7_EN 342 BSP_COM7_TX_PIN, 343 #endif 344 #if COM8_EN 345 BSP_COM8_TX_PIN, 346 #endif 347 }; 348 349 static const uint16_t COM_RX_PIN[COMn] = { 350 #if COM1_EN 351 BSP_COM1_RX_PIN, 352 #endif 353 #if COM2_EN 354 BSP_COM2_RX_PIN, 355 #endif 356 #if COM3_EN 357 BSP_COM3_RX_PIN, 358 #endif 359 #if COM4_EN 360 BSP_COM4_RX_PIN, 361 #endif 362 #if COM5_EN 363 BSP_COM5_RX_PIN, 364 #endif 365 #if COM6_EN 366 BSP_COM6_RX_PIN, 367 #endif 368 #if COM7_EN 369 BSP_COM7_RX_PIN, 370 #endif 371 #if COM8_EN 372 BSP_COM8_RX_PIN, 373 #endif 374 }; 375 376 static const uint32_t COM_DMA_DR_BASE[COMn] = { 377 #if COM1_EN 378 BSP_COM1_DMA_DR_BASE, 379 #endif 380 #if COM2_EN 381 BSP_COM2_DMA_DR_BASE, 382 #endif 383 #if COM3_EN 384 BSP_COM3_DMA_DR_BASE, 385 #endif 386 #if COM4_EN 387 BSP_COM4_DMA_DR_BASE, 388 #endif 389 #if COM5_EN 390 BSP_COM5_DMA_DR_BASE, 391 #endif 392 #if COM6_EN 393 BSP_COM6_DMA_DR_BASE, 394 #endif 395 #if COM7_EN 396 BSP_COM7_DMA_DR_BASE, 397 #endif 398 #if COM8_EN 399 BSP_COM8_DMA_DR_BASE, 400 #endif 401 }; 402 403 static const uint32_t COM_DMA_CLK[COMn] = { 404 #if COM1_EN 405 BSP_COM1_DMA_CLK, 406 #endif 407 #if COM2_EN 408 BSP_COM2_DMA_CLK, 409 #endif 410 #if COM3_EN 411 BSP_COM3_DMA_CLK, 412 #endif 413 #if COM4_EN 414 BSP_COM4_DMA_CLK, 415 #endif 416 #if COM5_EN 417 BSP_COM5_DMA_CLK, 418 #endif 419 #if COM6_EN 420 BSP_COM6_DMA_CLK, 421 #endif 422 #if COM7_EN 423 BSP_COM7_DMA_CLK, 424 #endif 425 #if COM8_EN 426 BSP_COM8_DMA_CLK, 427 #endif 428 }; 429 430 static const uint32_t COM_DMA_TX_FLAG[COMn] = { 431 #if COM1_EN 432 BSP_COM1_Tx_DMA_FLAG, 433 #endif 434 #if COM2_EN 435 BSP_COM2_Tx_DMA_FLAG, 436 #endif 437 #if COM3_EN 438 BSP_COM3_Tx_DMA_FLAG, 439 #endif 440 #if COM4_EN 441 BSP_COM4_Tx_DMA_FLAG, 442 #endif 443 #if COM5_EN 444 BSP_COM5_Tx_DMA_FLAG, 445 #endif 446 #if COM6_EN 447 BSP_COM6_Tx_DMA_FLAG, 448 #endif 449 #if COM7_EN 450 BSP_COM7_Tx_DMA_FLAG, 451 #endif 452 #if COM8_EN 453 BSP_COM8_Tx_DMA_FLAG, 454 #endif 455 }; 456 457 static const uint32_t COM_DMA_TX_CHANNEL[COMn] = { 458 #if COM1_EN 459 BSP_COM1_Tx_DMA_Channel, 460 #endif 461 #if COM2_EN 462 BSP_COM2_Tx_DMA_Channel, 463 #endif 464 #if COM3_EN 465 BSP_COM3_Tx_DMA_Channel, 466 #endif 467 #if COM4_EN 468 BSP_COM4_Tx_DMA_Channel, 469 #endif 470 #if COM5_EN 471 BSP_COM5_Tx_DMA_Channel, 472 #endif 473 #if COM6_EN 474 BSP_COM6_Tx_DMA_Channel, 475 #endif 476 #if COM7_EN 477 BSP_COM7_Tx_DMA_Channel, 478 #endif 479 #if COM8_EN 480 BSP_COM8_Tx_DMA_Channel, 481 #endif 482 }; 483 484 static DMA_Stream_TypeDef * const COM_DMA_TX_STREAM[COMn] = { 485 #if COM1_EN 486 BSP_COM1_Tx_DMA_Stream, 487 #endif 488 #if COM2_EN 489 BSP_COM2_Tx_DMA_Stream, 490 #endif 491 #if COM3_EN 492 BSP_COM3_Tx_DMA_Stream, 493 #endif 494 #if COM4_EN 495 BSP_COM4_Tx_DMA_Stream, 496 #endif 497 #if COM5_EN 498 BSP_COM5_Tx_DMA_Stream, 499 #endif 500 #if COM6_EN 501 BSP_COM6_Tx_DMA_Stream, 502 #endif 503 #if COM7_EN 504 BSP_COM7_Tx_DMA_Stream, 505 #endif 506 #if COM8_EN 507 BSP_COM8_Tx_DMA_Stream, 508 #endif 509 }; 510 511 512 static const uint32_t COM_RX_IRQn[COMn] = { 513 #if COM1_EN 514 BSP_COM1_IRQn, 515 #endif 516 #if COM2_EN 517 BSP_COM2_IRQn, 518 #endif 519 #if COM3_EN 520 BSP_COM3_IRQn, 521 #endif 522 #if COM4_EN 523 BSP_COM4_IRQn, 524 #endif 525 #if COM5_EN 526 BSP_COM5_IRQn, 527 #endif 528 #if COM6_EN 529 BSP_COM6_IRQn, 530 #endif 531 #if COM7_EN 532 BSP_COM7_IRQn, 533 #endif 534 #if COM8_EN 535 BSP_COM8_IRQn, 536 #endif 537 }; 538 539 static uint8_t * const COM_TX_BUFF[COMn] = { 540 #if COM1_EN 541 COM1_TX_BUFF, 542 #endif 543 #if COM2_EN 544 COM2_TX_BUFF, 545 #endif 546 #if COM3_EN 547 COM3_TX_BUFF, 548 #endif 549 #if COM4_EN 550 COM4_TX_BUFF, 551 #endif 552 #if COM5_EN 553 COM5_TX_BUFF, 554 #endif 555 #if COM6_EN 556 COM6_TX_BUFF, 557 #endif 558 #if COM7_EN 559 COM7_TX_BUFF, 560 #endif 561 #if COM8_EN 562 COM8_TX_BUFF, 563 #endif 564 }; 565 566 static const uint32_t COM_TX_BUFF_SIZE[COMn] = { 567 #if COM1_EN 568 BSP_COM1_Tx_BUFF_SIZE, 569 #endif 570 #if COM2_EN 571 BSP_COM2_Tx_BUFF_SIZE, 572 #endif 573 #if COM3_EN 574 BSP_COM3_Tx_BUFF_SIZE, 575 #endif 576 #if COM4_EN 577 BSP_COM4_Tx_BUFF_SIZE, 578 #endif 579 #if COM5_EN 580 BSP_COM5_Tx_BUFF_SIZE, 581 #endif 582 #if COM6_EN 583 BSP_COM6_Tx_BUFF_SIZE, 584 #endif 585 #if COM7_EN 586 BSP_COM7_Tx_BUFF_SIZE, 587 #endif 588 #if COM8_EN 589 BSP_COM8_Tx_BUFF_SIZE, 590 #endif 591 }; 592 593 static uint8_t * const COM_RX_BUFF[COMn] = { 594 #if COM1_EN 595 COM1_RX_BUFF, 596 #endif 597 #if COM2_EN 598 COM2_RX_BUFF, 599 #endif 600 #if COM3_EN 601 COM3_RX_BUFF, 602 #endif 603 #if COM4_EN 604 COM4_RX_BUFF, 605 #endif 606 #if COM5_EN 607 COM5_RX_BUFF, 608 #endif 609 #if COM6_EN 610 COM6_RX_BUFF, 611 #endif 612 #if COM7_EN 613 COM7_RX_BUFF, 614 #endif 615 #if COM8_EN 616 COM8_RX_BUFF, 617 #endif 618 }; 619 620 static const uint32_t COM_RX_BUFF_SIZE[COMn] = { 621 #if COM1_EN 622 BSP_COM1_Rx_BUFF_SIZE, 623 #endif 624 #if COM2_EN 625 BSP_COM2_Rx_BUFF_SIZE, 626 #endif 627 #if COM3_EN 628 BSP_COM3_Rx_BUFF_SIZE, 629 #endif 630 #if COM4_EN 631 BSP_COM4_Rx_BUFF_SIZE, 632 #endif 633 #if COM5_EN 634 BSP_COM5_Rx_BUFF_SIZE, 635 #endif 636 #if COM6_EN 637 BSP_COM6_Rx_BUFF_SIZE, 638 #endif 639 #if COM7_EN 640 BSP_COM7_Rx_BUFF_SIZE, 641 #endif 642 #if COM8_EN 643 BSP_COM8_Rx_BUFF_SIZE, 644 #endif 645 }; 646 647 static QUEUE8_TYPE * const COM_RX_QUEUE[COMn] = { 648 #if COM1_EN 649 &COM1_RX_QUEUE, 650 #endif 651 #if COM2_EN 652 &COM2_RX_QUEUE, 653 #endif 654 #if COM3_EN 655 &COM3_RX_QUEUE, 656 #endif 657 #if COM4_EN 658 &COM4_RX_QUEUE, 659 #endif 660 #if COM5_EN 661 &COM5_RX_QUEUE, 662 #endif 663 #if COM6_EN 664 &COM6_RX_QUEUE, 665 #endif 666 #if COM7_EN 667 &COM7_RX_QUEUE, 668 #endif 669 #if COM8_EN 670 &COM8_RX_QUEUE, 671 #endif 672 }; 673 674 static const uint16_t parityArr[3] = {USART_Parity_No, USART_Parity_Odd, USART_Parity_Even}; 675 676 /******************************************************************************* 677 * Function Name :BSP_Uart1Open 678 * Description :串口及引脚初始化 679 * Input : uartx: COM1,COM2,COM3.... 680 baud: 2400,4800,9600,19200,38400,57600,115200 681 data: 数据位数 8,9, 682 stop:停止位数 1,2 683 parity:效验 0: 无效验,1:奇效验,2:偶效验 684 * Output : 685 * Other : 686 * Date :2013.08.12 687 *******************************************************************************/ 688 void BSP_UartOpen(uint8_t COM, uint32_t baud, uint8_t data, uint8_t stop, uint8_t parity) 689 { 690 USART_InitTypeDef USART_InitStructure; 691 GPIO_InitTypeDef GPIO_InitStructure; 692 NVIC_InitTypeDef NvicInitdef; 693 DMA_InitTypeDef DMA_InitStructure; 694 695 /* DMA clock enable */ 696 RCC_AHB1PeriphClockCmd(COM_DMA_CLK[COM], ENABLE); 697 698 /* Enable GPIO clock */ 699 RCC_AHB1PeriphClockCmd(COM_TX_PORT_CLK[COM] | COM_RX_PORT_CLK[COM], ENABLE); 700 701 /* Enable UART clock */ 702 if ((COM_USART[COM] == USART1) || (COM_USART[COM] == USART6)) 703 { 704 RCC_APB2PeriphClockCmd(COM_USART_CLK[COM], ENABLE); 705 } 706 else 707 { 708 RCC_APB1PeriphClockCmd(COM_USART_CLK[COM], ENABLE); 709 } 710 USART_DeInit(COM_USART[COM]); 711 712 /* Connect PXx to USARTx_Tx*/ 713 GPIO_PinAFConfig(COM_TX_PORT[COM], COM_TX_AF_PIN[COM], COM_AF[COM]); 714 /* Connect PXx to USARTx_Rx*/ 715 GPIO_PinAFConfig(COM_RX_PORT[COM], COM_RX_AF_PIN[COM], COM_AF[COM]); 716 717 /* Configure USART Tx as alternate function push-pull */ 718 GPIO_InitStructure.GPIO_Pin = COM_TX_PIN[COM]; 719 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; 720 GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; 721 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 722 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; 723 GPIO_Init(COM_TX_PORT[COM], &GPIO_InitStructure); 724 725 /* Configure USART Rx as input floating */ 726 GPIO_InitStructure.GPIO_Pin = COM_RX_PIN[COM]; 727 GPIO_Init(COM_RX_PORT[COM], &GPIO_InitStructure); 728 729 /* USART configuration */ 730 USART_StructInit(&USART_InitStructure); 731 USART_InitStructure.USART_BaudRate = baud; 732 USART_InitStructure.USART_StopBits = (stop == 2)? USART_StopBits_2 : USART_StopBits_1; 733 USART_InitStructure.USART_WordLength = (data == 9)? USART_WordLength_9b : USART_WordLength_8b; 734 USART_InitStructure.USART_Parity = (parity < 3)? parityArr[parity] : USART_Parity_No; 735 USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; 736 USART_Init(COM_USART[COM], &USART_InitStructure); 737 738 /* Enable USART DMA_TX*/ 739 USART_DMACmd(COM_USART[COM], USART_DMAReq_Tx, ENABLE); 740 741 USART_ITConfig(COM_USART[COM], USART_IT_RXNE, ENABLE); 742 743 /* Enable USART */ 744 USART_Cmd(COM_USART[COM], ENABLE); 745 746 NvicInitdef.NVIC_IRQChannel = COM_RX_IRQn[COM]; 747 NvicInitdef.NVIC_IRQChannelPreemptionPriority = 3; 748 NvicInitdef.NVIC_IRQChannelSubPriority = 0; 749 NvicInitdef.NVIC_IRQChannelCmd = ENABLE; 750 NVIC_Init( &NvicInitdef ); 751 752 QUEUE_PacketCreate(COM_RX_QUEUE[COM], COM_RX_BUFF[COM], COM_RX_BUFF_SIZE[COM]); 753 /* -------------------------------DMA发送------------------------------ */ 754 /* DMA StreamX Config */ 755 DMA_DeInit(COM_DMA_TX_STREAM[COM]); 756 757 /* DMA StreamX disable */ 758 DMA_Cmd(COM_DMA_TX_STREAM[COM], DISABLE); 759 760 DMA_StructInit(&DMA_InitStructure); 761 DMA_InitStructure.DMA_Channel = COM_DMA_TX_CHANNEL[COM]; 762 DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)COM_DMA_DR_BASE[COM]; 763 DMA_InitStructure.DMA_Memory0BaseAddr = (u32)COM_TX_BUFF[COM]; 764 DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral; 765 DMA_InitStructure.DMA_BufferSize = 0; 766 DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; 767 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; 768 DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; 769 DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; 770 DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; 771 DMA_InitStructure.DMA_Priority = DMA_Priority_High; 772 DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Enable; 773 DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full; 774 DMA_Init(COM_DMA_TX_STREAM[COM], &DMA_InitStructure); 775 776 DMA_FlowControllerConfig(COM_DMA_TX_STREAM[COM], DMA_FlowCtrl_Memory); //控制流 取决于缓存大小 777 } 778 779 780 /******************************************************************************* 781 * Function Name : void BSP_UartClose(uint8_t COMx) 782 * Description : 串口关闭 783 * Input : COMx:通道x 784 * Output : 785 * Other : 786 * Date : 2013.08.12 787 *******************************************************************************/ 788 void BSP_UartClose(uint8_t COM) 789 { 790 if ((COM_USART[COM] == USART1) || (COM_USART[COM] == USART6)) 791 { 792 RCC_APB2PeriphClockCmd(COM_USART_CLK[COM], DISABLE); 793 } 794 else 795 { 796 RCC_APB1PeriphClockCmd(COM_USART_CLK[COM], DISABLE); 797 } 798 799 RCC_AHB1PeriphClockCmd(COM_DMA_CLK[COM], ENABLE); 800 DMA_Cmd(COM_DMA_TX_STREAM[COM], DISABLE); 801 USART_DMACmd(COM_USART[COM], USART_DMAReq_Tx, DISABLE); 802 USART_ITConfig(COM_USART[COM], USART_IT_RXNE, DISABLE); 803 USART_Cmd(COM_USART[COM], DISABLE); 804 } 805 806 /******************************************************************************* 807 * Function Name : uint32_t BSP_UartWrite(uint8_t COMx, uint8_t *buffter, uint32_t len) 808 * Description : 串口发送数据 809 * Input : COMx:通道x 810 * Output : 811 * Other : 812 * Date : 2013.08.12 813 *******************************************************************************/ 814 uint32_t BSP_UartWrite(uint8_t COM, uint8_t *buffter, uint32_t len) 815 { 816 if (COM >= COMn) 817 return 0; 818 819 if (0 == len) 820 return 0; 821 822 if ((DMA_GetCurrDataCounter(COM_DMA_TX_STREAM[COM]) == 0) 823 && (DMA_FIFOStatus_Empty == DMA_GetFIFOStatus(COM_DMA_TX_STREAM[COM]))) 824 { 825 uint32_t resLen = 0; 826 827 USART_ClearFlag(COM_USART[COM], USART_FLAG_TC); 828 resLen = (COM_TX_BUFF_SIZE[COM] > len)? len : COM_TX_BUFF_SIZE[COM]; 829 memcpy((void *)(COM_TX_BUFF[COM]), buffter, resLen); 830 DMA_Cmd(COM_DMA_TX_STREAM[COM], DISABLE); 831 DMA_ClearFlag(COM_DMA_TX_STREAM[COM], COM_DMA_TX_FLAG[COM]); 832 DMA_SetCurrDataCounter(COM_DMA_TX_STREAM[COM], resLen); 833 DMA_Cmd(COM_DMA_TX_STREAM[COM], ENABLE); 834 835 return resLen; 836 } 837 return 0; 838 } 839 840 /******************************************************************************* 841 * Function Name : uint32_t BSP_UartRead(uint8_t COMx, uint8_t *buffter, uint32_t len) 842 * Description : 串口读回数据 843 * Input : COMx:通道x 844 * Output : 845 * Other : 846 * Date : 2013.08.12 847 *******************************************************************************/ 848 uint32_t BSP_UartRead(uint8_t COM, uint8_t *buffter, uint32_t len) 849 { 850 return QUEUE_PacketOut(COM_RX_QUEUE[COM], buffter, len); 851 } 852 853 /******************************************************************************* 854 * Function Name : uint32_t BSP_UartTxIdleState(uint8_t COM) 855 * Description : 查询 发送是否 发送完成 856 * Input : 857 * Output : 1)忙碌 0)空闲 858 * Other : 859 * Date : 2013.08.12 860 *******************************************************************************/ 861 uint32_t BSP_UartTxIdleState(uint8_t COM) 862 { 863 return (DMA_GetCurrDataCounter(COM_DMA_TX_STREAM[COM]) 864 || (USART_GetFlagStatus(COM_USART[COM], USART_FLAG_TC) != SET)); 865 } 866 867 868 /******************************************************************************* 869 * Function Name : void _IRQHandler(uint8_t COM) 870 * Description : 中断函数 871 * Input : 872 * Output : 873 * Other : 874 * Date : 2013.08.12 875 *******************************************************************************/ 876 void _IRQHandler(uint8_t COM) 877 { 878 if (USART_GetITStatus(COM_USART[COM], USART_IT_RXNE) != RESET) 879 { 880 u8 ch = USART_ReceiveData(COM_USART[COM]); //读数据后 会自动清空标志 881 QUEUE_PacketIn(COM_RX_QUEUE[COM], &ch, 1); 882 } 883 } 884 885 #if COM1_EN > 0 886 /******************************************************************************* 887 * Function Name : USART1_IRQHandler 888 * Description : This function handles USART1 global interrupt request. 889 * Input : None 890 * Output : None 891 * Return : None 892 *******************************************************************************/ 893 void USART1_IRQHandler(void) 894 { 895 _IRQHandler(COM1); 896 } 897 #endif //COM1_EN > 0 898 899 #if COM2_EN > 0 900 /******************************************************************************* 901 * Function Name : USART2_IRQHandler 902 * Description : This function handles USART2 global interrupt request. 903 * Input : None 904 * Output : None 905 * Return : None 906 *******************************************************************************/ 907 void USART2_IRQHandler(void) 908 { 909 _IRQHandler(COM2); 910 } 911 #endif //COM2_EN > 0 912 913 #if COM3_EN > 0 914 /******************************************************************************* 915 * Function Name : USART3_IRQHandler 916 * Description : This function handles USART3 global interrupt request. 917 * Input : None 918 * Output : None 919 * Return : None 920 *******************************************************************************/ 921 void USART3_IRQHandler(void) 922 { 923 _IRQHandler(COM3); 924 } 925 #endif //COM3_EN > 0 926 927 #if COM4_EN > 0 928 /******************************************************************************* 929 * Function Name : USART4_IRQHandler 930 * Description : This function handles USART4 global interrupt request. 931 * Input : None 932 * Output : None 933 * Return : None 934 *******************************************************************************/ 935 void UART4_IRQHandler(void) 936 { 937 _IRQHandler(COM4); 938 } 939 #endif //COM4_EN > 0 940 941 #if COM5_EN > 0 942 /******************************************************************************* 943 * Function Name : USART5_IRQHandler 944 * Description : This function handles USART5 global interrupt request. 945 * Input : None 946 * Output : None 947 * Return : None 948 *******************************************************************************/ 949 void UART5_IRQHandler(void) 950 { 951 _IRQHandler(COM5); 952 } 953 #endif //COM5_EN > 0 954 955 #if COM6_EN > 0 956 /******************************************************************************* 957 * Function Name : USART6_IRQHandler 958 * Description : This function handles USART6 global interrupt request. 959 * Input : None 960 * Output : None 961 * Return : None 962 *******************************************************************************/ 963 void USART6_IRQHandler(void) 964 { 965 _IRQHandler(COM6); 966 } 967 #endif //COM6_EN > 0 968 969 #if COM7_EN > 0 970 /******************************************************************************* 971 * Function Name : USART7_IRQHandler 972 * Description : This function handles USART7 global interrupt request. 973 * Input : None 974 * Output : None 975 * Return : None 976 *******************************************************************************/ 977 void UART7_IRQHandler(void) 978 { 979 _IRQHandler(COM7); 980 } 981 #endif //COM7_EN > 0 982 983 #if COM8_EN > 0 984 /******************************************************************************* 985 * Function Name : USART8_IRQHandler 986 * Description : This function handles USART8 global interrupt request. 987 * Input : None 988 * Output : None 989 * Return : None 990 *******************************************************************************/ 991 void UART8_IRQHandler(void) 992 { 993 _IRQHandler(COM8); 994 } 995 #endif //COM8_EN > 0