山大单片机实验

更新时间:2023-10-29 18:27:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

必做实验

第二章 软件仿真实验 2.1实验1:汇编程序实验1

示例程序:

ORG 0000H AJMP MAIN ORG 0030H MAIN:

MOV SP,#60H ;堆栈底设置在60H

MOV A,#0H ;A置零

MOV R1,#30H ;起始单元地址为30H MOV R7,#10H ;R7用于计数,初值为10H

LOOP1: ;将30H开始的16个内存单元置零 MOV @R1,A INC R1 DJNZ R7,LOOP1

NOP

MOV R1,#30H

MOV R7,#10H ;重新赋计数初值和起始单元地址

1

LOOP: ;将0到F赋给30H开始的16个单元中; MOV @R1,A

INC R1 ;地址自增 INC A ;A自增 DJNZ R7,LOOP SJMP $ END

(3)示例程序的功能

将30H开始的16个内存单元清0,然后将值0到F赋给30H开始的16个单元。 (4)运行结果截图

② 自我完成实验程序

ORG 0030H MAIN:

MOV A,11111111B MOV R1,#30H MOV @R1,A MOV B,64H DIV AB INC R1 INC R1

ANL A,#0FH MOV @R1,A DEC R1

2

MOV A,B MOV B,#0AH DIV AB RL A RL A RL A RL A ADD A,B MOV @R1,A SJMP $ END

2.2实验2:汇编程序实验2

程序及其注释

ORG 0000H AJMP MAIN ORG 0030H MAIN:

MOV 30H, #45H ;待操作数存于30H单元 MOV A, 30H ;30H单元中的数送A

ANL A,#0FH ;高四位清零,保留低四位 MOV 31H,A ;结果存于31H单元 MOV A,30H ;重新取待操作数至A

ANL A, #0F0H ;低四位清零,保留高四位

SWAP A ;自交换实现待操作数的高四位表示的二进制数存于A MOV B, #10

MUL AB ;待操作数的高四位表示的二进制数乘以10

ADD A,31H ;待操作数的高四位表示的二进制数乘以10后和低四位表示的二进制数相加

3

MOV 31H,A ;存结果于31H单元 SJMP $ END

(3)示例程序的功能:

实现求得一个八位二进制数高四位表示的二进制数乘以10和低四位表示的二进制数的和。如为两位压缩BCD码,则实现求得相应十进制数值,并以二进制形式存于内存单元中。 (4)运行结果截图

② 自我完成实验程序

ORG 0000H AJMP START ORG 0030H START:

MOV DPTR,#TABLE MOV A,#00H MOV R7,#20H MOV R1,#30H MOV R2,#00H READ:

MOVC A,@A+DPTR MOV @R1,A INC R1 INC R2 MOV A,R2 DJNZ R7,READ MOV R0,#30H MOV R7,#31

4

LOOP: MOV A,R0 MOV R1,A MOV A,R7 MOV R6,A MOV A,R0 MOV R2,A MOV B,@R1 LOOP1: INC R1 MOV A,@R1 CJNE A,B,L1 L1: JC L2 MOV B,A MOV A,R1 MOV R2,A L2:

DJNZ R6,LOOP1 MOV A,B XCH A,@R1 MOV B,A MOV A,R2 MOV R1,A MOV @R1,B DJNZ R7,LOOP ORG 08F0H

TABLE:DB 1,3,9,2,17,4,11,6

DB 5,20,100,64,21,14,79,35 DB 92,7,91,23,65,16,13,18 DB 18,73,65,101,27,19,62,69 END

5

2.3 C语言程序实验

#include #include

char data a[32] _at_ 0x30; void main() {

char code b[32]={1,3,9,2,17,4,11,6,5,20,100,64,21,14,79,35,92,7,91,23,65,16,13,18,18,73,65,101,27,19,62,69}; int i=0; int t=0; int j=0;

for(i=0;i<32;i++) {a[i]=b[j]; j++; }

for(j=0;j<31;j++)

for(i=0;i<31-j;i++) if(a[i]>a[i+1]) {

t=a[i];

a[i]=a[i+1]; a[i+1]=t; }

while(1); }

6

3.1基本并行I/O口实验

ORG 0000H AJMP MAIN ORG 0030H MAIN:

MOV SP,#60H MOV P2,#0FFH MOV 20H,#0FEH MOV R7,#8 LOOP:

SETB P1.0

JNB P1.0,LOOP1 AJMP L LOOP1: MOV A,20H MOV P2,A ACALL DELAY MOV A,P2 RL A

MOV 20H,A

L:DJNZ R7,LOOP DELAY:

MOV R6,#200 L1:MOV R5,#250 DJNZ R5,$ DJNZ R6,L1 RET SJMP $

7

END

3.2扩展并行I/O口实验

ORG 0000H AJMP START ORG 0003H START:

MOV SP,#60H MOV P0,#0FFH CLR P3.6 STATE1:

MOV DPTR,#0FE00H MOV A,#0F3H MOVX @DPTR,A

8

MOV DPTR,#0FD00H MOV A,#0CH MOVX @DPTR,A ACALL DELAY2 STATE2:

MOV DPTR,#0FE00H MOV A,#0C3H MOVX @DPTR,A

MOV DPTR,#0FD00H MOV A,#0FH MOVX @DPTR,A ACALL DELAY1 STATE3:

MOV DPTR,#0FE00H MOV A,#0FCH MOVX @DPTR,A

MOV DPTR,#0FD00H MOV A,#03H MOVX @DPTR,A ACALL DELAY2 STATE4:

MOV DPTR,#0FE00H MOV A,#3CH MOVX @DPTR,A

MOV DPTR,#0FD00H MOV A,#0FH

MOVX @DPTR,A ACALL DELAY1 AJMP STATE1 DELAY1: MOV R7,#20 DL2:

MOV R6,#200 DL1:

MOV R5,#250 DJNZ R5,$ DJNZ R6,DL1 DJNZ R7,DL2 RET

DELAY2:

MOV R7,#100 L2:

MOV R6,#200 L1:

9

MOV R5,#250 DJNZ R5,$ DJNZ R6,L1 DJNZ R7,L2 RET END

3.3静态LED显示实验

ORG 0000H AJMP START ORG 0003H START:

MOV SP,#60H MOV R4,#0AH

10

MOV A,R3 CLR A MOV R3,A SETB P1.0 SETB P1.1 LOOP1:

JB P1.1,S1 LOOP2: MOV A,R4 LCALL CLOSE S1:

JB P1.0,LOOP1 MOV R3,#0AH MAIN:

MOV DPTR,#0FD00H MOV A,#0F9H MOVX @DPTR,A

MOV DPTR,#0FE00H MOV A,#0C0H MOVX @DPTR,A LCALL DELAY1

MOV DPTR,#0FD00H MOV A,#0C0H MOVX @DPTR,A LOOP: MOV A,R3

MOV DPTR,#TABLE MOVC A,@A+DPTR MOV DPTR,#0FE00H MOVX @DPTR,A LCALL DELAY1 DEC R3 MOV A,R3 INC A JNZ LOOP SPARK: CLR P3.0 LCALL DELAY2 SETB P3.0 LCALL DELAY2 JB P1.1,SPARK AJMP LOOP2 TABLE:

DB 0C0H,0F9H,0A4H,0B0H,99H

11

DB 92H,82H,0F8H,80H,90H CLOSE:

MOV DPTR,#0FE00H MOV A,#0FFH MOVX @DPTR,A

MOV DPTR,#0FD00H MOVX @DPTR,A RET

DELAY1: MOV R7,#10 L2:

MOV R6,#200 L1:

MOV R5,#250 DJNZ R5,$ DJNZ R6,L1 DJNZ R7,L2 RET

DELAY2:

MOV R6,#100 L:

MOV R5,#250 DJNZ R5,$ DJNZ R6,L RET SJMP $ END

12

3.4矩阵键盘扫描实验

#include\#include\

#define uchar unsigned char #define uint unsigned int sbit g0=P0^4;

uchar code T_TABLE[]={200,160,120,80,40}; uchar code key_code[]={0x22,0x12,0x21,0x11};

void delay() {

uchar t,ms; ms=5;

while(ms--)

for(t=0;t<120;t++); }

void main() {

int aa=0xfe; uint dir=1; uint speed=0;

int temp,temp2,keycode; int j,key; g0=0; while(1)

13

P3=0x30; temp=P3;

if((temp&0x30)!=0x30) {

delay(); delay(); P3=0x30; temp=P3;

if((temp&0x30)!=0x30) {

P3=0x03; temp2=P3;

keycode=temp|temp2; for(j=0;j<4;j++) {

if(keycode==key_code[j]) {

key=j; } }

if(key==0) dir=1; if(key==1) dir=0; if(key==2) {

speed++;

if(speed==5) speed=4; }

if(key==3) {

if(speed==0) speed++; speed--; }

switch (speed) {

case 0:P0=0xef;break; case 1:P0=0xf7;break; case 2:P0=0xfb;break; case 3:P0=0xfd;break; case 4:P0=0xfe;break; default:break; }

P3=0x03;

14

{

}

}

while(!(P3==0x03)); } } if(dir==1) {

P1=aa;

for(j=0;j

aa=_crol_(aa,1);//

}

if(dir==0) {

P1=aa;

for(j=0;j

aa=_cror_(aa,1); }

15

3.5定时计数器实验

#include\

#define uchar unsigned char #define uint unsigned int

uchar code led_table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};

uchar xdata da001 _at_ 0xfe00; uchar xdata da01 _at_ 0xfd00; uchar xdata da1 _at_ 0xfb00; uchar xdata da10 _at_ 0xf700; uchar xdata da100 _at_ 0xef00; uchar xdata da1k _at_ 0xdf00;

uchar dv001,dv01,dv1,dv10,dv100,dv1k;

long sumtime=0;

float frequency,ptime;

uint timer0H; uint timer0L;

void s_timer0() interrupt 1 {

EA=0;

sumtime=sumtime+65536; TH0=timer0H;

16

TL0=timer0L; EA=1; }

void s_timer1() interrupt 3 {

EA=0;

sumtime=sumtime+TH0*256+TL0; TH0=timer0H; TL0=timer0L;

ptime=(float)sumtime/200; sumtime=0;

frequency=(float)1000000/ptime; dv1k=(uchar)(frequency/1000);

frequency=frequency-dv1k*1000; dv100=(uchar)(frequency/100);

frequency=frequency-dv100*100; dv10=(uchar)(frequency/10);

frequency=frequency-dv10*10; dv1=(uchar)frequency;

frequency=frequency-dv1; frequency=frequency*10; dv01=(uchar)frequency;

frequency=frequency-dv01; frequency=frequency*10; dv001=(uchar)frequency;

da001=led_table[dv001]; da01=led_table[dv01]; da1=led_table[dv1]; da10=led_table[dv10]; da100=led_table[dv100]; da1k=led_table[dv1k]; EA=1; }

17

void main() {

TMOD=0X61;//T1计数器,方式2,T0定时器,方式1 timer0H=0;//T0定时器初值 timer0L=0;

TH1=TL1=56;//T1计数器初值 256-200=56 EA=1;//开总中断

ET0=1;//开定时器0中断 TR0=1;//启动定时器0 ET1=1;//开启T1中断 TR1=1;//开启T1

while(1); }

18

3.6串口通信实验

#include #include

#define uchar unsigned char #define uint unsigned int uchar code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};

uchar rdata,tdata,temp; sbit P11=P1^1; sbit P10=P1^0; void main() {

while(1) {

P11=1;

while(P11); P10=0;

SCON=0x10; while(!RI); temp=SBUF; RI=0; P10=1;

while(!P11); rdata=temp&0x0f; tdata=table[rdata]; rdata=temp&0xf0;

19

rdata=rdata/16;

rdata=table[rdata]; SBUF=tdata; while(!TI); TI=0;

SBUF=rdata; while(!TI); TI=0; } }

20

{

checkstate(); RS=0; RW=0;

DATA=com; EN=1; _nop_(); _nop_(); EN=0; }

void setline(uchar page) {

page=0xb8|page;

sendcommandtolcd(page); }

void setstartline(uchar startline) {

startline=0xc0|startline; sendcommandtolcd(startline); }

void setcolumn(uchar column) {

column=column&0x3f; column=0x40|column;

sendcommandtolcd(column); }

void setonoff(uchar onoff) {

onoff=0x3e|onoff;

sendcommandtolcd(onoff); }

void writebyte(uchar dat) {

checkstate(); RS=1; RW=0;

DATA=dat; EN=1; _nop_();

46

_nop_(); EN=0; }

void selectscreen(uchar screen) {

switch(screen) {

case 0: cs1=0; _nop_(); _nop_(); _nop_(); cs2=0; _nop_(); _nop_(); _nop_(); break; case 1: cs1=0; _nop_(); _nop_(); _nop_(); cs2=1; _nop_(); _nop_(); _nop_(); break; case 2: cs1=1; _nop_(); _nop_(); _nop_(); cs2=0; _nop_(); _nop_(); _nop_(); break; } }

void clearscreen(uchar screen) {

uchar i,j;

selectscreen(screen); for(i=0;i<8;i++) {

47

setline(i); setcolumn(0);

for(j=0;j<64;j++) {

writebyte(0x00); } } }

void initlcd() {

checkstate(); selectscreen(0); setonoff(0);

selectscreen(0); setonoff(1);

selectscreen(0); clearscreen(0); setstartline(0); }

void display(uchar ss,uchar page,uchar column,uchar number) {

int i;

selectscreen(ss); column=column&0x3f; setline(page);

setcolumn(column); for(i=0;i<16;i++) {

writebyte(HZK[i+32*number]); }

setline(page+1); setcolumn(column); for(i=0;i<16;i++) {

writebyte(HZK[i+32*number+16]); } }

48

void main() {

uint i; initlcd();

clearscreen(0); while(1) {

for(i=0;i<64;i++) {

setstartline(i+1); display(1,0,0x00,0); display(1,0,0x0f,1); display(1,0,2*16,2); display(1,0,3*16,3); display(2,0,4*16,4); display(2,0,5*16,5); display(2,0,6*16,6); display(2,0,7*16,7); selectscreen(0); delay(100); } } }

49

50

选做实验

3.7LCD1602显示实验

#include //头文件 #define uint unsigned int // #define uchar unsigned char

sbit lcden=P1^5; //定义引脚 sbit rs=P1^7; sbit rw=P1^6; sbit busy=P0^7;

char i,j,temp,num;

long a,b,c,d; //a,第一个数 b,第二个数 c,得数 d,余数 float a_c,b_c;

uchar flag,fuhao;//flag表示是否有符号键按下,fuhao表征按下的是哪个符号

uchar code table[]={ 0,1,2,3, 4,5,6,7, 8,9,0,0, 0,0,0,0};

uchar code table1[]={ 0,1,2,3, 4,5,6,7,

8,9,0x2b-0x30,0x2d-0x30,

0x2a-0x30,0x2f-0x30,0x01-0x30,0x3d-0x30};

21

uchar code table2[]=\

void delay(uchar z) // 延迟函数 {

uchar y;

for(z;z>0;z--)

for(y=0;y<110;y++); }

void check() // 判断忙或空闲 {

do {

P2=0xFF;

rs=0; //指令 rw=1; //读

lcden=0; //禁止读写

delay(1); //等待,液晶显示器处理数据 lcden=1; //允许读写 }

while(busy==1); //判断是否为空闲,1为忙,0为空闲}

void write_com(uchar com) // 写指令函数 {

P2=com; //com指令付给P0口 rs=0; rw=0; lcden=0; check(); lcden=1; }

void write_date(uchar date) // 写数据函数 {

P2=date; rs=1; rw=0; lcden=0; check(); lcden=1; }

void init() //初始化

22

{

num=-1;

lcden=1; //使能信号为高电平 write_com(0x38); //8位,2行

write_com(0x0c); //显示开,光标关,不闪烁*/ write_com(0x06); //增量方式不移位 write_com(0x80); //检测忙信号

write_com(0x01); //显示开,光标关,不闪烁 i=0; j=0;

a=0; //第一个参与运算的数 b=0; //第二个参与运算的数 c=0; d=0;

flag=0; //flag表示是否有符号键按下, fuhao=0; // fuhao表征按下的是哪个符号 }

void keyscan() // 键盘扫描程序 {

P3=0xfe; if(P3!=0xfe) {

delay(20); if(P3!=0xfe) {

temp=P3&0xf0; switch(temp) {

case 0xe0:num=0; break;

case 0xd0:num=1; break;

case 0xb0:num=2; break;

case 0x70:num=3; break; } }

while(P3!=0xfe);

if(flag==0)//没有按过符号键 {

a=a*10+table[num]; }

23

else//如果按过符号键 {

b=b*10+table[num]; }

i=table1[num];

write_date(0x30+i);

}

P3=0xfd;

if(P3!=0xfd) {

delay(5); if(P3!=0xfd) {

temp=P3&0xf0; switch(temp) {

case 0xe0:num=4; break;

case 0xd0:num=5; break;

case 0xb0:num=6; break;

case 0x70:num=7; break; } }

while(P3!=0xfd);

if(flag==0)//没有按过符号键 {

a=a*10+table[num]; }

else//如果按过符号键 {

b=b*10+table[num]; }

i=table1[num];

write_date(0x30+i); }

P3=0xfb;

24

if(P3!=0xfb) {

delay(5); if(P3!=0xfb) {

temp=P3&0xf0; switch(temp) {

case 0xe0:num=8; break;

case 0xd0:num=9; break;

case 0xb0:num=10; break;

case 0x70:num=11; break; } }

while(P3!=0xfb);

if(num==8||num==9)//如果按下的是'8','9' {

if(flag==0)//没有按过符号键 {

a=a*10+table[num]; }

else//如果按过符号键 {

b=b*10+table[num]; } }

else if(num==10)//如果按下的是'+' {

flag=1;

fuhao=1;//2表示加号已按 }

else if(num==11)//如果按下的是'-' {

flag=1;

fuhao=2;//2表示减号已按 }

i=table1[num];

25

write_date(0x30+i); }

P3=0xf7;

if(P3!=0xf7) {

delay(5); if(P3!=0xf7) {

temp=P3&0xf0; switch(temp) {

case 0xe0:num=12; break;

case 0xd0:num=13; break;

case 0xb0:num=14; break;

case 0x70:num=15; break; } }

while(P3!=0xf7); switch(num) {

case 12:{write_date(0x30+table1[num]); flag=1;fuhao=3;} break;

case 13:{write_date(0x30+table1[num]); flag=1;fuhao=4;} break; case 14:{write_com(0x01);i=0;j=0;a=0;b=0;c=0;d=0;flag=0;fuhao=0;}//按下的是\清零\

break; case 15:{ j=1;

if(fuhao==1){write_com(0x80+0x4f);//按下等于键,光标前进至第二行最后一个显示处

write_com(0x04); //设置从后住前写数据,每写完一个数据,光标后退一格

c=a+b;

while(c!=0) {

26

write_date(0x30+c); c=c/10; }

write_date(0x3d); //再写\ a=0;b=0;flag=0;fuhao=0; }

else if(fuhao==2){write_com(0x80+0x4f);//光标前进至第二行最后一个显示处

write_com(0x04); //设置从后住前写数据,每写完一个数据,光标后退一格)

if(a-b>0) c=a-b; else c=b-a; while(c!=0) {

write_date(0x30+c); c=c/10; }

if(a-b<0)

write_date(0x2d);

write_date(0x3d); //再写\ a=0;b=0;flag=0;fuhao=0; }

else if(fuhao==3) {

write_com(0x80+0x4f); write_com(0x04); c=a*b;

while(c!=0) {

write_date(0x30+c); c=c/10; }

write_date(0x3d); a=0;b=0;flag=0;fuhao=0; }

else if(fuhao==4) {

write_com(0x80+0x4f); write_com(0x04); if(b==0) {

i=0;

27

while(table2[i]!='\\0') {

write_date(table2[i]); i++; }

a=0;b=0;flag=0;fuhao=0; }

else if((a%b==0)&&(b!=0)) {

c=a/b;

while(c!=0) {

write_date(0x30+c); c=c/10; }

if(a/b<=0)

write_date(0x30);

write_date(0x3d); a=0;b=0;flag=0;fuhao=0; }

else if((a%b!=0)&&(b!=0)) {

d=a%b;

while(d!=0) {

write_date(0x30+d); d=d/10; }

write_date(0x2e); write_date(0x2e); c=a/b;

while(c!=0) {

write_date(0x30+c); c=c/10; }

if(a/b<=0)

write_date(0x30);

write_date(0x3d); a=0;b=0;flag=0;fuhao=0; } 28

write_date(0x2e); } }

break; } } }

main() {

init(); while(1) {

keyscan(); } }

29

3.8 ADC0808/9信号采集实验

#include \#include \

#define byte unsigned char #define word unsigned int

byte data line[16];

byte code numchar[]={'0','1','2','3','4','5','6','7','8','9'};

sbit RS = P2^0; sbit RW = P2^1; sbit E = P2^2; sbit clk = P2^3; sbit start = P2^4; sbit oe = P2^5; sbit out = P2^6; sbit eoc = P2^7;

byte ADdata1,ADdata0,f1,f2,f3; word num,frequency,t; bit ADend;

void delayms(word ms) {

word i,j;

for(i=0;i

for(j=0;j<120;j++); }

bit lcd_busy() {

bit flag; RS=0; RW=1; E=1;

_nop_(); _nop_(); _nop_(); _nop_();

flag=(bit)(P1&0x80); E=0;

30

return flag; }

void lcd_wcmd(byte cmd) {

while(lcd_busy()); RS=0; RW=0; E=0;

_nop_(); _nop_(); P1=cmd; _nop_(); _nop_(); _nop_(); _nop_(); E=1;

_nop_(); _nop_(); _nop_(); _nop_(); E=0; }

void lcd_clr() {

lcd_wcmd(0x01); delayms(2); }

void lcd_wdat(byte dat) {

while(lcd_busy()); RS=1; RW=0; E=0;

_nop_(); _nop_(); P1=dat; _nop_(); _nop_(); _nop_(); _nop_(); E=1;

31

_nop_(); _nop_(); _nop_(); _nop_(); E=0; }

void lcd_init() {

delayms(15); lcd_wcmd(0x38); delayms(5);

lcd_wcmd(0x0c); delayms(5);

lcd_wcmd(0x06); delayms(5);

lcd_wcmd(0x01); delayms(5); }

//以上为lcd显示程序 ,以下为AD程序void displaystr(byte m) {

byte i; switch(m) {

case 0:

lcd_wcmd(0x80);break; case 1:

lcd_wcmd(0xc0);break; } i=0;

while(line[i]!='\\0') {

lcd_wdat(line[i]); // delayms(1); i++; } }

//以上为lcd显示程序 ,以下为AD程序 void s_T0() interrupt 1 {

EA=0; t++;

if(t==20)

32

{

frequency=num/2; f3=frequency/100;

f2=(frequency0)/10; f1=frequency; num=0; t=0; }

TH0=0x3c; TL0=0xb0; EA=1; }

void s_T1() interrupt 3 {

clk=~clk; }

void readAD() //读取ad {

start=0;

while(eoc!=1); ADdata0=ADdata1; P0=0xff; _nop_(); _nop_(); _nop_(); _nop_(); oe=1;

ADdata1=P0; oe=0; ADend=1; }

void operation() {

while(!ADend);

if(((ADdata0<128)&&(ADdata1>128))||((ADdata0>128)&&(ADdata1<128))) {

num++; out=1; _nop_(); _nop_(); _nop_();

33

_nop_(); _nop_(); out=0; } }

void main() {

TMOD=0x21;

TH1=0xf6; // 246 TL1=0xf6;

TH0=0x3c; // 60 TL0=0xb0; EA=1; ET1=1; ET0=1; TR1=1; TR0=1; out=0; start=0;

ADdata0=0; ADdata1=0; t=0;

lcd_init(); lcd_clr(); delayms(2);

while(1) {

ADend=0; start=1; // delayms(1); // start=0; readAD(); operation(); line[0]='f'; line[1]=':';

line[2]=numchar[f3]; line[3]=numchar[f2]; line[4]=numchar[f1]; line[5]='H'; line[6]='z';

34

line[7]='\\0'; displaystr(0); } }

35

3.10 I2C扩展实验

#include \#include \

#define byte unsigned char #define word unsigned int

#define fivenop(); _nop_();_nop_();_nop_();_nop_();_nop_();

byte KEY_TABLE[]={0x22,0x12,0x21,0x11}; word SPEED_TABLE[]={125,100,75,50,25};

byte LED_TABLE[]={0xef,0xf7,0xfb,0xfd,0xfe}; byte m;

sbit scl = P1^0; sbit sda = P1^1;

bit bdata i2c_ack; bit bdata rsuc; bit run;

byte rdata,wdata,time; //byte begintime=99;

36

byte data w2402buf[3]; byte data r2402buf[3]; byte sa8574=0x40; byte sa2402=0xa0; byte sa2402r=0xa1;

void i2c_start() {

sda=1; _nop_(); scl=1;

fivenop(); sda=0;

fivenop(); scl=0; _nop_(); _nop_(); }

void i2c_stop() {

sda=0; _nop_(); scl=1;

fivenop(); sda=1;

fivenop(); }

bit i2c_checkack(void) {

byte errtime=255; sda=1;

fivenop(); scl=1;

fivenop(); while(sda) {

errtime--;

if(errtime==0) {

i2c_stop(); return(0); }

37

sda=1; } scl=0; _nop_(); return(1); }

void i2c_sendB(byte c) {

byte bitcnt;

for(bitcnt=0;bitcnt<8;bitcnt++) {

if((c<

_nop_(); _nop_();

i2c_ack=i2c_checkack(); _nop_(); _nop_(); }

byte i2c_recB() {

byte retc; byte bitcnt; retc=0; sda=1;

for(bitcnt=0;bitcnt<8;bitcnt++) {

_nop_(); scl=0; fivenop(); scl=1; _nop_(); _nop_();

retc=retc<<1; if(sda==1) {

38

retc=retc+1; }

_nop_(); _nop_(); }

scl=0; _nop_(); _nop_();

return(retc); }

void i2c_ackn(bit a) {

if(a==0) sda=0; else sda=1; fivenop(); scl=1;

fivenop(); scl=0; _nop_(); _nop_(); }

bit w1Bto8574(byte sla,byte c) {

i2c_start();

i2c_sendB(sla);

if(!i2c_ack) return(0); i2c_sendB(c);

if(!i2c_ack) return(0);

i2c_stop(); return(1); }

bit w1Bto2402(byte sla,byte suba,byte c) {

i2c_start();

i2c_sendB(sla);

if(!i2c_ack) return(0); i2c_sendB(suba);

if(!i2c_ack) return(0);

39

i2c_sendB(c);

if(!i2c_ack) return(0);

i2c_stop(); return(1); }

bit r1Bfrom2402(byte sla,byte suba,byte *c) {

i2c_start();

i2c_sendB(sla);

if(!i2c_ack) return(0); i2c_sendB(suba);

if(!i2c_ack) return(0);

i2c_start();

i2c_sendB(sla+1);

if(!i2c_ack) return(0);

*c=i2c_recB(); i2c_ackn(1);

i2c_stop(); return(1); }

void delayms(word n) {

word i,j;

for(i=0;i

for(j=0;j<120;j++); }

byte keyscan() {

byte i,temp,key,num; P3=0x30;

if(P3!=0x30) {

delayms(50); P3=0x30;

if(P3!=0x30)

40

本文来源:https://www.bwwdw.com/article/5mm2.html

Top