最近买了一个51单片机最小系统板,准备学习单片机。
最小系统板:只是一块板子,相当于电脑主板,如果想要通电,需要插芯片。
于是买了一个stc89c52rc芯片,对着b站江协科技的教程开始学。(只不过教程里的芯片不一样,用keil编程的时候选at89c51RC2)
晶振:11.0592MHz。11.0592MHz除12为921600Hz,就是一秒921600次机器周期,10ms=9216次机器周期。
机器周期可以掌管计数器和中断,比如下面是让led灯每1秒切换一次状态的代码:
#include <at89c51RC2.h>
#include <intrins.h>
#define TIMER_VALUE 65536-46080
static unsigned int cnt = 0;
void Timer0_ISR() interrupt 1
{
TF0 = 0;
TH0 = (unsigned char)(TIMER_VALUE >> 8);
TL0 = (unsigned char)(TIMER_VALUE & 0xff);
cnt ++;
if (cnt >= 20) {
cnt = 0;
P2_0 = ~P2_0;
}
}
void main()
{
TMOD = 0x01;
TH0 = (unsigned char)(TIMER_VALUE >> 8);
TL0 = (unsigned char)(TIMER_VALUE & 0xff);
ET0 = 1;
TR0 = 1;
EA = 1;
while (1)
{
}
}
舵机
180度舵机的控制需要MCU产生一个20ms的脉冲信号,以0.5ms到2.5ms的高电平来控制舵机的角度。0.5ms 0度;1.0ms 45度;1.5ms 90度;2.0ms 135度;2.5ms 180度。
360度舵机只能控制转速和转向,不能控制角度。0.5ms 正向最大转速;1.5ms 速度为0;2.5ms 反向最大转速。
不过其实0.5毫秒是无法整除9216对应的10毫秒的,所以只能近似了。比如下面是一段产生1ms高电平的20ms的pwm:
#include <at89c51RC2.h>
#include <intrins.h>
void Timer0_ISR() interrupt 1
{
TF0 = 0;
if (P2_3) {
P2_3 = ~P2_3;
TH0 = (unsigned char)((65536-18432+922) >> 8);
TL0 = (unsigned char)((65536-18432+922) & 0xff);
}
else {
P2_3 = ~P2_3;
TH0 = (unsigned char)((65536-922) >> 8);
TL0 = (unsigned char)((65536-922) & 0xff);
}
}
void main()
{
TMOD = 0x01;
P2_3 = 0;
TH0 = (unsigned char)((65536-18432+922) >> 8);
TL0 = (unsigned char)((65536-18432+922) & 0xff);
ET0 = 1;
TR0 = 1;
EA = 1;
while (1)
{
}
}
输入
输入暂时没搞明白硬件层面的原理。
串口
串口其实就是协议。