| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464 |
- /**
- *****************************************************************************
- * 系统串口设置相关的函数
- *
- * (C) Copyright 2000-2020, ***
- * All Rights Reserved
- *****************************************************************************
- *
- * @File : usart.c
- * @By : 陈桂东
- * @Version : V1.0
- * @Date : 2012 / 10 / 20
- *
- *****************************************************************************
- * Update
- * @Version : V1.0.1
- * @By : 陈桂东
- * @Date : 2014 / 05 / 24
- * @Brief : 增加对C++环境支持
- *
- * @Version : V1.1
- * @By : 陈桂东
- * @Date : 2015 / 10 / 03
- * @Brief : 增加103和407之间切换宏定义
- *
- * @Version : V1.2
- * @By : 陈桂东
- * @Date : 2016 / 04 / 27
- * @Brief : A、增加对STM32F0系列支持
- * B、增加对IAR环境支持
- *
- *****************************************************************************
- **/
- #include "usart.h"
- #if _SYSTEM_SUPPORT_ROTS == 1
- #if _RTOS_Type_Support == 1 // RAW-OS
- #include "raw_api.h"
- #else // uCOS
- #include "includes.h"
- #endif
- #endif
- #if Printf_Support_En == 0
- #include <stdarg.h>
- #endif
- /******************************************************************************
- 加入以下代码,支持printf函数,而不需要选择use MicroLIB
- ******************************************************************************/
- #if Printf_Support_En == 1
- #ifdef __ICCARM__ //IAR支持
- /**
- *****************************************************************************
- * @Name : 重定义out_char函数
- *
- * @Brief : none
- *
- * @Input : ch:发送字符
- *
- * @Output : none
- *
- * @Return : none
- *****************************************************************************
- **/
- int putchar ( int c )
- {
- uint16_t timeout = 0;
- USART_SendData ( USART1, ( uint16_t ) c ); //发送数据
- while ( USART_GetFlagStatus ( USART1, USART_FLAG_TC ) == RESET ) //循环发送,直到发送完毕
- {
- timeout++;
- if ( timeout > 800 )
- {
- timeout = 0;
- break;
- }
- }
- return c;
- }
- #else //MDK支持
- #pragma import(__use_no_semihosting)
- //
- //标准库需要的支持函数
- //
- struct __FILE
- {
- int handle;
- };
- /* FILE is typedef’ d in stdio.h. */
- FILE __stdout;
- //
- //定义_sys_exit()以避免使用半主机模式
- //
- _sys_exit ( int x )
- {
- x = x;
- }
- /**
- *****************************************************************************
- * @Name : 重定义fputc函数
- *
- * @Brief : none
- *
- * @Input : ch:发送字符
- * *f: FILE指针
- *
- * @Output : none
- *
- * @Return : none
- *****************************************************************************
- **/
- int fputc ( int ch, FILE *f )
- {
- uint16_t timeout = 0;
- while ( USART_GetFlagStatus ( USART1, USART_FLAG_TC ) == RESET ) //循环发送,直到发送完毕
- {
- timeout++;
- if ( timeout > 800 )
- {
- timeout = 0;
- break;
- }
- }
- USART_SendData ( USART1, ( uint16_t ) ch ); //发送数据
- return ch;
- }
- #endif
- #else
- /**
- *****************************************************************************
- * @Name : 串口发送一个字节
- *
- * @Brief : none
- *
- * @Input : byte:发送字符
- *
- * @Output : none
- *
- * @Return : none
- *****************************************************************************
- **/
- void uart_sendbyte ( uint8_t byte )
- {
- while ( USART_GetFlagStatus ( USART1, USART_FLAG_TC ) == RESET );
- USART_SendData ( USART1, byte );
- while ( USART_GetFlagStatus ( USART1, USART_FLAG_TC ) == RESET );
- }
- /**
- *****************************************************************************
- * @Name : 串口发送字符串
- *
- * @Brief : none
- *
- * @Input : *str:发送字符串
- *
- * @Output : none
- *
- * @Return : none
- *****************************************************************************
- **/
- void uart_senfstring ( uint8_t * str )
- {
- while ( USART_GetFlagStatus ( USART1, USART_FLAG_TC ) == RESET );
- while ( *str != '\0' )
- {
- USART_SendData ( USART1, * ( str++ ) );
- while ( USART_GetFlagStatus ( USART1, USART_FLAG_TC ) == RESET );
- }
- }
- /**
- *****************************************************************************
- * @Name : 串口格式化打印
- *
- * @Brief : none
- *
- * @Input : *format:格式化字符串
- * ...: 变长参数
- *
- * @Output : none
- *
- * @Return : none
- *****************************************************************************
- **/
- void uart_printf ( char *format, ... )
- {
- va_list ap;
- char string[512];
- va_start ( ap, format );
- vsprintf ( string, format, ap );
- va_end ( ap );
- uart_senfstring ( ( uint8_t * ) string );
- }
- #endif
- /************************************* end *******************************/
- /**
- *****************************************************************************
- * @Name : 初始化IO 串口
- *
- * @Brief : none
- *
- * @Input : bound:波特率
- *
- * @Output : none
- *
- * @Return : none
- *****************************************************************************
- **/
- void uart_init ( uint32_t bound )
- {
- GPIO_InitTypeDef GPIO_InitStructure;
- USART_InitTypeDef USART_InitStructure;
- NVIC_InitTypeDef NVIC_InitStructure;
- #if __CORTEX_M == 0x00 //Cortex-M0
- RCC_AHBPeriphClockCmd ( RCC_AHBPeriph_GPIOA, ENABLE );
- RCC_APB2PeriphClockCmd ( RCC_APB2Periph_USART1, ENABLE );
- //
- //管脚复用
- //
- GPIO_PinAFConfig ( GPIOA, GPIO_PinSource9, GPIO_AF_1 );
- #if EN_USART1_RX == 1 //使能接收
- GPIO_PinAFConfig ( GPIOA, GPIO_PinSource10, GPIO_AF_1 );
- #endif
- //
- //初始化管脚
- //
- #if EN_USART1_RX == 1 //使能接收
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;
- #else
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
- #endif
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
- GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
- GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
- GPIO_Init ( GPIOA, &GPIO_InitStructure );
- #elif __CORTEX_M == 0x03 //Cortex-M3
- //
- //打开时钟
- //
- RCC_APB2PeriphClockCmd ( RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE );
- //
- //初始化管脚
- //
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9 TXD
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
- GPIO_Init ( GPIOA, &GPIO_InitStructure );
- #if EN_USART1_RX == 1 //使能接收
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //PA.10 RXD
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入
- GPIO_Init ( GPIOA, &GPIO_InitStructure );
- #endif
- #elif __CORTEX_M == 0x04 //Cortex-M4
- //
- //打开时钟
- //
- RCC_AHB1PeriphClockCmd ( RCC_AHB1Periph_GPIOA, ENABLE ); //使能GPIOA时钟
- RCC_APB2PeriphClockCmd ( RCC_APB2Periph_USART1, ENABLE ); //使能USART1时钟
- //
- //管脚复用
- //
- GPIO_PinAFConfig ( GPIOA, GPIO_PinSource9, GPIO_AF_USART1 ); //TXD管脚
- #if EN_USART1_RX == 1 //使能接收
- GPIO_PinAFConfig ( GPIOA, GPIO_PinSource10, GPIO_AF_USART1 ); //RXD管脚
- #endif
- //
- //初始化管脚
- //
- #if EN_USART1_RX == 1 //使能接收
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;
- #else
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //只初始化TXD管脚
- #endif
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; //复用功能
- GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽输出
- GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉
- GPIO_Init ( GPIOA, &GPIO_InitStructure );
- #endif //end __CORTEX_M
- //
- //配置串口参数
- //
- USART_InitStructure.USART_BaudRate = bound; //波特率
- USART_InitStructure.USART_WordLength = USART_WordLength_8b; //数据长度8
- USART_InitStructure.USART_StopBits = USART_StopBits_1; //停止位1
- USART_InitStructure.USART_Parity = USART_Parity_No; //无奇偶校验
- USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //无数据流控制
- #if EN_USART1_RX == 1 //使能接收
- USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
- #else
- USART_InitStructure.USART_Mode = USART_Mode_Tx;
- #endif
- USART_Init ( USART1, &USART_InitStructure );
- //
- //使能串口
- //
- USART_Cmd ( USART1, ENABLE );
- USART_ClearFlag ( USART1, USART_FLAG_TC );
- //
- //初始化串口中断优先级
- //
- #if EN_USART1_RX == 1 //使能接收
- //
- //开启串口中断接收
- //
- USART_ITConfig ( USART1, USART_IT_RXNE, ENABLE );
- NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; //中断号
- #if __CORTEX_M == 0x00 //Cortex-M0
- NVIC_InitStructure.NVIC_IRQChannelPriority = 3;
- #else
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3; //抢先优先级
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //响应优先级
- #endif
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
- NVIC_Init ( &NVIC_InitStructure );
- #endif
- }
- #if EN_USART1_RX == 1 //使能接收
- //注意,读取USARTx->SR能避免莫名其妙的错误
- uint8_t USART_RX_BUF[USART_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节
- //接收状态
- //bit15:接收完成标志
- //bit14:接收到0x0d
- //bit13~0:接收到的有效字节数目,最大512字节
- uint16_t USART_RX_STA = 0; //接收状态标记
- /**
- *****************************************************************************
- * @Name : 串口1接收中断服务程序
- *
- * @Brief : none
- *
- * @Input : none
- *
- * @Output : none
- *
- * @Return : none
- *****************************************************************************
- **/
- void USART1_IRQHandler ( void )
- {
- uint8_t res;
- #if _SYSTEM_SUPPORT_ROTS == 1
- #if _RTOS_Type_Support == 1 // RAW-OS
- raw_enter_interrupt();
- #else // uCOS
- OSIntEnter();
- #endif
- #endif
- if ( USART_GetITStatus ( USART1, USART_IT_RXNE ) != RESET ) //接收到数据
- {
- res = USART_ReceiveData ( USART1 ); //读取接收到的数据
- if ( ( USART_RX_STA & 0x8000 ) == 0 ) //接收未完成
- {
- if ( USART_RX_STA & 0x4000 ) //接收到了0x0d
- {
- /***********************************************
- 修改内容如下
- 当用户数据当中有0x0d的时候修正的错误的判断
- ***********************************************/
- if ( res != 0x0a )
- {
- USART_RX_BUF[USART_RX_STA & 0x3fff] = 0x0d; //补上丢失的0x0d数据
- USART_RX_STA++;
- USART_RX_BUF[USART_RX_STA & 0x3fff] = res; //继续接收数据
- USART_RX_STA++;
- USART_RX_STA &= 0xbfff; //清除0x0d标志
- }
- /***********************************************
- 修改完成
- ***********************************************/
- else USART_RX_STA |= 0x8000; //接收完成了
- }
- else //还没收到0x0d
- {
- if ( res == 0x0d ) USART_RX_STA |= 0x4000;
- else
- {
- USART_RX_BUF[USART_RX_STA & 0x3fff] = res;
- USART_RX_STA++;
- if ( USART_RX_STA > ( USART_REC_LEN - 1 ) ) USART_RX_STA = 0; //接收数据错误,重新开始接收
- }
- }
- } //end 接收未完成
- } //end 接收到数据
- #if _SYSTEM_SUPPORT_ROTS == 1
- #if _RTOS_Type_Support == 1 // RAW-OS
- raw_finish_int();
- #else // uCOS
- OSIntExit();
- #endif
- #endif
- }
- #endif //end EN_USART1_RX
|