libsbuf微信怎么用用

文章来源:http://blog.csdn.net/zistxym/article/details/7433072
tuxedo入门教程
修复文中的一些小错误 感谢周泳
===============
先介绍下目录结构
bin& etc& include& lib& log&& src
bin 目录用来存放服务命令和客户端命令
etc 用来存放ubb配置文件
include 用来存放头文件
lib& 用来存放库文件
log 日志目录
src 源文件
src下有四个目录
client& public& realize& service
client 用来存放客户端命令
public 用来存在公共函数
realize 用来存放实现和数据库通信的某种函数
service 用来存放服务程序
文件组成:
bin& etc& include& lib& log& src
client& service&
tuxconfig& ubb.txt
./include:
libpublic.a& librealize.a
client& public& realize& service
./src/client:
client& client.c& makefile
./src/public:
makefile& public.c
./src/realize:
makefile& realize.pc
./src/service:
makefile& service& service.pc
本文假定已经安装oracle和TUXEDO。
先看client.c程序
================
#include &stdio.h&
#include &atmi.h& /*包含TUXEDO系统的头文件&atmi.h&, 以便引用TUXEDO的函数和变量定义。*/
#define ALLOClEN 80 /*定义输入和返回的长度*/&
int main(int argvc, char** agr)
&&& char *inbuf=NULL;
&&& char *outbuf=NULL;
&&& long len=0;
&&& long outlen=0;
&&& /*客户端调用tpinit()连接应用*/
&&& if& (tpinit((TPINIT * )NULL) == -1)
&&&&&&& exit(1);
&&& /*用tpalloc()分配一个STRING类型数据缓冲*/
&&& if (NULL==(inbuf=tpalloc(&STRING&, NULL, ALLOClEN)))
&&&&&&& tpterm();
&&&&&&& exit(2);
&&& /*用tpalloc()分配一个STRING类型数据缓冲*/
&&& if (NULL==(outbuf=tpalloc(&STRING&, NULL, ALLOClEN)))
&&&&&&& tpterm();
&&&&&&& exit(-1);
&&& /*将&hello world&拷贝进缓冲*/
&&& strcpy(inbuf,& &ht&);
&&& printf(&\t请求报文====&[%s]\n&,inbuf);
&&& /*先连上数据库,这里inbuf,outbuf,outlen没有什么作用*/
&&& if ( tpcall(&sv_connect&, inbuf, 0, &outbuf, &outlen, 0)== -1)
&&&&&&& fprintf(stderr, &sv_connect fail.\n&);
&&&&&&& tpfree(inbuf);
&&&&&&& tpfree(outbuf);
&&&&&&& tpterm();
&&&&&&& exit(-1);
&&& /*用tpcall()包含数据缓冲,向交易&TOUPPER&发一个同步请求*/
&&& if ( tpcall(&sv_update&, inbuf, 0, &outbuf, &outlen, 0)== -1)
&&&&&&& fprintf(stderr, &service requst fail.\n&);
&&&&&&& tpfree(inbuf);
&&&&&&& tpfree(outbuf);
&&&&&&& tpterm();
&&&&&&& exit(-1);
&&& /*打印出改变的数据缓冲*/
&&& printf(&\n&);
&&& printf(&\t返回报文&======[%s]\n&, outbuf);
&&& tpfree(inbuf);
&&& tpfree(outbuf);
&&& /*调用tpterm()切断与应用的连接*/
&&& tpterm();
&&& exit(0);
这个函数用以下命令编译:
buildclient -f client.c -o client -v
编译后把生成的client, 移到bin目录下。
在这里建一个makefile, 内容如下:
&&& buildclient -f client.c -o client -v
&&& @cp client ../../bin
注意,buildclient前面不是空格,是一个tab. @表示执行命令时不显示拷贝的过程。
在写服务程序之前,先写一个日志程序,这样可以打印日志。
#ifndef __PUBLIC_H__
#define __PUBLIC_H__
#include &ctype.h&
#include &stdio.h&
#include &stdlib.h&&& &
#include &sqlca.h&
#include &oraca.h&
#include &sqlcpr.h&
#include &assert.h&&& &
#include &stdarg.h&
#include &string.h&
#include &math.h&
#include &time.h&
#include &sys/timeb.h&
char *GetTimeChar();
int WriteLog(int LogLevel,char * format,...);
#endif& /* __PUBLIC.H__*/&
#include &public.h&
int&&& GLogLevel=0; /*记日志的级别. 记日志的级别有:0,1,2。 0级别最高*/
char GLogFile[100]= &../log/serv%s.log&;
char *GetTimeChar()
&&& int&&& year = 0;
&&& static char tt[20] = &&;
&&& time(&now);
&&& t = *localtime(&now);
&&& year=t.tm_
&&&&&&& if (year&50)
&&&&&&&&&&&&&&& year+=2000;
&&&&&&& else
&&&&&&&&&&&&&&& year+=1900;
&&& sprintf(tt,&%04d-%02d-%02d %02d:%02d:%02d&,year,t.tm_mon+1,t.tm_mday,t.tm_hour,t.tm_min,t.tm_sec);
/***************************************************************************
函数名称:WriteLog
函数功能:写日志文件
输入参数:filename:文件名;format:参数
输出参数:无
返 回 值:0:正确;其他:失败
***************************************************************************/
int WriteLog(int LogLevel,char * format,...)
&&& FILE *
&&& char *ttime&&&& = NULL;
&&& char ddate[9]=&&;
&&& char LogPath[50]=&&;
&&& ttime=GetTimeChar();
&&& strncpy(ddate,ttime,4);
&&& strncat(ddate,(ttime+5),2);
&&& strncat(ddate,(ttime+8),2);
&&& sprintf(LogPath,GLogFile,ddate);
&&& if (LogLevel&=GLogLevel)
&&&&&&& if((fp=fopen(LogPath,&a+&))==NULL)
&&&&&&&&&&& perror(&Create or Open LogFile Error! GLogFile\n&);
&&&&&&&&&&& return -1;
&&&&&&& fprintf(fp,&[%s]&,GetTimeChar());
&&&&&&& va_start(args,format);
&&&&&&& vfprintf(fp,format,args);
&&&&&&& va_end(args);
&&&&&&& va_start(args,format);
&&&&&&& vprintf(format,args);& &
&&&&&&& va_end(args);
&&&&&&& fclose(fp);
&&& return 0;
makefile文件:
=============
&&& gcc& -c& public.c& -I$(TUXDIR)/include&& -I../../include& -I$(ORACLE_HOME)/precomp/public
&&& ar -r&& libpublic.a *.o
&&& @mv libpublic.a ../../lib
&&& @rm *.o
这里把公用函数生成一个静态库,以后服务程序可以直接用。
service.pc这个文件中存放服务调用,由这里入口。
============================================
#include &public.h&
#include &atmi.h&
#define BUF_SIZE 100
/************************************************
& 函数名称:sv_connect
& 函数功能:连接数据库
& 输入参数:
& TPSVCINFO *不用
& 输出参数:TPSVCINFO *不用
& 返 回 值:无
&************************************************/
void sv_connect(TPSVCINFO *rqst)
&&& EXEC SQL BEGIN DECLARE SECTION;
&&& char username[100]=&hstest&;
&&& char password[100]=&hstest&;
&&& char server[100]=&ora10g&;
&&& EXEC SQL END DECLARE SECTION;
&&& char *sBuf = NULL;
&&& sBuf = tpalloc(&STRING&,NULL,BUF_SIZE);
&&& if(sBuf == NULL) {
&&&&&&& WriteLog(0,&分配内存错误!&);
&&& /* 连接到数据库 */
&&& EXEC SQL CONNECT :username IDENTIFIED BY :password USING :
&&& if (sqlca.sqlcode & 0)
&&&&&&& WriteLog(0,&connect oracle error:%.*s&,sqlca.sqlerrm.sqlerrml,sqlca.sqlerrm.sqlerrmc);
&&&&&&& sprintf(sBuf,&7002;数据库连接失败:%.*s&,sqlca.sqlerrm.sqlerrml,sqlca.sqlerrm.sqlerrmc);
&&&&&&& strcpy(sBuf,&0&);
&&& oraca.oradbgf& = 1;&&&&&&&&&&&&& /* enable debug operations */
&&& oraca.oracchf& = 1;&&&&&&&&&&&& /* gather cursor cache statistics */
&&& oraca.orastxtf = 3;&&&&&&&&&&&&& /* always save the SQL statement */
&&& tpreturn(TPSUCCESS, 0, sBuf, 0L, 0);
/*******************************************
& 函数名称:sv_update
& 函数功能: 测试
& 输入参数:
& TPSVCINFO *&
& rqst-&data格式:NAME
& 输出参数:TPSVCINFO *
& 成功:0;OK
& 失败:1;错误原因
& 返 回 值:无
&*******************************************/
void sv_update(TPSVCINFO *rqst)
&&& char *sBuf = NULL;
&&& sBuf = tpalloc(&STRING&,NULL,BUF_SIZE);
&&& if(sBuf == NULL) {
&&&&&&& WriteLog(0,&分配内存错误!&);
&&& WriteLog(0,&预处理开始\n&);
&&& if(TOUPPER(rqst-&data) != 0){
&&&&&&& sprintf(sBuf,&1;%s&,&ERROR!&);
&&&&&&& strcpy(sBuf,&0;OK!&);
&&& WriteLog(0,&预处理完成\n&);
&&& tpreturn(TPSUCCESS, 0, sBuf, 0L, 0);
&&& proc& PARSE=NONE include=-I/home/oracle/product/10.2.0/precomp/public include=-I/home/oracle/product/10.2.0/rdbms/public&
sqlcheck=full USerid=hstest/hstest iname=service.pc
&&& gcc -c service.c -I./ -I/home/oracle/product/10.2.0/precomp/public -I/home/oracle/product/10.2.0/plsql/public -I/home/oracle/product/10.2.0//rdbms/demo
-I/home/tuxedo/bea/tuxedo8.1/include -I../../include
&&& buildserver -v -o service& -f &service.o & -s sv_connect -s sv_update -f &-L/home/oracle/product/10.2.0/lib& -lclntsh -lc
-lm & -f &-L../../lib -lpublic -lrealize&
&&& cp service ../../bin
&&& @rm *.lis *.c *.o
realize.pc
==========
#include &atmi.h&
#include &public.h&
/*包含TUXEDO系统头文件&atmi.h&*/
/*从客户端收到的数据放在TPSVCINFO结构中,是唯一的入参*/
int TOUPPER (const char *inbuf)
&&& EXEC SQL WHENEVER SQLERROR
&&& EXEC SQL UPDATE& plsqltest SET salary=256 WHERE name=:
&&& EXEC SQL COMMIT WORK;
&&& WriteLog(0,&update successfully.&);
&&& return 0;
&&& WriteLog(0, &%.*s\n&, sqlca.sqlerrm.sqlerrml, sqlca.sqlerrm.sqlerrmc);
&&& return -1;
&&& proc&& include=/home/oracle/product/10.2.0/precomp/public include=/home/oracle/product/10.2.0/rdbms/public include=../../include
include=/home/tuxedo/bea
/tuxedo8.1/include& ORACA=YES LINES=YES MODE=ORACLE DBMS=V7 SQLCHECK=SEMANTICS UNSAFE_NULL=YES& USerid=hstest/hstest iname=realize.pc
&&& gcc& -c& realize.c& -I./ -I/home/oracle/product/10.2.0/precomp/public -I/home/oracle/product/10.2.0/plsql/public -I/home/oracle/product/10.2.0/rdbms/demo
-I/home/tuxedo/bea/tuxedo8.1/include -I../../include
&&& ar -r&& librealize.a *.o
&&& @mv librealize.a ../../lib
&&& @rm *.o *.c *.lis
*RESOURCES
IPCKEY 55000&
MASTER SITE1
&vmlinux& LMID=SITE1& ---&&vmlunx&机器名
&&& TUXDIR=&/home/tuxedo/bea/tuxedo8.1&& --&根据实际情况
&&& APPDIR=&/home/hsta/tux_test/tst_02/bin&& --&根据实际情况
&&& TUXCONFIG=&/home/hsta/tux_test/tst_02/etc/tuxconfig& --&根据实际情况
&&& ULOGPFX=&/home/hsta/tux_test/tst_02/log/ULOG& --&根据实际情况
GROUP1 LMID=SITE1 GRPNO=1&
service SRVGRP=GROUP1 SRVID=1&
sv_connect
.bash_profile
==============
PATH=$PATH:$HOME/bin
export PATH
unset USERNAME
export TUXDIR=/home/tuxedo/bea/tuxedo8.1& --&根据实际情况
export ORACLE_BASE=/home/oracle --&根据实际情况
export ORACLE_HOME=$ORACLE_BASE/product/10.2.0 --&根据实际情况
export ORACLE_SID=ora10g --&根据实际情况
export NLS_LANG=AMERICAN_AMERICA.ZHS16GBK
export LD_LIBRARY_PATH=$ORACLE_HOME/lib:/lib:/usr/lib/:/usr/local/lib:$TUXDIR/lib:$TUXDIR/lib
export TUXCONFIG=$HOME/tux_test/tst_02/etc/tuxconfig --&根据实际情况, 和ubb.txt中保持一致
export PATH=$PATH:$ORACLE_HOME/bin:$TUXDIR/bin:.
export LANG=C
要把client,public,realize,service目录下进行make编译
用tmloadcf -y ubb.txt编译生成tuxconfig
tmboot -y 启动程序 这里可以看到启动的进程。
键入tmadmin, 然后输入psc 可看到启动的服务。 按Q键退出。
tmshutdown -y关闭进程
数据库表结构
=============
create table PLSQLTEST
&salary NUMBER,
&NAME&& VARCHAR2(10)
insert into plsqltest (salary, NAME)
&&& values (1000, 'xym');
insert into plsqltest (salary, NAME)
&&& values (2000, 'ht');
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:8066次
排名:千里之外
译文:18篇
(1)(1)(18);R2存放从机地址,R4数据帧计数器,#03H请求数据命令,#00H广播命令,#0FFH结束命令;&&&&&&&&&&&&&&&&&串行通信主机接收子程序&&&&&&&&&&&&&&&&&&&;容错机制善不健全&&&&&&& ORG 0000H&&&&&&& LJMP MAIN&&&&&&& ORG 0023H&&&&&&& LJMP SERVE1&&&&&&& ORG 0060HMAIN:&& MOV TMOD,#20H&& ;程序序初始化&&&&&&& MOV TH1,#0F3H&&&&&&& MOV TL1,#0F3H&&&&&&&
TR1&&&&&&& MOV PCON,#80H&&&&&&& MOV SCON,#0D0H&&&&&&& MOV R4,#03H&&&&&&& SETB ES&&&&&&& SETB EA&&&&&&& SETB TB8&&&&&&& MOV P2,#0FFH&&&&&&& MOV R3,#00H&&&&&&& CLR P2.1&&&&&&& MOV R5,#10HKEY:&&& LCALL DT10&&&&&&&
R5,KEY&&&&&&& MOV ,#LIB0&&&&&&& MOV A,R3&&&&&&&
A,@A+DPTR&&&&&&& MOV R2,A&&&&&&& MOV ,R2&&&&&&& SETB P2.1&&&&&&& SJMP $;&&&&中断服务程序&&&&SERVE1:JBC RI,LOP&&&&&&&& ;接收中断,清RI,转LOP&&&&&& CLR TI&&&&&&&&&&&& ;是发送中断,清除标志,&&&&&& SJMP ENDTLOP:&& MOV R5,SBUF&&&&&&& ;据&&&&&& MOV A,R5&&&&&&
A,R2&&&&&&&&&& ;判断地址&&&&&& JZ LOP2LOP1:& MOV SBUF,#0FFH&&&&&& SJMP ENDT&&&&&&&&& ;*跳转返回LOP2:& CLR P2.3&&&&&& SETB TB8&&&&&&&&&& ;******************&&&&&& MOV R1,#LIB1&&&&&& MOV R0,#LIB1&&&&&& ;*****************&&&&&& MOV SBUF,#03H&&&&& ;发送请求数据命令&&&&&&
RI,$LOP3:& MOV A,SBUF&&&&&&&& ;帧&&&&&& MOV @R1,A&&&&&& INC R1&&&&&&&&&&&& ;*&&&&&& SHOW:&& CLR P2.1SHO2:&& MOV A,@R0&&&&&&& MOV P1,A&&&&&&& INC R0&&&&&&& LCALL DT10&&&&&&& LCALL DT10&&&&&&& MOV P1,#0FFH&&&&&&& SETB P2.1&&&&&&&& RETDT10:&&& MOV R7,#0EFH&& TS1:& MOV R6,#0FFH&& TS2:& DJNZ R6,TS2&&&&&&&& DJNZ R7,TS1&&&&&&&& RETDT11:&&& MOV R7,#04FH&& TD1:& MOV R6,#0FFH&& TD2:& DJNZ R6,TD2&&&&&&&& DJNZ R7,TD1&&&&&& ;********调用数码管显示子程序;调用时 单片机无反应&&&&&&&& ret&&&&&& CLR RI&&&&&& CLR P2.5&&&&&& MOV SBUF,#03H&&&&& ;发送请求数据命令&&&&&& MOV A,R4&&&&&& JZ LOP4&&&&&&&&&&& ;*****************************************&&&&&& JNB RI,$&&&&&&&&&& ;***需加故障处理LOP4:& CLR P2.7&&&&&& DJNZ R4,LOP3&&&&&& ;循环指令接收数据&&&&&& ;MOV SBUF,#0FFH&&&& ;发结束命令&&&&&& CLR P2.1&;SED:&& NOP&&&&&&&&&&&&&& ;扫描从机&&&&&& ;NOP&&&&&& ;SETB TB8&&&&&& ;INC R3&&&&&& ; R3,#02H,LOP5&&&&&& ;CLR ES&&&&&& ;;LOP5:& MOV DPTR,#LIB0&&&&& ;**&&&&&& ;MOV R3,A&&&&&& ;MOVC A,@A+DPTR&&&&&& ;MOV R2,A&&&&&& ;MOV SBUF,R2ENDT:& CLR RI&&&&&& RETI;&&&&&&&&&&&&&&&&&&&数码管显示子程序&&&&&&&&&&&&&&&&&&&&;&&&&&&&存储空间&&&&&&&&&&&LIB0:& DB 01H,02H,03HLIB1:& DS 0FH&&&&&& END
为本词条添加和相关影像
互动百科的词条(含所附图片)系由网友上传,如果涉嫌侵权,请与客服联系,我们将按照法律之相关规定及时进行处理。未经许可,禁止商业网站等复制、抓取本站内容;合理使用者,请注明来源于。
登录后使用互动百科的服务,将会得到个性化的提示和帮助,还有机会和专业认证智愿者沟通。
您也可以使用以下网站账号登录:
此词条还可添加&
编辑次数:1次
参与编辑人数:1位
最近更新时间: 11:05:28
贡献光荣榜&&/&&&&/&&&&/&&
通信的三种基本类型
常用的通信从传输方向上可以分为单工通信、半双工通信、全双工通信三类。
单工通信就是指只允许一方向另外一方传送信息,而另一方不能回传信息。比如电视遥控器、收音机广播等,都是单工通信技术。
半双工通信是指数据可以在双方之间相互传播,但是同一时刻只能其中一方发给另外一方,比如我们的对讲机就是典型的半双工。
全双工通信就发送数据的同时也能够接收数据,两者同步进行,就如同我们的电话一样,我们说话的同时也可以听到对方的声音。
UART 模块介绍
IO 口模拟串口通信,让大家了解了串口通信的本质,但是我们的单片机程序却需要不停的检测扫描单片机 IO 口收到的数据,大量占用了单片机的运行时间。这时候就会有聪明人想了,其实我们并不是很关心通信的过程,我们只需要一个通信的结果,最终得到接收到的数据就行了。这样我们可以在单片机内部做一个硬件模块,让它自动接收数据,接收完了,通知我们一下就可以了,我们的 51 单片机内部就存在这样一个 UART 模块,要正确使用它,当然还得先把对应的特殊功能寄存器配置好。
51 单片机的 UART 串口的结构由串行口控制寄存器 SCON、发送和接收电路三部分构成,先来了解一下串口控制寄存器 SCON。如表 11-1 表 11-2 所示。
表 11-1 SCON&&串行控制寄存器的位分配(地址 0x98、可位寻址)
表 11-2& SCON&&串行控制寄存器的位描述
这两位共同决定了串口通信的模式&0~模式&3&共&4&种模式。我们最常用的
就是模式&1,也就是&SM0=0,SM1=1,下边我们重点就讲模式&1,其它模
多机通信控制位(极少用),模式&1&直接清零。
使能串行接收。由软件置位使能接收,软件清零则禁止接收。
模式&2&和&3&中要发送的第&9&位数据(很少用)。
模式&2&和&3&中接收到的第&9&位数据(很少用),模式&1&用来接收停止位。
发送中断标志位,当发送电路发送到停止位的中间位置时,TI&由硬件置&1,
必须通过软件清零。
接收中断标志位,当接收电路接收到停止位的中间位置时,RI&由硬件置&1,
必须通过软件清零。
前边学了那么多寄存器的配置,相信 SCON 这个地方,对于大多数同学来说已经不是难点了,应该能看懂并且可以自己配置了。对于串口的四种模式,模式 1 是最常用的,就是我们前边提到的 1 位起始位,8 位数据位和 1 位停止位。下面我们就详细介绍模式 1 的工作细节和使用方法,至于其它 3 种模式与此也是大同小异,真正遇到需要使用的时候大家再去查阅相关资料就行了。
在我们使用 IO 口模拟串口通信的时候,串口的波特率是使用定时器 T0 的中断体现出来的。在硬件串口模块中,有一个专门的波特率发生器用来控制发送和接收数据的速度。对于STC89C52 单片机来讲,这个波特率发生器只能由定时器 T1 或定时器 T2 产生,而不能由定时器 T0 产生,这和我们模拟的通信是完全不同的概念。
如果用定时器 2,需要配置额外的寄存器,默认是使用定时器 1 的,我们本章内容主要就使用定时器 T1 作为波特率发生器来讲解,方式 1 下的波特率发生器必须使用定时器 T1 的模式 2,也就是自动重装载模式,定时器的重载值计算公式为:
& & TH1 = TL1 = 256 - 晶振值/12 /2/16 /波特率
和波特率有关的还有一个寄存器,是一个电源管理寄存器 PCON,他的最高位可以把波特率提高一倍,也就是如果写 PCON |= 0x80 以后,计算公式就成了:
& & TH1 = TL1 = 256 - 晶振值/12 /16 /波特率
公式中数字的含义这里解释一下,256 是 8 位定时器的溢出值,也就是 TL1 的溢出值,晶振值在我们的开发板上就是
是说 1 个机器周期等于 12 个时钟周期,值得关注的是这个 16,我们来重点说明。在 IO 口模拟串口通信接收数据的时候,采集的是这一位数据的中间位置,而实际上串口模块比我们模拟的要复杂和精确一些。他采取的方式是把一位信号采集 16 次,其中第 7、8、9 次取出来,这三次中其中两次如果是高电平,那么就认定这一位数据是 1,如果两次是低电平,那么就认定这一位是 0,这样一旦受到意外干扰读错一次数据,也依然可以保证最终数据的正确性。
了解了串口采集模式,在这里要给大家留一个思考题。&晶振值/12/2/16/波特率&这个地方计算的时候,出现不能除尽,或者出现小数怎么办,允许出现多大的偏差?把这部分理解了,也就理解了我们的晶振为何使用 11.0592M 了。
串口通信的发送和接收电路在物理上有 2 个名字相同的 SBUF 寄存器,它们的地址也都是 0x99,但是一个用来做发送缓冲,一个用来做接收缓冲。意思就是说,有 2 个房间,两个房间的门牌号是一样的,其中一个只出人不进人,另外一个只进人不出人,这样的话,我们就可以实现 UART 的全双工通信,相互之间不会产生干扰。但是在逻辑上呢,我们每次只操作 SBUF,单片机会自动根据对它执行的是&读&还是&写&操作来选择是接收 SBUF 还是发送 SBUF,后边通过程序,我们就会彻底了解这个问题。
UART 串口程序
一般情况下,我们编写串口通信程序的基本步骤如下所示:
配置串口为模式 1。
配置定时器 T1 为模式 2,即自动重装模式。
根据波特率计算 TH1 和 TL1 的初值,如果有需要可以使用 PCON 进行波特率加倍。
打开定时器控制寄存器 TR1,让定时器跑起来。
这里还要特别注意一下,就是在使用 T1 做波特率发生器的时候,千万不要再使能 T1 的中断了。
我们先来看一下由 IO 口模拟串口通信直接改为使用硬件 UART 模块时的程序代码,看看程序是不是简单了很多,因为大部分的工作硬件模块都替我们做了。程序功能和 IO 口模拟的是完全一样的。
#include &reg52.h&
void ConfigUART(unsigned int baud);
void main(){
ConfigUART(9600); //配置波特率为 9600
while (1){
while (!RI); //等待接收完成
RI = 0; //清零接收中断标志位
SBUF = SBUF + 1; //接收到的数据+1 后,发送回去
while (!TI); //等待发送完成
TI = 0; //清零发送中断标志位
/* 串口配置函数,baud-通信波特率 */
void ConfigUART(unsigned int baud){
SCON = 0x50; //配置串口为模式 1
TMOD &= 0x0F; //清零 T1 的控制位
TMOD |= 0x20; //配置 T1 为模式 2
TH1 = 256 - (/32)/ //计算 T1 重载值
TL1 = TH1; //初值等于重载值
ET1 = 0; //禁止 T1 中断
TR1 = 1; //启动 T1
当然了,这个程序还是用在主循环里等待接收中断标志位和发送中断标志位的方法来编写的,而实际工程开发中,当然就不能这么干了,我们也只是为了用直观的对比来告诉同学们硬件模块可以大大简化程序代码,那么实际使用串口的时候就用到串口中断了,来看一下用中断实现的程序。请注意一点,因为接收和发送触发的是同一个串口中断,所以在串口中断函数中就必须先判断是哪种中断,然后再作出相应的处理。
#include &reg52.h&
void ConfigUART(unsigned int baud);
void main(){
EA = 1; //使能总中断
ConfigUART(9600); //配置波特率为 9600
while (1);
/* 串口配置函数,baud-通信波特率 */
void ConfigUART(unsigned int baud){
SCON = 0x50; //配置串口为模式 1
TMOD &= 0x0F; //清零 T1 的控制位
TMOD |= 0x20; //配置 T1 为模式 2
TH1 = 256 - (/32)/ //计算 T1 重载值
TL1 = TH1; //初值等于重载值
ET1 = 0; //禁止 T1 中断
ES = 1; //使能串口中断
TR1 = 1; //启动 T1
/* UART 中断服务函数 */
void InterruptUART() interrupt 4{
if (RI){ //接收到字节
RI = 0; //手动清零接收中断标志位
SBUF = SBUF + 1; //接收的数据+1 后发回,左边是发送 SBUF,右边是接收 SBUF
if (TI){ //字节发送完毕
TI = 0; //手动清零发送中断标志位
大家可以试验一下,看看是不是和前边用 IO 口模拟通信实现的效果一致,而主循环却 完全空出来了,我们就可以随意添加其它功能代码进去。如何用串口将数据传给单片机里面的寄存器?也就是串口接收的数据来更新寄存器的值_百度知道

我要回帖

更多关于 微信怎么用 的文章

 

随机推荐