|
技术交流 | 电路欣赏 | 工控天地 | 数字广电 | 通信技术 | 电源技术 | 测控之家 | EMC技术 | ARM技术 | EDA技术 | PCB技术 | 嵌入式系统 驱动编程 | 集成电路 | 器件替换 | 模拟技术 | 新手园地 | 单 片 机 | DSP技术 | MCU技术 | IC 设计 | IC 产业 | CAN-bus/DeviceNe |
LPC900,请教一个模拟串口问题 |
作者:zy005021 栏目:MCU技术 |
LPC900,请教一个模拟串口问题,我看了前面提供的那个模拟串口的程序,但是我的电路还没有搭出来的情况下,我想先在KEIL C下模拟一下这个模拟串口,让它通过一根九针线缆发送给另外一台计算机.我以前是用单片机的串口模拟的,可以实现,但是模拟串口就不知道能不能实现了. 希望能指点一下:) |
2楼: | >>参与讨论 |
作者: LPC900 于 2005/5/24 13:09:00 发布:
用I/O模拟串行口例程 下面的程序是我以前写的,适合于80C52内核的单片机,不能直接用在LPC900系列单片机上。我现在懒了,不想再修改,如果要用,您自己动手做一些修改吧: 首先,该程序中的定时器用的是T2,然而LPC900系列单片机中没有T2。您可以将其换成T0或者是T1。 RXD_pin和TXD_pin的属性要重新做一些设置,使之能够在您的LPC900单片机上运行。 晶振不能用22.1184MHZ那么高,建议用低于12MHZ的晶振或者直接使用片内RC振荡器。 /* 52单片机实用的IO模拟串行口C语言源程序 作者:LPC900 用途:短距离、波特率要求不高、环境干扰不大的场合 特点: 程序简练、实用、移植方便 占用定时器T2 只消耗约600字节的ROM 有详细的注释 参数: 晶振:22.1184MHZ 波特率:1200 起始位:1 数据位:8 校验位:无 停止位:1 */ #include <reg52.h> //将T2定时器的自动重装寄存器定义成16位SFR,以方便访问 sfr16 RCAP2 = 0xCA; //修改如下定义将方便程序移植 sbit RXD_pin = P3^0; //定义接收引脚 sbit TXD_pin = P3^1; //定义发送引脚 #define MAIN_CLK 22118400L //定义主频 #define BAUD_RATE 1200L //定义波特率(数值不能太高,因为要给T2中断服务程序留足执行时间) #define HITS 8 //定义采样率(应当是偶数;减少采样率能提高波特率,但为保证可靠工作,最小不能少于6次) #define RXD_BUF_LEN 32 //定义接收缓冲区大小 volatile unsigned CHAR RXD_buf[RXD_BUF_LEN]; //定义接收缓冲区(循环队列) volatile unsigned CHAR RXD_p1; //指向缓冲区,由中断程序自动修改 volatile unsigned CHAR RXD_p2; //指向缓冲区,由主程序修改 #define TXD_BUF_LEN 32 //定义发送缓冲区大小 volatile unsigned CHAR TXD_buf[TXD_BUF_LEN]; //定义发送缓冲区(循环队列) volatile unsigned CHAR TXD_p1; //指向TXD_buf,由主程序修改 volatile unsigned CHAR TXD_p2; //指向TXD_buf,由中断程序修改 //定时器T2初始化 extern void T2_init() { EA = 0; T2CON = 0x00; PT2 = 1; //将T2中断设置成高级优先级 RCAP2 = 65536L - ( MAIN_CLK / 12 ) / ( BAUD_RATE * HITS ); //此公式值得你琢磨一下 TH2 = RCAP2H; TL2 = RCAP2L; ET2 = 1; TR2 = 1; EA = 1; } //接收初始化 extern void RXD_init() { unsigned CHAR i; RXD_pin = 1; RXD_p1 = 0; RXD_p2 = 0; for ( i=0; i<RXD_BUF_LEN; i++ ) { RXD_buf[i] = 0x00; } } //发送初始化 extern void TXD_init() { unsigned CHAR i; TXD_pin = 1; TXD_p1 = 0; TXD_p2 = 0; for ( i=0; i< TXD_BUF_LEN; i++ ) { TXD_buf[i] = 0x00; } } //发送单个字符 extern void TXD_Send_Char(const unsigned CHAR c) { unsigned CHAR p; //临时变量 p = TXD_p1 + 1; if ( p >= TXD_BUF_LEN ) p = 0; while ( p == TXD_p2 ); //判断发送缓冲队列是否已满,如果是,则暂时不能发送 TXD_buf[TXD_p1] = c; //先将c写入队列 TXD_p1 = p; //再修改TXD_p1 //在T2中断服务程序里会自动完成发送 } //发送字符串(不包括末尾的'\0') extern void TXD_Send_String(const unsigned CHAR s[]) { unsigned CHAR c; unsigned int i = 0; for (;;) { c = s[i++]; if ( c == '\0' ) break; TXD_Send_Char(c); } } //定义接收缓冲字符 volatile unsigned CHAR bdata RXD_ch; sbit RXD_ch_MSB = RXD_ch^7; //定义发送缓冲字符 volatile unsigned CHAR bdata TXD_ch; sbit TXD_ch_LSB = TXD_ch^0; //T2中断服务程序 //每中断HITS次处理1位 static void T2INTSVC() interrupt 5 using 3 { //定义接收所需要的变量 static bit RXD_doing = 0; //正在接收的标志 static unsigned CHAR RXD_t = HITS/2; //接收时计数T2的中断次数 static unsigned CHAR RXD_cnt; //接收时bit位的计数器 //定义发送所需要的变量 static bit TXD_doing = 0; & |
3楼: | >>参与讨论 |
作者: zy005021 于 2005/5/24 15:14:00 发布:
谢谢,再请问一下 谢谢给予的回答,我现在在做一个通讯转发的程序,要实现的功能是,单片机从一个采集模块接收数据,再转发给一台计算机和一个GPRS系统,请问是不是可以先通过单片机的固有串口接受数据,再通过设置的两个模拟串口转发数据来实现?还有没有其他的办法来实现呢?? 请教一下:) |
4楼: | >>参与讨论 |
作者: LPC900 于 2005/5/24 15:25:00 发布:
用I/O模拟串行口是最便宜的方案 转发数据的方法很多。用I/O模拟串行口是最便宜的方案,只是速度不够快。还有快速的方案:采用双口RAM,但是价钱就高了。还有一种方法是采用专门的串行口扩展芯片,比软件模拟要快。 |
5楼: | >>参与讨论 |
作者: zy005021 于 2005/5/24 16:42:00 发布:
你的这个模拟串口的速率能不能达到4800? 你的这个模拟串口的速率能不能达到4800? |
6楼: | >>参与讨论 |
作者: LPC900 于 2005/5/24 16:57:00 发布:
没问题,可以达到4800 如果使用LPC900系列单片机,软件模拟串行口的波特率完全可以达到4800,因为LPC900比标准80C51快6倍。 |
7楼: | >>参与讨论 |
作者: zy005021 于 2005/5/26 8:33:00 发布:
LPC900,再提一个问题 51 IO口模拟串口通讯C源程 #include <reg51.h> sbit BT_SND =P1^0; sbit BT_REC =P1^1; /********************************************** IO 口模拟232通讯程序 使用两种方式的C程序 占用定时器0 **********************************************/ #define MODE_QUICK #define F_TM F0 #define TIMER0_ENABLE TL0=TH0; TR0=1; #define TIMER0_DISABLE TR0=0; sbit ACC0= ACC^0; sbit ACC1= ACC^1; sbit ACC2= ACC^2; sbit ACC3= ACC^3; sbit ACC4= ACC^4; sbit ACC5= ACC^5; sbit ACC6= ACC^6; sbit ACC7= ACC^7; void IntTimer0() interrupt 1 { F_TM=1; } //发送一个字符 void PSendChar(unsigned CHAR inch) { #ifdef MODE_QUICK ACC=inch; F_TM=0; BT_SND=0; //start bit TIMER0_ENABLE; //启动 while(!F_TM); BT_SND=ACC0; //先送出低位 F_TM=0; while(!F_TM); BT_SND=ACC1; F_TM=0; while(!F_TM); BT_SND=ACC2; F_TM=0; while(!F_TM); BT_SND=ACC3; F_TM=0; while(!F_TM); BT_SND=ACC4; F_TM=0; while(!F_TM); BT_SND=ACC5; F_TM=0; while(!F_TM); BT_SND=ACC6; F_TM=0; while(!F_TM); BT_SND=ACC7; F_TM=0; while(!F_TM); BT_SND=1; F_TM=0; while(!F_TM); TIMER0_DISABLE; //停止timer #else unsigned CHAR ii; ii=0; F_TM=0; BT_SND=0; //start bit TIMER0_ENABLE; //启动 while(!F_TM); while(ii<8) { if(inch&1) { BT_SND=1; } else { BT_SND=0; } F_TM=0; while(!F_TM); ii++; inch>>=1; } BT_SND=1; F_TM=0; while(!F_TM); #endif TIMER0_DISABLE; //停止timer } //接收一个字符 unsigned CHAR PGetChar() { #ifdef MODE_QUICK TIMER0_ENABLE; F_TM=0; while(!F_TM); //等过起始位 ACC0=BT_REC; TL0=TH0; F_TM=0; while(!F_TM); ACC1=BT_REC; F_TM=0; while(!F_TM); ACC2=BT_REC; F_TM=0; while(!F_TM); ACC3=BT_REC; F_TM=0; while(!F_TM); ACC4=BT_REC; F_TM=0; while(!F_TM); ACC5=BT_REC; F_TM=0; while(!F_TM); ACC6=BT_REC; F_TM=0; while(!F_TM); ACC7=BT_REC; F_TM=0; while(!F_TM) { if(BT_REC) { break; } } TIMER0_DISABLE; //停止timer return ACC; #else unsigned CHAR rch,ii; TIMER0_ENABLE; F_TM=0; ii=0; rch=0; while(!F_TM); //等过起始位 while(ii<8) { rch>>=1; if(BT_REC) { rch|=0x80; } ii++; F_TM=0; while(!F_TM); } F_TM=0; while(!F_TM) { if(BT_REC) { break; } } TIMER0_DISABLE; //停止timer return rch; #endif } //检查是不是有起始位 bit StartBitOn() { return (BT_REC==0); } void main() { unsigned CHAR gch; TMOD=0x22; /*定时器1为工作模式2(8位自动重装),0为模式2(8位 自动重装) */ PCON=00; 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; PSendChar(0x55); PSendChar(0xaa); PSendChar(0x00); PSendChar(0xff); while(1) { if(StartBitOn()) { gch=PGetChar(); PSendChar(gch); } } } 这同样是一个51模拟串口的程序,为什么写得这么简单呢?这样写的话,通讯还正常吗????因为我没有在硬件上调试,因此不知道这个和你那个程序的结果谁更稳定. |
8楼: | >>参与讨论 |
作者: LPC900 于 2005/5/26 8:54:00 发布:
解决同一个问题,不同的人写出程序往往是不同的 我写的程序特点是:程序书写格式好、实用、移植方便。上面那个程序不知是不是你写的,但第一眼看上去,程序书写格式极差,连Tab缩进都没有,由于这容易造成理解上的困难,我已经不想看下去。第二眼看过去,C51源程序中竟然去操控累加器ACC,良好的C51编程风格只会访问SFR寄存器而不会去引用系统寄存器的,我看不下去了。第三眼,已经没有第三眼了。 最后你说“没有在硬件上调试”,那先调试了再说。我的程序是经过多次软硬件调试通过的。 |
|
|
Copyright © 1998-2006 tgdrjb.cn 浙ICP证030469号 |