|
![](static/image/common/ico_lz.png)
楼主 |
发表于 2008-11-4 10:29:44
|
显示全部楼层
麻烦【7楼】 ywl0409 老黄牛,请你讲一下吧,其实我在学校里面也是好好读书的学生,但比较菜.谢谢ywl0409 老黄牛!
这是本坛里的一些例子:
1.来自:http://www.ouravr.com/bbs/bbs_content.jsp?bbs_sn=441416&bbs_page_no=1&search_mode=1&search_text=spwm&bbs_id=9999
小妹刚用Atmega16L写程序来实现spwm(采用的是快速SPWM方式),按常规思路,从芯片的PB3输出信号为只有正值的SPWM信号,而且经过一RC低通滤波之后,确实为非常标准的正弦信号,但仔细分析才发现,SPWM信号与滤波后sin信号已经是有正有负的了,也就是说,从mega16L的PB3输出信号也就含有了负信号,无需做处理,这样正确吗?是不是mega16L 内部已经做了这部分功能, 请求高手指点论证,谢谢
#include<avr/io.h>
#include<stdio.h>
#include<avr/interrupt.h>
#include<avr/signal.h>
#include<avr/sleep.h>
#include<avr/eeprom.h>
#define PWMOUT PD5
#define PWMOUTB PD4
#define OCR OCR1A
#define OCRB OCR1B
#define PORTPWMOUT DDRD
unsigned char
sin_table[]={0,1,2,3,4,6,7,9,11,13,16,18,21,24,27,30,34,37,41,45,49,53,57,62,66,71,76,80,85,90,95,100,105,110,115,121,126,133,136,143,146,154,157,163,167,173,176,183,186,192,195,204,209,212,217,220,224,227,230,234,237,239,241,244,246,248,250,251,252,254,255,255,255,255,254,252,251,246,248,246,244,241,239,237,234,230,227,224,220,217,212,209,204,195,192,186,183,176,173,167,163,157,154,146,143,138,136,133,126,121,115,110,105,100,95,90,85,80,76,71,66,62,57,53,49,45,41,37,34,30,27,24,21,18,16,13,11,9,7,6,4,3,2,1,0}; //145 point
unsigned char step=8,id = 0;
void init(void)
{
DDRB |= 0x08;
OCR0 = 128;
TIMSK = 0x02;
TCCR0 = 0x68; //enable it out of work
sei(); //置位全局中断
}
int main(void)
{
init();
while(1)
{
TCCR0 = 0x69; //enbale it work
}
}
SIGNAL(SIG_OUTPUT_COMPARE0)
{
OCR0 = sin_table[id ++];
if( id ==145)
id =0;
}
2.来自:
http://www.ouravr.com/bbs/bbs_content.jsp?bbs_sn=539211&bbs_page_no=1&search_mode=1&search_text=spwm&bbs_id=9999
我做了一个spwm的程序,效果还可以。可以参考一下。
#include<iom8v.h>
#include<macros.h>
#define uchar unsigned char
unsigned short spwm[200]={ 400,399,399,398,397,396,394,393,391,389,
387,385,382,380,377,374,371,367,364,360,
356,352,348,344,339,335,330,325,320,315,
310,304,299,294,291,285,279,274,268,262,
256,250,247,241,231,228,222,216,209,203,
201,200,199,199,198,198,197,196,194,193,
191,189,187,185,182,180,177,174,170,167,
164,160,156,152,148,144,139,135,130,125,
120,115,110,104, 99, 94, 88, 82, 76, 71,
65, 59, 53, 47, 41, 34, 28, 22, 16, 9,
3, 1, 6, 13, 19, 25, 31, 37, 44, 50,
56, 62, 68, 74, 79, 85, 91, 96,102,107,
112,118,123,127,132,137,141,146,150,154,
158,162,165,169,172,175,178,181,184,186,
188,190,192,194,195,196,197,198,199,199,
200,200,206,213,219,225,231,237,244,250,
256,262,268,274,279,285,291,296,302,307,
312,318,323,328,332,337,341,346,350,354,
358,362,365,369,372,375,378,381,384,386,
388,390,392,394,395,396,397,398,399,400};
/*{201,212,225,237,250,262,274,285,296,307,318,327,337,346,354,//带直流分量的正弦波
362,369,375,381,386,390,394,396,398,400,398,396,
394,390,386,381,375,369,362,354,346,337,327,318,307,296,285,
274,262,250,237,225,212,201,187,175,163,150,138,126,115,104,
93,82,73,63,54,46,38,31,25,19,14,10,6,4,2,0,0,0,0,0,2,4,6,10,
14,19,25,31,38,46,54,63,73,82,93,104,115,126,138,150,163,175,187};*/
unsigned int k=0;
//****************系统初始化***************************
void timer1_init(void)
{
TCCR1B=0x00; //清零
TCNT1=0x0000; //计数器赋初值
OCR1A=0xc8; //A路比较值(***OCR1A/OCR1B中的值不得超过ICR1的值***)
ICR1=0x0190; //400,即8khz
//改变频率-ICR1(反比)
TCCR1A=0xA2;
TCCR1B=0x13 ; //无预分频 8分频
}
//---------------------------------------------------
//*****************主程序*********************************
//---------------------------------------------------------
#pragma interrupt_handler timer1_ovf_isr:7
#pragma interrupt_handler timer1_ovf_isr:8
/*---------------------------------------------------------*/
//***********定时器T1中断程序***************************
/*---------------------------------------------------------*/
uchar i=0;
void timer1_ovf_isr(void)
{
OCR1A=spwm[i++]; //重新赋初值
if(i>=200)
{
i=0;
}
}
void main(void)
{
unsigned int top=0x0190;//////0x258;0x002c;0x0050;
DDRB=0xFF;
PORTB=0xff;
timer1_init(); //初始化定时器T1
TIMSK=0x18; //开比较中断
SEI(); //开全局中断
OCR1A=0;
while (1)
{
}
} |
|