avr-51板的pwm實驗, 利用pwm控制led光暗及峰鳴器音量大小.
//ICC-AVR application builder : 2005-4-18 12:46:03// Target : M16
// Crystal: 4.0000Mhz
#include <iom16v.h>
#include <macros.h>
#define uchar unsigned char
#define uint unsigned int
void port_init(void);
void timer0_init(void);
void init_devices(void);
void delay_short(uint t);
uchar scan_key(void);
void port_init(void)
{
PORTA = 0x00;
DDRA= 0x00;
PORTB = BIT(PB3);
DDRB= BIT(PB3);
PORTC = 0x00; //m103 output only
DDRC= 0x00;
PORTD = 0x00;
DDRD= 0x00;
}
// WGM: PWM Phase correct
// desired value: 1KHz
// actual value:0.980KHz (-2.0%)
void timer0_init(void)
{
TCCR0 = 0x00; //stop
TCNT0 = 0x01; //set count
OCR0= 0xFF;//set compare
TCCR0 = 0x62; //start timer ; 相位修正, 8分頻
}
//call this routine to initialize all peripherals
void init_devices(void)
{
//stop errant interrupts until set up
CLI(); //disable all interrupts
port_init();
timer0_init();
MCUCR = 0x00;
GICR= 0x00;
TIMSK = 0x00; //timer interrupt sources
SEI(); //re-enable interrupts
//all peripherals are now initialized
}
void delay_short(uint t) // 短延時
{
uint i;
for (i=0;i<t;i++);
}
uchar scan_key(void)// 按鍵掃瞄
{
uchar v;
v = 0;
if ((PIND & 0x07) != 0x07)
{
if ((PIND & 0x01) == 0)
{
v = 1;
delay_short(1000);
}
if ((PIND & 0x2) == 0)
{
v = 2;
delay_short(1000);
}
if ((PIND & 0x4) == 0)
{
v = 3;
delay_short(1000);
}
};
while((PIND & 0x07) != 0x07); // 判斷按鍵是不是放開
return v;
}
//
void main(void)
{
uchar key, OCR0_V;
init_devices();
OCR0_V = 0xff;
while(1)
{
key = scan_key();
if (key > 0)
{
if (key==1) // 減少佔空比
{
OCR0_V -= 10;
OCR0 = OCR0_V;
};
if (key==2) // 增加佔空比
{
OCR0_V += 10;
OCR0 = OCR0_V;
};
if (key==3) // 全黑,佔空比為100%
{
OCR0_V = 0xff;
OCR0 = OCR0_V;
};
}
};
}
實驗板接線:
PB3 -----> JA.1 及 JM
PD0 -----> K1
PD1 -----> K2
PD2 -----> K3 發覺led在佔空比大於20%, led的光暗就不明顯了...
用pwm做led白光燈可以省70%以上的電啊!! 好好好好,正郁闷怎么利用avr51实验板呢。
谢谢。 你的有意思 请问一个新手问题: 就是TCNT0的初始值的计算和设置
---------根据myhk007 提供的算法--------
最原始的方法:以T0记到255溢出为例,如果AVR的主频是8M,T0为1024分频的话,那么T0每加1,需要的时间就是1024/8000000,加255次的总共延时就是1024/8000000*255,依次类推。
--------------------------------------
如果"TCNT0 = 0x01; " ,则计数次数应为255次, 总时间应为 255*8/4000000=0.00051s, 频率应是约2kHz, 而楼主上面的代码中是1kHz, 困惑中~~!
是否我什么地方还没理解正确 這可能是icc的bug吧,pwm的代碼我是用icc的自生成做的(說明也是icc加上去的), 我做的時候就沒有認真的計算過,因為只是做實驗! 用示波器看了一下波形, 跟想像的形状差不多, 这个实验很有意思 果然有意思,在proteus防真,效果不错哟 avrboy:
有跳线图吗?我也想试试。 哎呀,对不起!我再次看时见到了跳线了。我试试。有情况再请教 哎呀,对不起!我再次看时见到了跳线了。我试试。有情况再请教 avrboy:iccavr在那里下载?双龙的只是45天的演示版 我终于又能在实验板上运行。在示波器上也能清楚地看到波形。谢谢! 非GCC的,不要。
呵呵 请问这个试验板的资源有哪些啊?如果有图片就好了。我想买一块?是否是AVR和51都有? 在相位修正模式中,上,下记数怎么理解 刚做了一块实验板,正好在上面试试。 赞楼主,不错 不错,我已经按楼主的方法做了一个DEMO板,效果还不错,
小弟按自己的意见稍加改动了,各位大哥给点建议。
//***********************PWM 程序*********************
//***********************PWM 程序*********************
//***********************PWM 程序*********************
//ICC-AVR application builder : 2005-4-18 12:46:03
// Target : M16
// Crystal: 4.0000Mhz
#include <iom8515v.h>
#include <macros.h>
#define uchar unsigned char
#define uint unsigned int
//****************定义过程中要的程序***********************//
void port_init(void);
void timer0_init(void);
void init_devices(void);
void delay_short(uint t);
uchar scan_key(void);
void port_init(void)
{
PORTA = 0x00;
DDRA= 0x00;
PORTB = BIT(PB0);
DDRB= BIT(PB0);
PORTC = 0x00; //m103 output only
DDRC= 0x00;
PORTD = 0x38;///config my testing board
DDRD= 0x38;
}
// WGM: PWM Phase correct
// desired value: 1KHz
// actual value:0.980KHz (-2.0%)
void timer0_init(void)
{
TCCR0 = 0x00; //stop//控制寄存器,此时为无时钟,不工作//
TCNT0 = 0x01; //set count
OCR0= 0xFF;//set compare
TCCR0 = 0x62; //start timer ; 相位修正, 8分頻
}
//call this routine to initialize all peripherals
void init_devices(void)
{
//stop errant interrupts until set up
CLI(); //disable all interrupts
port_init();
timer0_init();
MCUCR = 0x00;
GICR= 0x00;
TIMSK = 0x00; //timer interrupt sources
SEI(); //re-enable interrupts
//all peripherals are now initialized
}
void delay_short(uint t) // 短延時
{
uint i;
for (i=0;i<t;i++);
}
uchar scan_key(void)// 按鍵掃瞄
{
uchar v;
v = 0;
if ((PIND & 0x38) != 0x38)
{
if ((PIND & 0x10) == 0)//config my testing board
{
v = 1;
delay_short(1000); //delay 去抖处理//
}
if ((PIND & 0x20) == 0)
{
v = 2;
delay_short(1000);
}
if ((PIND & 0x08) == 0)
{
v = 3;
delay_short(1000);
}
};
while((PIND & 0x38) != 0x38); // 判斷按鍵是不是放開
return v;
}
//
void main(void)
{
uchar key, OCR0_V;
init_devices();
OCR0_V = 0xe6;
while(1)
{
key = scan_key();
if (key > 0)
{
if (key==1) // 減少佔空比
{
OCR0_V -= 10;
if(OCR0_V<11)
{
OCR0_V = 0x0b;
OCR0 = OCR0_V;
}
else
{
OCR0 = OCR0_V;
}
};
if (key==2) // 增加佔空比
{
OCR0_V += 10;
if(OCR0_V>240)
{
OCR0_V = 0xe7;
OCR0 = OCR0_V;
}
else
{
OCR0 = OCR0_V;
}
};
if (key==3) // 全黑,佔空比為100%
{
OCR0_V = 0x00;
OCR0 = OCR0_V;
OCR0_V = 0x0a;
};
}
};
} 消化一下 avrboy =單騙皇帝=
你的联系是多少呀?我的QQ是641677143,想和你交流一下,感觉你做的不错! 好奇怪哦,我的程序就是运行不出这样的效果,看不到灯的亮度变化。。 mark 很好用 mark 这个要记号…… 留个爪子 印记 mark mark mark pwm,mark 我学的是ATTINY13!希望高手指点!这个程序能移植到ATTINY13里能用吗?谢谢! mark 谢谢分享
页:
[1]