预备知识
编码器
编码器:测转速
在下降沿或这上升沿的时候,检测两个端口的值。
脉冲信号的周期定为2Π,就可以理解啦
PWM
定时器实现PWM
STC8-PWM/DAC
频率决定其周期。
频率一般取1KHZ。
模拟电压值:电压*占空比
PWM
最高的精度是2^15次方(32768)。
- 根据频率得出周期值。
- 算出占空比对应的周期,以它为最小单位,开始往上加。
DAC
- 配置主频
- 配置精度
- 什么时候高,什么时候低
PWM控制舵机(伺服电机)
0.5ms/20ms*100 =2.5%(0°)
2.5ms/20ms*100= 12.5%(180°)
1.5ms/20ms*100 = 7.5% (中间)
例程:19.2.1 输出任意周期和任意占空比的波形
PWMCR = 0x80; //启动 PWM 模块
void main()
{
P_SW2 = 0x80;
PWMCKS = 0x00; // PWM 时钟为系统时钟
PWMC = 0x1000; //设置 PWM 周期为 1000H 个 PWM 时钟
PWM0T1= 0x0100; //在计数值为 100H 地方输出低电平
PWM0T2= 0x0500; //在计数值为 500H 地方输出高电平
PWM0CR= 0x80; //使能 PWM0 输出
P_SW2 = 0x00;
PWMCR = 0x80; //启动 PWM 模块
while (1);
}
第三行:外设端口切换控制寄存器2的EAXFR置1
第四行:
第六行和第七行:
第八行:允许第0通道PWM中断
第十一行:允许计数器中断
结果:
输出2.70KHZ
计算公式:1/(11.0592*1000000*4096(1000H))
例程:19.2.2 两路PWM实现互补对称带死区控制的波形
实际上输出互补的两个波形
例程:19.2.3 PWM实现渐变灯(呼吸灯)
#define CYCLE 0x1000
void PWM_Isr() interrupt 22
{
static bit dir = 1;
static int val = 0;
char store;
if (PWMCFG & 0x80)//PWM计数器归零中断标志位
//当15位的PWM计数器记满溢出归零时,硬件自动将此位置1,并向CPU提出中断请求,此标志
//位需要软件清零。
{
PWMCFG &= ~0x80; //清中断标志
if (dir)
{
val++;
if (val >= CYCLE) dir = 0;
}
else
{
val--;
if (val <= 1) dir = 1;
}
store = P_SW2;
P_SW2 |= 0x80;
PWM0T2 = val;
P_SW2 = store;
}
}
void main()
{
P_SW2 = 0x80; //开启读取外部寄存器指令
PWMCKS = 0x00; // PWM时钟为系统时钟
PWMC = CYCLE; //设置PWM周期为
PWM0T1= 0x0000; //计时器的值
PWM0T2= 0x0001; //
PWM0CR= 0x80; //使能PWM0输出
P_SW2 = 0x00; //关闭读取外部寄存器指令
PWMCR = 0xc0; //启动PWM模块
//使能PWM波形发生器,PWM计数器开始计数
//ENPWM控制位既是整个PWM模块的的使能位,也是PWM计数器开始计数的控制位。在PWM
//计数器计数的过程中,ENPWM控制位被关