
ORG 0000H
SJMP 0050H
ORG 0023H
LJMP S_INT
TAB:DB 20H,49H,20H,47H,45H,54H,20H,'NULL'
ORG 0050H
MOV TMOD,#20H
MOV TH1,#0FDH
MOV TL1,#0FDH
SETB TR1
SETB SM1
CLR SM0
SETB EA
SETB ES
MOV R0,#30H
MOV A,#1H
MAIN:SETB REN
ACALL DELAY
JNZ MAIN
MOV R2,#0
MOV DPTR,#TAB
MOV R7,#7
SEND:MOV A,R2
MOVC A,@A+DPTR
CLR ES
MOV SBUF,A
JNB TI,$
CLR TI
INC R2
DJNZ R7,SEND
MOV R0,#30H
SHOW:MOV A,@R0
MOV SBUF,A
JNB TI,$
CLR TI
INC R0
CJNE A,#40H,SHOW
SETB ES
MOV A,#1
MOV R0,#30H
SJMP MAIN
S_INT:CLR RI
MOV A,SBUF
MOV @R0,A
CJNE A,#40H,NEXT
MOV A,#0
NEXT:INC R0
RETI
DELAY:MOV 7DH,#200
LOOP1:MOV 7EH,#40
DJNZ 7EH,$
DJNZ 7DH,LOOP1
RET
END
这个是方式一的
#include <REG52H>
#define uchar unsigned char
#define uint unsigned int
sbit ring=P3^7;
sbit CASE1=P2^0;
sbit CASE2=P2^1;
sbit CASE3=P2^2;
sbit CASE4=P2^3;
uchar se=0,re=0;
uchar temp=0;
void wait(uint cnt)
{
while(--cnt);
}
void send(uchar se)
{
SBUF=se; //发送数据
while(TI == 0);
TI = 0;
}
//串口接收程序
uchar receive(void)
{
re=SBUF; //接收数据
while(RI==0);
RI=0;
return re;
}
//串口初始化
void sinti(void)
{
SCON = 0x50;
TMOD |= 0x20;
TH1 = 0xFD;
TR1 = 1;
EA = 1;
ES = 1;
}
void delay(int cnt)
{
while(--cnt);
}
//主程序
int main (void)
{
int i;
sinti(); //串口初始化程序
ring=1;
while(1)
{
while (1)
{
if(CASE1==0)
{
send('a');
ring=0;
break;
}
if(CASE2==0)
{
send('b');
ring=0;
break;
}
if(CASE3==0)
{
send('c');
ring=0;
break;
}
if(CASE4==0)
{
send('d');
ring=0;
break;
}
}
if(ring==0)
{
wait(60000);
ring=1;
}
for(i=0;i<10000;i++);
}
}
//串口中断程序
void UART_SER (void) interrupt 4 //串行中断服务程序
{
if(RI) //判断是接收中断产生
{
RI=0; //标志位清零
temp=SBUF;
}
if(TI) //如果是发送标志位,清零
TI=0;
}
/串口2收到一个字符中断子函数 /
void uart2_get_char(void) interrupt 8
{
……
……
}//这里,好像,多了一个(右)大括号。
}
#include<reg51h>
#include<intrinsh>
#include<stdioh>
#define uchar unsigned char
#define uint unsigned int
sbit SPL=P2^5; //shift/load
//延时
void DelayMS(uint ms)
{
uchar i;
while(ms--) for(i=0;i<120;i++);
}
//主程序
void main()
{
SCON=0x10; //串口模式0,允许串口接收
while(1)
{
SPL=0; //置数(load),读入并行输入口的8位数据
SPL=1; //移位(shift),并口输入被封锁,串行转换开始
while(RI==0); //未接收1字节时等待
RI=0; //RI软件置位
P0=SBUF; //接收到的数据显示在P0口,显示拨码开关的值
DelayMS(20);
}
}
串口收发,要有通信协议。也就是什么时候开始接收,接收到指令后,转发什么数据。这个要知道,才可以写。而且使用不同的51单片机,其内部寄存器配置是不同的。
一般来说,过程如下:
1,配置串口参数、波特率等,开启串口中断;
void Init_UART()
{
}
2,中断函数里写中断响应函数,根据接收的指令或者数据,执行相应的动作;
程序一般为:
void UART_ISR() interrupt x using y
{
;串口中断处理函数
}
x - 单片机的C51中断号
y - 指定使用的当前工作寄存器组号(0-3 PSW中的RS0,RS1组合)
3,主程序
int main(void)
{
Init_UART();
while(1)
{
;//数据发送函数
}
}
首先要确定串口调试助手的波特率也是2400,并接收要以十六进制数显示,最好发送也以十六进制数发送。
程序没有问题,是因为发送的num1在0-255之间,而用串口调试助手的字符显示方式不是全部都能显示出来的,有一部分就是显示乱码的,而显示十六进制数就没有问题了。
串行发送程序 Txasm :
PCON, #00H ;; 波特率不倍增
SETB TR1 ;; 启动定时器T1
MOV IE, #0 ;; 禁止任何中断
CALL DLY125 ;; 延时125ms
;;--------------------------------------------
T_X: ;; 透传发送字串
ACALL DSPLED ;; P20控制LED闪亮
MOV R3, #4 ;; 待发送字符个数
MOV DPTR, #TAB_TX ;; 数据表首址
TX_LP1: CLR A
MOVC A, @A+DPTR ;; A←数据表的1个字符
CLR TI ;; TI清零,允许发送
MOV SBUF,A ;; 发送1个字符
JNB TI, $ ;; 等待1个字符帧发送结束
DJNZ R3, TX_next
CALL DLY500 ;; 延时500ms
SJMP T_X ;; 重复发送
TX_next: ;; 发送另一字符
INC DPTR ;; 数据表指针移动
SJMP TX_LP1
;;--------------------------------------------
DSPLED: ;;开机或复位,P20控制LED闪亮6遍
MOV R2, #6 ;; 循环次数
LEDLP1: CLR P20 ;; LED亮
CALL DLY125 ;; 延时125ms
SETB P20 ;; LED灭
CALL DLY125
DJNZ R2,LEDLP1 ;; 循环
RET
;;----------------------------------------------
DLY125: ;; 延时125ms
DLY125A: MOV R5,#250
DLY125B: MOV R6,#250
DJNZ R6,$
DJNZ R5,DLY125B
RET
;; 2502502μs=125 000μs =125ms
;;----------------------------------------------
DLY500: ;; 延时500ms
MOV R7,#4
DLY500A: MOV R6,#250
DLY500B: MOV R5,#250
DJNZ R5,$
DJNZ R6,DLY500B
DJNZ R7,DLY500A
RET
;; 42502502μs=500 000μs =500ms
;;-------------------------------------------------
TAB_TX: DB 38H,30H,35H,31H,
;; 8 0 5 1
;;----------------------------------------------
END
以上就是关于51单片机汇编语言写串口程序全部的内容,包括:51单片机汇编语言写串口程序、51单片机串口通信c语言编程、51单片机串口程序问题等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)