找回密码
 立即注册
查看: 46|回复: 1

STC32G12K128 高速高级PWMA怎么实现脉冲可调输出

[复制链接]
  • 打卡等级:初来乍到
  • 打卡总天数:4
  • 最近打卡:2026-07-15 15:02:39
已绑定手机

3

主题

4

回帖

41

积分

新手上路

积分
41
发表于 2026-7-8 16:09:40 | 显示全部楼层 |阅读模式
//测试工作频率为 12MHz
//#include "stc8h.h"
#include "stc32g.h" //头文件见下载软件
#include "intrins.h"
#define FOSC 12000000UL
#define HSCK_MCLK 0
#define HSCK_PLL 1
#define HSCK_SEL HSCK_PLL
#define PLL_96M 0
#define PLL_144M 1
#define PLL_SEL PLL_144M
#define CKMS 0x80
#define HSIOCK 0x40
#define MCK2SEL_MSK 0x0c
#define MCK2SEL_SEL1 0x00
#define MCK2SEL_PLL 0x04
#define MCK2SEL_PLLD2 0x08
#define MCK2SEL_IRC48 0x0c
#define MCKSEL_MSK 0x03
#define MCKSEL_HIRC 0x00
#define MCKSEL_XOSC 0x01
#define MCKSEL_X32K 0x02
#define MCKSEL_IRC32K 0x03
#define ENCKM 0x80
#define PCKI_MSK 0x60
#define PCKI_D1 0x00
#define PCKI_D2 0x20
#define PCKI_D4 0x40
#define PCKI_D8 0x60

sbit PWM1P = P1^0;
typedef         unsigned char        u8;
typedef         unsigned int        u16;
typedef         unsigned long        u32;

u8 count ,i;
/*************  本地变量声明    **************/
bit B_1ms;          //1ms标志
bit PWM1_Flag;

u16 Period;
u8 msSecond;
#define Timer0_Reload   (65536UL -(FOSC / 1000))
void UpdatePwm(void);
void TxPulse(u8 rep);
void delay()
{
        int i;
        for (i=0; i<100; i++);
}
/*
char ReadPWMA(char addr)
{
        char dat;
        while (HSPWMA_ADR & 0x80); //等待前一个异步读写完成
        HSPWMA_ADR = addr | 0x80; //设置间接访问地址,只需要设置原 XFR 地址的低 7 位
        //HSPWMA_ADR 寄存器的最高位写 1,表示读数据
        while (HSPWMA_ADR & 0x80); //等待当前异步读取完成
        dat = HSPWMA_DAT; //读取异步数据
        return dat;
}*/
void WritePWMA(char addr, char dat)
{
        while (HSPWMA_ADR & 0x80); //等待前一个异步读写完成
        HSPWMA_DAT = dat; //准备需要写入的数据
        HSPWMA_ADR = addr & 0x7f; //设置间接访问地址,只需要设置原 XFR 地址的低 7 位
                                                                //HSPWMA_ADR 寄存器的最高位写 0,表示写数据
}
void main()
{
       
        EAXFR = 1; //使能访问 XFR
        CKCON = 0x00;//设置外部数据总线速度为最快
        WTST = 0x00;
//        HIRCCR = 0x80; //启动内部高速 IRC
//while (!(HIRCCR & 1)); //等待时钟稳定
//CLKSEL = 0x00; //选择内部高速 HIRC
        //选择 PLL 输出时钟
        #if (PLL_SEL == PLL_96M)
        CLKSEL &= ~CKMS; //选择 PLL 的 96M 作为 PLL 的输出时钟
        #elif (PLL_SEL == PLL_144M)
        CLKSEL |= CKMS; //选择 PLL 的 144M 作为 PLL 的输出时钟
        #else
        CLKSEL &= ~CKMS; //默认选择 PLL 的 96M 作为 PLL 的输出时钟
        #endif
                                        //选择 PLL 输入时钟分频,保证输入时钟为 12M
        USBCLK &= ~PCKI_MSK;
        #if (FOSC == 12000000UL)
        USBCLK |= PCKI_D1; //PLL 输入时钟 1 分频
        #elif (FOSC == 24000000UL)
        USBCLK |= PCKI_D2; //PLL 输入时钟 2 分频
        #elif (FOSC == 48000000UL)
        USBCLK |= PCKI_D4; //PLL 输入时钟 4 分频
        #elif (FOSC == 96000000UL)
        USBCLK |= PCKI_D8; //PLL 输入时钟 8 分频
        #else
        USBCLK |= PCKI_D1; //默认 PLL 输入时钟 1 分频
        #endif

       

                                                        //启动 PLL
        USBCLK |= ENCKM; //使能 PLL 倍频
        delay(); //等待 PLL 锁频
        //选择 HSPWM/HSSPI 时钟
        /*#if (HSCK_SEL == HSCK_MCLK)
        CLKSEL &= ~HSIOCK; //HSPWM/HSSPI 选择主时钟为时钟源
        #elif (HSCK_SEL == HSCK_PLL)
        CLKSEL |= HSIOCK; //HSPWM/HSSPI 选择 PLL 输出时钟为时钟源
        #else
        CLKSEL &= ~HSIOCK; //默认 HSPWM/HSSPI 选择主时钟为时钟源
        #endif*/
        CLKSEL |= HSIOCK; //HSPWM/HSSPI 选择 PLL 输出时钟为时钟源
        HSCLKDIV = 0; //HSPWM/HSSPI 时钟源不分频
        HSPWMA_CFG = 0x03; //使能 PWMA 相关寄存器异步访问功能
        //通过异步方式设置 PWMA 的相关寄存器
       
    PWM1_Flag = 0;
    Period = 70;

    //  Timer0初始化
    AUXR = 0x80;    //Timer0 set as 1T, 16 bits timer auto-reload,
    TH0 = (u8)(Timer0_Reload / 256);
    TL0 = (u8)(Timer0_Reload % 256);
    ET0 = 1;    //Timer0 interrupt enable
    TR0 = 1;    //Tiner0 run
        EA =1;
            UpdatePwm();
        while (1)
        {
/*
                        WritePWMA((char)&PWMA_CCER1, 0x00);
                        WritePWMA((char)&PWMA_CCMR1, 0x00); //CC1 为输出模式
                        WritePWMA((char)&PWMA_CCMR1, 0x60); //OC1REF 输出 PWM1(CNT<CCR 时输出有效电平 1)
                        WritePWMA((char)&PWMA_CCER1, 0x05); //使能 CC1/CC1N 上的输出功能
                        WritePWMA((char)&PWMA_ENO, 0x03); //使能 PWM 信号输出到端口
                        WritePWMA((char)&PWMA_BKR, 0x80); //使能主输出
                        WritePWMA((char)&PWMA_CCR1H, (70>>1) >> 8); //设置输出 PWM 的占空比
                        WritePWMA((char)&PWMA_CCR1L, (70>>1));
                        WritePWMA((char)&PWMA_ARRH, 70 >> 8);//WritePWMA((char)&PWMA_ARRH, 1000 >> 8); //设置输出 PWM 的周期
                        WritePWMA((char)&PWMA_ARRL, 70);//WritePWMA((char)&PWMA_ARRL, 1000);
                        WritePWMA((char)&PWMA_DTR, 10); //设置互补对称输出 PWM 的死区
                        WritePWMA((char)&PWMA_CR1, 0x01); //开始 PWM 计数
*/
        if(B_1ms)
        {
            B_1ms = 0;
            msSecond++;
            if(msSecond >= 10)  //10ms启动一次PWM输出
            {
                msSecond = 0;
                TxPulse(10);    //输出10个脉冲
            }
        }
        }
}
/************* 发送脉冲函数 **************/
void TxPulse(u8 rep)
{
    if(rep == 0) return;
    rep -= 1;

    PWMA_RCR = rep;    //重复计数寄存器,计数 rep 个脉冲后产生更新事件
    PWMA_CR1 |= 0x89;  //使能ARR预装载,单脉冲模式,开始计时
}

/********************** Timer0 1ms中断函数 ************************/
void timer0(void) interrupt 1
{
    B_1ms = 1;
    if(PWM1_Flag)
    {
        Period++;  //周期递增
        if(Period >= 0x1000) PWM1_Flag = 0;
    }
    else
    {
        Period--;  //周期递减
        if(Period <= 0x0100) PWM1_Flag = 1;
    }
    UpdatePwm();        //设置周期、占空比
}

/******************* PWM中断函数 ********************/
//void PWMA_ISR() interrupt 26
//{
//    if(PWMA_SR1 & 0X01)
//    {
//        PWMA_SR1 &=~0X01;    //清标志位
//    }
//}

//========================================================================
// 函数: UpdatePwm(void)
// 描述: 更新PWM周期占空比.
// 参数: none.
// 返回: none.
// 版本: V1.0, 2012-11-22
//========================================================================
void UpdatePwm(void)
{
    PWMA_ARRH = (u8)(Period >> 8); //设置周期时间
    PWMA_ARRL = (u8)Period;
    PWMA_CCR1H = (u8)((Period >> 1) >> 8); //设置占空比时间: Period/2
    PWMA_CCR1L = (u8)((Period >> 1));
       
       
                                WritePWMA((char)&PWMA_CCER1, 0x00);
                        WritePWMA((char)&PWMA_CCMR1, 0x00); //CC1 为输出模式
                        WritePWMA((char)&PWMA_CCMR1, 0x60); //OC1REF 输出 PWM1(CNT<CCR 时输出有效电平 1)
                        WritePWMA((char)&PWMA_CCER1, 0x05); //使能 CC1/CC1N 上的输出功能
                        WritePWMA((char)&PWMA_ENO, 0x03); //使能 PWM 信号输出到端口
                        WritePWMA((char)&PWMA_BKR, 0x80); //使能主输出
                        //WritePWMA((char)&PWMA_CCR1H, (70>>1) >> 8); //设置输出 PWM 的占空比
                        //WritePWMA((char)&PWMA_CCR1L, (70>>1));
                        //WritePWMA((char)&PWMA_ARRH, 70 >> 8);//WritePWMA((char)&PWMA_ARRH, 1000 >> 8); //设置输出 PWM 的周期
                        //WritePWMA((char)&PWMA_ARRL, 70);//WritePWMA((char)&PWMA_ARRL, 1000);
                        WritePWMA((char)&PWMA_DTR, 10); //设置互补对称输出 PWM 的死区
                        WritePWMA((char)&PWMA_CR1, 0x01); //开始 PWM 计数
}

执行后P1.0怎么一点反应都没有

回复

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:410
  • 最近打卡:2026-07-21 09:39:09

83

主题

7972

回帖

1万

积分

超级版主

积分
17025
发表于 2026-7-8 16:42:43 | 显示全部楼层
请下载下面的例程包,测试01B或02B就是HSPWM的。

STC32G-高级PWM范例程序下载
https://www.stcaimcu.com/thread-1778-1-1.html
(出处: 国芯人工智能技术交流网站)
回复

使用道具 举报 送花

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2026-7-22 10:32 , Processed in 0.068302 second(s), 46 queries .

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表