单片机编程 同步串口应用于LED静态显示8051单片机

单片机编程 同步串口应用于LED静态显示8051单片机,第1张

利用50H、51H和52H,作为计数单元,程序如下:

ORG 0000H

SJMP MAIN

ORG 0030H

MAIN:

MOV SCON, #00H 设置串行口工作在方式0

MOV 50H, #00H 个位清零

MOV 51H, #00H

MOV 52H, #00H

DL_LOOP:

LCALL DL_100MS

MOV A, 50H

ADD A, #1

MOV 50H, A

CJNE A, #10, XIAN_SHI

MOV 50H, #0

MOV A, 51H

ADD A, #1

MOV 51H, A

CJNE A, #10, XIAN_SHI

MOV 51H, #0

MOV A, 52H

ADD A, #1

MOV 52H, A

CJNE A, #10, XIAN_SHI

MOV 52H, #0

XIAN_SHI:

MOV DPTR, #SEGPT

MOV A, 50H 先串行输出个位

MOVC A, @A+DPTR

MOV SBUF, A

JNB TI, $ 等待输出结束

CLR TI

MOV A, 51H 串行输出十位

MOVC A, @A+DPTR

MOV SBUF, A

JNB TI, $

CLR TI

MOV A, 52H 串行输出百位

MOVC A, @A+DPTR

MOV SBUF, A

JNB TI, $

CLR TI

LJMP DL_LOOP反复循环

DL_100MS: 这里的数字,可以自行调整到延时100ms

MOV R3, #10

D1: MOV R4, #20

D2: MOV R5, #248

DJNZ R5, $

DJNZ R4, D2

DJNZ R3, D1

RET

SEGPT: DB 0C0H, 0F9H, 0A4H, 0B0H 0、1、2、3

DB 99H, 92H, 82H, 0F8H 4、5、6、7

DB 80H, 90H, 88H, 83H 8、9、A、B

DB 0C6H, 0A1H, 86H, 8EH C、D、E、F

END

#include<reg51.h>

sbit p1_0=p1^o//管脚定义,可能是光耦三极管,错把字母o当成数字0

void main()

{

unsigned char i,j

SCON=0x00//串口工作方式0,允许接收

j=0x01//要从串口发送的数据

for()//死循环,相当于while(1)

{

p1_0=0

SBUF=j//j送到SBUF,从串口发送

while(!TI) { }//等待发送完成

p1_0=0TI=0//TI软件清0

for ( i=0i<=254i++) { }//延时

j=j*2//左移一位,即led灯往左轮流亮

if (j= =0x00) j=0x01//一轮左移完成,从头再次左移,循环左移

}

}

#include <reg52.h>

#include <intrins.h>

#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 = 0k <120k++)

}

}

/******************************************************************/

/**/

/*检查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) //16*2显示,5*7点阵,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=0m<16m++)

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

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

{

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

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

}

playflag=0

count=0x00

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

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=0m<16m++)

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

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

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

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

while(1)

{

play()

}

}

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

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

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


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

原文地址: http://outofmemory.cn/yw/11067277.html

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

发表评论

登录后才能评论

评论列表(0条)

保存