STC89C52单片机C程序求解(有完整程序)

#include <reg52.h>

#define uint unsigned int
#define uchar unsigned char

sbit CS = P2^0;
sbit CLK = P2^1;
sbit SDO = P2^2;

void DELAY(void)
{
uint x,y;
for(y = 5;y > 0;y--)
for(x = 110;x > 0;x--);
}

void main(void)
{
uint i = 0;
uint j = 0;
uint k = 0;
TMOD = 0X20;
TH1 = 0XF3;
TL1 = 0XF3;
TR1 = 1;
REN = 1;
SM0 = 0;
SM1 = 1;

while(1)
{
CLK = 0;
CS = 1;
SDO = 0;

DELAY();

for(i=0;i<16;i++)
{
CS = 0;
CLK = 1;
DELAY();
k = SDO;
j = j + k;
j = j << 1;
DELAY();
CLK = 0;
DELAY();
DELAY();
}

CS = 1;

SBUF = (j >> 8) & 0XFF;
while(!TI);
TI = 0;

SBUF = j & 0XFF;
while(!TI);
TI = 0;

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

以上每一行都是什么意思?尤其是后半段~

我给你解释一下吧 希望帮得上你

#include <reg52.h> // 头文件

#define uint unsigned int //宏定义 把uint 等价为 unsigned int
#define uchar unsigned char

sbit CS = P2^0; //定义三个特殊功能位, 我感觉应该是驱动一个东西吧,CS
sbit CLK = P2^1; 是片选 高选中或者低选中, CLK是通信的时钟线,
sbit SDO = P2^2; SDO应该是驱动芯片的数据输出口, 不过应该有输入口的??
怎么没看到程序里有????
void DELAY(void) //简单的延时子程序
{
uint x,y;
for(y = 5;y > 0;y--)
for(x = 110;x > 0;x--);
}

void main(void)
{
uint i = 0;
uint j = 0;
uint k = 0; 定义三个变量
TMOD = 0X20;
TH1 = 0XF3; 定时器工作方式 和初值
TL1 = 0XF3;
TR1 = 1; 打开定时器
REN = 1; REN SM0 SM1 是串口这里的设置 具体的你自己看文档 我就不
SM0 = 0; 细说了
SM1 = 1;

while(1)
{
CLK = 0;
CS = 1;
SDO = 0;

DELAY();

for(i=0;i<16;i++) 循环16次 应该是要传输2个字节的数据吧吧
{
CS = 0; 这个片选貌似应该放在循环外面
CLK = 1; 时钟线的控制
DELAY();
k = SDO; 把驱动芯片输出的数据赋值给K
j = j + k;
j = j << 1; 刚才的K 只是一个位, 这里两句是要把它整理成uint型的即16位的,
DELAY();
CLK = 0; 进行延时 和CLK时钟控制,即模拟驱动芯片的驱动时序
DELAY();
DELAY();
}

CS = 1; 选中或者取消片选 我感觉应该是取消

SBUF = (j >> 8) & 0XFF; 把刚才从驱动芯片里读出的uint 16位数据 取高八位 送入
while(!TI); 串口的SBUF 寄存器 貌似是要传给电脑 或者上位机软件
TI = 0; 等待传输完成 清 标志位

SBUF = j & 0XFF; 把刚才从驱动芯片里读出的uint 16位数据 取低八位 送入
while(!TI); 串口的SBUF 寄存器 貌似是要传给电脑 或者上位机软件
TI = 0; 等待传输完成 清 标志位

上面这次 正好把 UINT型的 16位 2个字节全部传输到上位机

SBUF = 0XFF; 最后在传输0xff 这个数据给上位机
while(!TI);
TI = 0;
}
}

好了 回答完了 , 希望能帮得上你。
温馨提示:答案为网友推荐,仅供参考
第1个回答  2011-08-26
蜂鸣器唱《祝你平安》 *
; *
;********************************************************************************/
SPK bit P2.3

ORG 0000H
LJMP START
ORG 000BH
INC 20H ;中断服务,中断计数器加1
MOV TH0,#0D8H
MOV TL0,#0EFH ;12M晶振,形成10毫秒中断
RETI

START:
MOV SP,#50H
MOV TH0,#0D8H
MOV TL0,#0EFH
MOV TMOD,#01H
MOV IE,#82H
MUSIC0:
NOP
MOV DPTR,#DAT ;表头地址送DPTR
MOV 20H,#00H ;中断计数器清0
MOV B,#00H ;表序号清0
MUSIC1:
NOP
CLR A
MOVC A,@A+DPTR ;查表取代码
JZ END0 ;是00H,则结束
CJNE A,#0FFH,MUSIC5
LJMP MUSIC3
MUSIC5:
NOP
MOV R6,A
INC DPTR
MOV A,B
MOVC A,@A+DPTR ;取节拍代码送R7
MOV R7,A
SETB TR0 ;启动计数
MUSIC2:
NOP
CPL SPK
MOV A,R6
MOV R3,A
LCALL DEL
MOV A,R7
CJNE A,20H,MUSIC2 ;中断计数器(20H)=R7否?
;不等,则继续循环
MOV 20H,#00H ;等于,则取下一代码
INC DPTR
; INC B
LJMP MUSIC1
MUSIC3:
NOP
CLR TR0 ;休止100毫秒
MOV R2,#0DH
MUSIC4:
NOP
MOV R3,#0FFH
LCALL DEL
DJNZ R2,MUSIC4
INC DPTR
LJMP MUSIC1
END0:
NOP
MOV R2,#64H ;歌曲结束,延时1秒后继续
MUSIC6:
MOV R3,#00H
LCALL DEL
DJNZ R2,MUSIC6
LJMP MUSIC0
DEL:
NOP
DEL3:
MOV R4,#02H
DEL4:
NOP
DJNZ R4,DEL4
NOP
DJNZ R3,DEL3
RET
NOP
DAT:
db 26h,20h,20h,20h,20h,20h,26h,10h,20h,10h,20h,80h,26h,20h,30h,20h
db 30h,20h,39h,10h,30h,10h,30h,80h,26h,20h,20h,20h,20h,20h,1ch,20h
db 20h,80h,2bh,20h,26h,20h,20h,20h,2bh,10h,26h,10h,2bh,80h,26h,20h
db 30h,20h,30h,20h,39h,10h,26h,10h,26h,60h,40h,10h,39h,10h,26h,20h
db 30h,20h,30h,20h,39h,10h,26h,10h,26h,80h,26h,20h,2bh,10h,2bh,10h
db 2bh,20h,30h,10h,39h,10h,26h,10h,2bh,10h,2bh,20h,2bh,40h,40h,20h
db 20h,10h,20h,10h,2bh,10h,26h,30h,30h,80h,18h,20h,18h,20h,26h,20h
db 20h,20h,20h,40h,26h,20h,2bh,20h,30h,20h,30h,20h,1ch,20h,20h,20h
db 20h,80h,1ch,20h,1ch,20h,1ch,20h,30h,20h,30h,60h,39h,10h,30h,10h
db 20h,20h,2bh,10h,26h,10h,2bh,10h,26h,10h,26h,10h,2bh,10h,2bh,80h
db 18h,20h,18h,20h,26h,20h,20h,20h,20h,60h,26h,10h,2bh,20h,30h,20h
db 30h,20h,1ch,20h,20h,20h,20h,80h,26h,20h,30h,10h,30h,10h,30h,20h
db 39h,20h,26h,10h,2bh,10h,2bh,20h,2bh,40h,40h,10h,40h,10h,20h,10h
db 20h,10h,2bh,10h,26h,30h,30h,80h,00H

END
第2个回答  2011-08-25
这应该是一个某芯片的驱动程序,在一芯片或端口读入数据再利用单片机串口将数据输出到另一芯片或端口,此程序从严格的意义上看有不妥之处且运行效率不高,有较大优化空间。具体动作较明显恕不赘述追问

怎么个不妥,麻烦您指出来吧,小弟新手在做TLC4541的驱动,这是我导师给的,我不懂问他他笑而不语,我实在弄不明白了……

追答

我也是新手,只是有点较为浅薄的认识,单从这个for循环说一下吧:
for(i=0;i<16;i++)
{
CS = 0; 这一句每次循环都有相同结果,没必要反复,如果时序没错的话,应该把它放在for
循环前面即使你的for尾部有DELAY(); 但这是操作外部端口,应考虑到电磁辐射
CLK = 1;
DELAY();
k = SDO;//从你上面的语句看你的IO口应该设置在默认的传统51IO模式,此句为读端口,理论上应
j = j + k; 先写1
j = j << 1;
DELAY();
CLK = 0;
DELAY();
DELAY();
}
你的程序用了uint型数据,操作这样的16位数据,编译后增加语句长度,尽量用uchar型的8位数据根据情况自己设计算法实现用8位数操作,可能会节省时间,这在学习时的实验中可能不太明显也显得不是很重要,但工程实际中这是非常重要的,初学时应建立此观念

这个程序如果是用来学习,能做出正确的时序,是较好的程序,因为比较直接

第3个回答  2011-08-25
你只要了解了这块芯片的工作方式,基本上这个代码就可以理解了。自己慢慢理解。多看芯片资料。

相关了解……

你可能感兴趣的内容

本站内容来自于网友发表,不代表本站立场,仅表示其个人看法,不对其真实性、正确性、有效性作任何的担保
相关事宜请发邮件给我们
© 非常风气网