老师们
你们好,我最近刚学习单片机,写的是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};*/
//=====================周期为20ms,spwm频率为20k===========================//
short list2[]={
0,4,7,10,13,16,19,22,25,28,31,34,37,39,42,45,48,51,54,57,60,
62,65,68,71,74,76,79,82,84,87,90,92,95,97,100,103,105,108,110,112,115,117,
119,122,124,126,128,131,133,135,137,139,141,143,145,147,149,151,152,154,156,
157,159,161,162,164,165,167,168,169,171,172,173,174,176,177,178,179,180,181,
182,182,183,184,185,185,186,186,187,187,188,188,189,189,189,189,189,189,189,
189,189,189,189,189,189,189,188,188,187,187,186,186,185,185,184,183,182,182,
181,180,179,178,177,176,174,173,172,171,169,168,167,165,164,162,161,159,157,
156,154,152,151,149,147,145,143,141,139,137,135,133,131,128,126,124,122,119,
117,115,112,110,108,105,103,100,97,95,92,90,87,84,82,79,76,74,71,68,65,62,
60,57,54,51,48,45,42,39,37,34,31,28,25,22,19,16,13,10,7,4,0
};
unsigned int k=0;
//****************系统初始化***************************
void timer1_init(void)
{
TCCR1B=0x00; //清零
TCNT1=0x0000; //计数器赋初值
OCR1A=0xc8; //A路比较值(***OCR1A/OCR1B中的值不得超过ICR1的值***)
OCR1B=0xc8;
ICR1=200; //400,即8khz
//改变频率-ICR1(反比)
TCCR1A=0xA2; //BIT1:0波形发生 BIT3:2通道AB强制输出比较,非PWM时被激活,PWM必须清0 BIT7:4通道A/B输出模式。
TCCR1B=0x11; //BIT2:0时钟选择位 BIT4:3波形发生位 BIT5保留位必须为0,BIT6输入捕捉触发边沿BIT7输入捕捉噪声抑制器
} // WGM3:0 1010 相位修正PWM TOP=ICR1,OCR1X在TOP更新。TOV1在BOTTOM置位。
// CS12:0 011 64分频
// COMA1:B0 1010 在相位修正模式下 OC1A/OC1B升序匹配清0,降序匹配置位
//--------------------------------------------------- -----
//*****************主程序*********************************
//---------------------------------------------------------
#pragma interrupt_handler timer1_ovf_isr:7
#pragma interrupt_handler timer1_ovf_isr:8
/*---------------------------------------------------------*/
//***********定时器T1中断程序***************************
/*---------------------------------------------------------*/
volatile int i=0;
void timer1_ovf_isr(void)
{
k++;
if(i<200)
{
OCR1A=list2[i++]; //重新赋初值
}
else if((i>=200)&&(i<400))
{
OCR1B=list2[(i++)-200];
}
else i=0;
}
void main(void)
{
//unsigned int top=0x0190;//////0x258;0x002c;0x0050;
DDRB=0xFF;
PORTB=0xff;
timer1_init(); //初始化定时器T1
TIMSK=0x18; //开比较中断
//7 TC2输出比较匹配使能 0
//6 TC2溢出使能 0
//5 TC1输入捕捉中断使能 0
//4 TC1A输出比较A匹配使能 1
//3 B匹配 1
//2 TC1溢出中断使能 TOV1职位就开始执行中端程序 0
//1 0
//0 TC0 中断使能 0
SEI(); //开全局中断
OCR1A=0;
OCR1B=0;
while (1)
{
}
}
OCR1A,OCR1B都能匹配。。但是计数器由BOTTOM到了TOP以后不返回到BOTTOM,而是继续到0X1FF,但是我在程序里面设置的模式是WGM13:0=10,不是3.我在AVR STUDIO里面仿真一直都不是按BOTTOM-ICR1-BOTTOM的模式.不知道是编译器仿真不准,还是这个程序有错误。多方请教,无人解答。希望能在论坛里面得到答
案。另外我结合PROTUES仿真发现OCR1A或者OCR1B匹配时中断只有100个脉宽不同的方波,我的不是200个样本点吗。怎么少了100个 |