打印

菜鸟求助:关于pwm产生一个正弦波

[复制链接]
6250|24
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 fenggdfs 于 2011-10-4 15:49 编辑


我想要pwm波产生一个正弦波

pwm波的频率大概是2000hz

我一个正弦波应该是分成100个点~

为什么出来的正弦波是100hz(不应是20hz吗(2000hz的pwm波有100个)??

这是我的程序:
#include <iom16v.h>
#include <macros.h>
#define  uchar unsigned char
#define  uint  unsigned int
#pragma data:code

const  table1[]={
1000,1063,1125,1187,1249,1309,1368,1426,1482,1536,1588,1637,1685,1729,1771,1809,
1844,1876,1905,1930,1951,1969,1982,1992,1998,2000,1998,1992,1982,1969,1951,1930,
1905,1876,1844,1809,1771,1729,1685,1637,1588,1536,1482,1426,1368,1309,1249,1187,
1125,1063,1000,937 ,875 ,812 ,751 ,691 ,632 ,574 ,518 ,464 ,412 ,363 ,315 ,271 ,
229 ,190 ,156 ,124 ,95  ,70  ,49  ,31  ,18  ,8   ,2   ,0   ,2   ,8   ,18  ,31  ,
49  ,79  ,95  ,124 ,157 ,191 ,229 ,271 ,315 ,363 ,412 ,464 ,518 ,574 ,632 ,691 ,
751 ,813 ,875 ,937 ,
};
void main()
{uchar i=0;
while(1)
       { DDRD|=0X30;
   
    TCCR1A=0X63;
    TCCR1B=0X11;
   
    OCR1A=2000;
    //OCR1B=500;
    OCR1B=table1;
    i++;
    if(i==101)
    i=0;
    }
}

最后我弱弱的问一句:
发帖子时  那个帖子的分数  这个是什么意思?

相关帖子

沙发
fenggdfs|  楼主 | 2011-10-5 23:52 | 只看该作者
真心求助~~

使用特权

评论回复
板凳
nongfuxu| | 2011-10-6 14:59 | 只看该作者
LZ,你把事情说明白点。是滤波成正弦,还是用SPWM来输出功率正弦波?后面的LC滤波是怎么回事都说明些,好一些。

使用特权

评论回复
地板
maychang| | 2011-10-6 15:48 | 只看该作者
从几个寄存器名称TCCR1A、TCCR1B、OCR1A等等,估计使用的是ATmega8或ATmega16这类单片机。但时钟频率却不说清楚。
示波器图中数字看不清,何以见得PWM频率是2kHz?正弦是20Hz?

使用特权

评论回复
5
fenggdfs|  楼主 | 2011-10-6 17:15 | 只看该作者
3# nongfuxu

噢噢  不好意思~是输出的是pwm方波,然后滤成正弦波

使用特权

评论回复
6
fenggdfs|  楼主 | 2011-10-6 17:39 | 只看该作者
4# maychang
晶振用的是8M的~是用ATMEGA16(厄 居然就看寄存器就看出来)
图中的数字
pwm:某此到最高的时间点:475us  下一次最高点 的时间点1.01ms  我算了一下,一个周期大概  5*10^-4,频率是2000hz

正弦函数     我是看最低点对应时间是44.7ms   到 下一次对于时间56.6ms    算出周期大概0.01  频率大概就是 100hz

我觉得pwm的频率是2000hz,我不断地从数组取数改变它的占空比,  数组是有100个数据,其中的数值是按照((sin(x*3.6)+1)/2)*2000,x从0取到99.

这样应该就做到sin(90)对应占空比是1,sin(0)对应占空比是0.5,sin(270)对应占空比是0,应该是一个正弦波吧 。  它的对应100个值,而且又100个占空比不一样,但频率都是2000hz的pwm波组成。所以我觉得这个正弦波的频率是1/(100*(1/2000))=20hz

不知道我的思路有没有错??

使用特权

评论回复
7
fenggdfs|  楼主 | 2011-10-6 17:43 | 只看该作者
3# nongfuxu

这个是我的电路图,不好意思,我表达得不是很好,如果还是不清楚的话,请继续问,我会尽量讲清楚,谢谢

电路图.png (7.93 KB )

电路图.png

使用特权

评论回复
8
nongfuxu| | 2011-10-7 07:23 | 只看该作者
用低通滤波和带通滤波都行.输出失真大有二个原因:1/查截止频率对不对;2/带外衰减够味不够味.

使用特权

评论回复
9
fenggdfs|  楼主 | 2011-10-7 10:19 | 只看该作者
8# nongfuxu

:'(听不懂~~

使用特权

评论回复
10
maychang| | 2011-10-7 21:40 | 只看该作者
6楼:
别太着急。
我今天怕是没有时间了,明天可以给出确定结果。

使用特权

评论回复
11
fenggdfs|  楼主 | 2011-10-8 10:09 | 只看该作者
10# maychang
谢谢:lol

使用特权

评论回复
12
maychang| | 2011-10-8 20:03 | 只看该作者
由TCCR1A、TCCR1B寄存器设置看,WGM13:WGM10=0B1011=11,PWM为相位修正模式,以OCR1A内容为计数上限。相位修正模式即计数器先加计数,达到上限后变为减计数,减计数达到零后又回到加计数。计数过程中若计数值与OCR1B相等则为比较匹配。
CS12:0=1,分频因子为1,即PWM时钟等于晶体频率,为8MHz。
今OCR1A设置为2000,即每个PWM周期为4000时钟,故PWM频率为8MHz/4000=2kHz。这与示波器测量结果相符。
但主程序main中使用while语句。主程序执行完毕后立即重新执行,并不管本次PWM脉冲是否已达4000时钟。再执行一次的结果是i又增加1,再执行两次的结果是i增加2。因为main相当短,执行一次用不了太多时间,所以在PWM的一个周期内执行多次。结果就是OCR1B赋值并非上一个PWM周期OCR1B所赋值之后那个数据,而很可能i增加了好几次,跳过了好几个数据。
每一个PWM周期改变一次OCR1B,这样的程序应该使用中断。不应该使用比较匹配中断,而是使用T/C1溢出中断。在PWM模式11中,T/C1计数到零发生T/C1溢出中断。这会产生一个问题:中断发生到重置OCR1B需要若干时钟,如果给OCR1B赋一个很小的值,可能会丢失一次比较匹配。
另外,建议不要使用PWM模式11,用快速PWM模式比较好。

使用特权

评论回复
13
fenggdfs|  楼主 | 2011-10-8 22:39 | 只看该作者
12# maychang

使用T/C1溢出中断?
那是在pwm的比较寄存器计数同时,再有一个t/c1以相同时间同时计数吗?

使用特权

评论回复
14
maychang| | 2011-10-8 22:58 | 只看该作者
13楼:
不是。
比较寄存器并不计数,计数的是T/C1。详见ATmega16手册。

使用特权

评论回复
15
fenggdfs|  楼主 | 2011-10-8 23:31 | 只看该作者
14# maychang
我尝试了一下,中断是产生了,但为什么我的i值没有变化呢?

#pragma interrupt_handler tt:9
void tt()
{
    i++;
    if(i==100)
       i=0;
       PORTA|=BIT(0);
     
}

void init()
{
      DDRD|=0X30;
   
     TCCR1A=0X63;
     TCCR1B=0X19;
   
     OCR1A=3999;
     OCR1B=table;
   
     TIMSK|=BIT(2);
     SREG|=BIT(7);
}


void main()
{     
       init();
       while(1)
       {
           while(1)
        {
        DDRA|=BIT(0);//0000 0001
        PORTA&=~BIT(0);
        }
       }
}


那个DDRA|=BIT(0);PORTA&=~BIT(0);  我是想看看中断是否产生~

中断.png (38.41 KB )

中断.png

使用特权

评论回复
16
fenggdfs|  楼主 | 2011-10-8 23:31 | 只看该作者
忽略那个笑脸~

使用特权

评论回复
17
fenggdfs|  楼主 | 2011-10-9 21:12 | 只看该作者
14# maychang

我把OCR1B的取值放到中断里面就可以成功取值,用这种方法想获取20khz的正弦波?是不是不能去太多点?

使用特权

评论回复
18
fenggdfs|  楼主 | 2011-10-9 22:21 | 只看该作者
14# maychang

我尝试输出一个20khz的正弦波,频率是正确的,但不知道为什么电压很小,我把滤波器的电阻降到1k,出来的峰值也只要2mV。这是为什么呢?
假如原来是这样  有没有办法使最小电压>6v呢

20khz.png (109.93 KB )

20khz.png

使用特权

评论回复
19
maychang| | 2011-10-9 22:28 | 只看该作者
18楼:
用ATmega16,8MHz系统频率,要输出20kHz正弦波,你自己算算一个正弦波周期是多长时间,可以容纳多少个PWM周期?假定PWM用快速模式,计数最大值是8位二进制数。

使用特权

评论回复
20
fenggdfs|  楼主 | 2011-10-9 23:02 | 只看该作者
19# maychang

恩,我18楼那幅图就是输出来了,不过就是搞不懂为什么电压会如此的小~

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

主题

32

帖子

1

粉丝