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的显示程序是用来验证是否通信成功,这部分你可作为参考。这部分你大可用小灯显示程序来替代。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)