题目是这样的:
[例8-1]如图8-6所示,编写程序控制8个发光极管流水点亮。 图中 74LS164的8脚(CLK端)为同步脉冲输入端,9脚为控制端,9脚的电平由单片机的P1.0控制,当9脚为0时,允许串行数据由RXD端(P3.0) 向74LS164 的串行数据输入端A和B(1脚和2脚)输入,但是74LS164的8位并行输出端关闭:当9脚为1时,A和B输入端关闭,但是允许74LS164中的8位数据并行输出。当串行口将8位串行数据发送完毕后,申请中断,在中断服务程序中,单片机向串行口输出下一个8位数据。
#include <reg51.h>
#include <stdio.h>
sbit P1_0=0x90;
unsigned char nSendByte;
void delay(unsigned int i)
{
unsigned char j;
for(;i>0;i--)
for(j=0;j<125;j++)
;
}
void main()
{
SCON=0x00;
EA=1;
ES=1;
nSendByte=1;
SBUF=nSendByte;
P1_0=0;
while(1)
{;}
}
void Serial_Port() interrupt 4 using 0
{
//if(TI)
//{
P1_0=1;
SBUF=nSendByte;//不明白这句为什么要写,逻辑上感觉可以没有这句,但进到Proteus仿真后这句必须要有才能顺利实现流水点灯
delay(500);
P1_0=0;
nSendByte=nSendByte<<1;
if(nSendByte==0)
nSendByte=1;
SBUF=nSendByte;//感觉有这句足矣
//}
TI=0;
RI=0;
}
个人感觉思路上:SBUF在第一次从主函数中引脚获得了1值,P1_0=0 74LS164去接收1值,进入中断,P1_0=1 74LS164不再接收,把内部的1值送去点亮第一个小灯,SBUF=nSendByte这个时候又把1值送入到引脚,延时500,把P1_0打开,这时又开始接收数据,刚才引脚上的1传进了74LS164,不过没什么用,因为数据储备的1值马上变成2值,SBUF=nSendByte这个时候又把2值送入到引脚,这时74LS164又是可以接收数据的状态,2传进了74LS164覆盖了刚才的1,然后再进中断,P1_0=1 74LS164不再接收,把内部的2值送去点亮第二个小灯,SBUF=nSendByte这个时候又把2值送入到引脚,延时500,把P1_0打开,这时又开始接收数据,刚才引脚上的2传进了74LS164,不过没什么用,因为数据储备的2值马上变成3值,SBUF=nSendByte这个时候又把3值送入到引脚,这时74LS164又是可以接收数据的状态,3传进了74LS164覆盖了刚才的2。
如此往复。
如果是SBUF一旦有了值就不停的朝引脚送值,只不过是74LS164打开之后送的值才到了74LS164里吗,那这样就是每一次中断函数TI刚置0,又因为SBUF一直在送值,TI又迅速置成了1,所以刚一出中断函数,就发现又满足中断条件就再进入中断了。是这样吗?
你理解有问题
74LS164 的控制端是复位。
P1_0 = 0 74LS164输出复位,全输出 0
P1_0 = 1 74LS164正常输出
将中断程序修改了下,你试试结果。
void Serial_Port() interrupt 4 using 0
{
TI=0;
RI=0;
//if(TI)
//{
P1_0=1;
SBUF=nSendByte;//不明白这句为什么要写,逻辑上感觉可以没有这句,但进到Proteus仿真后这句必须要有才能顺利实现流水点灯
delay(500);
P1_0=0;
nSendByte=nSendByte<<1;
if(nSendByte==0)
nSendByte=1;
//SBUF=nSendByte;//将这行去掉
//}
//TI=0;
//RI=0;
}
您好,我是有问必答小助手,您的问题已经有小伙伴帮您解答,感谢您对有问必答的支持与关注!根据大佬的解释,写了一篇个人的理解http://t.csdn.cn/y7fcI