用51单片机编写个小程序

用51单片机编写个小程序,第1张

#include <reg52.h>

#include "delay.h"

#include "lcd1602.h"

sbit SCK = P2^0//sbit定义单片机的特殊功能寄存器变量

sbit SDA = P2^1

bit ack = 0//bit定义变量

void iic_start()

{

SDA = 1

SCK = 1

delay_us(1)

SDA = 0

delay_us(1)

SCK = 0//钳住总线,等待下次使用

}

void icc_stop()

{

SDA = 0

SCK = 1

delay_us(1)

SDA = 1

delay_us(1)

SCK = 0//钳住总线,等待下次使用

}

void iic_send_byte(unsigned char byte)

{

unsigned char i

for(i = 0i<8i++)

{

SDA = byte &0x80//非0为1

SCK = 1

delay_us(1)

SCK = 0

byte <<=1//左移一位

}

SDA = 1

SCK = 1

delay_us(1)

if(0 == SDA)//有应答

ack = 0

else //无应答

ack =1

SCK = 0//钳住总线,等待下次使用

}

unsigned char iic_rcv_byte()

{

unsigned char i,temp

SDA = 1

for(i = 0i <8i ++)

{

SCK = 0

delay_us(1)

SCK = 1

delay_us(1)

temp <<= 1

if(SDA)

temp = temp+ 1

}

SCK = 0

return temp

}

void iic_ack()

{

SDA = 0

SCK = 1

delay_us(1)

SCK = 0

}

void iic_noack()

{

SDA = 1

SCK = 1

delay_us(1)

SCK = 0

}

void AT_send_str(unsigned char deviceaddr,unsigned char romaddr,unsigned char *s,unsigned char num)

{

unsigned char i

iic_start()

iic_send_byte(deviceaddr)

if(ack == 1)

return

iic_send_byte(romaddr)

if(ack == 1)

return

for(i = 0i <numi ++)

{

iic_send_byte(*s)

if(ack == 1)

return

s++

}

icc_stop()

}

void AT_rcv_str(unsigned char deviceaddr,unsigned char romaddr,unsigned char *s,unsigned char num )

{

unsigned char i

//SDA = 1

iic_start()

iic_send_byte(deviceaddr)

if(ack == 1)

return

iic_send_byte(romaddr)

if(ack == 1)

return

iic_start()

iic_send_byte(deviceaddr + 1)

if(ack == 1)

return

for(i = 0i <num - 1i++)

{

*s = iic_rcv_byte()

iic_ack()//

s++

}

*s = iic_rcv_byte()

iic_noack()

icc_stop()

}

void main()

{

unsigned char i

unsigned char testbuf[20] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,16,16,17,18,19}

unsigned char rcvbuf[20]

lcd_init()

AT_send_str(0xae,0,testbuf,10)

delay_ms(200)

AT_rcv_str(0xae,0,rcvbuf,10)

for(i = 0i <10i++)

{

display_lcd_char(i,0,rcvbuf[i]+0x30)

}

while(1)

}

(1)P3.3小键盘按下P1.3亮再按0.5秒灭。

org 0000h

ajmp main0

org 0080h

MAIN0:

CLR 21H 清标志

main:

mov c,p3.3 检测按键

jc main

MOV R6,#200 设定延时

MOV R7,#200

TT0:

JNB 21H,TT2 检测灯状态

tt:

mov c,p3.3 检测按键

jnc tt1

JNB 20H,MAIN 检测时间标志

CLR 20H

AJMP TT3

TT2:

mov c,p3.3 检测按键

jnc tt2

TT3:

CPL 21H 改变灯状态

cpl p1.3

ajmp main

TT1: NOP 延时但不是子程序

NOP

NOP

NOP

NOP

NOP

DJNZ R6,TT

MOV R6,#200

DJNZ R7,TT

MOV R7,#200

SETB 20H

AJMP TT

end

(2)数码管数据 p0,数码管控制p2 独立按键p1口 ,对独立键进行按键次数计数,三位数码管显示。 *

K1按下后,进行加1计数 *

K2按下后,进行减1计数。 *

K3按下后,进行加5计数。*

K4按下后,清计数单元,数码管显示0。 *

按住键可以快速计数。

K1 BIT P1.4

K2 BIT P1.5

K3 BIT P1.6

K4 BIT P1.7

K_OLD EQU 30H

K_NEW EQU 31H

K_COUNT EQU 32H

DISSTART EQU 40H显示单元首地址

LED_DATA EQU P0 数码管数据口定义

---------------------------------------------------------

ORG 0000H

JMP MAIN

ORG 0080H

---------------------------------------------------------

MAIN:

MOV SP,#60H

MOV P1,#0FFH

MOV P0,#0FFH

MOV K_OLD,#00H

MOV K_COUNT,#00H

MAIN1:

CALL CONVT

CALL PLAY

CALL KEY_PROG

JMP MAIN1

KEY_PROG:

CALL K_SCAN 键扫描

MOV A,K_NEW

CJNE A,K_OLD,KEY_P1

JMP KEY_P_END

KEY_P1:

MOV R4,#20

KEY_P2:

CALL CONVT用显示程序来进行键延时

CALL PLAY

DJNZ R4,KEY_P2

CALL K_SCAN 再判断键是否按下

MOV A,K_NEW

CJNE A,K_OLD,KEY_P3

JMP KEY_P_END

KEY_P3:

JB ACC.0,LOOP1 K1按下

JB ACC.1,LOOP2 K2按下

JB ACC.2,LOOP3 K3按下

JB ACC.3,LOOP4 K4按下

JMP KEY_P_END

LOOP1:

INC K_COUNT 键计数加1

JMP KEY_P_END

LOOP2:

DEC K_COUNT 键计数减1

JMP KEY_P_END

LOOP3:

INC K_COUNT 键计数加5

INC K_COUNT

INC K_COUNT

INC K_COUNT

INC K_COUNT

JMP KEY_P_END

LOOP4:

MOV K_COUNT,#00H 键计数单元清零

KEY_P_END:

RET

---------------------------------------------------------

代码变换 (HEX TO BCD)

---------------------------------------------------------

CONVT:

MOV A,K_COUNT

MOV B,#100

DIV AB

MOV DISSTART+2,A百位存放在DISSTART+2

MOV A,#10

XCH A,B

DIV AB

MOV DISSTART+1,A十位存放在DISSTART+1

MOV DISSTART,B 个位存放在DISSTART

RET

---------------------------------------------------------

键扫描子程序

---------------------------------------------------------

K_SCAN:

MOV P1,#0FFH

MOV K_NEW,#00H

MOV A,P1

CPL A

ANL A,#0F0H

SWAP A

MOV K_NEW,A

RET

---------------------------------------------------------

延时子程序

---------------------------------------------------------

DELAY:

MOV R6,#200

DEL:

MOV R7,#0FFH

DJNZ R7,$

DJNZ R6,DEL

RET

---------------------------------------------------------

PLAY:

MOV R0,#DISSTART 获得显示单元首地址

MOV R1,#07FH 从第一个数码管开始

MOV R2,#03H 共显示3位数码管

DISP1:

MOV A,@R0 获得当前位地址

MOV DPTR,#TAB_NU 获得表头

MOVC A,@A+DPTR查表获得显示数据

MOV LED_DATA,A显示数据

MOV P2,R1 开始显示当前位

MOV A,R1 准备显示下一位

RR A

MOV R1,A 下一位

INC R0取下一个单元地址

LCALL DELAY2MS延时 2 MS

DJNZ R2,DISP1 重复显示下一个

MOV P2,#0FFH 关闭显示

RET 显示完成,返回

---------------------------------------------------------

延时子程序

---------------------------------------------------------

DELAY2MS:

MOV R6,#10

DEL1:

MOV R7,#100

DJNZ R7,$

DJNZ R6,DEL1

RET

TAB_NU:

db 28h,7eh,0a2h,62h,74h,61h,21h,7ah,20h,60h 字形代码表

**********************************************************

END

两个例子我想够你明白的了。详细的解释,代表性的例子,可慢慢学习


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

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

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

发表评论

登录后才能评论

评论列表(0条)

保存