完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
RT。。最近整了个灯的样品在玩,通过逻辑分析仪抓到的16路PWM波形,16路周期都为5ms,其中有6路PWM是持续输出,剩下的10路间断输出,每一路的占空比都在3个周期后改变。观察到的占空比无任何规律,求解应如何做才比较好。。
|
|
相关推荐
19个回答
|
|
|
|
|
|
用定时器比较输出功能
|
|
|
|
|
|
|
|
|
|
|
|
周期都是一样的,我现在的做法是将所有占空比做成一个表格的形式来做,单一路占空比的个数就有247个,且相互间没有任何规律,将10个通道间断工作的时间也做成表格的形式去对比判断,但效果很不理想 |
|
|
|
|
|
个人认为你可能需要更换更快速的单片机,
假定PWM频率是1K,即周期是1毫秒,假定占空比是128分,则最短的时间是7。8微秒,即当占空比是1/128时,需要有一个7。8微秒的定时,再加上16路通道中间的判断和必要的操作,定时时间预留一个数量级,就是0。78微秒,不知道有没有算错,这个参数好像有点要求高了,不过个人认为应该这样算。 另外你贴出来的图是占空比图,还是PWM的启停图,占空比图的话,那这些PWM的频率很低,而且电平为高的部分应该是空心的,到更象是PWM启停图,高电平部分是PWM在工作,低电平部分是关闭了PWM,不知道是不是这样 |
|
|
|
|
人中狼 发表于 2017-7-22 12:09 PWM的启停图没错,所有通道的周期都是5ms,每格50us,一共分为100格,就像图片看到的除去6路通道的PWM一直都工作的,剩下的10个通道都是间断性的工作,所以所要判断的东西又变多了。。 |
|
|
|
|
|
|
|
|
|
|
|
用定时器貌似可以
|
|
|
|
|
|
单片机做如此多的PWM,可以考虑用一个定时器做时基,溢出触发DMA,内存数据搬运到GPIO,然后占空比和周期这部分通过内存里的数据来控制。假设定时器10us溢出1次,数组数据0b11111111 11111111,0b11111111 11111110,0b11111111 11111101,0b11111111 11111100,0b11111111 11111111,0b11111111 11111110,0b11111111 11111001,0b11111111 11111100,这样子输出到GPIA的话,GPIOA0 口输出的PWM占空比为50%,周期20us;GPIOA1的占空比为50%,周期40us,GPIOA2的占空比为20%,周期50us。其他口同理,需要修改数组数据。
这样子的话,CPU负担也很小,主要工作由DMA完成,CPU只需要计算那组数据放在内存。等待DMA输出就可以。 评分
|
||
|
|
||
he07413 发表于 2017-7-24 11:50 额..8位机..不是32位机。。 |
|
|
|
|
|
用定时器模拟一个PWM就可以了,要算好占空比的范围,确定好最短的定时时间,然后决定单片机的速度就可以了
|
|
|
|
|
|
这是STC-ISP提供的例程,使用定时器0做16路软件PWM /*---------------------------------------------------------------------*/ /* --- STC MCU Limited ------------------------------------------------*/ /* --- STC 1T Series MCU Demo Programme -------------------------------*/ /* --- Mobile: (86)13922805190 ----------------------------------------*/ /* --- Fax: 86-0513-55012956,55012947,55012969 -----------------------*/ /* --- Tel: 86-0513-55012928,55012929,55012966 ------------------------*/ /* --- Web: www.STCMCU.com --------------------------------------------*/ /* --- Web: www.GXWMCU.com --------------------------------------------*/ /* --- QQ: 800003751 -------------------------------------------------*/ /* 如果要在程序中使用此代码,请在程序中注明使用了STC的资料及程序 */ /*---------------------------------------------------------------------*/ /************* 功能说明 ************** 使用Timer0模拟16通道PWM驱动程序。 输出为 P1.0 ~ P1.7, P2.0 ~ P2.7, 对应 PWM0 ~ PWM15. 定时器中断频率一般不要超过100KHZ, 留足够的时间给别的程序运行. 本例子使用11.0592MHZ时钟, 25K的中断频率, 250级PWM, 周期为10ms. 中断里处理的时间不超过6us, 占CPU时间大约为15%. ******************************************/ #include #define MAIN_Fosc 11059200UL //定义主时钟 #define Timer0_Rate 25000 //中断频率 typedef unsigned char u8; typedef unsigned int u16; typedef unsigned long u32; sfr AUXR = 0x8E; sfr P1M1 = 0x91; //PxM1.n,PxM0.n =00--->Standard, 01--->push-pull sfr P1M0 = 0x92; // =10--->pure input, 11--->open drain sfr P0M1 = 0x93; sfr P0M0 = 0x94; sfr P2M1 = 0x95; sfr P2M0 = 0x96; sfr P3M1 = 0xB1; sfr P3M0 = 0xB2; sfr P4M1 = 0xB3; sfr P4M0 = 0xB4; sfr P5M1 = 0xC9; sfr P5M0 = 0xCA; sfr P6M1 = 0xCB; sfr P6M0 = 0xCC; sfr P7M1 = 0xE1; sfr P7M0 = 0xE2; #define Timer0_Reload (65536UL -(MAIN_Fosc / Timer0_Rate)) //Timer 0 重装值 //************** PWM8 变量和常量以及IO口定义 *************** //******************** 8通道8 bit 软PWM ******************** #define PWM_DUTY_MAX 250 // 0~255 PWM周期, 最大255 #define PWM_ON 1 // 定义占空比的电平, 1 或 0 #define PWM_OFF (!PWM_ON) #define PWM_ALL_ON (0xff * PWM_ON) u8 bdata PWM_temp1,PWM_temp2; //影射一个RAM,可位寻址,输出时同步刷新 ***it P_PWM0 = PWM_temp1^0; // 定义影射RAM每位对应的IO ***it P_PWM1 = PWM_temp1^1; ***it P_PWM2 = PWM_temp1^2; ***it P_PWM3 = PWM_temp1^3; ***it P_PWM4 = PWM_temp1^4; ***it P_PWM5 = PWM_temp1^5; ***it P_PWM6 = PWM_temp1^6; ***it P_PWM7 = PWM_temp1^7; ***it P_PWM8 = PWM_temp2^0; ***it P_PWM9 = PWM_temp2^1; ***it P_PWM10 = PWM_temp2^2; ***it P_PWM11 = PWM_temp2^3; ***it P_PWM12 = PWM_temp2^4; ***it P_PWM13 = PWM_temp2^5; ***it P_PWM14 = PWM_temp2^6; ***it P_PWM15 = PWM_temp2^7; u8 pwm_duty; //周期计数值 u8 pwm[16]; //pwm0~pwm15 为0至15路PWM的宽度值 bit B_1ms; u8 cnt_1ms; u8 cnt_20ms; /**********************************************/ void main(void) { u8 i; P0M0 = 0x00; P0M1 = 0x00; P1M0 = 0x00; P1M1 = 0x00; P2M0 = 0x00; P2M1 = 0x00; P3M0 = 0x00; P3M1 = 0x00; P4M0 = 0x00; P4M1 = 0x00; P5M0 = 0x00; P5M1 = 0x00; P6M0 = 0x00; P6M1 = 0x00; P7M0 = 0x00; P7M1 = 0x00; AUXR |= (1<<7); // Timer0 set as 1T mode TMOD &= ~(1<<2); // Timer0 set as Timer TMOD &= ~0x03; // Timer0 set as 16 bits Auto Reload TH0 = Timer0_Reload / 256; //Timer0 Load TL0 = Timer0_Reload % 256; ET0 = 1; //Timer0 Interrupt Enable PT0 = 1; //高优先级 TR0 = 1; //Timer0 Run EA = 1; //打开总中断 cnt_1ms = Timer0_Rate / 1000; //1ms计数 cnt_20ms = 20; for(i=0; i<16; i++) pwm = i * 15 + 15; //给PWM一个初值 while(1) { if(B_1ms) //1ms到 { B_1ms = 0; if(--cnt_20ms == 0) //PWM 20ms改变一阶 { cnt_20ms = 20; for(i=0; i<16; i++) pwm++; } } } } /********************** Timer0 1ms中断函数 ************************/ void timer0 (void) interrupt 1 { P1 = PWM_temp1; //影射RAM输出到实际的PWM端口 P2 = PWM_temp2; if(++pwm_duty == PWM_DUTY_MAX) //PWM周期结束,重新开始新的周期 { pwm_duty = 0; PWM_temp1 = PWM_ALL_ON; PWM_temp2 = PWM_ALL_ON; } ACC = pwm_duty; if(ACC == pwm[0]) P_PWM0 = PWM_OFF; //判断PWM占空比是否结束 if(ACC == pwm[1]) P_PWM1 = PWM_OFF; if(ACC == pwm[2]) P_PWM2 = PWM_OFF; if(ACC == pwm[3]) P_PWM3 = PWM_OFF; if(ACC == pwm[4]) P_PWM4 = PWM_OFF; if(ACC == pwm[5]) P_PWM5 = PWM_OFF; if(ACC == pwm[6]) P_PWM6 = PWM_OFF; if(ACC == pwm[7]) P_PWM7 = PWM_OFF; if(ACC == pwm[8]) P_PWM8 = PWM_OFF; if(ACC == pwm[9]) P_PWM9 = PWM_OFF; if(ACC == pwm[10]) P_PWM10 = PWM_OFF; if(ACC == pwm[11]) P_PWM11 = PWM_OFF; if(ACC == pwm[12]) P_PWM12 = PWM_OFF; if(ACC == pwm[13]) P_PWM13 = PWM_OFF; if(ACC == pwm[14]) P_PWM14 = PWM_OFF; if(ACC == pwm[15]) P_PWM15 = PWM_OFF; if(--cnt_1ms == 0) { cnt_1ms = Timer0_Rate / 1000; B_1ms = 1; // 1ms标志 } } 评分 |
|
|
|
|
|
本帖最后由 小S咯 于 2017-7-27 09:14 编辑
我用的是新塘的51单片机,给你参考假设输出为p00~p07,p10~p1716个引脚; u8 pwm1,pwm2 ......pwm16; void Timer0_Init(void) { TMOD &= ~0XF; TMOD |= 0X1; TIMER0_MODE1_ENABLE; set_T0M; //时钟源为系统时钟 TH0 = TH0_INIT; //设置频率 TL0 = TL0_INIT; set_ET0; set_EA; set_TR0; } void Timer0_ISR (void) interrupt 1 { static u8 count=0; //这是计数器,用一个变量与他比较就是PWM clr_TR0; TH0 = TH0_INIT; TL0 = TL0_INIT; set_TR0; //重新装值 count++; if(count>=120) count=0; if(pwm1>count) p00=1; else p00=0; if(pwm2>count) p01=1; else p01=0; . . . if(pwm16>count) p17=1; else p17=0; } 在mian函数中改变pwm的值就可以改变占空比了!0~120之间。 评分 |
|
|
|
|
|
只能用定时器模拟了。
|
|
|
|
|
|
高手!
|
|
|
|
|
|
很好,不错,学习了,谢谢!感谢楼主分享 !
|
|
|
|
|
|
很好,不错,学习了,谢谢!感谢楼主分享 !
|
|
|
|
|
|
很好,不错,学习了,谢谢!感谢楼主分享 !
|
|
|
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
265 浏览 0 评论
【原创】【RA4M2-SENSOR开发板评测】低功耗+USB综合测试
789 浏览 0 评论
1306 浏览 2 评论
787 浏览 0 评论
【RA4M2-SENSOR开发板评测】Analogue+Timers综合测试
1587 浏览 0 评论
【youyeetoo X1 windows 开发板体验】少儿AI智能STEAM积木平台
16901 浏览 31 评论
/9
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2025-12-2 07:13 , Processed in 1.561046 second(s), Total 88, Slave 80 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191

淘帖
1245