|
马老师:
我刚刚接触AVR单片机,目前我在做一个程序,使用M8输出频率和占空比均可调节的波形.
选用相位与频率可调模式,使用OCB1为输出;PORTD为输入端(低5位分别对应5个不同的频率值,高3位对占空比进行调节)
使用ICCAVR编译C代码,用AVR STUDIO4进行仿真,但在对定时器1初始化后,OCR1AH,OCR1BH和TCNT1H的值均自动清零;而在后面对OCR1A的写入时,都是写入高位和低位后执行下一条指令后,OCR1AH自动清零.难道是访问16位寄存器时出的问题,可我写入时都是先写高八位,再写低八位,不清楚,求教.
程序代码如下:
//ICC-AVR application builder : 2008-3-20 15:39:09
// Target : M88
// Crystal: 8.0000Mhz
#include<iom88v.h>
#include<macros.h>
void port_init(void)
{
PORTB = BIT(PB2);
DDRB = BIT(PB2);
PORTC = 0x00; //m103 output only
DDRC = 0x00;
PORTD = 0xfe;
DDRD = 0x00;
PIND = 0xFE;
}
//TIMER1 initialize - prescale:1
// WGM: 9) PWM phz freq correct, TOP=OCRnA
// desired value: 73Hz
// actual value: 73.001Hz (0.0%)
void timer1_init(void)
{
TCCR1B = 0x10; //stop
TCNT1H = 0x29; //setup
TCNT1L = 0xF6;
OCR1AH = 0xD6;
OCR1AL = 0x0A;
OCR1BH = 0x6B;
OCR1BL = 0x05;
TCCR1A = 0x11;
TCCR1B = 0x11; //start Timer
}
//call this routine to initialize all peripherals
void init_devices(void)
{
//stop errant interrupts until set up
CLI(); //disable all interrupts
port_init();
timer1_init();
MCUCR = 0x00;
EICRA = 0x00; //extended ext ints
EIMSK = 0x00;
TIMSK0 = 0x00; //timer 0 interrupt sources
TIMSK1 = 0x00; //timer 1 interrupt sources
TIMSK2 = 0x00; //timer 2 interrupt sources
PCMSK0 = 0x00; //pin change mask 0
PCMSK1 = 0x00; //pin change mask 1
PCMSK2 = 0x00; //pin change mask 2
PCICR = 0x00; //pin change enable
PRR = 0x00; //power controller
SEI(); //re-enable interrupts
//all peripherals are now initialized
}
void delay_short(int t) // 短延時
{
int i;
for (i=0;i<t;i++);
}
char scan_key1(void) // 按鍵掃瞄
{
char s;
s = 0;
if ((PIND & 0x1f) != 0x1f)
{
if ((PIND & 0x01) == 0)
{
s = 1;
delay_short(1000);
}
if ((PIND & 0x2) == 0)
{
s = 2;
delay_short(1000);
}
if ((PIND & 0x4) == 0)
{
s = 3;
delay_short(1000);
}
if ((PIND & 0x8) == 0)
{
s = 4;
delay_short(1000);
}
if ((PIND & 0x10) == 0)
{
s = 5;
delay_short(1000);
}
PIND=0xff;
};
while((PIND & 0x1f) != 0x1f); // 判斷按鍵是不是放開
return s;
}
char scan_key2(void) // 按鍵掃瞄
{
char v;
v = 0;
if ((PIND & 0xe0) != 0xe0)
{
if ((PIND & 0x20) == 0)
{
v = 1;
delay_short(1000);
}
if ((PIND & 0x40) == 0)
{
v = 2;
delay_short(1000);
}
if ((PIND & 0x80) == 0)
{
v = 3;
delay_short(1000);
}
};
while((PIND & 0xe0) != 0xe0); // 判斷按鍵是不是放開
return v;
}
void main(void)
{
char key1,key2,OCR1_VH,OCR1_VL;
init_devices();
OCR1_VL = OCR1AL;
OCR1_VH = OCR1AH;
while(1)
{
key1 = scan_key1();
if (key1 > 0)
{
if (key1==1) // 设定频率值
{
OCR1AH = 0x6B;
OCR1AL = 0x05;
OCR1BH = 0x35;
OCR1BL = 0x82;
};
if (key1==2) // 设定频率值
{
OCR1AH = 0x35;
OCR1AL = 0x82;
OCR1BH = 0x1A;
OCR1BL = 0xC1;
};
if (key1==3) //设定频率值
{
OCR1AH = 0x1A;
OCR1AL = 0xC1;
OCR1BH = 0x0D;
OCR1BL = 0x60;
};
if (key1==4) // 设定频率值
{
OCR1AH = 0x0D;
OCR1AL = 0x60;
OCR1AH = 0x06;
OCR1AL = 0xB0;
};
if (key1==5) // 设定频率值
{
OCR1AH = 0x06;
OCR1AL = 0xB0;
OCR1AH = 0x03;
OCR1AL = 0x5B;
};
}
key2 = scan_key2();
if (key2 > 0)
{
if (key2==1) // 減少佔空比
{
if(OCR1_VL > 100)
{
OCR1_VL -= 100;
}
else
{
if (OCR1_VH > 0)
{
OCR1_VH -= 1;
OCR1_VL += 156;
}
else
{
OCR1_VH = 0;
OCR1_VL= 0;
}
}
OCR1BH = OCR1_VH;
OCR1BL = OCR1_VL;
};
if (key2==2) // 增加佔空比
{
if(OCR1_VL < 156)
{
OCR1_VL += 100;
}
else
{
if (OCR1_VH < 255)
{
OCR1_VH += 1;
OCR1_VL -= 156 ;
}
else
{
OCR1_VH = 0xFF;
OCR1_VL = 0xFF;
}
}
OCR1BH = OCR1_VH;
OCR1BL = OCR1_VL;
};
if (key2==3) // 全黑,佔空比為100%
{
OCR1_VH = OCR1AH;
OCR1_VL = OCR1AL;
OCR1BH = OCR1_VH;
OCR1BL = OCR1_VL;
};
}
};
} |
阿莫论坛20周年了!感谢大家的支持与爱护!!
曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……
|