读书人

关于c语言和51汇编语言的有关问题

发布时间: 2012-03-31 13:13:26 作者: rapoo

关于c语言和51汇编语言的问题
我做了一个从串行EEPROM 93c46 写数据和读数据的程序。分别用c语言和51汇编实现。51汇编没有问题,只是c的程序没结果。请高人指点一下我的c程序错在哪里?
di和d0是按位操作

c程序如下:
#include "reg51.h "
sbit cs=P2^0;/*片选信号由P2.0产生*/
sbit sk=P2^1;/*时钟信号由P2.1产生*/
sbit di=P2^2;/*dI输入由P2.2产生*/
sbit d0=P2^3;/*dO输出由P2.3产生*/
sbit c=ACC^7;/*定义位变量*/
sbit ci=ACC^0;
unsigned char addr=0x20;/*使用93c46地址为20H的单元*/
unsigned char dat =0x55;/*写入数据为055H*/
bdata unsigned char com;
bdata unsigned char acc;
void tran8()/*发送一字节数据子函数*/
{
unsigned char i;
for(i=0; i <8; i++) /*发送8位数据*/
{
ACC=com; /*将数据放入a中*/
di=c; /*a的最高位输出*/
sk=1; /*sck产生一个上跳变*/
;
sk=0;
com=com < <1; /*数据左移一位*/
}
/*一字节数据发送结束,di清零*/
return;
}
void tran7()/*发送一字节数据子函数*/
{
unsigned char i;
for(i=0; i <7; i++) /*发送8位数据*/
{
ACC=com; /*将数据放入a中*/
di=c; /*a的最高位输出*/
sk=1; /*sck产生一个上跳变*/
;


sk=0;
com=com < <1; /*数据左移一位*/
}
/*一字节数据发送结束,di清零*/
return;
}
void tran5()/*发送一字节数据子函数*/
{
unsigned char i;
for(i=0; i <5; i++) /*发送5位数据*/
{
ACC=com; /*将数据放入a中*/
di=c; /*a的最高位输出*/
sk=1; /*sk产生一个上跳变*/
;
sk=0;
com=com < <1; /*数据左移一位*/
}
/*一字节数据发送结束,di清零*/
return;
}
void tran3()/*发送一字节数据子函数*/
{
unsigned char i;
for(i=0; i <3; i++) /*发送3位数据*/
{
ACC=com; /*将数据放入a中*/
di=c; /*a的最高位输出*/
sk=1; /*sk产生一个上跳变*/
;
sk=0;
com=com < <1; /*数据左移一位*/


}
/*一字节数据发送结束,di清零*/
return;
}
void delay() /*延时子函数*/
{
unsigned int d1,d2;
for(d1=0; d1 <16; d1++)
for(d2=0; d2 <256; d2++);
return;
}
main()
{
unsigned char i;
while(1)
{
sk=0;
com=0x98; /*发送写使能命令*/
cs=1;
tran3(); /*调用三位发送子程序*/
com=0x0c0;
tran7(); /*调用七位发送子程序*/
cs=0;
delay(); /*写使能命令发送结束延时*/
cs=1;
com=0x0a0; /*发送写操作指令,101*/
tran3();
com=addr; /*发送地址*/
tran7();
com=dat; /*发送数据*/
tran8();
cs=0;
delay(); /*写结束*/

cs=1;
com=0x0c0; /*发送读操作指令,11000000*/
tran3();
com=addr; /*发送地址*/
tran7();
for(i=0;i <8;i++)
{
sk=0;
sk=1;
ci=d0;
acc=acc < <1;
}
P1=acc;
cs=0;
}
}

51汇编如下:
CS EQU P2.0 ;p3.2; ;片选信号由P2.0产生
SK EQU P2.1 ;p3.3; ;时钟信号由P2.1产生
DI EQU P2.2 ;p3.4; ;DI由P2.2产生


DO EQU P2.3 ;p3.5; ;DO由P2.3产生
ADDR EQU 20H ;使用93c4610h的单元
DAT EQU 55H ;写入数据为055H
ORG 00H ;主程序

XWRITE:
clr sk
MOV A, #98H ;发送写使能命令 1 0011
SETB CS
ACALL TRAN3 ;调用发送子程序
mov a,#0c0h
acall tran7
clr cs
ACALL DELAY ;写使能命令发送结束演延时

SETBCS ;
MOV A, #0A0H;5H ;发送写操作指令,101
ACALL TRAN3 ;
MOV A, #ADDR ;发送地址
ACALL TRAN7 ;


MOV A, #DAT ;发送数据
ACALL TRAN8
CLR CS ;
ACALL DELAY ;调用延时子程序

aaa: SETB CS
XREAD: MOV A, #0C0H;6H ;发送读操作指令,11000000
ACALL TRAN3
MOV A, #ADDR ;发送地址
ACALL TRAN7
MOV R0, #08H ;R0为位数计数器
READ1: CLR SK
SETB SK
MOV C, DO ;读一位数据
RLC A ;将读入的一位数据移入A中
DJNZ R0, READ1 ;判断一字节的数据是否读完
MOV P1, A ;将读出的数据送到P1口显示
clr cs

JMP XWRITE

TRAN3: MOV R0, #03H ;发送一字节数据子程序


TRAN2: RLC A ;将A的最高位移入C中
MOV DI, C ;将C中的数据输出到DI
SETB SK
nop
CLR SK ;SK产生一个上跳变
DJNZ R0, TRAN2 ;3位未发送完,转移
;发送结束
RET
TRAN5: MOV R0, #05H ;发送一字节数据子程序
TRAN4: RLC A ;将A的最高位移入C中
MOV DI, C ;将C中的数据输出到DI
SETB SK
nop
CLR SK ;SK产生一个上跳变
DJNZ R0, TRAN4 ;5位未发送完,转移
RET
TRAN7: MOV R0, #07H ;发送一字节数据子程序
TRAN6: RLC A ;将A的最高位移入C中


MOV DI, C ;将C中的数据输出到DI
SETB SK
nop
CLR SK ;SK产生一个上跳变
DJNZ R0, TRAN6 ;7位未发送完,转移
RET
TRAN8: MOV R0, #08H ;发送一字节数据子程序
TRAN1: RLC A ;将A的最高位移入C中
MOV DI, C ;将C中的数据输出到DI
SETB SK
nop
CLR SK ;SK产生一个上跳变
DJNZ R0, TRAN1 ;8位未发送完,转移
;发送结束
RET
DELAY: MOV R1, #1H ;延时子程2.1MS?
LP1: MOV R0, #10H
LP2: DJNZ R0, LP2
DJNZ R1, LP1


RET
end




[解决办法]

sk=1; /*sck产生一个上跳变*/
;
sk=0;

这里是不是有些问题?会不会被编译器优化掉?
[解决办法]
lddLinan(不再五行中)
你所说的编译器优化掉是什么意思?我用的是keil软件
sk=1; /*sck产生一个上跳变*/
;
sk=0;
我这里需要一个空操作以延长sk脉冲的时间。
c语言中有没有别的办法加空操作? 我用_nop_()试了一下,编译通不过。

读书人网 >C语言

热点推荐