zhp
发表于 2023-6-13 20:09:17
250MHz时钟源 PWM,STC32F12K54-56MHz
——高速PWM应用1:高速PWM输出
——高速PWM应用2:捕获外部高速脉宽(查询方式)
——高速PWM应用3:捕获外部高速脉宽(中断方式)
高速PWM应用2: 捕获外部高速脉宽(查询方式)
高速PWM可使用内建500MHz高速HPLL作为时钟源【输出高速PWM】/【捕获外部高速脉宽】
(注:500MHz的HPLL时钟2分频输出50%占空比的PLL输出时钟可作为高速PWM的时钟源)
/*************功能说明 **************
时钟说明:由内部IRC产生24MHz的时钟分频为6M提供给HPLL当作HPLL输入时钟,PLL锁频到246MHz输出作为高速PWM的时钟源,
PWM高速输出说明:PWMA的CC1通道配置为输出模式,并从P2.0口输出频率为24.6MHz,占空比为20%的PWM型号
PWM高速捕获说明:PWMB的CC5和CC6通道配置为捕获输入模式,CC5口P2.0口捕获信号的周期值,CC6从P2.0口捕获信号的占空比
测试说明:最后通过查询方式得到周期值和占空比并从串口送到PC显示
下载时, 选择默认IRC时钟 24MHz。
******************************************/
#include "stc32g.h"
#include "stdio.h"
#define FOSC 24000000UL
#define BAUD (65536 - FOSC/4/115200)
#define HSCK_MCLK 0
#define HSCK_PLL 1
#define HSCK_SEL HSCK_PLL
#define HSIOCK 0x40
#define ENHPLL 0x80
#define HPLLDIV_52 0x00
#define HPLLDIV_54 0x01
#define HPLLDIV_56 0x02
#define HPLLDIV_58 0x03
#define HPLLDIV_60 0x04
#define HPLLDIV_62 0x05
#define HPLLDIV_64 0x06
#define HPLLDIV_66 0x07
#define HPLLDIV_68 0x08
#define HPLLDIV_70 0x09
#define HPLLDIV_72 0x0A
#define HPLLDIV_74 0x0B
#define HPLLDIV_76 0x0C
#define HPLLDIV_78 0x0D
#define HPLLDIV_80 0x0E
#define HPLLDIV_82 0x0F
#define ENCKM 0x80
#define PCKI_MSK 0x60
#define PCKI_D1 0x00
#define PCKI_D2 0x20
#define PCKI_D4 0x40
#define PCKI_D8 0x60
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_ADDR寄存器的最高位写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_ADDR寄存器的最高位写0,表示写数据
}
char ReadPWMB(char addr)
{
char dat;
while (HSPWMB_ADR & 0x80); //等待前一个异步读写完成
HSPWMB_ADR = addr | 0x80; //设置间接访问地址,只需要设置原XFR地址的低7位
//HSPWMB_ADDR寄存器的最高位写1,表示读数据
while (HSPWMB_ADR & 0x80); //等待当前异步读取完成
dat = HSPWMB_DAT; //读取异步数据
return dat;
}
void WritePWMB(char addr, char dat)
{
while (HSPWMB_ADR & 0x80); //等待前一个异步读写完成
HSPWMB_DAT = dat; //准备需要写入的数据
HSPWMB_ADR = addr & 0x7f; //设置间接访问地址,只需要设置原XFR地址的低7位
//HSPWMB_ADDR寄存器的最高位写0,表示写数据
}
int main()
{
EAXFR = 1;
P0M0 = 0; P0M1 = 0;
P1M0 = 0; P1M1 = 0;
P2M0 = 0; P2M1 = 0;
P3M0 = 0; P3M1 = 0;
P4M0 = 0; P4M1 = 0;
P5M0 = 0; P5M1 = 0;
SCON = 0x52;
AUXR = 0x40;
TMOD = 0x00;
TL1 = BAUD;
TH1 = BAUD >> 8;
TR1 = 1;
//选择HPLL输入时钟分频,保证输入时钟为6M
USBCLK &= ~PCKI_MSK;
#if (FOSC == 6000000UL)
USBCLK |= PCKI_D1; //PLL输入时钟1分频
#elif (FOSC == 12000000UL)
USBCLK |= PCKI_D2; //PLL输入时钟2分频
#elif (FOSC == 24000000UL)
USBCLK |= PCKI_D4; //PLL输入时钟4分频
#elif (FOSC == 48000000UL)
USBCLK |= PCKI_D8; //PLL输入时钟8分频
#else
USBCLK |= PCKI_D4; //默认PLL输入时钟4分频
#endif
//设置HPLL的除频系数
// HPLLCR = HPLLDIV_52; //F_HPLL=6M*52/2=156M
// HPLLCR = HPLLDIV_54; //F_HPLL=6M*54/2=162M
// HPLLCR = HPLLDIV_56; //F_HPLL=6M*56/2=168M
// HPLLCR = HPLLDIV_58; //F_HPLL=6M*58/2=174M
// HPLLCR = HPLLDIV_60; //F_HPLL=6M*60/2=180M
// HPLLCR = HPLLDIV_62; //F_HPLL=6M*62/2=186M
// HPLLCR = HPLLDIV_64; //F_HPLL=6M*64/2=192M
// HPLLCR = HPLLDIV_66; //F_HPLL=6M*66/2=198M
// HPLLCR = HPLLDIV_68; //F_HPLL=6M*68/2=204M
// HPLLCR = HPLLDIV_70; //F_HPLL=6M*70/2=210M
// HPLLCR = HPLLDIV_72; //F_HPLL=6M*72/2=216M
// HPLLCR = HPLLDIV_74; //F_HPLL=6M*74/2=222M
// HPLLCR = HPLLDIV_76; //F_HPLL=6M*76/2=228M
// HPLLCR = HPLLDIV_78; //F_HPLL=6M*78/2=234M
// HPLLCR = HPLLDIV_80; //F_HPLL=6M*80/2=240M
HPLLCR = HPLLDIV_82; //F_HPLL=6M*82/2=246M
//启动HPLL
HPLLCR |= ENHPLL; //使能HPLL
delay(); //等待HPLL时钟稳定
//选择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
HSCLKDIV = 0; //HSPWM/HSSPI时钟源不分频
HSPWMA_CFG = 0x03; //使能PWMA相关寄存器异步访问功能
HSPWMA_CFG = 0x03; //使能PWMA相关寄存器异步访问功能
HSPWMB_CFG = 0x03; //使能PWMB相关寄存器异步访问功能
PWMA_PS = 0x01; //PWMA_CC1高速PWM输出到P2.0口
//PWMB_CC5/PWMB_CC6从P2.0口进行捕获
//注意:PWMA_PS和PWMB_PS属于I/O控制寄存器,不能使用异步方式进行读写
//通过异步方式设置PWMA/PWMB的相关寄存器
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, 0x01); //使能PWM信号输出到端口
WritePWMA((char)&PWMA_BKR, 0x80); //使能主输出
WritePWMA((char)&PWMA_CCR1H, 0x00); //设置输出PWM的占空比
WritePWMA((char)&PWMA_CCR1L, 0x02);
WritePWMA((char)&PWMA_ARRH, 0x00); //设置输出PWM的周期
WritePWMA((char)&PWMA_ARRL, 0x09);
WritePWMA((char)&PWMA_CR1, 0x01); //开始PWM计数
WritePWMB((char)&PWMB_CCER1, 0x00);
WritePWMB((char)&PWMB_CCMR1, 0x01); //CC5为输入模式,且映射到TI5FP5上
WritePWMB((char)&PWMB_CCMR2, 0x02); //CC6为输入模式,且映射到TI6FP5上
WritePWMB((char)&PWMB_CCER1, 0x31); //使能CC5上的捕获功能(上升沿捕获)
WritePWMB((char)&PWMB_SMCR, 0x54); //上升沿复位模式
WritePWMB((char)&PWMB_CR1, 0x01); //开始PWM计数
while (1)
{
if (ReadPWMB((char)&PWMB_SR1) & 0x02) //等待捕获完成
{
WritePWMB((char)&PWMB_SR1, 0x00); //清除完成标志
//读取捕获到的周期值
printf("%02x", (unsigned int)ReadPWMB((char)&PWMB_CCR5H) & 0xff);
printf("%02x", (unsigned int)ReadPWMB((char)&PWMB_CCR5L) & 0xff);
printf(" ");
//读取捕获到的占空比值
printf("%02x", (unsigned int)ReadPWMB((char)&PWMB_CCR6H) & 0xff);
printf("%02x", (unsigned int)ReadPWMB((char)&PWMB_CCR6L) & 0xff);
printf("\n");
}
}
}
zhp
发表于 2023-6-13 20:15:33
250MHz时钟源 PWM,STC32F12K54-56MHz
——高速PWM应用1:高速PWM输出
——高速PWM应用2:捕获外部高速脉宽(查询方式)
——高速PWM应用3:捕获外部高速脉宽(中断方式)
高速PWM应用3: 捕获外部高速脉宽(中断方式)
高速PWM可使用内建500MHz高速HPLL作为时钟源【输出高速PWM】/【捕获外部高速脉宽】
(注:500MHz的HPLL时钟2分频输出50%占空比的PLL输出时钟可作为高速PWM的时钟源)
/*************功能说明 **************
时钟说明:由内部IRC产生24MHz的时钟分频为6M提供给HPLL当作HPLL输入时钟,PLL锁频到246MHz输出作为高速PWM的时钟源,
PWM高速输出说明:PWMA的CC1通道配置为输出模式,并从P2.0口输出频率为24.6MHz,占空比为20%的PWM型号
PWM高速捕获说明:PWMB的CC5和CC6通道配置为捕获输入模式,CC5口P2.0口捕获信号的周期值,CC6从P2.0口捕获信号的占空比
测试说明:最后通过中断方式得到周期值和占空比并从串口送到PC显示(注意要避免中断与主循环同时调用相同函数)
下载时, 选择默认IRC时钟 24MHz。
******************************************/
#include "stc32g.h"
#include "stdio.h"
#define FOSC 24000000UL
#define BAUD (65536 - FOSC/4/115200)
#define HSCK_MCLK 0
#define HSCK_PLL 1
#define HSCK_SEL HSCK_PLL
#define HSIOCK 0x40
#define ENHPLL 0x80
#define HPLLDIV_52 0x00
#define HPLLDIV_54 0x01
#define HPLLDIV_56 0x02
#define HPLLDIV_58 0x03
#define HPLLDIV_60 0x04
#define HPLLDIV_62 0x05
#define HPLLDIV_64 0x06
#define HPLLDIV_66 0x07
#define HPLLDIV_68 0x08
#define HPLLDIV_70 0x09
#define HPLLDIV_72 0x0A
#define HPLLDIV_74 0x0B
#define HPLLDIV_76 0x0C
#define HPLLDIV_78 0x0D
#define HPLLDIV_80 0x0E
#define HPLLDIV_82 0x0F
#define ENCKM 0x80
#define PCKI_MSK 0x60
#define PCKI_D1 0x00
#define PCKI_D2 0x20
#define PCKI_D4 0x40
#define PCKI_D8 0x60
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_ADDR寄存器的最高位写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_ADDR寄存器的最高位写0,表示写数据
}
char ReadPWMB(char addr)
{
char dat;
while (HSPWMB_ADR & 0x80); //等待前一个异步读写完成
HSPWMB_ADR = addr | 0x80; //设置间接访问地址,只需要设置原XFR地址的低7位
//HSPWMB_ADDR寄存器的最高位写1,表示读数据
while (HSPWMB_ADR & 0x80); //等待当前异步读取完成
dat = HSPWMB_DAT; //读取异步数据
return dat;
}
void WritePWMB(char addr, char dat)
{
while (HSPWMB_ADR & 0x80); //等待前一个异步读写完成
HSPWMB_DAT = dat; //准备需要写入的数据
HSPWMB_ADR = addr & 0x7f; //设置间接访问地址,只需要设置原XFR地址的低7位
//HSPWMB_ADDR寄存器的最高位写0,表示写数据
}
int main()
{
EAXFR = 1;
P0M0 = 0; P0M1 = 0;
P1M0 = 0; P1M1 = 0;
P2M0 = 0; P2M1 = 0;
P3M0 = 0; P3M1 = 0;
P4M0 = 0; P4M1 = 0;
P5M0 = 0; P5M1 = 0;
SCON = 0x52;
AUXR = 0x40;
TMOD = 0x00;
TL1 = BAUD;
TH1 = BAUD >> 8;
TR1 = 1;
//选择HPLL输入时钟分频,保证输入时钟为6M
USBCLK &= ~PCKI_MSK;
#if (FOSC == 6000000UL)
USBCLK |= PCKI_D1; //PLL输入时钟1分频
#elif (FOSC == 12000000UL)
USBCLK |= PCKI_D2; //PLL输入时钟2分频
#elif (FOSC == 24000000UL)
USBCLK |= PCKI_D4; //PLL输入时钟4分频
#elif (FOSC == 48000000UL)
USBCLK |= PCKI_D8; //PLL输入时钟8分频
#else
USBCLK |= PCKI_D4; //默认PLL输入时钟4分频
#endif
//设置HPLL的除频系数
// HPLLCR = HPLLDIV_52; //F_HPLL=6M*52/2=156M
// HPLLCR = HPLLDIV_54; //F_HPLL=6M*54/2=162M
// HPLLCR = HPLLDIV_56; //F_HPLL=6M*56/2=168M
// HPLLCR = HPLLDIV_58; //F_HPLL=6M*58/2=174M
// HPLLCR = HPLLDIV_60; //F_HPLL=6M*60/2=180M
// HPLLCR = HPLLDIV_62; //F_HPLL=6M*62/2=186M
// HPLLCR = HPLLDIV_64; //F_HPLL=6M*64/2=192M
// HPLLCR = HPLLDIV_66; //F_HPLL=6M*66/2=198M
// HPLLCR = HPLLDIV_68; //F_HPLL=6M*68/2=204M
// HPLLCR = HPLLDIV_70; //F_HPLL=6M*70/2=210M
// HPLLCR = HPLLDIV_72; //F_HPLL=6M*72/2=216M
// HPLLCR = HPLLDIV_74; //F_HPLL=6M*74/2=222M
// HPLLCR = HPLLDIV_76; //F_HPLL=6M*76/2=228M
// HPLLCR = HPLLDIV_78; //F_HPLL=6M*78/2=234M
// HPLLCR = HPLLDIV_80; //F_HPLL=6M*80/2=240M
HPLLCR = HPLLDIV_82; //F_HPLL=6M*82/2=246M
//启动HPLL
HPLLCR |= ENHPLL; //使能HPLL
delay(); //等待HPLL时钟稳定
//选择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
HSCLKDIV = 0; //HSPWM/HSSPI时钟源不分频
HSPWMA_CFG = 0x03; //使能PWMA相关寄存器异步访问功能
HSPWMB_CFG = 0x07; //使能PWMB相关寄存器异步访问功能,并使能异步模式的PWMB中断
PWMA_PS = 0x01; //PWMA_CC1高速PWM输出到P2.0口
//PWMB_CC5/PWMB_CC6从P2.0口进行捕获
//注意:PWMA_PS和PWMB_PS属于I/O控制寄存器,不能使用异步方式进行读写
//通过异步方式设置PWMA/PWMB的相关寄存器
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, 0x01); //使能PWM信号输出到端口
WritePWMA((char)&PWMA_BKR, 0x80); //使能主输出
WritePWMA((char)&PWMA_CCR1H, 0x00); //设置输出PWM的占空比
WritePWMA((char)&PWMA_CCR1L, 0x02);
WritePWMA((char)&PWMA_ARRH, 0x00); //设置输出PWM的周期
WritePWMA((char)&PWMA_ARRL, 0x09);
WritePWMA((char)&PWMA_CR1, 0x01); //开始PWM计数
WritePWMB((char)&PWMB_CCER1, 0x00);
WritePWMB((char)&PWMB_CCMR1, 0x01); //CC5为输入模式,且映射到TI5FP5上
WritePWMB((char)&PWMB_CCMR2, 0x02); //CC6为输入模式,且映射到TI6FP5上
WritePWMB((char)&PWMB_CCER1, 0x31); //使能CC5上的捕获功能(上升沿捕获)
WritePWMB((char)&PWMB_SMCR, 0x54); //上升沿复位模式
WritePWMB((char)&PWMB_CR1, 0x01); //开始PWM计数
WritePWMB((char)&PWMB_IER, 0x02); //使能CC5捕获中断
EA = 1;
while (1);
}
void PWMB_ISR() interrupt 27
{
if (ReadPWMB((char)&PWMB_SR1) & 0x02) //等待捕获完成
{
WritePWMB((char)&PWMB_SR1, 0x00); //清除完成标志
//读取捕获到的周期值
printf("%02x", (unsigned int)ReadPWMB((char)&PWMB_CCR5H) & 0xff);
printf("%02x", (unsigned int)ReadPWMB((char)&PWMB_CCR5L) & 0xff);
printf(" ");
//读取捕获到的占空比值
printf("%02x", (unsigned int)ReadPWMB((char)&PWMB_CCR6H) & 0xff);
printf("%02x", (unsigned int)ReadPWMB((char)&PWMB_CCR6L) & 0xff);
printf("\n");
}
}
zhp
发表于 2023-6-14 09:59:03
307MHz时钟源 PWM, STC32F12K54-56MHz
——高速PWM应用1:高速PWM输出
——高速PWM应用2:捕获外部高速脉宽(查询方式)
——高速PWM应用3:捕获外部高速脉宽(中断方式)
高速PWM应用1: 高速PWM输出(CPU工作频率60MHz+ICache)
高速PWM可使用内建500MHz高速HPLL作为时钟源【输出高速PWM】/【捕获外部高速脉宽】
(特别的:高速HPLL时钟输入范围6M~12M。本范例高速HPLL输入频率为7.5MHz,
产生615MHz的HPLL时钟2分频输出50%占空比的PLL输出频率307.5MHz可作为高速PWM的时钟源)
/*************功能说明 **************
时钟说明:由内部IRC产生60MHz的时钟当作CPU时钟,同时8分频产生7.5M提供给HPLL
当作HPLL输入时钟,PLL锁频到307.5MHz输出作为高速PWM的时钟源,
PWM高速输出说明:PWMA的CC1通道配置为输出模式,并从P1.0/P1.1口输出频率为3.705MHz,
占空比为50%的互补对称带死区的PWM波形
CPU时钟说明:ISP下载软件根据CPU工作频率为60MHz,会自动将WTST设置为2
用户代码中不用对WTST进行设置。范例中使能了ICACHE功能,
可有效的提高代码执行效率
下载时, 选择默认IRC时钟 60MHz。
******************************************/
#include "stc32g.h"
#define FOSC 60000000UL
#define HSCK_MCLK 0
#define HSCK_PLL 1
#define HSCK_SEL HSCK_PLL
#define HSIOCK 0x40
#define ENHPLL 0x80
#define HPLLDIV_52 0x00
#define HPLLDIV_54 0x01
#define HPLLDIV_56 0x02
#define HPLLDIV_58 0x03
#define HPLLDIV_60 0x04
#define HPLLDIV_62 0x05
#define HPLLDIV_64 0x06
#define HPLLDIV_66 0x07
#define HPLLDIV_68 0x08
#define HPLLDIV_70 0x09
#define HPLLDIV_72 0x0A
#define HPLLDIV_74 0x0B
#define HPLLDIV_76 0x0C
#define HPLLDIV_78 0x0D
#define HPLLDIV_80 0x0E
#define HPLLDIV_82 0x0F
#define ENCKM 0x80
#define PCKI_MSK 0x60
#define PCKI_D1 0x00
#define PCKI_D2 0x20
#define PCKI_D4 0x40
#define PCKI_D8 0x60
void delay()
{
int i;
for (i=0; i<100; i++);
}
void ICacheOn()
{
bit fEA;
if (WTST > 0) //WTST为0时不需要且不能使能ICACHE
{
fEA = EA; //保存EA
EA = 0; //关闭中断
_nop_();
_nop_();
TA = 0xaa; //写入触发命令序列1
//此处不能有其他任何指令
TA = 0x55; //写入触发命令序列2
//此处不能有其他任何指令
ICHECR = 0x01; //写保护暂时关闭,可以修改ICHECR中的EN位
//EN位再次进入写保护状态
_nop_();
_nop_();
EA = fEA; //恢复EA
}
}
char ReadPWMA(char addr)
{
char dat;
while (HSPWMA_ADR & 0x80); //等待前一个异步读写完成
HSPWMA_ADR = addr | 0x80; //设置间接访问地址,只需要设置原XFR地址的低7位
//HSPWMA_ADDR寄存器的最高位写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_ADDR寄存器的最高位写0,表示写数据
}
int main()
{
ICacheOn(); //使能ICACHE功能
EAXFR = 1;
P0M0 = 0; P0M1 = 0;
P1M0 = 0; P1M1 = 0;
P2M0 = 0; P2M1 = 0;
P3M0 = 0; P3M1 = 0;
P4M0 = 0; P4M1 = 0;
P5M0 = 0; P5M1 = 0;
//选择HPLL输入时钟分频
USBCLK &= ~PCKI_MSK;
USBCLK |= PCKI_D8; //PLL输入时钟8分频
//设置HPLL的除频系数
HPLLCR = HPLLDIV_82; //F_HPLL=60M/8*82/2=307.5M
//启动HPLL
HPLLCR |= ENHPLL; //使能HPLL
delay(); //等待HPLL时钟稳定
//选择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
HSCLKDIV = 0; //HSPWM/HSSPI时钟源不分频
HSPWMA_CFG = 0x03; //使能PWMA相关寄存器异步访问功能
PWMA_PS = 0x00; //PWMA_CC1/CC1N高速PWM输出到CC1/CC1N口
//注意:PWMA_PS属于I/O控制寄存器,不能使用异步方式进行读写
//通过异步方式设置PWMA的相关寄存器
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信号输出到端口P1.0/P1.1
WritePWMA((char)&PWMA_BKR, 0x80); //使能主输出
WritePWMA((char)&PWMA_CCR1H, 0); //设置PWM占空比为50个PWM时钟
WritePWMA((char)&PWMA_CCR1L, 50);
WritePWMA((char)&PWMA_ARRH, 0); //设置输出PWM的周期为100个PWM时钟
WritePWMA((char)&PWMA_ARRL, 99);
WritePWMA((char)&PWMA_DTR, 10); //设置互补对称输出PWM的死区
WritePWMA((char)&PWMA_CR1, 0x01); //开始PWM计数
//P2 = ReadPWMA((char)&PWMA_ARRH); //异步方式读取寄存器
//P0 = ReadPWMA((char)&PWMA_ARRL);
while (1);
}
神农鼎
发表于 2023-6-14 16:56:33
HPLL的输入频率确实比我们原始定的规格【6~12M】的范围要宽,【2~16M】都可以
HPLL输出频率超过700M/2,也就是PWM输入时钟超过350M,测试4个样品均输出正常
HPLL输出频率超过800M/2,也就是PWM输入时钟超过400M,测试4个样品,两个样品PWM无输出
这 500MHz/2 后占空比是50% 的250MHz PWM时钟
==搞音频PWM发声,这个250MHz 的PWM时钟源因该很舒服了 !
16位PWM 当16位用,当10位用,当8位用,当2~16位用
16位PWM当8位用的PWM最高频率
https://www.stcaimcu.com/data/attachment/forum/202306/19/135245va7h529y8ryi02az.png
16位PWM当10位用的PWM最高频率
https://www.stcaimcu.com/data/attachment/forum/202306/19/135245gbxskr8rrlgrrbbj.png
16位PWM当16位用的PWM最高频率
https://www.stcaimcu.com/data/attachment/forum/202306/19/135245novl9eywyouwzz94.png
asxddz
发表于 2023-6-15 06:41:04
模拟DAC精度如何呢
神农鼎
发表于 2023-6-15 06:59:21
asxddz 发表于 2023-6-15 06:41
模拟DAC精度如何呢PWM模拟DAC的实际效果,取决于你实际测量他的ADC电路,
用这个ADC来检测反馈控制,高了就调低,低了就调高 !!!
信号发生器演示视频,STC32G12K128实验箱,老梁示波器 - STC 实验箱/核心功能实验板,原理图,MCU结构讨论区,大学教材 - 国芯论坛-STC全球32位8051爱好者互助交流社区 - STC全球32位8051爱好者互助交流社区 (stcaimcu.com)
jmg
发表于 2023-6-16 07:24:55
asxddz 发表于 2023-6-15 06:41
模拟DAC精度如何呢
PWM DAC's are very precise, because they are timing-determined.
Their drawback is the PWM needs to be filtered to give a varying analog value.
One trade off possible is to use two PWM pins and two resistors for faster updates.
Example if you use two 6 bit PWM and 10k and 640K resistors, you can output 4096 steps (12 bits) with faster PWM of SysCLK/64, which is more easily filtered externally.
The numbers given above of 250MHz and 307.5MHz PWM clocks, would give 3.90625MHz and 4.8046875MHz PWMs, for 2 x 6 bit, which can be easily filtered to give about 100kHz+ DAC performance.
神农鼎
发表于 2023-6-19 14:03:16
STC32F12K54-56MHz-LQFP48,7500片已到,全球发售,【免费+包邮】 送 !
另有 3万片途中,确保 全国大学生电子设计竞赛,全部大学生智能车竞赛
HPLL的输入频率确实比我们原始定的规格【6~12M】的范围要宽,【2~16M】都可以
HPLL输出频率超过700M/2,也就是PWM输入时钟超过350M,测试4个样品均输出正常
HPLL输出频率超过800M/2,也就是PWM输入时钟超过400M,测试4个样品,两个样品PWM无输出
这 500MHz/2 后占空比是50% 的250MHz PWM时钟
==搞音频PWM发声,这个250MHz 的PWM时钟源因该很舒服了 !
16位PWM 当16位用,当10位用,当8位用,当2~16位用
16位PWM当8位用的PWM最高频率
https://www.stcaimcu.com/data/attachment/forum/202306/19/135245va7h529y8ryi02az.png
16位PWM当10位用的PWM最高频率
https://www.stcaimcu.com/data/attachment/forum/202306/19/135245gbxskr8rrlgrrbbj.png
16位PWM当16位用的PWM最高频率
https://www.stcaimcu.com/data/attachment/forum/202306/19/135245novl9eywyouwzz94.png
马永锋
发表于 2023-6-20 15:41:09
购买的追风剑到货,发现引脚没有标注,使用起来找引脚就得半天。
WHX
发表于 2023-6-21 08:42:32
STC32F12K54-56MHz-LQFP48,8000片已到,【免费+包邮送】,是真的吗?
不会还是只针对全国大赛才供货吧?看来我们公司产品上面也该采用这款芯片了!
我目前尚在使用STC32G12K128——TSSOP-20的在开发中》。。。