1、添加头文件 首先我们先添加相应的头文件。既然我们要进行对串口的模拟,因此我们要先了解uart相关的通信协议。由于UART的通信方式是由1个起始位,8个数据位,包含一个奇偶校验位,和结束位构成因此我们将使用单片机中的两个普通的IO口电平的高低进行对相应时序的模拟。 includestm32f10x。hincludevuart2。h2、宏定义 使用到的io口为defineOI2TXDPDout(6)defineOI2RXDPDin(7)defineBuadRate29600104defineRecive2Byte19接收缓冲器的个数u8len20;接收计数u8USART2buf〔Recive2Byte〕;接收缓冲区 将IO口相应的位带操作函数进行宏定义从而使得在对不同的电平的进行转换的时候更为方便,并且减少了调用其他函数的过程所消耗的时间,程序执行效率更高。 在本次的传输过程中我选用的是使用波特率速率为9600,也就是1s中发送9600个字节,因此对每个字节数据进行计算1000000us9600可以得出,发一个字节的数据需要进行大概需要104。16us并且对于相应的电平持续时间要求误差不能超过5因此对我们进行时间的控制要求就显得比较重要了。3、枚举出各个位enum{COMSTARTBIT,COMD0BIT,COMD1BIT,COMD2BIT,COMD3BIT,COMD4BIT,COMD5BIT,COMD6BIT,COMD7BIT,COMSTOPBIT,};u8recvStat2COMSTOPBIT;u8recvData20;4、IOTXD进行模拟voidIO2TXD(u8Data){u8i0;OI2TXD0;delayus(BuadRate29600);for(i0;i8;i){if(Data0x01)OI2TXD1;elseOI2TXD0;delayus(BuadRate29600);DataData1;}OI2TXD1;delayus(BuadRate29600);} 由于发送的信号是将TXD信号进行拉低处理,因此在拉低TXD相应的IO口之后进行延时处理,再进行循环对我们需要发送的各个位的数据继续进行发送循环发送完成之后将电平拉高代表停止位。5、构建发送函数voidUSART2Send(u8buf,u8len2){u8t;for(t0;tlen2;t){IO2TXD(buf〔t〕);}} 其中的buf为需要发送的数据,len2为数据长度,进行循环调用IOTXD进行一个字节一个字节的数据发送。6、IO口初始化voidIO2Config(void){GPIOInitTypeDefGPIOInitStructure;初始化gpioNVICInitTypeDefNVICInitStructure;中断初始化函数EXTIInitTypeDefEXTIInitStruct;RCCAPB2PeriphClockCmd(RCCAPB2PeriphAFIORCCAPB2PeriphGPIODRCCAPB2PeriphGPIOC,ENABLE);使能PD,PC端口时钟SoftWareSerialTXDGPIOInitStructure。GPIOPinGPIOPin6;选择io口6GPIOInitStructure。GPIOModeGPIOModeOutPP;推挽输出GPIOInitStructure。GPIOSpeedGPIOSpeed50MHz;IO口速度为50MHzGPIOInit(GPIOD,GPIOInitStructure);GPIOSetBits(GPIOD,GPIOPin6);TXD默认电平拉高SoftWareSerialRXDGPIOInitStructure。GPIOPinGPIOPin7;GPIOInitStructure。GPIOModeGPIOModeIPU;GPIOInitStructure。GPIOSpeedGPIOSpeed50MHz;GPIOInit(GPIOD,GPIOInitStructure);GPIOEXTILineConfig(GPIOPortSourceGPIOD,GPIOPinSource7);对D7的下降沿进行中断采样,当接收到下降沿时代表接收到数据触发中断处理函数EXTIInitStruct。EXTILineEXTILine7;用到了中断7EXTIInitStruct。EXTIModeEXTIModeInterrupt;EXTIInitStruct。EXTITriggerEXTITriggerFalling;下降沿触发中断EXTIInitStruct。EXTILineCmdENABLE;EXTIInit(EXTIInitStruct);初始化中断NVICInitStructure。NVICIRQChannelEXTI95IRQn;中断发生于95的中断之中NVICInitStructure。NVICIRQChannelPreemptionPriority2;NVICInitStructure。NVICIRQChannelSubPriority2;NVICInitStructure。NVICIRQChannelCmdENABLE;NVICInit(NVICInitStructure);}7、定时器初始化voidTIM5IntInit(u16arr,u16psc){TIMTimeBaseInitTypeDefTIMTimeBaseStructure;NVICInitTypeDefNVICInitStructure;RCCAPB1PeriphClockCmd(RCCAPB1PeriphTIM5,ENABLE);时钟使能定时器TIM5初始化TIMTimeBaseStructure。TIMPeriodarr;设置在下一个更新事件装入活动的自动重装载寄存器周期的值TIMTimeBaseStructure。TIMPrescalerpsc;设置用来作为TIMx时钟频率除数的预分频值TIMTimeBaseStructure。TIMClockDivisionTIMCKDDIV1;设置时钟分割:TDTSTcktimTIMTimeBaseStructure。TIMCounterModeTIMCounterModeUp;TIM向上计数模式TIMTimeBaseInit(TIM5,TIMTimeBaseStructure);根据指定的参数初始化TIMx的时间基数单位TIMClearITPendingBit(TIM5,TIMFLAGUpdate);TIMITConfig(TIM5,TIMITUpdate,ENABLE);使能指定的TIM5中断,允许更新中断中断优先级NVIC设置NVICInitStructure。NVICIRQChannelTIM5IRQn;TIM5中断NVICInitStructure。NVICIRQChannelPreemptionPriority1;先占优先级1级NVICInitStructure。NVICIRQChannelSubPriority1;从优先级1级NVICInitStructure。NVICIRQChannelCmdENABLE;IRQ通道被使能NVICInit(NVICInitStructure);初始化NVIC寄存器} 对TIM5进行初始化操作使得定时器可以检测到各个位的电平持续性时间从而对接收到的数据进行分析。计时结束后进入中断TIM5处理。8、外部中断处理函数voidEXTI95IRQHandler(void){if(EXTIGetFlagStatus(EXTILine7)!RESET)对中断标志位进行采集{if(OI2RXD0){if(recvStat2COMSTOPBIT){recvStat2COMSTARTBIT;将当前的状态设置为开始位TIMCmd(TIM5,ENABLE);开启定时器计数}}EXTIClearITPendingBit(EXTILine7);清除中断标志}}9、定时器中断处理函数voidTIM5IRQHandler(void){if(TIMGetFlagStatus(TIM5,TIMFLAGUpdate)!RESET){TIMClearITPendingBit(TIM5,TIMFLAGUpdate);清除中断标志位recvStat2;将位置移动到第一位的数据if(recvStat2COMSTOPBIT)当运行到停止位时进入{TIMCmd(TIM5,DISABLE);停止tim5USART2buf〔len2〕recvData2;将采集到的各个数据传递给USART2bufif(len2Recive2Byte1)将数据通过回显到串口调试助手中{len20;USART2Send(USART2buf,Recive2Byte);}return;}if(OI2RXD)采集RXD各个电平{recvData2(1(recvStat21));}else{recvData2(1(recvStat21));}}}整体代码vuart2。cincludestm32f10x。hincludevuart2。h软件串口的实现(IO模拟串口)波特率:960018NTXD:PD6RXD:PD7使用外部中断对RXD的下降沿进行触发,使用定时器5按照9600波特率进行定时数据接收。Demo功能:接收11个数据,然后把接收到的数据发送出去defineOI2TXDPDout(6)defineOI2RXDPDin(7)defineBuadRate29600104defineRecive2Byte19接收缓冲器的个数u8len20;接收计数u8USART2buf〔Recive2Byte〕;接收缓冲区enum{COMSTARTBIT,COMD0BIT,COMD1BIT,COMD2BIT,COMD3BIT,COMD4BIT,COMD5BIT,COMD6BIT,COMD7BIT,COMSTOPBIT,};u8recvStat2COMSTOPBIT;u8recvData20;voidIO2TXD(u8Data){u8i0;OI2TXD0;delayus(BuadRate29600);for(i0;i8;i){if(Data0x01)OI2TXD1;elseOI2TXD0;delayus(BuadRate29600);DataData1;}OI2TXD1;delayus(BuadRate29600);}voidUSART2Send(u8buf,u8len2){u8t;for(t0;tlen2;t){IO2TXD(buf〔t〕);}}voidIO2Config(void){GPIOInitTypeDefGPIOInitStructure;NVICInitTypeDefNVICInitStructure;EXTIInitTypeDefEXTIInitStruct;RCCAPB2PeriphClockCmd(RCCAPB2PeriphAFIORCCAPB2PeriphGPIODRCCAPB2PeriphGPIOC,ENABLE);使能PB,PC端口时钟SoftWareSerialTXDGPIOInitStructure。GPIOPinGPIOPin6;GPIOInitStructure。GPIOModeGPIOModeOutPP;推挽输出GPIOInitStructure。GPIOSpeedGPIOSpeed50MHz;IO口速度为50MHzGPIOInit(GPIOD,GPIOInitStructure);GPIOSetBits(GPIOD,GPIOPin6);SoftWareSerialRXDGPIOInitStructure。GPIOPinGPIOPin7;GPIOInitStructure。GPIOModeGPIOModeIPU;GPIOInitStructure。GPIOSpeedGPIOSpeed50MHz;GPIOInit(GPIOD,GPIOInitStructure);GPIOEXTILineConfig(GPIOPortSourceGPIOD,GPIOPinSource7);EXTIInitStruct。EXTILineEXTILine7;EXTIInitStruct。EXTIModeEXTIModeInterrupt;EXTIInitStruct。EXTITriggerEXTITriggerFalling;下降沿触发中断EXTIInitStruct。EXTILineCmdENABLE;EXTIInit(EXTIInitStruct);NVICInitStructure。NVICIRQChannelEXTI95IRQn;NVICInitStructure。NVICIRQChannelPreemptionPriority2;NVICInitStructure。NVICIRQChannelSubPriority2;NVICInitStructure。NVICIRQChannelCmdENABLE;NVICInit(NVICInitStructure);}voidTIM5IntInit(u16arr,u16psc){TIMTimeBaseInitTypeDefTIMTimeBaseStructure;NVICInitTypeDefNVICInitStructure;RCCAPB1PeriphClockCmd(RCCAPB1PeriphTIM5,ENABLE);时钟使能定时器TIM5初始化TIMTimeBaseStructure。TIMPeriodarr;设置在下一个更新事件装入活动的自动重装载寄存器周期的值TIMTimeBaseStructure。TIMPrescalerpsc;设置用来作为TIMx时钟频率除数的预分频值TIMTimeBaseStructure。TIMClockDivisionTIMCKDDIV1;设置时钟分割:TDTSTcktimTIMTimeBaseStructure。TIMCounterModeTIMCounterModeUp;TIM向上计数模式TIMTimeBaseInit(TIM5,TIMTimeBaseStructure);根据指定的参数初始化TIMx的时间基数单位TIMClearITPendingBit(TIM5,TIMFLAGUpdate);TIMITConfig(TIM5,TIMITUpdate,ENABLE);使能指定的TIM5中断,允许更新中断中断优先级NVIC设置NVICInitStructure。NVICIRQChannelTIM5IRQn;TIM4中断NVICInitStructure。NVICIRQChannelPreemptionPriority1;先占优先级1级NVICInitStructure。NVICIRQChannelSubPriority1;从优先级1级NVICInitStructure。NVICIRQChannelCmdENABLE;IRQ通道被使能NVICInit(NVICInitStructure);初始化NVIC寄存器}voidEXTI95IRQHandler(void){if(EXTIGetFlagStatus(EXTILine7)!RESET){if(OI2RXD0){if(recvStat2COMSTOPBIT){recvStat2COMSTARTBIT;TIMCmd(TIM5,ENABLE);}}EXTIClearITPendingBit(EXTILine7);}}voidTIM5IRQHandler(void){if(TIMGetFlagStatus(TIM5,TIMFLAGUpdate)!RESET){TIMClearITPendingBit(TIM5,TIMFLAGUpdate);recvStat2;if(recvStat2COMSTOPBIT){TIMCmd(TIM5,DISABLE);USART2buf〔len2〕recvData2;if(len2Recive2Byte1){len20;USART2Send(USART2buf,Recive2Byte);}return;}if(OI2RXD){recvData2(1(recvStat21));}else{recvData2(1(recvStat21));}}}vuart2。hifndefVUART2HdefineVUART2Hincludestm32f10x。hvoidIO2TXD(u8Data);voidUSART2Send(u8buf,u8len);voidIO2Config(void);voidTIM5IntInit(u16arr,u16psc);endif 本文来源网络,免费传达知识,版权归原作者所有。如涉及作品版权问题,请联系我进行删除。