首先,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分,求帮忙~~~~等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)