求助,8G1K08A-36I-SOP8,想得到一个20ms周期的pwm
想用 8G1K08A-36I-SOP8 驱动舵机,请问如何才能得到一个周期为20ms,精度为2us的脉冲例程上貌似PAC高速脉冲可以达到这种效果,但是芯片手册上对高速脉冲的介绍几笔带过,不是很清楚
请大佬帮忙讲解一下,感谢
使用PCA高速输出,分辨率1us。
舵机使用的是1.000~2.000ms的PPM信号,分辨率1us可以到1000步。
建议使用STC8H系列带16位PPM的单片机,不需要软件中断处理。 STC8H8K64U-45Mhz-TSSOP20 ,高级PWM,1.9元含税,硬件USB,支持USB下载 USB仿真 我觉得这个最适合
国学芯用 发表于 2023-2-6 12:17
STC8H8K64U-45Mhz-TSSOP20 ,高级PWM,1.9元含税,硬件USB,支持USB下载 USB仿真 我觉得这个最适合
...
感谢 梁工 发表于 2023-2-6 12:13
使用PCA高速输出,分辨率1us。
舵机使用的是1.000~2.000ms的PPM信号,分辨率1us可以到1000步。
建议使用STC ...
请问我这部分我已经实现了, 但是我有个疑问, 因为我舵机周期是20ms的, 我pwm的控制频率可以是1ms吗?或者这么做会有什么影响吗? peitianyu 发表于 2024-10-22 09:57
请问我这部分我已经实现了, 但是我有个疑问, 因为我舵机周期是20ms的, 我pwm的控制频率可以是1ms吗?或者这 ...
舵机的PPM信号是20ms,就要用20ms周期的PWM产生PPM信号去控制舵机。
一般舵机最短可以接受周期为4ms左右的PPM信号,根据具体响应速度要求确定周期。 梁工 发表于 2024-10-22 10:59
舵机的PPM信号是20ms,就要用20ms周期的PWM产生PPM信号去控制舵机。
一般舵机最短可以接受周期为4ms左右 ...
好的, 感谢 本帖最后由 Lkck8210 于 2024-10-22 13:09 编辑
首先把PAC的时钟设为2us(12Mhz/2,24Mhz/4)
然后中断里选择电平的维持时间
unsigned int value;
unsigned int Hvalue = 500;//500 * 2us = 1000us
#define Lvalue (10000 - Hvalue)
void PCA_Isr() interrupt 7
{
CCF0 = 0;
CCAP0L = value;
CCAP0H = value >> 8;
if(P32)
{
value += Hvalue;
}else{
value += Lvalue;
}
}以上代码没实验过,可能电平判断那里要取反一下
这是我用的stc8g08a-8pin代码, 可以参考一下, 我测下来还行, io口设置的是p32 p33 p55
#include "driver/pca.h"
static u16 g_pwm_tmps;
static u16 g_pwm_highs={PCA_T1US*500, PCA_T1US*2500};
static u16 g_pwm_lows={PWM_DUTY-PCA_T1US*500, PWM_DUTY-PCA_T1US*2500};
void PCA_Init(void)
{
CCON = 0x00;
CMOD = 0x00; //PCA时钟为系统时钟12分频
CL = 0x00;
CH = 0x00;
CCAPM1 = 0x4d; //PCA模块0为16位定时器模式并使能脉冲输出
g_pwm_tmps = PCA_T1US*500;
CCAP1L = g_pwm_tmps;
CCAP1H = g_pwm_tmps >> 8;
g_pwm_tmps += PCA_T1US*500;
CCAPM2 = 0x4d;
g_pwm_tmps = PCA_T1US*500;
CCAP2L = g_pwm_tmps;
CCAP2H = g_pwm_tmps >> 8;
g_pwm_tmps += PCA_T1US*500;
CR = 1; //启动PCA计时器
}
void UpdatePCA(u8 pin, u16 pwm_high)
{
CR = 0;
g_pwm_highs = pwm_high*PCA_T1US;
g_pwm_lows = PWM_DUTY-g_pwm_highs;
CR = 1;
}
void PCA_Isr() interrupt 7
{
if(CCF1) {
CCF1 = 0;
if(P33) g_pwm_tmps += g_pwm_highs;
else g_pwm_tmps += g_pwm_lows;
CCAP1L = g_pwm_tmps;
CCAP1H = g_pwm_tmps >> 8;
}
if(CCF2) {
CCF2 = 0;
if(P55) g_pwm_tmps += g_pwm_highs;
else g_pwm_tmps += g_pwm_lows;
CCAP2L = g_pwm_tmps;
CCAP2H = g_pwm_tmps >> 8;
}
if(CF) CF = 0;
}
#ifndef __PCA_H__
#define __PCA_H__
#include "firmware/config.h"
#define PCA_T1US (MAIN_Fosc / 12 / 1000000) // 1us 12分频
#define PWM_DUTY (20000*PCA_T1US) // 20ms
void PCA_Init(void);
void UpdatePCA(u8 pin, u16 pwm_high);
#endif // __PCA_H__
页:
[1]