28BYJ的一点收获

时间:2022-03-06 19:41:31
#include <reg52.h>

unsigned long beats = 0;


void StartMotor(unsigned int angle);
void main()
{
TMOD = 0x01;
TH0 = 0xF8;
TL0 = 0xCD;
ET0 = 1;
TR0 = 1;

StartMotor(360*2+180);
while(1);
}

void StartMotor(unsigned long angle)
{
EA = 0;
beats = (angle*4076)/360;
EA = 1;
}

void InterruptTimer0() interrupt 1
{
unsigned char tmp;
static unsigned char index = 0;
unsigned char code BeatCode[8] = {
0xE, 0xC, 0xD, 0x9, 0xB, 0x3, 0x7, 0x6
};

if(beats!=0)
{
tmp = P1;
tmp = tmp & 0xF0;
tmp = tmp | BeatCode[index];
P1 = tmp;
index++;
beat--;
index = index & 0x07;
}
else
{
P1 = P1 | 0xFF;
}
}

51是8位单片机,8位的概念就是按8位一个字节进行的,那么要操作多个字节,就得分多次了。而程序中定义的unsigned long很明显是4个字节,如果要赋值就得分四次进行。如果此时没有EA = 0, 此时中断发生,发生借位,程序肯定要出错了!
如果定义成char或者bit的话当然没问题了!因为它们在CPU的一次操作中完成的。

中断

void InterruptTimer0() inerrupt 1
{
static bit div = 0;
TH0 = 0xFC;
TL0 = 0x67;
KeyScan();
div = ~div;
if(div == 0)
{
TurnMotor();
}
}

这里有一个小技巧,因为按键扫描是1ms,而电机的扫描则是2ms,但是中断扔定义1ms,同时利用了一个分频的技术,两个1ms才进行一次电机启动

-1 & 0x07

最后的结果为7;
原因为,整数的二进制就是其原码本身,负数的二进制码为其补码,所谓补码的概念为原码除符号位外,所有的位取反并加1