|
楼主 |
发表于 2008-2-13 15:41:50
|
显示全部楼层
此程序利用定时器3 在OC3B引脚上产生一个320HZ的正弦波电压:
//ICC-AVR application builder : 2006-8-4 11:06:22
// Target : M128
// Crystal: 14.7456Mhz
#include <iom128v.h>
#include <macros.h>
#include <math.h>
#define U8 unsigned char
#define U16 unsigned int
#define U32 unsigned long
#define I8 signed char
#define I16 signed int
#define I32 signed long
#define F32 float
//-----------------------------------------------------------------------------
// 变量
I16 SinTable[36]={0}; //正弦表(用于小数乘法)
I16 CosTable[36]={0}; //余弦表(用于小数乘法)
I16 PWMTable[36]={0}; //PWM波形表
U16 FrqCnt=0; //分频计数
U16 PWMCnt=0; //PWM计数
U16 DFTCnt=0; //DFT计数
U16 TestPointCnt=0; //测试点数计数
I32 au1=0,bu1=0,au2=0,bu2=0; //测试矢量
U16 PointNum=36; //每周波点数
U16 WaveNum=32; //周波数
U16 TestNum=36*32; //总测试点数
#define PointNum 36 //PWM点数
//=============================================================================
// 端口初始化
//=============================================================================
void port_init(void)
{
PORTA = 0xFF;
DDRA = 0x00;
PORTB = 0xFF;
DDRB = 0x43;//CAN-RST/,SCK,CAN-CS OUT
PORTC = 0xFF; //m103 output only
DDRC = 0x00;
PORTD = 0xFF;
DDRD = 0x00;
PORTE = 0xE4;
DDRE = 0x10; //BIT4 :OC3B OUT 0, BIT2:CAN-INT/ IN 1,
PORTF = 0xFC;
DDRF = 0x00; // ADC0,ADC1 IN 高阻态
PORTG = 0x18;
DDRG = 0x18; // BIT4,BIT3:LED OUT 1,BIT2 ALE,BIT1 RD/,BIT0 WR/
}
//ADC initialisation
// Conversion time: 56uS
void adc_init(void)
{
ADCSRA = 0x00; //disable adc
ADMUX = 0xc0; //2.56V 片内基准电压,转换结果右对齐,精度10位,模拟通道0
ACSR = 0x80;
ADCSRA = 0x81;//ADEN,ADSC=0,ADFR=0,ADIF=0,ADIE=0,CLOCK/2,停止连续转换
}
//=============================================================================
// 定时器3初始化
//=============================================================================
//TIMER3 initialisation - prescale:8
// WGM: 10) PWM phz correct, TOP= ICRn ,OCRn更新时刻:bottom
// desired value: 23040Hz
// actual value: 23040.00Hz (0.0%)
void timer3_init(void)
{
TCCR3B = 0x00; //stop
TCNT3H = 0xFE; //setup
TCNT3L = 0xC0;
OCR3AH = 0x01;
OCR3AL = 0x40;
OCR3BH = 0x01;
OCR3BL = 0x40;
OCR3CH = 0x01;
OCR3CL = 0x40;
ICR3H = 0x01; //top=320
ICR3L = 0x40; //升序计数时,比较匹配清零,降序计数时置位OC3B
TCCR3A = 0x20; // 1000相位、频率校正PWM, OC3B输出 预分频1
//TCCR3B = 0x11;
ETIMSK|= 0x04; //使能T3溢出中断
}
#pragma interrupt_handler timer3_ovf_isr:30
void timer3_ovf_isr(void)//正弦波频率320Hz
{
unsigned long int j;
unsigned long int i;//TIMER3 has overflowed
static I16 AD0;
static I16 AD1;
if (++FrqCnt>=2)
{
FrqCnt=0;
SEI();
OCR3BH = PWMTable[PWMCnt]>>8; //reload counter high value
OCR3BL = PWMTable[PWMCnt]; //reload counter low value
if (++PWMCnt>=PointNum)
{PWMCnt=0;}
if(ADCSRA&(1<<ADIF))
{
AD0=ADCL|(ADCH<<8); //ADCH*256+ADCL, 取值
}
ADMUX=0xc1; //2.56V 片内基准电压,转换结果右对齐,精度10位,模拟通道1
ADCSRA|= (1<<ADEN); //ADEN,ADSC,-,-,-,CLOCK/64,单次转换
ADCSRA|= (1<<ADSC);
if(ADCSRA&(1<<ADIF))
{
AD1=ADCL|(ADCH<<8); //ADCH*256+ADCL, 取值
}
ADMUX =0xc0;
ADCSRA|= (1<<ADEN);
ADCSRA|= (1<<ADSC);
}
}
//call this routine to initialise all peripherals
void init_devices(void)
{
//stop errant interrupts until set up
CLI(); //disable all interrupts
XDIV = 0x00; //xtal divider
XMCRA = 0x00; //external memory
port_init();
adc_init();
timer3_init();
MCUCR = 0x00;
EICRA = 0x00; //extended ext ints
EICRB = 0x00; //extended ext ints
EIMSK = 0x00;
TIMSK = 0x00; //timer interrupt sources
ETIMSK = 0x04; //extended timer interrupt sources
SEI(); //re-enable interrupts
//all peripherals are now initialised
}
//============================================================================
// 延时子程序(毫秒)
//============================================================================
void delay_ms(unsigned int t)
{
unsigned int i=0;
for(i=0;i<t;i++){
delay(982);
WDR();
}
}
//============================================================================
// 延时子程序(微秒)
//============================================================================
void delay(unsigned int t)
{ asm("push r24");
asm("in r24,0x3f");
asm("push r24");
asm("push r25");
asm("clr r24");
asm("clr r25");
asm("_loopu::nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("subi r24,-1");
asm("sbci r25,-1");
asm("cp r24,%t");
asm("cpc r25,r17");
asm("brlo _loopu");
asm("pop r25");
asm("pop r24");
asm("out 0x3f,r24");
asm("pop r24");
}
void main(void)
{
unsigned long int i;
unsigned long int j;
init_devices();
timer3_init();
ETIMSK|=0x04;
ADCSRA|=(1<<ADIF);
ADCSRA|=BIT(ADSC);
SEI();
ADMUX =0xc0;
ADCSRA|=BIT(ADSC);
PORTG=0X00;
while(1)
{
for (i=0;i<PointNum;i++)
{
PWMTable=160-90*sin(2*3.14159*i/PointNum);
}
TCCR3B = 0x11;
}
} |
|