|
技术交流 | 电路欣赏 | 工控天地 | 数字广电 | 通信技术 | 电源技术 | 测控之家 | EMC技术 | ARM技术 | EDA技术 | PCB技术 | 嵌入式系统 驱动编程 | 集成电路 | 器件替换 | 模拟技术 | 新手园地 | 单 片 机 | DSP技术 | MCU技术 | IC 设计 | IC 产业 | CAN-bus/DeviceNe |
寻找软串口的源代码 |
作者:luya 栏目:单片机 |
2楼: | >>参与讨论 |
作者: luya 于 2005/2/1 12:58:00 发布:
软串口 |
3楼: | >>参与讨论 |
作者: winhiwang 于 2005/2/1 12:59:00 发布:
有人刚发过,你查一下 |
4楼: | >>参与讨论 |
作者: jcsasm 于 2005/2/1 13:00:00 发布:
什么叫软串口?? |
5楼: | >>参与讨论 |
作者: luya 于 2005/2/1 14:16:00 发布:
大多是用汇编写的,请问有没有用C51写的呢? |
6楼: | >>参与讨论 |
作者: maychang 于 2005/2/1 14:17:00 发布:
老古网上有 |
7楼: | >>参与讨论 |
作者: 雁舞白沙 于 2005/2/1 15:07:00 发布:
LPC932 软串口 1200 void INT_INT0(void) interrupt 0 { unsigned CHAR BitData; bit BitChk; EA=0; EX0=0; WDT(); EX0=0; BitData=0; BitChk=1; SeriesInData=0; Delay(130); //等过起始位 while(BitData<9) { if(BitData==8) { SeriesBitNine=RXD; } if(RXD==1) { SeriesInData|=0x0080; BitChk=~BitChk; } BitData++; if(BitData<8) { SeriesInData>>=1; } Delay(90); } if(BitChk) { if(ComEn) { ComBit=1; SeriesSt=0; } else { ComEn=1; ComBit=1; SeriesSt=1; } } EX0=1; EA=1; } void DataCom(void) { if(ComBit) { //串口数据集合校验 if(ComEn) { if(SeriesSt) { if(SeriesBufDptr<60) { if(SeriesBufDptr==0) //数据缓冲区地址指针是否为零 { if(SeriesInData==0x68) //缓冲区的第一个数据是否等于0x68*/ { ComDataBuf[0]=SeriesInData; //数据保存到缓冲区*/ SeriesBufDptr++; //缓冲区地址累加*/ } else { SeriesBufDptr=0; } } else { ComDataBuf[SeriesBufDptr]=SeriesInData; //数据保存到缓冲区*/ SeriesBufDptr++; //缓冲区地址累加*/ } } else { SeriesBufDptr=0; } if(SendOverFg) { if(ComDataBuf[ComDataBuf][9]+11]==0x16) &nb |
8楼: | >>参与讨论 |
作者: hotpower 于 2005/2/2 0:23:00 发布:
厉害 |
9楼: | >>参与讨论 |
作者: luya 于 2005/2/2 9:32:00 发布:
太好了!还没有看呢,先赞一下!! 很感谢! |
10楼: | >>参与讨论 |
作者: 雁舞白沙 于 2005/2/2 11:26:00 发布:
什么厉害? |
11楼: | >>参与讨论 |
作者: xymxym 于 2005/2/2 23:55:00 发布:
!!! 我最近用T2和INT两个中断模拟了串口,效果还不错,摘出里面的一部分供你参考 #include "reg52.h" #include <intrins.h> #define uCHAR unsigned CHAR #define uint unsigned int #define StartBit 0 #define EndBit 9 #define N 10 sbit F_Receive = P3^2; uCHAR data AUX_Count,AUX_Time,AUX_State,AUX_Mode,AUX_Temp; uCHAR data AUX_Buf[N]; bit AUX_Received,AUX_En; void T_Rece(void) interrupt 2 { //INT2中断 AUX_Time = 11; if (!AUX_En) { //开始接收数据串的准备工作 AUX_Count = 0; //接收字节数初始 AUX_State = 1; //假设现在为为起始位,则下一次应该指向数据的第一位 AUX_Received = 0; //整个数据串接收完毕,此位置1 AUX_Buf[0] = 0x00; //接收缓冲区初始 AUX_En = SET; T2High = SysBpsH; T2Low = SysBpsL; //填入要模拟的串口的波特率位时间,由T2进行中断 TH2 = T2High; TL2 = T2Low; TF2 = 0; TR2 = SET; ET2 = SET; //启动T2进行计数的中断 PT2 = SET; //T2为最高权 } } void Time2(void) interrupt 5 { TH2 = T2High; //定时器2每隔bps秒中断,作为模拟串口的位时间 TL2 = T2Low; TF2 = 0; if (--AUX_Time != 0) { //位数减一 if (AUX_State == StartBit) { //现在的中断刚好落在起始位状态,不作任何处理 AUX_State++; //只将状态指向数据态 } else if (AUX_State == EndBit) { //现在是终止位状态, AUX_State = StartBit; //将接收的状态指向起始位,准备下一个数据的接收 AUX_Buf[AUX_Count++] = AUX_Temp; //将接收的字节数据存入数组 AUX_Temp = 0x00; } else { AUX_Temp >>= 1; //不是起始位也不是终止位的状态,那只能是数据位了 if (F_Receive) AUX_Temp |= 0x80; ++AUX_State; //接收状态指向下一态 } } else { //如果计满11位的时间,AUX_Time未再被重置,说明数据串已接收完毕 EX1 = SET; IE1 = CLR; TR2 = CLR; ET2 = CLR; PT2 = CLR; AUX_En = CLR; AUX_Received = SET; //该位置1,在主程序中查询并调用子程序对所接收的数据处理 } } |
12楼: | >>参与讨论 |
作者: luya 于 2005/2/3 14:13:00 发布:
万分感谢! |
13楼: | >>参与讨论 |
作者: tianle1010 于 2005/2/3 14:55:00 发布:
我给你发一个,希望你有用~~ //****************************************************************************** // MSP-FET430X110 DEMO - Timer_A UART Ultra-low POWER 2400 Echo, 32KHZ ACLK // // DESCRIPTION: Use timer_A CCR0 HARDWARE OUTPUT modes and SCCI data latch to // to implement UART function @ 2400 baud. SOFTWARE does not directly read and // write to RX and TX pins, instead proper use of OUTPUT modes and SCCI data // latch are demonstrated. Use of these HARDWARE features eliminates ISR // latency effects as HARDWARE insures that OUTPUT and input bit latching and // timing are perfectly synchronised with timer_A regardless of other // SOFTWARE activity. In the Mainloop the UART function readies the UART to // receive one CHARacter and waits in LPM3 with all activity interrupt driven. // After a CHARacter has been received, the UART receive function forces exit // from LPM3 in the Mainloop which echo's BACK the received CHARacter. // ACLK = TACLK = LFXT1 = 32768, MCLK = SMCLK = DCO ~ 800K // //*An external watch CRYSTAL is required on XIN XOUT for ACLK*// // // MSP430F1121 // ----------------- // /|\| XIN|- // | | | 32KHZ // --|RST XOUT|- // | | // | CCI0A/TXD/P1.1|--------> // | | 2400 8N1 // | CCI0B/RXD/P2.2|<-------- // #define RXD 0x04 // RXD on P2.2 #define TXD 0x02 // TXD on P1.1 // Conditions for 2400 Baud SW UART, ACLK = 32768 #define Bitime_5 0x06 // ~ 0.5 bit length + small adjustment #define Bitime 0x0E // 427us bit length ~ 2341 baud unsigned int RXTXData; unsigned CHAR BitCnt; void TX_Byte (void); void RX_Ready (void); // M.Buccini // Texas Instruments, Inc // September 2003 // Built with IAR Embedded Workbench Version: 1.26B // January 2004 // Updated for IAR Embedded Workbench Version: 2.21B //****************************************************************************** #include <msp430x11x1.h> void main (void) { WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer CCTL0 = OUT; // TXD Idle as Mark TACTL = TASSEL_1 + MC_2; // ACLK, continuous mode P1SEL = TXD; // P1.1/TA0 for TXD function P1DIR = TXD; // TXD OUTPUT on P1 P2SEL = RXD; // P2.2/TA0 as RXD input // Mainloop for (;;) { RX_Ready(); // UART ready to RX one Byte _BIS_SR(LPM3_bits + GIE); // Enter LPM3 w/ interr until CHAR RXed TX_Byte(); // TX BACK RXed Byte Received } } // Function Transmits Character from RXTXData Buffer void TX_Byte (void) { BitCnt = 0xA; // Load Bit counter, 8data + ST/SP while (CCR0 != TAR) // Prevent async capture CCR0 = TAR; // Current state of TA counter CCR0 += Bitime; // Some time till first bit RXTXData |= 0x100; // Add mark stop bit to RXTXData RXTXData = RXTXData << 1; // Add space start bit CCTL0 = OUTMOD0 + CCIE; // TXD = mark = idle while ( CCTL0 & CCIE ); // Wait for TX completion } // Function Readies UART to Receive Character into RXTXData Buffer void RX_Ready (void) { BitCnt = 0x8; // Load Bit counter CCTL0 = SCS + CCIS0 + OUTMOD0 + CM1 + CAP + CCIE; // Sync, Neg Edge, Cap } // Timer A0 interrupt service routine #pragma vector=TIMERA0_VECTOR __interrupt void Timer_A (void) { CCR0 += Bitime; // Add Offset to CCR0 // RX if (CCTL0 & CCIS0) // RX on CCI0B? { if( CCTL0 & CAP ) // Capture mode = start bit edge { CCTL0 &= ~ CAP; // SWITCH from capture to compare mode CCR0 += Bitime_5; } else { RXTXData = RXTXData >> 1; if (CCTL0 & SCCI) // Get bit waiting in receive latch RXTXData |= 0x80; BitCnt --; // All bits RXed? if ( BitCnt == 0) //>>>>>>>>>> Decode of Received Byte Here <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< { CCTL0 &= ~ CCIE; // All bits RXed, disable interrupt _BIC_SR_IRQ(LPM3_bits); // Clear LPM3 bits from 0(SR) } //>>>>>>>>>> Decode of Received Byte Here <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< } } // TX else { if ( BitCnt == 0) CCTL0 &= ~ CCIE; // All bits TXed, disable interrupt else { CCTL0 |= OUTMOD2; // TX Space if (RXTXData & 0x01) CCTL0 &= ~ OUTMOD2; // TX Mark RXTXData = RXTXData >> 1; BitCnt --; } } } |
14楼: | >>参与讨论 |
作者: luya 于 2005/2/6 20:01:00 发布:
十分感谢! |
15楼: | >>参与讨论 |
作者: luya 于 2005/2/6 20:05:00 发布:
请问雁舞白沙 请问,雁舞白沙,你的波特率是如何设制的? |
16楼: | >>参与讨论 |
作者: luya 于 2005/2/17 16:03:00 发布:
请您把变量定义也发给我好么,这样更可读一些。多谢 |
17楼: | >>参与讨论 |
作者: 雁舞白沙 于 2005/2/18 13:04:00 发布:
倒数的关系 luya ;请问雁舞白沙 ,你的波特率是如何设制的? 雁:延时---1200的倒数 |
18楼: | >>参与讨论 |
作者: yang96381 于 2005/2/18 13:55:00 发布:
哈哈,我详细说一下原理 以51单片机为例,晶振采用12M,波特率9600,1位起始位,8位数据位,1位停止 位,采用P1口中的任意两只引脚,如果接收采用中断方式,那么还得用一个外部 中断0或1引脚,用来检测负跳变的起始位!!! 波特率9600的倒数为104微秒, 这就是发送1位所需的时间,每隔104微秒发送1位数据,因为采用I/O口模拟串口,所以对软件延时十分严格,否则所发送或接收的数据误码大。适当减少波特 率可减少误差。 采用这种方法适合发送或接收少量的数据!!! |
19楼: | >>参与讨论 |
作者: lql441 于 2005/2/18 15:52:00 发布:
IO口模拟232通讯程序占用定时器0,晶振为11.0592MHZ /********************************************** IO口模拟232通讯程序占用定时器0,晶振为11.0592MHZ **********************************************/ #include <at89x51.h> sbit TX =P1^0; sbit RX =P1^1; #define TIMER0_ENABLE TL0=TH0; TR0=1; #define TIMER0_DISABLE TR0=0; volatile bit F_TM; void IntTimer0() interrupt 1 { F_TM=1; } /*发送一个字符*/ void SendChar(unsigned CHAR inch) { unsigned CHAR i; i=0; F_TM=0; TX=0; //start bit TIMER0_ENABLE; //启动 while(!F_TM); while(i<8) { if(inch&1)//数据由低位到高位发送 { TX=1; } else { TX=0; } F_TM=0; while(!F_TM); i++; inch>>=1; } TX=1; F_TM=0; while(!F_TM); TIMER0_DISABLE; //停止timer } /*接收一个字符*/ unsigned CHAR ReceChar() { unsigned CHAR rch,i; TIMER0_ENABLE; F_TM=0; i=0; rch=0; while(!F_TM); //等过起始位 while(i<8) { rch>>=1; if(RX) { rch|=0x80; //数据从低位到高位接收 } i++; F_TM=0; while(!F_TM); } F_TM=0; while(!F_TM) { if(RX) { break; } } TIMER0_DISABLE; //停止timer return rch; } /*检查是不是有起始位*/ bit StartBitOn() { return (RX==0); } void main() { TMOD=0x22; //定时器1为工作模式2(8位自动重装),0为模式2(8位重装) PCON=0x00; TR0=0; //在发送或接收才开始使用 TF0=0; TH0=(256-96); //9600bps 就是1000000/9600=104.167微秒 执行的timer是104.167*11.0592/12= 96// TL0=TH0; ET0=1; EA=1; while(1) { SendChar('e'); } } |
20楼: | >>参与讨论 |
作者: luya 于 2005/2/18 17:49:00 发布:
多谢各位!! yang96381说的很明白,我今天下午看了一个网上下载的程序也有同样的体会,多谢热心人! |
|
|
免费注册为维库电子开发网会员,参与电子工程师社区讨论,点此进入 |
Copyright © 1998-2006 www.dzsc.com 浙ICP证030469号 |