中科因仑“3+1”工程特种兵精英论坛
标题:
PWM输出
[打印本页]
作者:
张衍波
时间:
2015-4-8 13:25
标题:
PWM输出
#define MAIN_C
#include "includes.h"
/***************************/
/*PWM*/
/*晶振为4MHz*/
/*利用Timer1的OC1A脚输出占空比可调的信号*/
/*通过按键控制OCR1A的值*/
/***************************/
#define PwmOut PD5 //A通道的PWM输出
#define OCR OCR1A
#define KeyUp PA0 //增大PWM值的按键
#define KeyDown PA1 //减小PWM值的按键
#define Above PA2 //设置位值过高指示
#define Below PA3 //设置位值过低指示
#define STEP 64 //定义按键时的步进值
int OcrReg = 1024; //OCR1A初始值
int Icr1Reg = 0x7ff; //PWM的计数顶部值 Icr1Reg = 2047
//unsigned char *show = "0000";
unsigned char temp;
void init(void) //初始化函数
{
//比较匹配时清零,计数到最大时置位OC1A
TCCR1A |= (1<<COM1A1)|(1<<WGM11);
//11位分辨率,快速PWM模式,使用系统时钟作为计数时钟
TCCR1B |= (1<<WGM13)|(1<<WGM12)|(1<<CS10);
ICR1 = Icr1Reg;
OCR = 0 ;
DDRD |= (1<<PwmOut); //置PWM为输出
DDRA |= (1<<Above)|(1<<Below); //指示灯定义为输出
DDRA &= ~((1<<KeyUp)|(1<<KeyDown)); //按键定义为输入
PORTA |= (1<<KeyUp)|(1<<KeyDown); //按键开启上拉
PORTA |= (1<<Above)|(1<<Below); //关闭两个指示灯
//TIMSK |= (1<<OCIE1A); //允许计数器比较匹配中断
//SREG |= (1<<7); //开全局中断
}
void ShowValue(int value)
{
unsigned char *temp = "0000";
temp[0] = value/1000 + 0x30;
value = value%1000;
temp[1] = value/100 +0x30;
value = value%100;
temp[2] = value/10 + 0x30;
value = value%10;
temp[3] = value + 0x30;
ClearLine(2);
LCD_DisplayString(2,1,"OCR1A = ");
LCD_DisplayString(2,9,temp);
}
void main(void)
{
unsigned char i;
init();
Init_LCD();
OCR = OcrReg;
LCD_DisplayString(1,1,"PWM test");
LCD_DisplayString(2,1,"OCR1A = ");
ShowValue(OcrReg);
while(1)
{
if(!(PINA&(1<<KeyUp)))
{
delay_nms(10); //按键消抖
if(!(PINA&(1<<KeyUp)))
{
while(!(PINA&(1<<KeyUp))); //等待按键释放
if(OcrReg >= (Icr1Reg+1))
{
for(i=0;i<5;i++)
{
PORTA ^= (1<<Above);
delay_nms(200);
}
ClearLine(2);
LCD_DisplayString(2,1,"Value MAX!");
}
else
{
PORTA |= (1<<Above);
OcrReg += STEP;
OCR = OcrReg;
ShowValue(OcrReg);
}
}
}
if(!(PINA&(1<<KeyDown)))
{
delay_nms(10); //按键消抖
if(!(PINA&(1<<KeyDown)))
{
while(!(PINA&(1<<KeyDown))); //等待按键释放
if(OcrReg <= 0)
{
for(i=0;i<5;i++)
{
PORTA ^= (1<<Below);
delay_nms(200);
}
ClearLine(2);
LCD_DisplayString(2,1,"Value MIN!");
}
else
{
PORTA |= (1<<Below);
OcrReg -= STEP;
OCR = OcrReg;
ShowValue(OcrReg);
}
}
}
}
}
//比较中断子程序,可以用来产生正弦波
/*#pragma vector = TIMER1_COMPA_vect
__interrupt void CompA_isr( void )
{
OcrReg = st[j];
OCR = OcrReg;
j++;
if(j>88)
{
j = 0;
}
}*/
[attach]2125[/attach]
欢迎光临 中科因仑“3+1”工程特种兵精英论坛 (http://bbs.enlern.com/)
Powered by Discuz! X3.4