找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1497|回复: 9
收起左侧

请教用大循环发送PWM,慢一点原因

[复制链接]
ID:734017 发表于 2022-2-28 10:11 | 显示全部楼层 |阅读模式
本帖最后由 happy2058 于 2022-2-28 10:16 编辑

请教一下,下面写法,大循环跑不动原因    用定时器反转一个标志位,大循环判断发送。8H1K08   24M     开了串口1串口2 不在中断状态      
我想定时器多用的情况下,反转不同的标志位让大循环判断输出
void main()
{                        
                        P_SW2 |= 0x80;                        //扩展 RAM 区特殊功能寄存器(XFR)访问控制寄存器
                        CKSEL = 0x00;         //8H默认内部IRC
                        CLKDIV =0x00;           //不分频SYSCLK时钟
                        IOsatar();                                //IO口模式
                        Timer0();                                 //定时器0 100uS
                        Uart_Init();                          //串口中断
                        EA=1;
                        //WDT_CONTR = 0x24; //?????,?????? 1s
                        
                                
while(1)
        {
                key_service2();                      //串口接收判断,空闲
                Circular_transmission();           //串口队列发送,空闲
                TXD_Send_out_uart2();          //直接发送,空闲
                Set_time();                          //时间队列发送,空闲  
                facecare_start()        ;                 //时间队列发送,空闲  
                Microneedle_forward_PWM_out ();                       //PWM  输出
        }
        
}



ode unsigned char Microneedle_speed_intensity[11]={0,1,2,3,4,5,6,7,8,9,10};
unsigned char Microneedle_speed_counters_time=0;
unsigned char Microneedle_speed=0;
bit Open_speed_dose_key=0;
//=====================================================================
void Microneedle_forward_PWM_out ()
{
        if(Microneedle_speed_counters)
        {
                Microneedle_speed_counters=~Microneedle_speed_counters;
                Microneedle_speed_counters_time++;
                if(Microneedle_speed_counters_time<=Microneedle_speed_intensity[Microneedle_speed])
                {
                                        Microneedle_PWM_out=1;
                }
                        else         
                        {
                                Microneedle_PWM_out=0;
                                
                        }
                        if(Microneedle_speed_counters_time>=10)
                                        Microneedle_speed_counters_time=0;
                }        
}


void Timer0()      100US   
{        
        AUXR |= 0x80;                        //1T
        TMOD &= 0xF0;           //清零T0的控制位
        TL0 = 0xA0;                //设置定时初始值
        TH0 = 0xF6;                //设置定时初始值置定时初始值
        ET0 = 1;        //使能T0中断
        TF0  = 0;                //清除TF0标志
        TR0 = 1;        //启动T0
}

//****************************************************************
void TM0_Isr() interrupt 1                                        //定时器0中断
{               
        
        //if(UL_INO_CLOK_lock||MIC_lock||RSM_lock)                                                                                                                                         
        //        {
                        //facecare_Time_Counter=~facecare_Time_Counter;
        //        }
                        
                if(Open_speed_dose_key)
                                 {
                                                Microneedle_speed_counters=~Microneedle_speed_counters;
                                 }                                         
                                 
  }
51hei截图_20220228101354.png


占空比前后抖动,如果是写在定时器里面是不会的
oid TM0_Isr() interrupt 1                                        //定时器0中断
{               
      
        //if(UL_INO_CLOK_lock||MIC_lock||RSM_lock)                                                                                                                                       
        //        {
                        //facecare_Time_Counter=~facecare_Time_Counter;
        //        }
                       
               Microneedle_speed_counters_time++;
                if(Microneedle_speed_counters_time<=Microneedle_speed_intensity[Microneedle_speed])
                {
                                        Microneedle_PWM_out=1;
                }
                        else        
                        {
                                Microneedle_PWM_out=0;
                              
                        }
                        if(Microneedle_speed_counters_time>=10)
                                        Microneedle_speed_counters_time=0;
                                 
  }这个子是不会有问题


回复

使用道具 举报

ID:123289 发表于 2022-2-28 14:32 | 显示全部楼层
提示:
1、PWM的基础时钟取自何处?(假设来自于事件A。)
2、A事件在其它中断发生时,会不会受到影响?(其它中断更高级,会打断A!)
回复

使用道具 举报

ID:734017 发表于 2022-2-28 16:26 | 显示全部楼层
yzwzfyz 发表于 2022-2-28 14:32
提示:
1、PWM的基础时钟取自何处?(假设来自于事件A。)
2、A事件在其它中断发生时,会不会受到影响?( ...

是啊,我试了好久,发现不能这写设到T0最高级  TO做100us标志位反转,时间基准
事件A 在while(1)判断标志位,自加,反转输出,反转标志位,为下一次TO中断判断。

输出不一至的原因,可能是事件A 在while(1)顺序,他不是中断后马上判断,造成延迟了。
回复

使用道具 举报

ID:8222 发表于 2022-2-28 16:47 | 显示全部楼层
为什么不是发送控制参数,让从机按参数要求产生PWM?
回复

使用道具 举报

ID:401564 发表于 2022-2-28 19:09 | 显示全部楼层
1,你要设定要好各个中断的优先等级,100uS的定时器中断时间是很短的,你要根据你自己的实际要求来设定好优先等级,默认的等级都是一样的,但查询是有先后顺序的,当定时器进入中断之后,串口中断就被阻断了
2,更改PWM占空比在主函数更改,定时器只作一个加载的,调节会慢一点,但不会有太大影响的,给个代码参考一下

void timer1_pwm()interrupt 3                        //利用t1定时器产生PWM波形
{       
        TF1 = 0;                                                        //清除TF1标志
                        if(HI)
                        {
                                TH1=pwm_l_H; //低电平时间
                                TL1=pwm_l_L; //
                                HI=0;
                                PWM=0;
                        }
                           else
                        {
                                TH1=pwm_h_H;                 //高电平时间
                                TL1=pwm_h_L;                 //
                                HI=1;
                                PWM=1;
                        }
        TR1 = 1;                        //定时器1开始计时                                                                
}
在主函数调节pwm_l_H和pwm_l_L这两个全局变量就可以了
回复

使用道具 举报

ID:734017 发表于 2022-2-28 20:21 | 显示全部楼层
Y_G_G 发表于 2022-2-28 19:09
1,你要设定要好各个中断的优先等级,100uS的定时器中断时间是很短的,你要根据你自己的实际要求来设定好优先 ...

谢谢这位大哥,这个你之前已经教过我了,再次感谢。现在是一个定时器处理多个任务。
回复

使用道具 举报

ID:401564 发表于 2022-2-28 20:43 | 显示全部楼层
happy2058 发表于 2022-2-28 20:21
谢谢这位大哥,这个你之前已经教过我了,再次感谢。现在是一个定时器处理多个任务。

如果不是商业机密,就把完整的代码上传
如果是不方便,你至少是要说明,现在要做什么,一共要做几个任务,或者是要给个电路图看一下是怎么一回事
不然的话,大多的网友其实是不知道你要做什么的
回复

使用道具 举报

ID:734017 发表于 2022-2-28 21:55 | 显示全部楼层
Y_G_G 发表于 2022-2-28 20:43
如果不是商业机密,就把完整的代码上传
如果是不方便,你至少是要说明,现在要做什么,一共要做几个任务,或 ...

51hei截图_20220228212917.png 这是A板串口2负责与屏幕发送接收通信,还有一个B板串口1负责发送,不接收,屏幕发送数据到A板,A板返回要显示的内容,执行功能,如果是A板上功能就A板输上。B板就再用串口2发送出去。现在A板是单功能的,三个IO口控制两个电机。
现在我写A板功能这部份,有的别的板有这个功能,所以我现在写的时候不能把输出写在中断里,功能多了,还要加功能在定时器里面,以后不方便移,。定时器1用来保留用0.5US可调占空比用的、
这是我写的,A板通信,我写了可以直接发送和大循环发送,大循环发送一次可以处理两条指令,不占用大循环时间,A板功能在最下面一个,他被TO调用,MAIN调用,串口通信部分判断,执行A板通信部分,再执行功能部分。 51hei截图_20220228215051.png 51hei截图_20220228213129.png 51hei截图_20220228214832.png 51hei截图_20220228214740.png

51hei截图_20220228214909.png
回复

使用道具 举报

ID:734017 发表于 2022-2-28 22:08 | 显示全部楼层
Y_G_G 发表于 2022-2-28 20:43
如果不是商业机密,就把完整的代码上传
如果是不方便,你至少是要说明,现在要做什么,一共要做几个任务,或 ...

A板就输出两路PWM 2K的 占空比10%可调,用一个定时器,尽量不要过多的操作,后期方便移值,因为后期一个定时器要干几个功能。
回复

使用道具 举报

ID:401564 发表于 2022-2-28 22:35 | 显示全部楼层
happy2058 发表于 2022-2-28 22:08
A板就输出两路PWM 2K的 占空比10%可调,用一个定时器,尽量不要过多的操作,后期方便移值,因为后期一个 ...

2KHZ的%10就是50uS,那就是说最坏的情况就是两次中断的间隔是50uS,整体就是每500uS进入定时器中断两次,如果定时器中断做的事情太多了,主函数就会慢下来了
进入定时器中断尽可能的不要处理太多东西,但凡是能在主函数处理的,就不要在中断中处理
定时器优先等级设定为最高,这样就保证PWM占空比的稳定
串口的波特率要尽量的设定低一点,这样就不会丢数据
个人感觉,如果量不大的话,就换成STC8G1K08的,这个有片上PWM,能省事很多,价格也就高了那么一两毛的而已
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表