之前解决过的一个问题,换了个方式又出现了.(已解决)
本帖最后由 vb2002 于 2024-11-23 21:40 编辑已解决,之前按照硬件pwm的思路去弄,弄了好些天都不行,不管先后 怎么设置IO口模式都没用,放在程序后面都没用
刚刚搜了一下T0CLKO这个关键词.在一篇帖子里见到姚总说T0CLKO T1CLKO输出方波没问题.然后继续搜.也无果.突然灵机一动.会不会是我的频率有问题,导致T0CLKO输出太快了
我就把思路换了一下.干脆把频率放慢点,之前是系统的变量来改变中断频率的.
我索性把频率改成1ms进一次中断.,,奇迹出现了.竟然断电上电不会闪一下了.
但是频率慢了.我想频闪不就出现了吗? 等于是拆东墙补西墙了.
但是拿出手机把iso调整到4000/1一拍.完全没有频闪.开心开心极了
之前用硬件pwm出现过占空比小的时候,通电会闪一下
现在用的8g1k08定时器生成pwm,通过T0CLKO 输出
当时通过把IO口设置放在程序的后面解决了.
现在用官方范例的定时器 9-16位生成pwm
把呼吸灯剔除. 只保存 占空比小的那个地方.
不管怎么设置,只要通电必须要闪一下.哪怕我设置delayms都没用.我怀疑是中断这个地方的问题.
但是我仿真过后.看到每次设置P55推挽那个地方就会开启IO口输出, 我试着把推挽设置放在程序的后面, 或者初始化关闭定时器 INTCLKO |=0x00; 也没有作用.
这个是代码.
我就改了一下端口.
/*------------------------------------------------------------------*/
/* --- STC MCU International Limited -------------------------------*/
/* --- STC 1T Series MCU RC Demo -----------------------------------*/
/* --- Mobile: (86)13922805190 -------------------------------------*/
/* --- Fax: 86-0513-55012956,55012947,55012969 --------------------*/
/* --- Tel: 86-0513-55012928,55012929,55012966 ---------------------*/
/* --- Web: www.GXWMCU.com -----------------------------------------*/
/* --- QQ:800003751 ----------------------------------------------*/
/* If you want to use the program or the program referenced in the*/
/* article, please specify in which data and procedures from STC */
/*------------------------------------------------------------------*/
#include <stc8g.h>
/*************功能说明 **************
本程序演示使用定时器做软件PWM。
定时器0做16位自动重装,中断,从T0CLKO高速输出PWM。
本例程是使用STC15F/L系列MCU的定时器T0做模拟PWM的例程。
PWM可以是任意的量程。但是由于软件重装需要一点时间,所以PWM占空比最小为32T/周期,最大为(周期-32T)/周期, T为时钟周期。
PWM频率为周期的倒数。假如周期为6000, 使用24MHZ的主频,则PWM频率为4000HZ。
******************************************/
#define MAIN_Fosc 24000000UL //定义主时钟
#define PWM_DUTY 960 //定义PWM的周期,数值为时钟周期数,假如使用24.576MHZ的主频,则PWM频率为6000HZ。
#define PWM_HIGH_MIN 32 //限制PWM输出的最小占空比。用户请勿修改。
#define PWM_HIGH_MAX (PWM_DUTY-PWM_HIGH_MIN) //限制PWM输出的最大占空比。用户请勿修改。
typedef unsigned char u8;
typedef unsigned int u16;
typedef unsigned long u32;
sbit P_PWM = P5^5; //定义PWM输出引脚。
//sbitP_PWM = P1^4; //定义PWM输出引脚。STC15W204S
u16 pwm; //定义PWM输出高电平的时间的变量。用户操作PWM的变量。
u16 PWM_high,PWM_low; //中间变量,用户请勿修改。
void delay_ms(unsigned char ms);
void LoadPWM(u16 i);
/******************** 主函数**************************/
void main(void)
{
P_PWM = 0;
P5M1 &= ~(1 << 5);//P5.5 设置为推挽输出
P5M0 |=(1 << 5);
//P1M1 &= ~(1 << 4);//P1.4 设置为推挽输出 STC15W204S
//P1M0 |=(1 << 4);
TR0 = 0; //停止计数
ET0 = 1; //允许中断
PT0 = 1; //高优先级中断
TMOD &= ~0x03;//工作模式,0: 16位自动重装
AUXR |=0x80;//1T
TMOD &= ~0x04;//定时
INTCLKO |=0x01;//输出时钟
TH0 = 0;
TL0 = 0;
TR0 = 1; //开始运行
EA = 1;
pwm = 960; //给PWM一个初值,这里为10%占空比
LoadPWM(pwm); //计算PWM重装值
while (1)
{
}
}
//========================================================================
// 函数: voiddelay_ms(unsigned char ms)
// 描述: 延时函数。
// 参数: ms,要延时的ms数, 这里只支持1~255ms. 自动适应主时钟.
// 返回: none.
// 版本: VER1.0
// 日期: 2013-4-1
// 备注:
//========================================================================
voiddelay_ms(unsigned char ms)
{
unsigned int i;
do{
i = MAIN_Fosc / 13000;
while(--i) ;
}while(--ms);
}
/**************** 计算PWM重装值函数 *******************/
void LoadPWM(u16 i)
{
u16 j;
if(i > PWM_HIGH_MAX) i = PWM_HIGH_MAX; //如果写入大于最大占空比数据,则强制为最大占空比。
if(i < PWM_HIGH_MIN) i = PWM_HIGH_MIN; //如果写入小于最小占空比数据,则强制为最小占空比。
j = 65536UL - PWM_DUTY + i; //计算PWM低电平时间
i = 65536UL - i; //计算PWM高电平时间
EA = 0;
PWM_high = i; //装载PWM高电平时间
PWM_low= j; //装载PWM低电平时间
EA = 1;
}
/********************* Timer0中断函数************************/
void timer0_int (void) interrupt 1
{
if(P_PWM)
{
TH0 = (u8)(PWM_low >> 8); //如果是输出高电平,则装载低电平时间。
TL0 = (u8)PWM_low;
}
else
{
TH0 = (u8)(PWM_high >> 8);//如果是输出低电平,则装载高电平时间。
TL0 = (u8)PWM_high;
}
}
/*------------------------------------------------------------------*/
/* --- STC MCU International Limited -------------------------------*/
/* --- STC 1T Series MCU RC Demo -----------------------------------*/
/* --- Mobile: (86)13922805190 -------------------------------------*/
/* --- Fax: 86-0513-55012956,55012947,55012969 --------------------*/
/* --- Tel: 86-0513-55012928,55012929,55012966 ---------------------*/
/* --- Web: www.GXWMCU.com -----------------------------------------*/
/* --- QQ:800003751 ----------------------------------------------*/
/* If you want to use the program or the program referenced in the*/
/* article, please specify in which data and procedures from STC */
/*------------------------------------------------------------------*/
#include <stc8g.h>
/*************功能说明 **************
本程序演示使用定时器做软件PWM。
定时器0做16位自动重装,中断,从T0CLKO高速输出PWM。
本例程是使用STC15F/L系列MCU的定时器T0做模拟PWM的例程。
PWM可以是任意的量程。但是由于软件重装需要一点时间,所以PWM占空比最小为32T/周期,最大为(周期-32T)/周期, T为时钟周期。
PWM频率为周期的倒数。假如周期为6000, 使用24MHZ的主频,则PWM频率为4000HZ。
******************************************/
#define MAIN_Fosc 24000000UL //定义主时钟
#define PWM_DUTY 960 //定义PWM的周期,数值为时钟周期数,假如使用24.576MHZ的主频,则PWM频率为6000HZ。
#define PWM_HIGH_MIN 32 //限制PWM输出的最小占空比。用户请勿修改。
#define PWM_HIGH_MAX (PWM_DUTY-PWM_HIGH_MIN) //限制PWM输出的最大占空比。用户请勿修改。
typedef unsigned char u8;
typedef unsigned int u16;
typedef unsigned long u32;
sbit P_PWM = P5^5; //定义PWM输出引脚。
//sbitP_PWM = P1^4; //定义PWM输出引脚。STC15W204S
u16 pwm; //定义PWM输出高电平的时间的变量。用户操作PWM的变量。
u16 PWM_high,PWM_low; //中间变量,用户请勿修改。
void delay_ms(unsigned char ms);
void LoadPWM(u16 i);
/******************** 主函数**************************/
void main(void)
{
P_PWM = 0;
P5M1 &= ~(1 << 5);//P5.5 设置为推挽输出
P5M0 |=(1 << 5);
//P1M1 &= ~(1 << 4);//P1.4 设置为推挽输出 STC15W204S
//P1M0 |=(1 << 4);
TR0 = 0; //停止计数
ET0 = 1; //允许中断
PT0 = 1; //高优先级中断
TMOD &= ~0x03;//工作模式,0: 16位自动重装
AUXR |=0x80;//1T
TMOD &= ~0x04;//定时
INTCLKO |=0x01;//输出时钟
TH0 = 0;
TL0 = 0;
TR0 = 1; //开始运行
EA = 1;
pwm = 960; //给PWM一个初值,这里为10%占空比
LoadPWM(pwm); //计算PWM重装值
while (1)
{
}
}
//========================================================================
// 函数: voiddelay_ms(unsigned char ms)
// 描述: 延时函数。
// 参数: ms,要延时的ms数, 这里只支持1~255ms. 自动适应主时钟.
// 返回: none.
// 版本: VER1.0
// 日期: 2013-4-1
// 备注:
//========================================================================
voiddelay_ms(unsigned char ms)
{
unsigned int i;
do{
i = MAIN_Fosc / 13000;
while(--i) ;
}while(--ms);
}
/**************** 计算PWM重装值函数 *******************/
void LoadPWM(u16 i)
{
u16 j;
if(i > PWM_HIGH_MAX) i = PWM_HIGH_MAX; //如果写入大于最大占空比数据,则强制为最大占空比。
if(i < PWM_HIGH_MIN) i = PWM_HIGH_MIN; //如果写入小于最小占空比数据,则强制为最小占空比。
j = 65536UL - PWM_DUTY + i; //计算PWM低电平时间
i = 65536UL - i; //计算PWM高电平时间
EA = 0;
PWM_high = i; //装载PWM高电平时间
PWM_low= j; //装载PWM低电平时间
EA = 1;
}
/********************* Timer0中断函数************************/
void timer0_int (void) interrupt 1
{
if(P_PWM)
{
TH0 = (u8)(PWM_low >> 8); //如果是输出高电平,则装载低电平时间。
TL0 = (u8)PWM_low;
}
else
{
TH0 = (u8)(PWM_high >> 8);//如果是输出低电平,则装载高电平时间。
TL0 = (u8)PWM_high;
}
}
设置定时器初值时,一定先停止定时器,清除溢出标志,设置完再开。 晓飛飛 发表于 2024-11-22 21:20
设置定时器初值时,一定先停止定时器,清除溢出标志,设置完再开。
代码就是 这个哦, 怎么都会闪一下.
晓飛飛 发表于 2024-11-22 21:20
设置定时器初值时,一定先停止定时器,清除溢出标志,设置完再开。
定时器tr0 我也停了
T0CLKO也停了.. 都会闪!{:5_312:} vb2002 发表于 2024-11-22 21:49
定时器tr0 我也停了
T0CLKO也停了.. 都会闪!
先设置P55 = 0; 后设置P55模式 邮箱 发表于 2024-11-22 22:21
先设置P55 = 0; 后设置P55模式
没用,真的一点用都没有 vb2002 发表于 2024-11-22 22:27
没用,真的一点用都没有
也就P5.4会由于复位引脚复用的因素,上电时有6.5ms的4K上拉输出高电平时间,P5.5没有这方面的问题啊。 晓飛飛 发表于 2024-11-23 00:03
也就P5.4会由于复位引脚复用的因素,上电时有6.5ms的4K上拉输出高电平时间,P5.5没有这方面的问题啊。 ...
是啊,怎样都不行,奇怪了,
我怀疑是中断那高低电平的问题
页:
[1]
2