- 打卡等级:初来乍到
- 打卡总天数:4
- 最近打卡:2026-07-15 15:02:39
已绑定手机
新手上路
- 积分
- 41
|
//测试工作频率为 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怎么一点反应都没有
|
|