STC单片机的485通讯程序问题

STC单片机的485通讯程序问题,第1张

串口中断函数里面不能调用uart2_send_char(Rec);这个执行时间很长的函数。你可以把中断接收的数据放到一个数组的缓冲区内,然后定义一个字符串结束字符,当收到结束字符后再讲整个字符串返回计算机。

#include <reg52h>

#include <intrinsh>

#define uchar unsigned char

#define uint unsigned int

sbit LCD_RS = P2^0;

sbit LCD_RW = P2^1;

sbit LCD_EN = P2^2;

#define delayNOP(); {_nop_();_nop_();_nop_();_nop_();};

uchar data RXDdata[ ] = {0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,

0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20 };

uchar temp,buf,m,count;

bit playflag=0;

uchar code cdis1[ ] = {" SERILA TRANFER "};

uchar code cdis2[ ] = {" "};

/

延时子程序

/

char code SST516[3] _at_ 0x003b;

void delay1(uint ms)

{

uchar k;

while(ms--)

{

for(k = 0; k < 120; k++);

}

}

//

/ /

/检查LCD忙状态 /

/lcd_busy为1时,忙,等待。lcd-busy为0时,闲,可写指令与数据。 /

/ /

//

bit lcd_busy()

{

bit result;

LCD_RS = 0;

LCD_RW = 1;

LCD_EN = 1;

delayNOP();

result = (bit)(P0&0x80);

LCD_EN = 0;

return(result);

}

//

/ /

/写指令数据到LCD /

/RS=L,RW=L,E=高脉冲,D0-D7=指令码。 /

/ /

//

void lcd_wcmd(uchar cmd)

{

while(lcd_busy());

LCD_RS = 0;

LCD_RW = 0;

LCD_EN = 0;

_nop_();

_nop_();

P0 = cmd;

delayNOP();

LCD_EN = 1;

delayNOP();

LCD_EN = 0;

}

//

/ /

/写显示数据到LCD /

/RS=H,RW=L,E=高脉冲,D0-D7=数据。 /

/ /

//

void lcd_wdat(uchar dat)

{

while(lcd_busy());

LCD_RS = 1;

LCD_RW = 0;

LCD_EN = 0;

P0 = dat;

delayNOP();

LCD_EN = 1;

delayNOP();

LCD_EN = 0;

}

//

/ /

/ LCD初始化设定 /

/ /

//

void lcd_init()

{

delay1(15);

lcd_wcmd(0x01); //清除LCD的显示内容

lcd_wcmd(0x38); //162显示,57点阵,8位数据

delay1(5);

lcd_wcmd(0x38);

delay1(5);

lcd_wcmd(0x38);

delay1(5);

lcd_wcmd(0x0c); //开显示,显示光标,光标闪烁

delay1(5);

lcd_wcmd(0x01); //清除LCD的显示内容

delay1(5);

}

//

/ /

/ 设定显示位置 /

/ /

//

void lcd_pos(uchar pos)

{

lcd_wcmd(pos | 0x80); //数据指针=80+地址变量

}

/

发送数据函数

/

void senddata(uchar dat)

{

SBUF =dat;

while(!TI);

TI = 0;

}

/

串行中断服务函数

/

void serial() interrupt 4

{

ES = 0; //关闭串行中断

RI = 0; //清除串行接受标志位

buf = SBUF; //从串口缓冲区取得数据

playflag=1;

switch(buf)

{

case 0x31: senddata('X');break; //接受到1,发送字符'W'给计算机

case 0x32: senddata('L');break; //接受到2,发送字符'I'给计算机

case 0x33: senddata('1');break; //接受到3,发送字符'L'给计算机

case 0x34: senddata('0');break; //接受到4,发送字符'L'给计算机

case 0x35: senddata('0');break; //接受到5,发送字符'A'给计算机

case 0x36: senddata('0');break; //接受到5,发送字符'R'给计算机

default: senddata(buf);break; //接受到其它数据,将其发送给计算机

}

if(buf!=0x0D)

{

if(buf!=0x0A)

{

temp =buf;

if(count<16)

{

RXDdata[count]=temp;

count++;

}

}

}

ES = 1; //允许串口中断

}

/

数据显示函数

/

void play()

{

if(playflag)

{

lcd_pos(0x40); //设置位置为第二行

for(m=0;m<16;m++)

lcd_wdat(cdis2[m]); //清LCD1602第二行

for(m=0;m<16;m++)

{

lcd_pos(0x40+m); //设置显示位置为第二行

lcd_wdat(RXDdata[m]); //显示字符

}

playflag=0;

count=0x00;

for(m=0;m<16;m++)

RXDdata[m]=0x20; //清显存单元

}

}

/

主函数

/

void main(void)

{

P0 = 0xff;

P2 = 0xff;

SCON=0x50; //设定串口工作方式

PCON=0x00; //波特率不倍增

TMOD=0x20; //定时器1工作于8位自动重载模式, 用于产生波特率

EA=1;

ES = 1; //允许串口中断

TL1=0xf3;

TH1=0xf3; //波特率2400

TR1=1;

lcd_init();

lcd_pos(0x00); //设置显示位置为第一行

for(m=0;m<16;m++)

lcd_wdat(cdis1[m]); //显示字符

lcd_pos(0x40); //设置显示位置为第二行

for(m=0;m<16;m++)

lcd_wdat(cdis2[m]); //显示字符

while(1)

{

play();

}

}

这个串口通信程序在我的开发版上已经全部验证通过,你可以根据实际,攸 改里面某些参数,满足你自己的需要就行。

比如你你点亮小灯,这部分你只可在相应位置添加代码即可。单片机都是51的。

其中1602的显示程序是用来验证是否通信成功,这部分你可作为参考。这部分你大可用小灯显示程序来替代。

参考一下:

>

1、查询方式:

#include<reg51h>

main()

{

unsigned char dat;

TMOD=0x20;

TH1=TL1=0xfd;

SCON=0x50;

TR1=1;

while(1)

{

if(RI)//接收

{

RI=0;

dat=SBUF;

}

SBUF=dat;//发送

while(!TI);

TI=0;

}

}

2、中断方式:

#include<reg51h>

unsigned char dat;

bit flag;

void uart_isr() interrupt 4

{

if(RI)//接收

{

RI=0;

dat=SBUF;

flag=1;

}

if(TI)TI=0;

}

main()

{

TMOD=0x20;

TH1=TL1=0xfd;

SCON=0x50;

TR1=1;

EA=1;

ES=1;

flag=0;

while(1)

{

if(flag)

{

SBUF=dat;

flag=0;

}

}

}

通信线上传输了一个字节到单片机串口上,硬件自动将其接收并存储在SBUF里,此时会产生一个中断(串口接收中断),单片机的相应中断使能(ES,EA)打开的时候,就可以进入中断,方便处理通讯。关闭中断时,仍可以使用查询的方式进行通讯处理。查询RI位,

if(RI==1)

{RI=0;//需要对其清零,硬件不会自动清零的

//以下是处理程序

}

发送的时候把需要发送的字节送入SBUF即可启动硬件发送,单片机只需查询TI(发送标志位)看看发送是否完成就行了。TI也需软件清零。

#include <iom8vh>#include <macrosh>#define uchar unsigned char#define uint unsigned int

#define mclk 8000000#pragma interrupt_handler uart_rx:12uchar rdata,flag=0;void delay(uint ms){ uint i,j; for(i=0;i<ms;i++) { for(j=0;j<1141;j++); }}

void uart_init(uint baud){ UCSRB=0x00; UCSRA=0x00; //控制寄存器清零 UCSRC=(1<<URSEL)|(0<<UPM0)|(3<<UCSZ0); //选择UCSRC,异步模式,禁止 // 校验,1位停止位,8位数据位 baud=mclk/16/baud-1 ; //波特率最大为65K UBRRL=baud; UBRRH=baud>>8; //设置波特率 UCSRB=(1<<TXEN)|(1<<RXEN)|(1<<RXCIE); //接收、发送使能,接收中断使能 SREG=BIT(7); //全局中断开放 DDRD|=0X02; //配置TX为输出(很重要)

}void uart_sendB(uchar data){ while(!(UCSRA&(BIT(UDRE)))) ; UDR=data; while(!(UCSRA&(BIT(TXC)))); UCSRA|=BIT(TXC);}void uart_rx(){ UCSRB&=~BIT(RXCIE); rdata=UDR; flag=1; UCSRB|=BIT(RXCIE);}void main(){ //uchar i=4; //uchar j='a'; uart_init(19200); while(1) { if(flag) { uart_sendB(rdata); flag=0; } } }

以上就是关于STC单片机的485通讯程序问题全部的内容,包括:STC单片机的485通讯程序问题、高分求51单片机串口通信的程序、两个51单片机之间串口通讯程序等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zz/9304555.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-27
下一篇 2023-04-27

发表评论

登录后才能评论

评论列表(0条)

保存