上海石油期货交易中心:PWM生成正弦波的频率可变的程序

来源:百度文库 编辑:中财网 时间:2024/05/05 17:53:36
 
// Target : M32 
// Crystal: 4.0000Mhz 

#include  
#include 

#include "delay.h"
//#include                      // Use IAR-AVR library

#define uchar unsigned char 
#define uint unsigned int
#define   N     98


// 正弦波样本表 
__flash unsigned char auc_sinparam[N] = { 
  
    128,136,144,152,160,168,175,183,190,197,204,210,216,222,227,232,
237,241,244,247,250,252,253,254,255,255,254,253,252,250,247,244,
241,237,232,227,222,216,210,204,197,190,183,175,168,160,152,144,
136,128,119,111,103,95,87,80,72,65,58,51,45,39,33,28,
23,18,14,11,8,5,3,2,1,0,0,1,2,3,5,8,
11,14,18,23,28,33,39,45,51,58,65,72,80,87,95,103,
111,119
}; 

unsigned int  x_sw=1; 
unsigned int  indexU=0;  
unsigned int  indexV=N/3;  
unsigned int  indexW=2*N/3;


//timer0溢出中断
#pragma vector=TIMER0_OVF_vect 
__interrupt void timer0_ovf_isr(void) 
{  
    
    indexU+=x_sw;   
    if(indexU>(N-1))   indexU-=N;   
    OCR0  = auc_sinparam[indexU];
    
    indexV+=x_sw;
    if(indexV>(N-1))   indexV-=N;
    OCR1A = auc_sinparam[indexV];
    
    indexW+=x_sw;
    if(indexW>(N-1))   indexW-=N;
    OCR1B = auc_sinparam[indexW];



  
void system_init (void)
{
    //port init
    PORTB=0xf7;   
    DDRB=0xff; //PB3--OC0
    
    PORTD=0xff;//pd0-pd3 pull-up enable for key1-key4
    DDRD=0x30;//PD4--OC1A,PD5--0C1B
    
    //timer0 init   
    TCCR0=0x00;   
    OCR0=0xff; //初始值占空比为0
    TCCR0=0x62;//相位修正  8分频  正向输出  启动定时器
    
    //time1 init
    TCCR1A= 0x00;
    OCR1A = 0xff;//正向输出
    OCR1B = 0xff;//正向输出
    //ICR1  = 0xff;
    TCCR1A= 0xa1;
    TCCR1B= 0x02;//相位修正 8分频   启动定时器
    
    indexU=0;  
    indexV=N/3;  
    indexW=2*N/3; 
      
    TIMSK=0x01;//time0 over interrupt
    __enable_interrupt(); //re-enable interrupts
}


void main(void) 

    uchar tem,key;
    system_init();//系统初始化
    while(1) 
    {
        tem=0x0f&PIND;       //读取端口b
        if(tem!=0x0f)   //判断是否有按键按下
        {
  //s_ms(50);   //排除按键抖动和抗干扰
  delay_nms(35);
          key=0x0f&PIND;
  if(key==tem)
  {
            x_sw++;
            if(x_sw==6) x_sw=1;
            if(x_sw==1) //fsin=10hz
            {
              PORTB=(1<              PORTB&=~(1<            }
            if(x_sw==2)//fsin=20hz 
            {
              PORTB=(1<              PORTB&=~(1<            }
            if(x_sw==3)//fsin=30hz 
            {
              PORTB=(1<              PORTB&=~(1<            }
            if(x_sw==4)//fsin=40hz 
            {
              PORTB=(1<              PORTB&=~(1<            }
            if(x_sw==5)//fsin=50hz 
            {
              PORTB=(1<              PORTB&=~(1<            }
            //PORTB=0x0f|(key<<4);  //端口D输出按键值
          }
}
        //speed_switch();//按键调速
    }


上面的程序有两个错误:、
1、用示波器看到的正弦波频率不是20hz,40hz,60hz,80hz,100hz,而是10hz,20hz,30hz,40hz,50hz,请问是为什么

2、用示波器观察发现:随正弦波频率增大,正弦波幅值会越来越小,请问是为什么