主要特性
時(shí)基單元
16位PWMA_ARR寄存器的寫(xiě)操作
預(yù)分頻器
PWM模式
PWM邊沿對(duì)齊模式
寄存器描述
輸出使能寄存器(PWMx_ENO)
功能實(shí)現(xiàn)說(shuō)明:
通過(guò)定時(shí)器遞增或遞減來(lái)設(shè)置PWM的占空比調(diào)節(jié)亮度,最終顯示出呼吸燈的效果
代碼部分
PWM程序模塊
#ifndef _PWM_H_
#define _PWM_H_
#include "GPIO.h"
#define PWM1_CCMR1_ADDR 0xfec8 //CCMR2_ADDR = CCMR1_ADDR + 1
#define PWM1_CCR1_ADDR 0xfed5 //CCR2_ADDR = CCR1_ADDR + 2
#define PWM1_CCER1_ADDR 0xfecc //CCER2_ADDR = CCER1_ADDR + 1
#define PWM2_CCMR1_ADDR 0xfee8 //CCMR2_ADDR = CCMR1_ADDR + 1
#define PWM2_CCR1_ADDR 0xfef5 //CCR2_ADDR = CCR1_ADDR + 2
#define PWM2_CCER1_ADDR 0xfeec //CCER2_ADDR = CCER1_ADDR + 1
typedef enum
{
PWM1P_P10 = 0x00, PWM1N_P11,
PWM1P_P20, PWM1N_P21,
PWM1P_P60, PWM1N_P61,
PWM2P_P12 = 0x10, PWM2N_P13,
PWM2P_P22, PWM2N_P23,
PWM2P_P62, PWM2N_P63,
PWM3P_P14 = 0x20, PWM3N_P15,
PWM3P_P24, PWM3N_P25,
PWM3P_P64, PWM3N_P65,
PWM4P_P16 = 0x30, PWM4N_P17,
PWM4P_P26, PWM4N_P27,
PWM4P_P66, PWM4N_P67,
PWM4P_P34, PWM4N_P33,
PWM5_P20 = 0x40,
PWM5_P17,
PWM5_P00,
PWM5_P74,
PWM6_P21 = 0x50,
PWM6_P54,
PWM6_P01,
PWM6_P75,
PWM7_P22 = 0x60,
PWM7_P33,
PWM7_P02,
PWM7_P76,
PWM8_P23 = 0x70,
PWM8_P34,
PWM8_P03,
PWM8_P77,
}PWM_CH;
//-------------------------------------------------------------------------------------------------------------------
// @brief PWM_gpio配置
// @param pwmch PWM通道
// @return void
// Sample usage:
//-------------------------------------------------------------------------------------------------------------------
void pwm_set_gpio(PWM_CH pwmch)
{
switch (pwmch)
{
case PWM1P_P10:
{
pinMode(P10, GPIO_PP);
break;
}
case PWM1N_P11:
{
pinMode(P11, GPIO_PP);
break;
}
case PWM1P_P20:
{
pinMode(P20, GPIO_PP);
break;
}
case PWM1N_P21:
{
pinMode(P21, GPIO_PP);
break;
}
case PWM1P_P60:
{
pinMode(P60, GPIO_PP);
break;
}
case PWM1N_P61:
{
pinMode(P61, GPIO_PP);
break;
}
case PWM2P_P12:
{
pinMode(P12, GPIO_PP);
break;
}
case PWM2N_P13:
{
pinMode(P13, GPIO_PP);
break;
}
case PWM2P_P22:
{
pinMode(P22, GPIO_PP);
break;
}
case PWM2N_P23:
{
pinMode(P23, GPIO_PP);
break;
}
case PWM2P_P62:
{
pinMode(P62, GPIO_PP);
break;
}
case PWM2N_P63:
{
pinMode(P63, GPIO_PP);
break;
}
case PWM3P_P14:
{
pinMode(P14, GPIO_PP);
break;
}
case PWM3N_P15:
{
pinMode(P15, GPIO_PP);
break;
}
case PWM3P_P24:
{
pinMode(P24, GPIO_PP);
break;
}
case PWM3N_P25:
{
pinMode(P25, GPIO_PP);
break;
}
case PWM3P_P64:
{
pinMode(P64, GPIO_PP);
break;
}
case PWM3N_P65:
{
pinMode(P65, GPIO_PP);
break;
}
case PWM4P_P16:
{
pinMode(P16, GPIO_PP);
break;
}
case PWM4N_P17:
{
pinMode(P17, GPIO_PP);
break;
}
case PWM4P_P26:
{
pinMode(P26, GPIO_PP);
break;
}
case PWM4N_P27:
{
pinMode(P27, GPIO_PP);
break;
}
case PWM4P_P66:
{
pinMode(P66, GPIO_PP);
break;
}
case PWM4N_P67:
{
pinMode(P67, GPIO_PP);
break;
}
case PWM4P_P34:
{
pinMode(P34, GPIO_PP);
break;
}
case PWM4N_P33:
{
pinMode(P33, GPIO_PP);
break;
}
case PWM5_P20:
{
pinMode(P20, GPIO_PP);
break;
}
case PWM5_P17:
{
pinMode(P17, GPIO_PP);
break;
}
case PWM5_P00:
{
pinMode(P00, GPIO_PP);
break;
}
case PWM5_P74:
{
pinMode(P74, GPIO_PP);
break;
}
case PWM6_P21:
{
pinMode(P21, GPIO_PP);
break;
}
case PWM6_P54:
{
pinMode(P54, GPIO_PP);
break;
}
case PWM6_P01:
{
pinMode(P01, GPIO_PP);
break;
}
case PWM6_P75:
{
pinMode(P75, GPIO_PP);
break;
}
case PWM7_P22:
{
pinMode(P22, GPIO_PP);
break;
}
case PWM7_P33:
{
pinMode(P33, GPIO_PP);
break;
}
case PWM7_P02:
{
pinMode(P02, GPIO_PP);
break;
}
case PWM7_P76:
{
pinMode(P76, GPIO_PP);
break;
}
case PWM8_P23:
{
pinMode(P23, GPIO_PP);
break;
}
case PWM8_P34:
{
pinMode(P34, GPIO_PP);
break;
}
case PWM8_P03:
{
pinMode(P03, GPIO_PP);
break;
}
case PWM8_P77:
{
pinMode(P77, GPIO_PP);
break;
}
}
}
//-------------------------------------------------------------------------------------------------------------------
// @brief PWM初始化
// @param pwmch PWM通道
// @param freq PWM頻率64Hz-3MHz)
// @param duty PWM占空比
// @return void
// Sample usage:
// pwm_init(PWM0_P00, 100, 5000); //通道PWM0 引腳P0.0 頻率100 占空比5000
// PWM_DUTY_MAX為10000
//-------------------------------------------------------------------------------------------------------------------
void pwm_init(PWM_CH pwmch, uint32 freq, uint16 duty)
{
uint16 match_temp;
uint16 period_temp;
uint16 freq_div = 0;
P_SW2 |= 0x80;
//GPIO端口配置
pwm_set_gpio(pwmch);
freq_div = ((uint32)(sys_clk / freq)) >> 16; //分頻
period_temp = (sys_clk / freq) / (freq_div + 1) - 1; //周期時(shí)間
match_temp = period_temp * ((float)duty / PWM_DUTY_MAX); //占空比
if (PWM5_P20 <= pwmch) //PWM5-8
{
PWM2_ENO |= (1 << ((2 * ((pwmch >> 4) - 4)))); //使能輸出
PWM2_PS |= ((pwmch & 0x03) << ((2 * ((pwmch >> 4) - 4)))); //輸出腳選擇
// 配置通道輸出使能和極性
(*(unsigned char volatile xdata*)(PWM2_CCER1_ADDR + (((pwmch >> 4) - 4) >> 1))) |= (1 << (((pwmch >> 4) & 0x01) * 4));
//通道模式配置
(*(unsigned char volatile xdata*)(PWM2_CCMR1_ADDR + ((pwmch >> 4) - 4))) |= 0x06 << 4; //
(*(unsigned char volatile xdata*)(PWM2_CCMR1_ADDR + ((pwmch >> 4) - 4))) |= 1 << 3; //PWM模式2
//設(shè)置周期時(shí)間(高字節(jié)先寫(xiě)入)
//PWM2_ARR = (uint16)period_temp;
PWM2_ARRH = period_temp >> 8;
PWM2_ARRL = period_temp;
//PWM2_ARR=2000;
//PWM預(yù)分頻(高字節(jié)先寫(xiě)入)
PWM2_PSCRH = freq_div >> 8;
PWM2_PSCRL = freq_div;
//設(shè)置占空比(高字節(jié)先寫(xiě)入)
(*(unsigned char volatile xdata*)(PWM2_CCR1_ADDR + 2 * ((pwmch >> 4) - 4))) = match_temp >> 8;
(*(unsigned char volatile xdata*)(PWM2_CCR1_ADDR + 2 * ((pwmch >> 4) - 4) + 1)) = match_temp;
PWM2_BKR = 0x80; //使能主輸出
PWM2_CR1 = 0x01; //PWM開(kāi)始計(jì)時(shí)
}
else
{
PWM1_ENO |= (1 << (pwmch & 0x01)) << ((pwmch >> 4) * 2); //使能輸出
PWM1_PS |= ((pwmch & 0x07) >> 1) << ((pwmch >> 4) * 2); //輸出腳選擇
// 配置通道輸出使能和極性
(*(unsigned char volatile xdata*)(PWM1_CCER1_ADDR + (pwmch >> 5))) |= (1 << ((pwmch & 0x01) * 2 + ((pwmch >> 4) & 0x01) * 0x04));
(*(unsigned char volatile xdata*)(PWM1_CCMR1_ADDR + (pwmch >> 4))) |= 0x06 << 4;
(*(unsigned char volatile xdata*)(PWM1_CCMR1_ADDR + (pwmch >> 4))) |= 1 << 3; //PWM模式2
//設(shè)置周期時(shí)間(高字節(jié)先寫(xiě)入)
//PWM1_ARR = period_temp;
PWM1_ARRH = period_temp >> 8;
PWM1_ARRL = period_temp;
//PWM預(yù)分頻(高字節(jié)先寫(xiě)入)
PWM1_PSCRH = freq_div >> 8;
PWM1_PSCRL = freq_div;
//設(shè)置占空比(高字節(jié)先寫(xiě)入)
(*(unsigned char volatile xdata*)(PWM1_CCR1_ADDR + 2 * (pwmch >> 4))) = match_temp >> 8;
(*(unsigned char volatile xdata*)(PWM1_CCR1_ADDR + 2 * (pwmch >> 4) + 1)) = match_temp;
PWM1_BKR = 0x80; //使能主輸出
PWM1_CR1 = 0x01; //PWM開(kāi)始計(jì)時(shí)
}
//P_SW2 &= 0x7F;
}
//-------------------------------------------------------------------------------------------------------------------
// @brief PWM調(diào)整占空比
// @param pwmch PWM引腳
// @param duty PWM占空比
// @return void
// Sample usage: pwm_duty(PWM0_P00, 5000); //通道PWM0 引腳P0.0 占空比5000
//
//-------------------------------------------------------------------------------------------------------------------
void pwm_duty(PWM_CH pwmch, uint16 duty)
{
uint16 match_temp;
// P_SW2 |= 0x80;
if (PWM5_P20 <= pwmch) //PWM5-8
{
match_temp = PWM2_ARRH;
match_temp = match_temp << 8;
match_temp = match_temp + PWM2_ARRL;
match_temp = match_temp * ((float)duty / PWM_DUTY_MAX); //占空比
(*(unsigned char volatile xdata*)(PWM2_CCR1_ADDR + 2 * ((pwmch >> 4) - 4))) = match_temp >> 8;
(*(unsigned char volatile xdata*)(PWM2_CCR1_ADDR + 2 * ((pwmch >> 4) - 4) + 1)) = match_temp;
}
else
{
match_temp = PWM1_ARRH;
match_temp = match_temp << 8;
match_temp = match_temp + PWM1_ARRL;
match_temp = match_temp *((float)duty / PWM_DUTY_MAX); //占空比
(*(unsigned char volatile xdata*)(PWM1_CCR1_ADDR + 2 * (pwmch >> 4))) = match_temp >> 8;
(*(unsigned char volatile xdata*)(PWM1_CCR1_ADDR + 2 * (pwmch >> 4) + 1)) = match_temp;
}
// P_SW2 &= ~0x80;
}
//-------------------------------------------------------------------------------------------------------------------
// @brief PWM調(diào)整頻率和占空比
// @param pwmch PWM通道
// @param freq PWM頻率
// @param duty PWM占空比
// @return void
// Sample usage: pwm_freq(PWM0_P00, 50, 5000); //通道PWM0 引腳P0.0 頻率50 占空比5000
//-------------------------------------------------------------------------------------------------------------------
void pwm_freq_duty(PWM_CH pwmch, uint16 freq, uint16 duty)
{
uint16 match_temp;
uint16 period_temp;
uint16 freq_div = 0;
freq_div = (sys_clk / freq) >> 15; //分頻
period_temp = sys_clk / freq / (freq_div + 1); //頻率
//match_temp = period_temp * duty;
//match_temp = match_temp / PWM_DUTY_MAX;
match_temp = period_temp * ((float)duty / PWM_DUTY_MAX); //占空比
// P_SW2 |= 0x80;
if (PWM5_P20 <= pwmch) //PWM5-8
{
//周期(高字節(jié)先寫(xiě)入)
//PWM2_ARR = (uint16)period_temp;
PWM2_ARRH = period_temp >> 8;
PWM2_ARRL = period_temp;
//PWM預(yù)分頻(高字節(jié)先寫(xiě)入)
PWM2_PSCRH = freq_div>>8;
PWM2_PSCRL = freq_div;
//占空比(高字節(jié)先寫(xiě)入)
//(*(unsigned int volatile xdata*)(PWM2_CCR1_ADDR + 2 * ((pwmch >> 4) - 4))) = match_temp;
(*(unsigned char volatile xdata*)(PWM2_CCR1_ADDR + 2 * ((pwmch >> 4) - 4))) = match_temp >> 8;
(*(unsigned char volatile xdata*)(PWM2_CCR1_ADDR + 2 * ((pwmch >> 4) - 4) + 1)) = match_temp;
}
else
{
//周期(高字節(jié)先寫(xiě)入)
//PWM2_ARR = (uint16)period_temp;
PWM1_ARRH = period_temp >> 8;
PWM1_ARRL = period_temp;
//PWM預(yù)分頻(高字節(jié)先寫(xiě)入)
PWM1_PSCR = freq_div;
//占空比(高字節(jié)先寫(xiě)入)
//(*(unsigned int volatile xdata*)(PWM1_CCR1_ADDR + 2 * (pwmch >> 4))) = match_temp;
(*(unsigned char volatile xdata*)(PWM1_CCR1_ADDR + 2 * (pwmch >> 4))) = match_temp >> 8;
(*(unsigned char volatile xdata*)(PWM1_CCR1_ADDR + 2 * (pwmch >> 4) + 1)) = match_temp;
}
// P_SW2 &= ~0x80;
}
#endif
主函數(shù)部分文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-519310.html
//pwm_LED初始化--------------
pwm_init(PWM4P_P16, 2000, 800);//pwm初始化三個(gè)參數(shù)分別是引腳、頻率、占空比10/PWM_DUTY_MAX
中斷部分文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-519310.html
//========================================================================
// 描述: 定時(shí)器控制呼吸燈計(jì)數(shù)和ADC與DAC數(shù)據(jù)對(duì)比
// 參數(shù): none.
// 返回: none.
//========================================================================
void T_IRQ0(void) interrupt 12 using 0{
if(coun_advance == 1){
counter = counter + 10;
if(counter == 1000){
coun_advance = 0;
coun_retreat = 1;
}
}
else{
if(coun_retreat == 1){
counter = counter - 10;
if(counter == 0){
coun_retreat = 0;
coun_advance = 1;
}
}
}
pwm_duty(PWM4P_P16, counter);//pwm調(diào)整三個(gè)參數(shù)分別是引腳、頻率、占空比10/PWM_DUTY_MAX
}
到了這里,關(guān)于STC8H_PWM制作呼吸燈的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!