135 发表于 2023-2-6 10:27:34

求助,8G1K08A-36I-SOP8,想得到一个20ms周期的pwm

想用 8G1K08A-36I-SOP8 驱动舵机,请问如何才能得到一个周期为20ms,精度为2us的脉冲

例程上貌似PAC高速脉冲可以达到这种效果,但是芯片手册上对高速脉冲的介绍几笔带过,不是很清楚
请大佬帮忙讲解一下,感谢

梁工 发表于 2023-2-6 12:13:49

使用PCA高速输出,分辨率1us。
舵机使用的是1.000~2.000ms的PPM信号,分辨率1us可以到1000步。
建议使用STC8H系列带16位PPM的单片机,不需要软件中断处理。

国学芯用 发表于 2023-2-6 12:17:36

STC8H8K64U-45Mhz-TSSOP20 ,高级PWM,1.9元含税,硬件USB,支持USB下载 USB仿真    我觉得这个最适合

135 发表于 2023-2-6 14:25:15

国学芯用 发表于 2023-2-6 12:17
STC8H8K64U-45Mhz-TSSOP20 ,高级PWM,1.9元含税,硬件USB,支持USB下载 USB仿真    我觉得这个最适合
...

感谢

peitianyu 发表于 2024-10-22 09:57:13

梁工 发表于 2023-2-6 12:13
使用PCA高速输出,分辨率1us。
舵机使用的是1.000~2.000ms的PPM信号,分辨率1us可以到1000步。
建议使用STC ...
请问我这部分我已经实现了, 但是我有个疑问, 因为我舵机周期是20ms的, 我pwm的控制频率可以是1ms吗?或者这么做会有什么影响吗?

梁工 发表于 2024-10-22 10:59:40

peitianyu 发表于 2024-10-22 09:57
请问我这部分我已经实现了, 但是我有个疑问, 因为我舵机周期是20ms的, 我pwm的控制频率可以是1ms吗?或者这 ...

舵机的PPM信号是20ms,就要用20ms周期的PWM产生PPM信号去控制舵机。
一般舵机最短可以接受周期为4ms左右的PPM信号,根据具体响应速度要求确定周期。

peitianyu 发表于 2024-10-22 11:43:22

梁工 发表于 2024-10-22 10:59
舵机的PPM信号是20ms,就要用20ms周期的PWM产生PPM信号去控制舵机。
一般舵机最短可以接受周期为4ms左右 ...

好的, 感谢

Lkck8210 发表于 2024-10-22 11:51:39

本帖最后由 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;
      }
}以上代码没实验过,可能电平判断那里要取反一下

peitianyu 发表于 2024-10-22 14:53:31

这是我用的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]
查看完整版本: 求助,8G1K08A-36I-SOP8,想得到一个20ms周期的pwm