PWM学习之单路PWM输出(STC8G)
硬件:STC8G1K08-38I-TSSOP20这次用pin20 cpp0 进行输出,电路图
P35设置为推挽输出,高电平为LED供电。
P11设置为开漏输出,低电平点亮,高电平熄灭。
先测试一下管脚是否正常。
配置io
代码:
/*********************************************************/
#define MAIN_Fosc 11059200L //定义主时钟
#include "STC8Gxxx.h"
/************* 功能说明 *************
整体布局
功能 管脚 用途 输入输出 类型 PXM1PXM0
P11 PIN20 seg_a 输出 开漏输出1 1
P0M1 = 00000010B 0x02
P0M0 = 00000010B 0x02
功能 管脚 用途 输入输出 类型 PXM1PXM0
P35 PIN16 数码管共阳G1 输出 推挽输出0 1
P3M1 = 0000 0000B 0x00
P3M0 = 0010 0000B 0x20
******************************************/
/************* 本地常量声明 **************/
#define G1_ON (P35 = 1)
#define G1_OFF (P35 = 0)
#define LED_OFF (P11 = 1)
#define LED_ON (P11 = 0)
/************* 本地变量声明 **************/
/************* 本地函数声明 **************/
/****************外部函数声明和外部变量声明 *****************/
/**********************************************/
void Delay100ms(void) //@11.0592MHz
{
unsigned char data i, j, k;
_nop_();
_nop_();
i = 5;
j = 52;
k = 195;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
void main(void)
{
int time100ms = 0;
P_SW2 |= 0x80; //允许访问XSFR(扩展特殊功能寄存器)
//设置管脚模式
P1M1 = 0x02;
P1M0 = 0x02;
P3M1 = 0x00;
P3M0 = 0x20;
//打开LED供电
G1_ON;
while (1)
{
//点亮led
LED_ON;
//延时0.5s
for(time100ms = 5; time100ms > 0; time100ms--)
{
Delay100ms();
}
//熄灭led
LED_OFF;
//延时0.5s
for(time100ms = 5; time100ms > 0; time100ms--)
{
Delay100ms();
}
}
}
本帖最后由 hl1200aa 于 2024-1-1 14:56 编辑
PWM的设置包括
1. 输出管脚 (已经配置)
2. 模式配置
3. pwm频率设置
4. pwm占空比设置
这次根据手册里面的例程,配置一个频率为1hz,占空比特定的pwm。
pca的计数器结构图如下
PWM_CLK = CLK_in / 64
PWM_CLK = 1
CLK_in 则是64hz
系统时钟11059200, 12分配后也远超这个频率
所以选择用T0溢出。
配置T0输出64hz,则是每15625us溢出一次
CLK_in = 64hz
最简单的6位pwm模式,
PWM_CLK = CLK_IN/64
计算得到PWM_CLK = 1
看下手册里面的例程
CCON = 0x00;
CMOD = 0x08; //PCA 时钟为系统时钟
CL = 0x00;CH = 0x00;//清零计数寄存器
CCAPM0 = 0x42;//PCA 模块 0 为 PWM 工作模式
PCA_PWM0 = 0x80;//PCA 模块 0 输出 6 位 PWM
结合这张图可以看到,设置为0x80时,pwm工作在6bit模式
CH永远为0, EPC0L如果为0则可以比对,为1时,则永远为1。
在CL发生溢出时,EPC0H的值重载到EPC0L,CCAP0H的值重载到CCAP0L。
CCAP0L = 0x20; //PWM 占空比为 50%[(40H-20H)/40H]占空比一般是计算高电平的时间,对于我们这个,刚好相反,低电平为亮,那就是CCAP0L/64。
如果我们设置为8,则8/64*100%=12.5%,亮的时间短灭的时间长
CCAP0H = 0x20; //重载值最后记得打开计数开关
CR = 1; //开始计数
/*********************************************************/
#define MAIN_Fosc 11059200L //定义主时钟
#include "STC8Gxxx.h"
/************* 功能说明 *************
整体布局
功能 管脚 用途 输入输出 类型 PXM1PXM0
P11 PIN20 seg_a 输出 开漏输出1 1
P0M1 = 00000010B 0x02
P0M0 = 00000010B 0x02
功能 管脚 用途 输入输出 类型 PXM1PXM0
P35 PIN16 数码管共阳G1 输出 推挽输出0 1
P3M1 = 0000 0000B 0x00
P3M0 = 0010 0000B 0x20
******************************************/
/************* 本地常量声明 **************/
#define G1_ON (P35 = 1)
#define G1_OFF (P35 = 0)
#define LED_OFF (P11 = 1)
#define LED_ON (P11 = 0)
/************* 本地变量声明 **************/
/************* 本地函数声明 **************/
/****************外部函数声明和外部变量声明 *****************/
/**********************************************/
void Delay100ms(void) //@11.0592MHz
{
unsigned char data i, j, k;
_nop_();
_nop_();
i = 5;
j = 52;
k = 195;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
//初始化T0
void Timer0_Init(void) //15625微秒@11.0592MHz
{
AUXR &= 0x7F; //定时器时钟12T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0xC0; //设置定时初始值
TH0 = 0xC7; //设置定时初始值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
}
/*
//定时器0中断函数
void T0_ISR(void) interrupt 1
{
TF0=0; //清除TF位
}
*/
void main(void)
{
int time100ms = 0;
P_SW2 |= 0x80; //允许访问XSFR(扩展特殊功能寄存器)
//设置管脚模式
P1M1 = 0x02;
P1M0 = 0x02;
P3M1 = 0x00;
P3M0 = 0x20;
//初始化T0
Timer0_Init();
//打开LED供电
G1_ON;
CCON = 0x00;
CMOD = 0x04; //PCA 时钟为T0溢出
CL = 0x00;
CH = 0x00;//清零计数寄存器
CCAPM0 = 0x42;//PCA 模块 0 为 PWM 工作模式
PCA_PWM0 = 0x80;//PCA 模块 0 输出 6 位 PWM
CCAP0L = 0x8; //PWM 占空比为 CCAP0L/64*100%
CCAP0H = 0x8; //重载值
//ET0=1; //允许T0中断
//打开全局中断
//EA = 1;
CR = 1; //开始计数
while (1)
{
/*
//点亮led
LED_ON;
//延时0.5s
for(time100ms = 5; time100ms > 0; time100ms--)
{
Delay100ms();
}
//熄灭led
LED_OFF;
//延时0.5s
for(time100ms = 5; time100ms > 0; time100ms--)
{
Delay100ms();
}
*/
}
}
/**********************************************/
浪费 1个 I/O 的目的 ?
这个板是机器上的主板,控制两位数码管的,这只是个等效电路。当时这主板的stc8g坏了,换掉后自己编程序修好了,顺便拿来学习用,反正hex在手,要用时刷进去就行了。 神农鼎 发表于 2024-1-1 15:34
浪费 1个 I/O 的目的 ?
这个板是机器上的主板,控制两位数码管的,这只是个等效电路。当时这主板的stc8g坏了,换掉后自己编程序修好了,顺便拿来学习用,反正hex在手,要用时刷进去就行了。 楼主会玩,是个高手 hl1200aa 发表于 2024-1-1 14:58
弄个38K的红外发射接收电路和程序来学习一下
页:
[1]