一个相当经典的AVR中断程序
2009-09-04 22:29
176 查看
一个不错的avr的串口通讯代码,收藏于此,以备后用。
在此谢谢原创者。
在此谢谢原创者。
/************************************************************************************************** * 文 件 名 : Comm.H * 说 明 : * 1> 这一版本中最大的接收和发送缓存为255为INT8U类型的最大值 **************************************************************************************************/ #ifdef COMM_GLOBALS #define COMM_EXT #else #define COMM_EXT extern #endif /************************************************************************************************** * 全局常量 **************************************************************************************************/ #define COMM_MODULE_EN 1 // 串口模块总使能 0禁止 // 当串口的接收需要任务协助处理时下面两个定义有效 //#define TaskComm1Prio 1 // 定义串口0接收任务ID 注意: 在CONFIG.H中统一定义 //#define TaskComm2Prio 2 // 定义串口1接收任务ID #define COMM1_MEM_SEL // 串口0各种控制变量存储区选择 非C51一般为空 #define COMM2_MEM_SEL // 串口1各种控制变量存储区选择 非C51一般为空 #define COMM_CONST_SEL // 串口数据常量存储区选择 非C51一般为const或static #define COMM0_VECTOR // 串口0中断函数入口编号 #define COMM1_VECTOR // 串口1中断函数入口编号 #define X0N 17 // 流控制字符 继续发送 20% #define XOFF 19 // 流控制字符 停止发送 70% ////////////////////////////////////////////////------------串口配置---------- #define COMM_MODE 1 // 通信模式 0异步正常模式 1异步倍速模式 2同步主机模式 #define COMM_MORE_CPU_MODE 0 // 多处理器模式 1为多处理器模式有效 0为无效 #define COMM_ACCEPT_ISR_EN 1 // 接收结束中断 (1)使能 (0)禁止 #define COMM_SEND_ISR_EN 1 // 发送结束中断 (1)使能 (0)禁止 #define COMM_DATAFREE_ISR_EN 1 // 数据寄存器空中断 (1)使能 (0)禁止 #define COMM_SYN_CLOCK 1 // 同步工作模式时钟极性 (1)下降沿 (0)上升沿 // 两个处理CLK模块临界数据的两个宏 这里使用OS的临界宏 #define COMM_ENTER_CRITICAL() OS_ENTER_CRITICAL() // 进入临界宏 默认COMM_ENTER_CRITICAL() EA=0 #define COMM_EXIT_CRITICAL() OS_EXIT_CRITICAL() //退出临界宏 默认COMM_ENTER_CRITICAL() EA=1 // 串口0的常量定义 #define COMM1_UNIT_EN 1 // 串口0模块使能 0禁止 #define COMM1_DATA_STREAM_EN 0 // ASCII方式通讯时可采样XON/XOFF数据流模式来保证数据传输 #define COMM1_OS_SEL 1 // 选择在RTOS中使用则调用OSIntSendSignal 通知接收任务处理 // 串口数据 则启用定义TaskComm1Prio即接收任务ID 0=禁止 #define COMM1_OS_SIGNAL_SEL 1 // 0选择发送信号 1选择释放信号量 同时COMM1_OS_SEL要使能 // 来通知接收任务处理数据 #define COMM1_RXD_EN 1 // 串口0接收部分使能 0禁止 #define COMM1_GETNMSGS_EN 0 // 串口0的数据计数检测函数使能 0禁止 #define COMM1_GETS_EN 0 // 串口0接收多数据 0禁止 #define COMM1_RXD_SIZE 255 // 串口0的接收缓存配置 需要立即读数据 否则弃数据 必须>=1 #define COMM1_TXD_EN 1 // 串口0发送部分使能 0禁止 #define COMM1_PUTS_EN 0 // 串口0发送多数据 0禁止 #define COMM1_TXD_SIZE 128 // 串口0的发送缓存配置 必须>=1 //////////////////////////////////////////////// --------------串口的各种返回信息 不能更改------------ #define COMM_ERR 0 // 串口配置有错误 #define COMM_NO_ERR 1 // 串口配置没有错误 #define COMM_BAD_BAUD 2 // 波特率错误 #define COMM_BAD_MODE 3 // 串口工作为错误的工作方式 #define COMM_RXD_EMPTY 4 // 接收缓存没有数据 为空 #define COMM_RXD_FALSE 5 // 接收数据失败 只多字节接收时返回此信息 #define COMM_RXD_OK 6 // 接收数据正确 #define COMM_TXD_FALSE 7 // 发送失败 #define COMM_TXD_OK 8 // 发送正确 #define COMM_TXD_FLOOD 9 // 发送数据溢出 快速或多字节数据发送时 缓存溢出 //////////////////////////////////////////// #if (COMM_MODE == 0)||(COMM_MODE == 1) // 异步正常模式串,异步倍速模式串 #define UMSEL_MODE 0 #define UCPOL_MODE 0 #elif COMM_MODE == 2 // 同步模式串 #define UMSEL_MODE BIT(UMSEL) #if COMM_SYN_CLOCK == 0 // 同步工作模式时钟极性 #define UCPOL_MODE 0 #else #define UCPOL_MODE BIT(UCPOL) #endif #else // 选择其他模式 则停止编译 #error "(COMM_MODE)通信模式设置错误! " #endif #if COMM_MORE_CPU_MODE == 0 // 处理器模式 1为多处理器模式有效 0为无效 #define MPCM_MODE 0 // #elif COMM_MORE_CPU_MODE == 1 #define MPCM_MODE BIT(MPCM) #else #error "请正确配置多处理器模式中断使能信号 (COMM_MORE_CPU_MODE)!" #endif #if COMM_ACCEPT_ISR_EN == 0 // 接收结束中断 (1)使能 (0)禁止 #define RXCIE_MODE 0 // #elif COMM_ACCEPT_ISR_EN == 1 #define RXCIE_MODE BIT(RXCIE) #else #error "请正确配置接收结束中断中断使能信号 (COMM_ACCEPT_ISR_EN)!" #endif #if COMM_SEND_ISR_EN == 0 // 发送结束中断 (1)使能 (0)禁止 #define TXCIE_MODE 0 // #elif COMM_SEND_ISR_EN == 1 #define TXCIE_MODE BIT(TXCIE) #else #error "请正确配置发送结束中断中断使能信号 (COMM_SEND_ISR_EN)!" #endif #if COMM_DATAFREE_ISR_EN == 0 // 数据寄存器空中断 (1)使能 (0)禁止 #define UDRIE_MODE 0 // #elif COMM_DATAFREE_ISR_EN == 1 #define UDRIE_MODE BIT(UDRIE) #else #error "请正确配置数据寄存器空中断使能信号 (COMM_DATAFREE_ISR_EN)!" #endif //////////////////////////////////////////////// #define none 0 #define even 2 #define odd 3 /******************************************************************************************************** * 全局变量和数据类型 ********************************************************************************************************/ #if COMM_MODULE_EN > 0 #endif /******************************************************************************************************** * 函数 ********************************************************************************************************/ /* COMM1有关接口函数集 */ INT8U Comm1CfgPort (INT32U baud, INT8U parity, INT8U bits, INT8U stops); void Comm1VarInit (void); /* COMM1接收有关函数 */ INT8U Comm1RxGetChar (INT8U *Data); INT8U Comm1RxGetNMsgs (void); INT8U Comm1RxGetsChar (INT8U *s, INT8U len); /* COMM1发送有关函数 */ INT8U Comm1TxInBuf (INT8U Data); // 数据进入发送缓存 #define Comm1TxPutChar Comm1TxInBuf //INT8U Comm1TxPutChar (INT8U Data); INT8U Comm1TxPutsChar (INT8U *s, INT8U len); /******************************************************************************************************** * End Of File ********************************************************************************************************/
/************************************************************************************************** * 文 件 名 : Comm.C * 说 明 : 暂不支持9位数据流 * 1> 这一版本中最大的接收和发送缓存为255为INT8U类型的最大值 ****************************************************************************************************/ #define COMM_GLOBALS #include "includes.h" #if COMM_MODULE_EN > 0 /************************************************************************************************** * 局部常数 **************************************************************************************************/ #ifndef MCU_Fosc // MCU的晶振频率设置 这是计算波特率必须的参数 #error "no defien MCU_Fosc e.g. #define MCU_Fosc 11059200L" #endif /******************************************************************************************************** * 局部变量 ********************************************************************************************************/ static INT8U COMM1_MEM_SEL Comm1RxBuf[COMM1_RXD_SIZE]; // 串口1接收分配缓存 static INT8U COMM1_MEM_SEL Comm1RxBufCtr; // 串口1接收数据个数计数器 static INT8U COMM1_MEM_SEL Comm1RxInIx; // 串口1接收数据入缓存位置索引 static INT8U COMM1_MEM_SEL Comm1RxOutIx; // 串口1接收数据出缓存位置索引 static BOOL bComm1CanSend; // 串口1发送忙标志 0=不忙 1=忙 static INT8U COMM1_MEM_SEL Comm1TxBuf[COMM1_TXD_SIZE]; // 串口1发送分配缓存 static INT8U COMM1_MEM_SEL Comm1TxBufCtr; // 串口1发送数据个数计数器 static INT8U COMM1_MEM_SEL Comm1TxInIx; // 串口1发送数据入缓存位置索引 static INT8U COMM1_MEM_SEL Comm1TxOutIx; // 串口1发送数据出缓存位置索引 /************************************************************************************************** * 局部函数 **************************************************************************************************/ /************************************************************************************************** * COMM1相关函数集 **************************************************************************************************/ #define CR PutString("/r/n") //发送一个回车换行 #define NUL putstring("{post.content}") //发送一个空格 /************************************************************************************************** * 功 能 : COMM1 工作状态初始化 * 入 口 : 'baud' 波特率 最大波特率为实际硬件能支持的波特率和数据处理能力设置 * 'parity' 奇偶效验 none(无) even(偶校验) odd(奇校验) * 'bits' 数据位 为5,6,7,8,9位 * 'stops' 停止位 为1,2位 * 返 回 : 1> COMM_ON_ERR 串口设置没有错误 * 2> COMM_BAD_BUAD 错误的波特率 * 3> COMM_BAD_MODE 错误的工作模式 * 说 明 : ***************************************************************************************************/ #if (COMM1_UNIT_EN > 0 && COMM1_RXD_EN > 0) || ( COMM1_UNIT_EN > 0 && COMM1_TXD_EN > 0) INT8U Comm1CfgPort (INT32U baud, INT8U parity, INT8U bits, INT8U stops) { INT8U UCSRC_TEMP; //UBRRH和UCSRC的读写操作很特殊 COMM_ENTER_CRITICAL(); #if COMM_MODE == 0 UBRRH = (INT8U)((MCU_Fosc/16/(baud+1))>>8); // 设异步正常模式串口波特率 UBRRL = (INT8U)((MCU_Fosc/16/(baud+1))); UCSRA = MPCM_MODE; // 多机模式设定 #elif COMM_MODE == 1 UBRRH = (INT8U)((MCU_Fosc/8/(baud+1))>>8); // 设异步倍速模式串口波特率 UBRRL = (INT8U)((MCU_Fosc/8/(baud+1))); UCSRA = BIT(U2X)|MPCM_MODE; // 倍速发送和多机模式设定 #elif COMM_MODE == 2 UBRRH = (INT8U)((MCU_Fosc/2/(baud+1))>>8); // 设同步模式串口波特率 UBRRL = (INT8U)((MCU_Fosc/2/(baud+1))); UCSRA = MPCM_MODE; // #endif // 接收中断,发送中断,数据寄存器空中断,同步时钟极性,发送使能,接收使能设定 UCSRB =RXCIE_MODE|TXCIE_MODE|UDRIE_MODE|UCPOL_MODE|BIT(RXEN)|BIT(TXEN); switch (bits) { case 5 : UCSRC_TEMP = BIT(URSEL)|UMSEL_MODE; break; case 6: UCSRC_TEMP = BIT(URSEL)|UMSEL_MODE|BIT(UCSZ0); break; case 7: UCSRC_TEMP = BIT(URSEL)|UMSEL_MODE|BIT(UCSZ1); break; case 8 : UCSRC_TEMP = BIT(URSEL)|UMSEL_MODE|BIT(UCSZ1)|BIT(UCSZ0); break; case 9 : SETBIT(UCSRB,BIT(UCSZ2)); UCSRC_TEMP = BIT(URSEL)|UMSEL_MODE|BIT(UCSZ1)|BIT(UCSZ0); break; default: UCSRC_TEMP = BIT(URSEL)|UMSEL_MODE|BIT(UCSZ1)|BIT(UCSZ0); //默认为8BIT break; } if (stops == 2){ // 设停止位 SETBIT(UCSRC_TEMP,(BIT(URSEL)+BIT(USBS))); } switch (parity) { case none : // 无校验 break; case 1: // 系统保留 break; case even: SETBIT(UCSRC_TEMP,(BIT(URSEL)+BIT(UPM1))); // 偶校验 break; case odd : SETBIT(UCSRC_TEMP,(BIT(URSEL)+BIT(UPM1)+BIT(UPM0))); // 奇校验 break; default: //默认为无校验 break; } UCSRC = UCSRC_TEMP; COMM_EXIT_CRITICAL(); return (COMM_NO_ERR); } #endif /************************************************************************************************** * 功 能 : 串口接收中断响应函数 * 入 口 : 无 * 返 回 : 无 * 说 明 : 1> 使用串口中断前 先用Comm1CfgPort 函数配置好波特率 工作模式等信息 * 2> 使用串口中断前 再调用Comm1VarInit 函数初始化各种变量 否则工作可能出错 * 3> 如果使能串口0接收部分则 需要配置接收缓存 此缓存不能太小 发送方的数据根据波特率的关系处 * 理发送速度和MCU的处理速度(串口进缓存24MHz <40us)决定发送速度不能太快 否则后面的数据会 * 抛弃 造成数据的丢失 * 4> 如果使能串口发送部分 需要配置好发送缓存 此发送缓存的大小不做特殊要求 但太小会影响本地 * 的MCU的处理本地事务的能力 (特别是前后模式的程序和波特率低的情况) * 5> 如果是在OS中使用 可以启用通知函数给串口接收分析任务 分析接收的数据 参考程序中屏蔽的函数 * 6> 中断响应的速度与COMM_MEM_SEL和高优先级中断的响应时间有关 如果接收数据很快可以加 DISABLE命令 **************************************************************************************************/ ISR(SIG_UART_RECV){ //COMM_ENTER_CRITICAL(); // 进入临界处理 if (Comm1RxBufCtr < COMM1_RXD_SIZE) { Comm1RxBufCtr++; // 接收缓存计数器加1 Comm1RxBuf[Comm1RxInIx++] = UDR; // 接收到的数据进缓存 if (Comm1RxInIx >= COMM1_RXD_SIZE) { Comm1RxInIx = 0; } } //COMM_EXIT_CRITICAL(); // 退出临界 } /************************************************************************************************** * 功 能 : 串口发送完中断响应函数 * 入 口 : 无 * 返 回 : 无 * 说 明 : 1> 使用串口中断前 先用Comm1CfgPort 函数配置好波特率 工作模式等信息 * 2> 使用串口中断前 再调用Comm1VarInit 函数初始化各种变量 否则工作可能出错 * 3> 如果使能串口发送部分 需要配置好发送缓存 此发送缓存的大小不做特殊要求 但太小会影响本地 * 的MCU的处理本地事务的能力 (特别是前后模式的程序和波特率低的情况) * 4> 如果是在OS中使用 可以启用通知函数给串口接收分析任务 分析接收的数据 参考程序中屏蔽的函数 * 5> 中断响应的速度与COMM_MEM_SEL和高优先级中断的响应时间有关 如果接收数据很快可以加 DISABLE命令 **************************************************************************************************/ ISR(SIG_UART_TRANS){ //COMM_ENTER_CRITICAL(); // 进入临界 #if COMM_DATAFREE_ISR_EN == 0 if (Comm1TxBufCtr > 0) { // 检查发送消息缓存区是否为空 不为空则继续发数据 Comm1TxBufCtr--; // 缓存计数器减1 UDR = Comm1TxBuf[Comm1TxOutIx++]; // 读走一个数据到发送寄存器,自动清发送中断标志 if (Comm1TxOutIx >= COMM1_TXD_SIZE) { Comm1TxOutIx = 0; } } else { bComm1CanSend = 0; // 发送标志为0表示 可以直接发送信息 } #endif //COMM_EXIT_CRITICAL(); // 退出临界 } /************************************************************************************************** * 功 能 : 串口发送数据寄存器空中断函数 * 入 口 : 无 * 返 回 : 无 * 说 明 : 数据寄存器空UDRE标志位为1表示发送缓冲区可以接受一个新的数据 **************************************************************************************************/ #if COMM_DATAFREE_ISR_EN > 0 ISR(SIG_UART_DATA){ //COMM_ENTER_CRITICAL(); // 进入临界 if (Comm1TxBufCtr > 0) { // 检查发送消息缓存区是否为空 不为空则继续发数据 Comm1TxBufCtr--; // 缓存计数器减1 UDR = Comm1TxBuf[Comm1TxOutIx++]; // 读走一个数据到发送寄存器,自动清发送中断标志 if (Comm1TxOutIx >= COMM1_TXD_SIZE) { Comm1TxOutIx = 0; } } else { CLRBIT(UCSRB,BIT(UDRIE)); // 数据发送完,清数据寄存器中断使能位 bComm1CanSend = 0; // 发送标志为0表示 可以直接发送信息 } //COMM_EXIT_CRITICAL(); // 退出临界 } #endif /******************************************************************************************************** * 功 能 : 发送的数据进入发送缓存 * 入 口 : 'Data' 进入缓存的消息数据 * 返 回 : 1> COMM_TXD_FLOODL 发送数据进入缓存满 (失败) * 2> COMM_TXD_OK 发送数据进入缓存OK * 说 明 : 无 ********************************************************************************************************/ #if COMM1_UNIT_EN > 0 && COMM1_TXD_EN > 0 INT8U Comm1TxInBuf (INT8U Data) { INT8U err; err = COMM_TXD_FLOOD; // 设置发送缓存为满 COMM_ENTER_CRITICAL(); // 进入临界 if (!bComm1CanSend) { // 判断串口直接发送允许标志位 0为允许 bComm1CanSend = 1; // 设置为忙 UDR = Data; // 发送出数据 #if COMM_DATAFREE_ISR_EN > 0 SETBIT(UCSRB,BIT(UDRIE)); // 数据发送开始,置数据寄存器中断使能位 #endif COMM_EXIT_CRITICAL(); // 退出临界 return (COMM_TXD_OK); // 返回代码为发送OK } if (Comm1TxBufCtr < COMM1_TXD_SIZE) { // 处理发送缓存计数器 err = COMM_TXD_OK; // 设置发送缓存为正常 Comm1TxBufCtr++; // 发送缓存计数器加1 Comm1TxBuf[Comm1TxInIx++] = Data; // 来不及发送的数据进发送缓存 if (Comm1TxInIx >= COMM1_TXD_SIZE) { // 处理发送进缓存计数器 Comm1TxInIx = 0; // 复位发送进缓存计数器 } } COMM_EXIT_CRITICAL(); // 退出临界 开始准备发送多字符 return (err); } #endif /******************************************************************************************************** * 功 能 : COMM1 发送1 BYTE数据 * 入 口 : 'Date' 发送的数据 * 返 回 : 1> COMM_TXD_OK 发送数据OK * 2> COMM_TXD_FALSE 发送失败 一般是发送缓存已满 * 说 明 : 1> UDR发送寄存器为空时直接把要发送的数据放到发送缓存 * 2> UDR发送寄存器为忙时来不及发的数据进入到发送缓存 * 3> 发送缓存满时直接返回发送失败 ********************************************************************************************************/ /* INT8U Comm1TxPutChar (INT8U Data) { COMM_ENTER_CRITICAL(); // 进入临界 if (!bComm1CanSend) { // 判断串口直接发送允许标志位 0为允许 bComm1CanSend = 1; // 设置为忙 UDR = Data; // 发送出数据 COMM_EXIT_CRITICAL(); // 退出临界 return (COMM_TXD_OK); // 返回代码为发送OK } if (Comm1TxBufCtr >= COMM1_TXD_SIZE) { // 判断发送缓存计数器是否为最大发送缓存 COMM_EXIT_CRITICAL(); // 是退出临界 不处理 return (COMM_TXD_FALSE); // 发送缓存满 返回代码为发送失败 } else { Comm1TxInBuf(Data); // 来不及发送的数据一直等到进入发送缓存 COMM_EXIT_CRITICAL(); // 退出临界 return (COMM_TXD_OK); // 返回代码为发送OK } } */ /******************************************************************************************************** * 功 能 : COMM1 发送N BYTE数据 * 入 口 : 'p' 指向发送消息的指针 * 'len' 发送数据的长度 * 返 回 : 返回实际发送的数据长度 * 说 明 : 1> 如果是发送失败 则直接返回 这样在多任务里面就可以延时N个周期再尝试重发数据 这样就不会在这里 * 多等更多的时间 但这种情况不是绝对的 根据波特率是有很大的关系 * 2> 建议发送时的缓存最好保证>=即将发送的数据长度 数据流之间能留一定的时间间隔保证发送数据 * 3> 发送的数据长度大于实际能缓存的长度时 波特率是影响其工作效率的主要因素 MCU中的RAM一般比较小 ********************************************************************************************************/ INT8U Comm1TxPutsChar (INT8U *s, INT8U len) { INT8U i; //COMM_ENTER_CRITICAL(); // 进入临界 i = COMM1_TXD_SIZE - Comm1TxBufCtr; // 实际还有多少可用缓冲区 //COMM_EXIT_CRITICAL(); // 退出临界 if (i > len){ // 发送数据长度小于可用缓冲区时, i = len; // 所有数据能全部发送成功 }else{ len = i; } while (i--) { // 发送数据处理 Comm1TxInBuf(*s); // 发送的数据进入发送缓存 s++; // 数据指针加1 } return (len); // 返回实际发送的数据长度 } /******************************************************************************************************** * 功 能 : 串口1读1则数据 * 入 口 : 'err' 返回错误信息的指针 * 返 回 : 1> 读到的数据 * 2> err=COMM_RXD_EMPTY 接收缓存没有数据 * 3> err=COMM_RXD_OK 正确在接收缓存读到数据 * 说 明 : 1> 在调用此函数前 最好用Comm1RxGetNMsgs函数检查一下接收缓存里面有没有信息 * 2> 如果不按1>的用法用 则要对返回的错误代码分析 ********************************************************************************************************/ INT8U Comm1RxGetChar (INT8U *Data) { INT8U err = COMM_RXD_EMPTY; // 返回代码为接收为空 COMM_ENTER_CRITICAL(); // 进入临界 if (Comm1RxBufCtr > 0) { // 检测接收缓存是否有数据 Comm1RxBufCtr--; // 有数据计数器减1 *Data = Comm1RxBuf[Comm1RxOutIx++]; // 取出数据 err = COMM_RXD_OK; // 返回代码为读数据正确 if (Comm1RxOutIx >= COMM1_RXD_SIZE) { // 检查出数据计数器 是否大于最大接收缓存 Comm1RxOutIx = 0; // 是复位出数据计数器 } } COMM_EXIT_CRITICAL(); // 退出临界 return (err); } /******************************************************************************************************** * 功 能 : 检测接收缓存中的数据个数 * 入 口 : 无 * 返 回 : 缓存中的数据个数 * 说 明 : 无 ********************************************************************************************************/ INT8U Comm1RxGetNMsgs (void) { INT8U counter; COMM_ENTER_CRITICAL(); // 进入临界 counter = Comm1RxBufCtr; // 取接收计数器数据 COMM_EXIT_CRITICAL(); // 退出临界 return (counter); // 返回接收缓存计数 } /******************************************************************************************************** * 功 能 : 一次串口1读N则数据 * 入 口 : 'p' 返回数据信息的指针 * 'len' 读的数据长度 < COMM1_RXD_SIZE * 返 回 : 1> COMM_RXD_EMPTY 读数据为空 一般是len为空 或接收缓存中没有数据 * 2> COMM_RXD_FALSE 错误读数据 一般为len大于数据接收缓存中的数据 * 3> COMM_RXD_OK 数据正确读到 * 说 明 : 1> 对于返回参数2> 可以使用Comm1RxGetNMsgs 先取得缓存中的数据个数再一次读走 ********************************************************************************************************/ #if COMM1_UNIT_EN > 0 && COMM1_RXD_EN > 0 && COMM1_GETS_EN > 0 INT8U Comm1RxGetsChar (INT8U *s, INT8U len) { COMM_ENTER_CRITICAL(); // 进入临界 处理Comm1RxBufCtr if ((len == 0) || (Comm1RxBufCtr == 0)) { // 检查数据长度 和接收缓存是否为空 COMM_EXIT_CRITICAL(); // 退出临界 return (COMM_RXD_EMPTY); // 返回代码为接收空 } if (len > Comm1RxBufCtr) { // 检查读数长度跟实际接收缓存数据个数 COMM_EXIT_CRITICAL(); // 退出临界 return (COMM_RXD_FALSE); // 返回代码为 读数据失败 } COMM_EXIT_CRITICAL(); // 退出临界 // 必须退出临界以便其他的中断响应 否则len大时就会影响中断 while (len--) { // 读走len个数据 COMM_ENTER_CRITICAL(); // 进入临界 处理Comm1RxBufCtr *s++ = Comm1RxBuf[Comm1RxOutIx++]; // 取出数据 Comm1RxBufCtr--; // 接收缓存计数器减1 if (Comm1RxOutIx >= COMM1_RXD_SIZE) { // 处理接收出数据计数器 Comm1RxOutIx = 0; // 复位出数据计数器 } COMM_EXIT_CRITICAL(); // 退出临界 } return (COMM_RXD_OK); // 返回代码为 接收到正确数据 } #endif /******************************************************************************************************** * 功 能 : 初始化串口1的各种变量 * 入 口 : 无 * 返 回 : 无 * 说 明 : 无 ********************************************************************************************************/ void Comm1VarInit (void) { #if COMM1_RXD_EN > 0 // 初始化接收的各种变量 Comm1RxBufCtr = 0; Comm1RxInIx = 0; Comm1RxOutIx = 0; #endif #if COMM1_TXD_EN > 0 // 初始化发送的各种变量 Comm1TxBufCtr = 0; Comm1TxInIx = 0; Comm1TxOutIx = 0; bComm1CanSend = 0; // 串口0寄存器发送忙标志 #endif } #endif /******************************************************************************************************** * End Of File ********************************************************************************************************/
相关文章推荐
- 2、一个简单的AVR中断程序
- 一个简单的AVR测试程序
- Q:一个经典的helloworld程序需要几个文件?
- 牛人:一个女孩写的经典程序!
- 一个非常经典精巧的字符处理程序
- 一个经典的JAVA APPLET时钟程序(一)
- C语言经典实例008:一个简单的求和程序
- 一个经典的文件拷贝程序
- AVR单片机使用外部中断和定时器的NEC红外解码程序
- [C/C++]一个女孩写的经典程序
- 一个经典的JDBC连接MySQL的程序
- 一个女孩写的经典程序!!!
- 利用BIOS中断或DOS中断实现一个显示当前时间的程序
- 一个经典的JAVA APPLET程序(二)
- [转贴] ++ 一个北大女孩给男友的道歉信(爆笑!!!)相当经典
- 一个女孩写的经典程序
- 一个女孩写的经典程序!!! (转载)
- struts2入门-第一个例子==》第一个struts2实例——HelloWorld==》Struts2.0搭建和简单实例==>写一个Steuts2的经典入门案例,做了一个登陆程序作为入门例子
- 利用BIOS中断或DOS中断实现一个电子表的程序,要求精确到秒
- 一个女孩写的经典程序!!! (anen)