这是stm32f103c8t6的三个串口的库函数,没有使用重写printf实现串口的输出,其中第三个串口可配置成普通的串口或者RS485的接口。485接口使用的是SP3485芯片,并使用GPIOB8来使能发送和接收,是半双工的工作方式。
usart.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
#ifndef __USART_H #define __USART_H #include "stdio.h" #include "sys.h" /* 串口1配置 */ #define USART1_REC_LEN 200 //定义最大接收字节数 200 #define EN_USART1_RX 1 //使能(1)/禁止(0)串口1接收 #define USART1_BUFFER_LEN 100 // 最大能发送的长度 extern u8 USART1_RX_BUF[USART1_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节.末字节为换行符 extern u16 USART1_RX_STA; //接收状态标记 void uart1_init(u32 bound); void uart1_printf(char *fmt, ...); /* 串口2配置 */ #define USART2_REC_LEN 200 // 最大能够接收的长度 #define USART2_BUFFER_LEN 100 // 最大能发送的长度 extern u8 USART2_RX_BUF[USART2_REC_LEN]; extern u16 USART2_RX_STA; //接收状态标记 void uart2_init(u32 bound); void uart2_printf (char *fmt, ...); /* 串口3配置 RS485 */ #define USART3_REC_LEN 200 // 最大能够接收的长度 #define USART3_BUFFER_LEN 100 // 最大能发送的长度 #define RS485_TX_EN PBout(8) //485模式控制.0,接收;1,发送. extern u8 USART3_RX_BUF[USART3_REC_LEN]; extern u16 USART3_RX_STA; //接收状态标记 void uart3_init(u32 bound); void uart3_printf(char *fmt, ...); void RS485_Init(u32 bound); void RS485_Receive_Data(u8 *buf,u8 *len); void RS485_Send_Data(u8 *buf,u8 len); int hexadecimal_to_decimal(int x); int hexadecimalToDecimal(char hexVal[]); #endif |
usart.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 |
#include "sys.h" #include "usart.h" #include "stdarg.h" #include "stdio.h" #include "string.h" #include "stdio.h" #include "delay.h" #include "stdlib.h" #include "math.h" #if SYSTEM_SUPPORT_OS #include "FreeRTOS.h" //FreeRTOS使用 #endif #if 1 #pragma import(__use_no_semihosting) //标准库需要的支持函数 struct __FILE { int handle; }; FILE __stdout; //定义_sys_exit()以避免使用半主机模式 void _sys_exit(int x) { x = x; } u8 USART_PRINTF_FLAG = 1; // 默认串口1 //重定义fputc函数 int fputc(int ch, FILE *f) { while((USART1->SR&0X40)==0); //循环发送,直到发送完毕 USART1->DR = (u8) ch; return ch; } #endif u8 USART1_RX_BUF[USART1_REC_LEN]; // 接收缓冲,最大USART1_REC_LEN个字节. u8 USART2_RX_BUF[USART2_REC_LEN]; // 接收缓冲,最大USART2_REC_LEN个字节. u8 USART3_RX_BUF[USART3_REC_LEN]; // 接收缓冲,最大USART3_REC_LEN个字节. // 接收状态 // bit15, 接收完成标志 // bit14, 接收到0x0d // bit13~0, 接收到的有效字节数目 u16 USART1_RX_STA=0; // USART1 接收状态标记 u16 USART2_RX_STA=0; // USART2 接收状态标记 u16 USART3_RX_STA=0; // USART2 接收状态标记 u8 RS485_RX_CNT=0; // RS485接收到的数据长度 u8 RS485_RX_BUF[64]; //接收缓冲,最大64个字节. /* ************************************************************ * 函数名称: uart1_init * * 函数功能: 串口1初始化 * * 入口参数: bound波特率 * * * 返回参数: 无 * * 说明: PA9 PA10 ************************************************************ */ void uart1_init(u32 bound){ //GPIO端口设置 GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE); //使能USART1,GPIOA时钟 //USART1_TX GPIOA.9 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出 GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.9 //USART1_RX GPIOA.10初始化 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入 GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.10 //Usart1 NVIC 配置 NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//抢占优先级3 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //子优先级3 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能 NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器 //USART 初始化设置 USART_InitStructure.USART_BaudRate = bound;//串口波特率 USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式 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(USART1, &USART_InitStructure); //初始化串口1 USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启串口接受中断 USART_Cmd(USART1, ENABLE); //使能串口1 } void USART1_IRQHandler(void) //串口1中断服务程序 { u8 Res; if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //接收中断(接收到的数据必须是0x0d 0x0a结尾) { Res =USART_ReceiveData(USART1); //读取接收到的数据 if((USART1_RX_STA&0x8000)==0)//接收未完成 { if(USART1_RX_STA&0x4000)//接收到了0x0d { if(Res!=0x0a)USART1_RX_STA=0;//接收错误,重新开始 else USART1_RX_STA|=0x8000; //接收完成了 } else //还没收到0X0D { if(Res==0x0d)USART1_RX_STA|=0x4000; else { USART1_RX_BUF[USART1_RX_STA&0X3FFF]=Res ; USART1_RX_STA++; if(USART1_RX_STA>(USART1_REC_LEN-1))USART1_RX_STA=0;//接收数据错误,重新开始接收 } } } } } /* ************************************************************ * 函数名称: uart1_printf * * 函数功能: 串口1打印 * * 入口参数: fmt要打印的内容 * * 返回参数: 无 * * 说明: USART1_BUFFER_LEN 打印的长度 在.h中定义 ************************************************************ */ void uart1_printf(char *fmt, ...) { char buffer[USART1_BUFFER_LEN + 1]; u8 i = 0; const char *s; va_list arg_ptr; va_start(arg_ptr, fmt); vsnprintf(buffer, USART1_BUFFER_LEN + 1, fmt, arg_ptr); for (s = buffer; *s; s++) { USART_SendData(USART1, (u8) buffer[i++]); while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET); } va_end(arg_ptr); } /* ************************************************************ * 函数名称: uart2_init * * 函数功能: 串口2初始化 * * 入口参数: baud:设定的波特率 * * 返回参数: 无 * * 说明: TX-PA2 RX-PA3 ************************************************************ */ void uart2_init(u32 bound){ //GPIO端口设置 GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //使能GPIOA时钟 RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);//使能USART2时钟 //USART2_TX GPIOA.2 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //PA.2 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出 GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.2 //USART2_RX GPIOA.3初始化 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;//PA.3 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入 GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.3 //USART2 NVIC 配置 NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//抢占优先级3 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //子优先级3 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能 NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器 //USART 初始化设置 USART_InitStructure.USART_BaudRate = bound;//串口波特率 USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式 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); //初始化串口2 USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);//开启串口接受中断 USART_Cmd(USART2, ENABLE); //使能串口2 } /* ************************************************************ * 函数名称: USART2_IRQHandler * * 函数功能: 串口2中断函数 * * 入口参数: 无 * * 返回参数: 无 * * 说明: 无 ************************************************************ */ void USART2_IRQHandler(void) //串口2中断服务程序 { u8 Res; if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET) //接收中断(接收到的数据必须是0x0d 0x0a结尾) { Res = USART_ReceiveData(USART2); //读取接收到的数据 if((USART2_RX_STA&0x8000)==0)//接收未完成 { if(USART2_RX_STA&0x4000)//接收到了0x0d { if(Res!=0x0a)USART2_RX_STA=0;//接收错误,重新开始 else USART2_RX_STA|=0x8000; //接收完成了 } else //还没收到0X0D { if(Res==0x0d)USART2_RX_STA|=0x4000; else { USART2_RX_BUF[USART2_RX_STA&0X3FFF]=Res; USART2_RX_STA++; if(USART2_RX_STA>(USART2_REC_LEN-1))USART2_RX_STA=0;//接收数据错误,重新开始接收 } } } } } /* ************************************************************ * 函数名称: uart2_printf * * 函数功能: 串口2打印 * * 入口参数: fmt要打印的内容 * * 返回参数: 无 * * 说明: USART2_BUFFER_LEN 打印的长度 在.h中定义 ************************************************************ */ void uart2_printf(char *fmt, ...) { char buffer[USART2_BUFFER_LEN + 1]; u8 i = 0; const char *s; va_list arg_ptr; va_start(arg_ptr, fmt); vsnprintf(buffer, USART2_BUFFER_LEN + 1, fmt, arg_ptr); for (s = buffer; *s; s++) { USART_SendData(USART2, (u8) buffer[i++]); while (USART_GetFlagStatus(USART2, USART_FLAG_TC) == RESET); } va_end(arg_ptr); } /* ************************************************************ * 函数名称: uart3_init * * 函数功能: 串口3初始化 * * 入口参数: baud:设定的波特率 * * 返回参数: 无 * * 说明: TX-PB10 RX-PB11 ************************************************************ */ void uart3_init(u32 bound){ //GPIO端口设置 GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //使能GPIOB时钟 RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3,ENABLE);//使能USART3时钟 //USART3_TX GPIOB.10 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //PB.10 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出 GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIOB.2 //USART3_RX GPIOB.11初始化 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;//PB.11 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入 GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIOB.11 //USART2 NVIC 配置 NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=4 ;// 抢占优先级3 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; // 子优先级3 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // IRQ通道使能 NVIC_Init(&NVIC_InitStructure); // 根据指定的参数初始化NVIC寄存器 //USART 初始化设置 USART_InitStructure.USART_BaudRate = bound;// 串口波特率 USART_InitStructure.USART_WordLength = USART_WordLength_8b;// 字长为8位数据格式 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(USART3, &USART_InitStructure); // 初始化串口2 USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);// 开启串口接受中断 USART_Cmd(USART3, ENABLE); // 使能串口2 } /* ************************************************************ * 函数名称: USART3_IRQHandler * * 函数功能: 串口3中断函数 * * 入口参数: 无 * * 返回参数: 无 * * 说明: 无 ************************************************************ */ void USART3_IRQHandler(void) { // uart2_printf("%s","uart3接收中断触发"); // u8 Res; // if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET) //接收中断(接收到的数据必须是0x0d 0x0a结尾) // { // Res = USART_ReceiveData(USART3); //读取接收到的数据 // // if((USART3_RX_STA&0x8000)==0)//接收未完成 // { // if(USART3_RX_STA&0x4000)//接收到了0x0d // { // if(Res!=0x0a)USART3_RX_STA=0;//接收错误,重新开始 // else USART3_RX_STA|=0x8000; //接收完成了 // } // else //还没收到0X0D // { // if(Res==0x0d)USART3_RX_STA|=0x4000; // else // { // USART3_RX_BUF[USART3_RX_STA&0X3FFF]=Res; // USART3_RX_STA++; // if(USART3_RX_STA>(USART3_REC_LEN-1))USART3_RX_STA=0;//接收数据错误,重新开始接收 // } // } // } // } u8 res; if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET) //接收到数据 { res =USART_ReceiveData(USART3); //读取接收到的数据 if(RS485_RX_CNT<64) { RS485_RX_BUF[RS485_RX_CNT]=res; //记录接收到的值 RS485_RX_CNT++; //接收数据增加1 // uart2_printf("%d",RS485_RX_CNT); } } } /* ************************************************************ * 函数名称: uart3_printf * * 函数功能: 串口3打印 * * 入口参数: fmt要打印的内容 * * 返回参数: 无 * * 说明: USART3_BUFFER_LEN 打印的长度 在.h中定义 ************************************************************ */ void uart3_printf(char *fmt, ...) { char buffer[USART3_BUFFER_LEN + 1]; u8 i = 0; const char *s; va_list arg_ptr; va_start(arg_ptr, fmt); vsnprintf(buffer, USART3_BUFFER_LEN + 1, fmt, arg_ptr); for (s = buffer; *s; s++) { USART_SendData(USART3, (u8) buffer[i++]); while (USART_GetFlagStatus(USART3, USART_FLAG_TC) == RESET); } va_end(arg_ptr); } /* ************************************************************ * 函数名称: RS485_Init * * 函数功能: 初始化RS485 * * 入口参数: bound 波特率 * * 返回参数: 无 * * 说明: 其实就是串口3的初始化 ************************************************************ */ void RS485_Init(u32 bound) { GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);//使能GPIOB时钟 RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3,ENABLE);//使能USART3时钟 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; //PB8端口配置 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); // USART3_TX TX-PB10 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //PB10 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽 GPIO_Init(GPIOB, &GPIO_InitStructure); // USART3_RX TX-PB11 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;//PB11 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入 GPIO_Init(GPIOB, &GPIO_InitStructure); RCC_APB1PeriphResetCmd(RCC_APB1Periph_USART3,ENABLE);//复位串口2 RCC_APB1PeriphResetCmd(RCC_APB1Periph_USART3,DISABLE);//停止复位 USART_InitStructure.USART_BaudRate = bound;//波特率设置 USART_InitStructure.USART_WordLength = USART_WordLength_8b;//8位数据长度 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(USART3, &USART_InitStructure); ; //初始化串口 NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn; //使能串口2中断 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; //先占优先级2级 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; //从优先级2级 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道 NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器 USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);//开启中断 USART_Cmd(USART3, ENABLE); //使能串口 RS485_TX_EN=0; //默认为接收模式 } /* ************************************************************ * 函数名称: RS485_Send_Data * * 函数功能: 串口3打印 * * 入口参数: len:发送的字节数 buf:发送区首地址 * * 返回参数: 无 * * 说明: RS485发送len个字节 ************************************************************ */ void RS485_Send_Data(u8 *buf,u8 len) { u8 t; RS485_TX_EN=1; //设置为发送模式 for(t=0;t<len;t++) //循环发送数据 { while(USART_GetFlagStatus(USART3, USART_FLAG_TC) == RESET); USART_SendData(USART3,buf[t]); } while(USART_GetFlagStatus(USART3, USART_FLAG_TC) == RESET); // RS485_RX_CNT=0; RS485_TX_EN=0; //设置为接收模式 } /* ************************************************************ * 函数名称: RS485_Receive_Data * * 函数功能: RS485查询接收到的数据 * * 入口参数: len:读到的数据长度 buf:接收缓存首地址 * * 返回参数: 无 * * 说明: RS485发送len个字节 ************************************************************ */ void RS485_Receive_Data(u8 *buf,u8 *len) { u8 rxlen=RS485_RX_CNT; // uart2_printf("%s", "RS485_RX_CNT"); // uart2_printf("%d", RS485_RX_CNT); // uart2_printf("%s", "End\r\n"); u8 i=0; *len=0; //默认为0 delay_ms(1); //等待10ms,连续超过10ms没有接收到一个数据,则认为接收结束 if(rxlen == RS485_RX_CNT && rxlen)//接收到了数据,且接收完成了 { for(i=0; i<rxlen; i++) { buf[i]=RS485_RX_BUF[i]; } *len=RS485_RX_CNT; //记录本次数据长度 RS485_RX_CNT=0; //清零 } } /* ************************************************************ * 函数名称: hexadecimal_to_decimal * * 函数功能: 16进制转换为10进制 * * 入口参数: int x 16进制数据 * * 返回参数: 10进制数据 * * 说明: 无 ************************************************************ */ int hexadecimal_to_decimal(int x) { int decimal_number, remainder, count = 0; while(x > 0) { remainder = x % 10; decimal_number = decimal_number + remainder * pow(16, count); x = x / 10; count++; } return decimal_number; } |
main.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 |
#include "sys.h" #include "delay.h" #include "usart.h" #include "led.h" #include "FreeRTOS.h" #include "task.h" #include "usart.h" #include "projectConfig.h" // 起始任务 TaskHandle_t StartTask_Handler; void start_task(void *pvParameters); /* LED任务配置 */ TaskHandle_t LED0Task_Handler; void led0_task(void *pvParameters); /* USART1任务配置 */ TaskHandle_t UART1Task_Handler; //任务句柄 void uart1_task(void *pvParameters); //任务函数 /* USART2任务配置 */ TaskHandle_t UART2Task_Handler; //任务句柄 void uart2_task(void *pvParameters); //任务函数 /* USART3任务配置 */ TaskHandle_t UART3Task_Handler; //任务句柄 void uart3_task(void *pvParameters); //任务函数 int main(void) { NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//设置系统中断优先级分组4 delay_init(); //延时函数初始化 uart1_init(115200); //初始化串口1 uart2_init(115200); //初始化串口2 RS485_Init(9600); //初始化串口3 LED_Init(); //初始化LED //创建开始任务 xTaskCreate((TaskFunction_t )start_task, //任务函数 (const char* )"start_task", //任务名称 (uint16_t )START_STK_SIZE, //任务堆栈大小 (void* )NULL, //传递给任务函数的参数 (UBaseType_t )START_TASK_PRIO, //任务优先级 (TaskHandle_t* )&StartTask_Handler); //任务句柄 vTaskStartScheduler(); //开启任务调度 } //开始任务任务函数 void start_task(void *pvParameters) { taskENTER_CRITICAL(); //进入临界区 //创建LED0任务 xTaskCreate((TaskFunction_t )led0_task, (const char* )"led0_task", (uint16_t )LED0_STK_SIZE, (void* )NULL, (UBaseType_t )LED0_TASK_PRIO, (TaskHandle_t* )&LED0Task_Handler); // 创建uart1任务函数 xTaskCreate((TaskFunction_t )uart1_task, (const char* )"uart1_task", (uint16_t )UART1_STK_SIZE, (void* )NULL, (UBaseType_t )UART1_TASK_PRIO, (TaskHandle_t* )&UART1Task_Handler); // 创建uart2任务函数 xTaskCreate((TaskFunction_t )uart2_task, (const char* )"uart2_task", (uint16_t )UART2_STK_SIZE, (void* )NULL, (UBaseType_t )UART2_TASK_PRIO, (TaskHandle_t* )&UART2Task_Handler); // 创建uart3任务函数 xTaskCreate((TaskFunction_t )uart3_task, (const char* )"uart3_task", (uint16_t )UART3_STK_SIZE, (void* )NULL, (UBaseType_t )UART3_TASK_PRIO, (TaskHandle_t* )&UART3Task_Handler); vTaskDelete(StartTask_Handler); //删除开始任务 taskEXIT_CRITICAL(); //退出临界区 } //LED0任务函数 void led0_task(void *pvParameters) { while(1) { LED0=~LED0; vTaskDelay(pdMS_TO_TICKS(100)); //1秒 } } // UART1任务函数 void uart1_task(void *pvParameters) { u16 uart1_t; u16 uart1_len; u16 uart1_times=0; while(1){ if(USART1_RX_STA&0x8000) { uart1_len=USART1_RX_STA&0x3fff;//得到此次接收到的数据长度 uart1_printf("\r\nUART1您发送的消息为:\r\n\r\n"); for(uart1_t=0;uart1_t<uart1_len;uart1_t++) { USART_SendData(USART1, USART1_RX_BUF[uart1_t]);//向串口1发送数据 while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//等待发送结束 } uart1_printf("\r\n\r\n");//插入换行 USART1_RX_STA=0; }else { uart1_times++; if(uart1_times%5000==0) { uart1_printf("FeiFeiLink\n\r\n"); } if(uart1_times%100==0) { uart1_printf("UART1正在等待接收...\n"); } delay_ms(10); } } } void uart2_task(void *pvParameters) { u16 uart2_t; u16 uart2_len; u16 uart2_times=0; while(1){ if(USART2_RX_STA&0x8000) { uart2_len=USART2_RX_STA&0x3fff;//得到此次接收到的数据长度 uart2_printf("\r\nUART2您发送的消息为:\n"); uart2_printf("%s", "\r\nUART2您发送的消息为:\n"); for(uart2_t=0; uart2_t<uart2_len; uart2_t++) { USART_SendData(USART2, USART2_RX_BUF[uart2_t]); while(USART_GetFlagStatus(USART2,USART_FLAG_TC)!=SET);// } uart2_printf("\r\n\r\n");//插入换行 USART2_RX_STA=0; }else { uart2_times++; if(uart2_times%100==0) { // uart2_printf("%s", "UART2正在等待接收..."); } delay_ms(10); } } } void uart3_task(void *pvParameters) { u8 key; u8 i=0,t=0; u8 rs485buf[8]; // 初始化RS485指令 char sendBuf[]= {0x01, 0x03, 0x00, 0x00, 0x00, 0x01, 0x84, 0x0A}; while(1){ // 发送数据 for(i=0;i<8;i++) { rs485buf[i]=sendBuf[i];//填充发送缓冲区 } RS485_Send_Data(rs485buf,8);//发送8个字节 // 接收数据 RS485_Receive_Data(rs485buf,&key); if(key)//接收到有数据 { if(key>8)key=8;//最大是5个数据. // 将接收到的数据发送到串口2 // uart2_printf("%s", "UART3接收到了数据"); // uart2_printf("%d\r\n\r\n",hexadecimal_to_decimal(rs485buf[3])*256+hexadecimal_to_decimal(rs485buf[4])); // hexadecimal_to_decimal(rs485buf[3])*256+hexadecimal_to_decimal(rs485buf[4]) uart2_printf("%d",hexadecimal_to_decimal(0x6D)); // USART_SendData(USART2, rs485buf[0]); // USART_SendData(USART2, rs485buf[1]); // USART_SendData(USART2, rs485buf[2]); // USART_SendData(USART2, rs485buf[3]); // USART_SendData(USART2, rs485buf[4]); // USART_SendData(USART2, rs485buf[5]); } t++; delay_ms(100); //延迟1s } // u16 uart3_t; // u16 uart3_len; // u16 uart3_times=0; // while(1){ // if(USART3_RX_STA&0x8000) // { // uart3_len=USART3_RX_STA&0x3fff;//得到此次接收到的数据长度 // uart3_printf("\r\nUART3您发送的消息为:\n"); // uart3_printf("%s", "\r\nUART3您发送的消息为:\n"); // for(uart3_t=0; uart3_t<uart3_len; uart3_t++) // { // USART_SendData(USART3, USART3_RX_BUF[uart3_t]); // while(USART_GetFlagStatus(USART3,USART_FLAG_TC)!=SET);// // } // uart3_printf("\r\n\r\n");//插入换行 // USART3_RX_STA=0; // }else // { // uart3_times++; // if(uart3_times%20==0) // { // uart3_printf("%s", "UART3正在等待接收..."); // } // delay_ms(10); // } // } } |