stc8h单片机如何设置pwm频率

stc8h单片机如何设置pwm频率,第1张

首先,STC8H不需要外部晶振和外部复位,也可以外接。它的时钟4M-36M。和其它stc芯片的区别是它的运行速度够快,8路16位的高级pwm定时器,4路可以输出互补的脉冲信号,在用这个芯片的时候我发现手册上有些地方讲的不是太清楚,对照了32的手册才明白了原理,今天着重说一下高级定时器的那部分。     

STC8H 系列的单片机内部集成了 8 通道 16 位高级 PWM 定时器,分成两组周期可不同的 PWM,分别命名为 PWMA 和 PWMB可分别单独设置。第一组 PWM/PWMA 可配置成 4 组互补/对称/死区控制的 PWM 或捕捉外部信号,第二组 PWM/PWMB 可配置成 4 路 PWM 输出或捕捉外部信号。

pwmA可配置成输出比较,输入捕获以及pwm模式,pwm有边沿对齐以及中间对齐模式,可直接驱动一些小型的电机,在驱动一些小型的电机时一定要将相应的io口配成推挽输出在,不然驱动不起来,具体的原理就不写了,主要说一下主要寄存器以及主要模式的配置。

选择计数器时钟(内部、外部或者预分频器(PSCR)),我用的都是内部。

    预分频器看你想要输出的频率范围自己设置

2 将相应的数据写入 PWMA_ARR(设频率) 和 PWMA_CCRi (设占空比)寄存器中。频率=时钟/(PSCR+1)/(ARR+1)

3 如果要产生一个中断请求,设置 CCiIE 位,在中断判断SR1状态位,PWMA和PWMB不是一个中断号。

4 选择输出模式步骤:

1 设置 OCiM=011,在计数器与 CCRi 匹配时翻转 OCiM 管脚的输出

2 设置 OCiPE = 0,禁用预装载寄存器

3 设置 CCiP = 0,选择高电平为有效电平,开始输出高电平。

4 设置 CCiE = 1,使能输出

5 设置 PWMA_CR1 寄存器的 CEN 位来启动计数器。

输入捕获配置:

先设置PSCR,根据你的所测频率范围来设数据。设ARR一般为最大值

1选择有效输入端,设置 PWMA_CCMR1 寄存器中的 CC1S=01,此时通道被配置为输入,并且PWMA_CCR1 寄存器变为只读。

2 根据输入信号 TIi 的特点,可通过配置 PWMA_CCMR1 寄存器中的 IC1F 位来设置相应的输入滤波器的滤波时间。假设输入信号在最多 5 个时钟周期的时间内抖动,我们须配置滤波器的带宽长于 5 个时钟周期;因此我们可以连续采样 8 次,以确认在 TI1 上一次真实的边沿变换,即在PWMA_CCMR1 寄存器中写入 IC1F=0011,此时,只有连续采样到 8 个相同的 TI1 信号,信号才为有效(采样频率为 fMASTER)。

3 选择 TI1 通道的有效转换边沿,在 PWMA_CCER1 寄存器中写入 CC1P=0(上升沿)。

4 配置输入预分频器。在本例中,我们希望捕获发生在每一个有效的电平转换时刻,因此预分频器被禁止(写 PWMA_CCMR1 寄存器的 IC1PS=00)。

5 设置 PWMA_CCER1 寄存器的 CC1E=1,允许捕获计数器的值到捕获寄存器中。

6 如果需要,通过设置

PWMA_IER 寄存器中的 CC1IE 位允许相关中断请求。

7使能计数器设置 PWMA_CR1 寄存器的 CEN 位来启动计数器。

stc12c5410ad的pwm程序 就是进不去中断 CL不计数,PWM只要启动了就有中断。也就是说PWM是不支持中断的,

pca模块的时钟信号有:

T0的溢出率,

fosc/2,

fosc/12,

p34脚的输入时钟信号,

只要PWM模块启动了CR位,

就可以实现连续的输出脉冲,

只能调宽,

不支持中断(在PWM模式)。

PWM技术算不得很保密的技术,这里给出部分代码,以供参考:

for STC12C5628AD 系列

sfr CCON = 0xD8;

sbit CCF0 = CCON^0;

sbit CCF1 = CCON^1;

sbit CCF2 = CCON^2;

sbit CCF3 = CCON^3;

sbit CR = CCON^6;

sbit CF = CCON^7;

sfr CMOD = 0xD9;

sfr CL = 0xE9;

sfr CH = 0xF9;

sfr CCAPM0 = 0xDA;

sfr CCAP0L = 0xEA;

sfr CCAP0H = 0xFA;

sfr CCAPM1 = 0xDB;

sfr CCAP1L = 0xEB;

sfr CCAP1H = 0xFB;

sfr CCAPM2 = 0xDC;

sfr CCAP2L = 0xEC;

sfr CCAP2H = 0xFC;

sfr CCAPM3 = 0xDD;

sfr CCAP3L = 0xED;

sfr CCAP3H = 0xFD;

sfr PCAPWM0= 0xF2;

sfr PCAPWM1= 0xF3;

sfr PCAPWM2= 0xF4;

sfr PCAPWM3= 0xF5;

//PWM功能初始化

CCON = 0;

CL = 0;

CH = 0;

CMOD = 0x02; //Fosc/2 想降低频率改这里

CCAPM0 = 0x42; //作8位PWM脉宽调节输出 P37

CCAPM1 = 0x42; //作8位PWM脉宽调节输出 P35

CCAPM2 = 0x42; //作8位PWM脉宽调节输出 P20

CCAPM3 = 0x42; //作8位PWM脉宽调节输出 P24

PCAPWM0= 0x03;

CCAP0H = 0xFF;

PCAPWM1= 0x03;

CCAP1H = 0xFF;

PCAPWM2= 0x03;

CCAP2H = 0xFF;

PCAPWM3= 0x03;

CCAP3H = 0xFF;

CR = 1;

PCAPWM0= 0x00 且 CCAP0H = 0x00 P37输出恒为1

PCAPWM0= 0x00 且 CCAP0H 大于0小于等于255为占空比 256分之1到256分之255

PCAPWM0= 0x03 且 CCAP0H = 0xFF P37输出恒为0

硬件支持的PWM可应用于LED亮度控制或单个步进电机的微步 *** 作

STC89C52好象不带硬件PWM功能,建议用STC12C5A系列 和STC89C52管脚兼容,带AD和PWM功能,如果用不了那么多管脚的话,也可用STC12C5410 或STC12C5628系列 

我可以给你一个手动PWM程序供参考

STC单片机单/双键控制LED亮度PWM调光程序

输出口为P37(PWM0) S2 S3为亮度调节(可用来调速)按钮

液晶屏LCD1602用来显示1-20亮度或速度级数,可以去掉

 /

#include<STC12C54H>

#define uchar unsigned char

#define uint unsigned int

uchar vx=10;

//vx=10 在上电时为半亮度状态,可根据自己的用途及要求任意设定 vx=20为最亮

sbit rw=P1^4;

sbit rs=P1^3;

sbit lcden=P1^5;

sbit s2=P3^2;

sbit s3=P3^3;

sbit led=P3^7;

#define db P2

void Delay1ms(uint i) //1ms延时程序

{

uint j;

for(;i>0;i--)

{

for(j=0;j<125;j++)

{;}

}

}

void write_com(uchar com) //液晶屏写命令

{

db=com;

rs=0;

rw = 0;

lcden=0;

Delay1ms(10);

lcden=1;

Delay1ms(10);

lcden=0;

}

void write_date(uchar date)//液晶屏写数据

{

db=date;

rs=1;

rw = 0;

lcden=0;

Delay1ms(10);

lcden=1;

Delay1ms(10);

lcden=0;

}

void init2()//液晶屏初始化

{

rw=0;

write_com(0x38);

Delay1ms(10);

write_com(0x0f);

Delay1ms(10);

write_com(0x06);

Delay1ms(10);

write_com(0x01);

Delay1ms(10);

}

void display_brightness (uchar temp1) //I液晶屏显示程序 级数

{

uchar A1,A2;

init2();

A1=temp1/10;

A2=temp1%10;

write_com(0x80);

Delay1ms(10);

write_date(0x30+A1);

write_com(0x81);

Delay1ms(10);

write_date(0x30+A2);

}

//

void PWM_init (void){//PWM初始化函数

CMOD=0x02; //设置PCA定时器

CL=0x00;

CH=0x00;

CCAPM0=0x42; //PWM0设置PCA工作方式为PWM方式(0100 0010)

CCAP0L=0x00; //设置PWM0初始值与CCAP0H相同

CCAP0H=0x00; // PWM0初始时为0

CR=1; //启动PCA定时器

}

//

void PWM1_set (uchar a){//PWM1占空比设置函数

CCAP0L=a; //设置值直接写入CCAP1L

CCAP0H=a; //设置值直接写入CCAP1H

}

//

void DelayM(unsigned int a){//延时函数 1mS/次(用于1T单片机)

unsigned char n,i,j;

while(--a!=0){

for(n=1;n>0;n--)

for(j=222;j>0;j--)

for(i=12;i>0;i--);

} }

//

void main(void)

{

s2= 1;

s3 = 1;

PWM_init ();

display_brightness (vx);

while(1)

{

PWM1_set(vx12);//数字12是配合vx调试取得的,此时vx的赋值范围约为1-20对应最暗-最亮

if (s2 == 0 )//--------减调整---------//

{

DelayM(20); //延时20毫秒消抖动

if(s2 == 0) //如果20SM后KEY_L还是0状态则确认下调键是按下的

{

vx--;

if(vx<1) //如果设定vx=20,将语句改为if(vx<1){vx=10;}则为单按键循环控制,则可去除加调整控制部分

{

vx=10;

}

}

display_brightness (vx);

while(s2 == 0);//等待键松开

}

//--------加调整---------//

if (s3== 0 )

{

DelayM(20);

if(s3 == 0)

{

vx++;

if(vx>20)

{

vx=10;

}

}

display_brightness (vx);

while(s3 == 0);

}

}

}

PWMH DATA 30H ;高电平脉冲的个数

PWM DATA 31H ;PWM周期

COUNTER DATA 32H

TEMP DATA 33H

ORG 0000H

AJMP MAIN

ORG 000BH

AJMP INTT0

ORG 0100H

MAIN:

MOV SP,#60H ;给堆栈指针赋初值

MOV PWMH,#02H ;

MOV COUNTER,#01H

MOV PWM,#15H

MOV TMOD,#02H ;定时器0在模式2下工作

MOV TL0,#38H ;定时器每200us产生一次溢出

MOV TH0,#38H ;自动重装的值

SETB ET0 ;使能定时器0中断

SETB EA ;使能总中断

SETB TR0 ;开始计时

KSCAN:

JNB P11,K1CHECK ;扫描KEY1,

JNB P12,K2CHECK ;扫描KEY2,如果按下KEY2,跳转到KEY2处理程序

SJMP KSCAN

K1CHECK:

JB P11,K1HANDLE ;去抖动,如果按下KEY1,跳转到KEY1处理程序

SJMP K1CHECK

K1HANDLE:

MOV A,PWMH

CJNE A,PWM,K1H0 ;判断是否到达上边界

SJMP KSCAN ;是,则不进行任何 *** 作

K1H0:

MOV A,PWMH

INC A

CJNE A,PWM,K1H1 ;如果在加1后到达最大值

CLR TR0 ;定时器停止

SETB P10 ;P10为高电平

SJMP K1H2

K1H1:

CJNE A,#02H,K1H2 ;如果加1后到达下边界

SETB TR0 ;重开定时器

K1H2:

INC PWMH ;增加占空比

SJMP KSCAN

K2CHECK:

JB P12,K2HANDLE ;去抖动,如果按下KEY2,跳转到KEY2处理程序

SJMP K2CHECK

K2HANDLE:

MOV A,PWMH

CJNE A,#01H,K2H0 ;判断是否到达下边界

SJMP KSCAN ;是,则不进行任何 *** 作

K2H0:

MOV A,PWMH

MOV TEMP,PWM

DEC A

CJNE A,#01H,K2H1 ;如果在减1后到达下边界

CLR TR0 ;定时器停止

CLR P10 ;P10为低电平

SJMP K2H2

K2H1:

DEC TEMP

CJNE A,TEMP,K2H2 ;如果到达上边界

SETB TR0 ;启动定时器

K2H2:

DEC PWMH ;降低占空比

SJMP KSCAN

INTT0:

PUSH PSW ;现场保护

PUSH ACC

INC COUNTER ;计数值加1

MOV A,COUNTER

CJNE A,PWMH,INTT01 ;如果等于高电平脉冲数

CLR P10 ;P10变为低电平

INTT01:

CJNE A,PWM,INTT02 ;如果等于周期数

MOV COUNTER,#01H ;计数器复位

SETB P10 ;P10为高电平

INTT02:

POP ACC ;出栈

POP PSW

RETI

END

以上就是关于stc8h单片机如何设置pwm频率全部的内容,包括:stc8h单片机如何设置pwm频率、求大神指教 小弟实在不会了 stc12c5410ad的pwm程序 就是进不去中断 CL不计数、STC12C5604AD 如何使用其内部PWM求C语言程序~~解决了当然还可以加50分,求帮忙~~~~等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zz/10630972.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-10
下一篇 2023-05-10

发表评论

登录后才能评论

评论列表(0条)

保存