/*
Config
PIN21(PD7):PWM Output;
PIN18~20: Button1~3 Input;
PIN14~17: Display_Select Output;
PIN1~8: Display_Data Output;
*/
#include <iom16v.h>
#include <macros.h>
#define uchar unsigned char
#define uint unsigned int
#define BUT1 PD4
#define BUT2 PD5
#define BUT3 PD6
const uchar PWM[101]={
0, 2, 4, 7, 9, 12, 14, 17, 19, 22,
25, 27, 30, 32, 35, 37, 40, 43, 45, 48,
50, 53, 55, 58, 60, 63, 66, 68, 71, 73,
76, 78, 81, 83, 86, 89, 91, 94, 96, 99,
101, 104, 107, 109, 112, 114, 117, 119, 122, 124,
127, 130, 132, 135, 137, 140, 142, 145, 147, 150,
153, 155, 158, 160, 163, 165, 168, 171, 173, 176,
178, 181, 183, 186, 188, 191, 194, 196, 199, 201,
204, 206, 209, 211, 214, 217, 219, 222, 224, 227,
229, 232, 235, 237, 240, 242, 245, 247, 250, 252,
254}; //%0~%100 8Bit PWM DATA
uchar display_data[4]={0xBF, 0xBF, 0xBF, 0xBF};
void Display_integer(uint itg)
{
const uchar seg7[10]={
0xC0, 0xF9, 0xA4, 0xB0, 0x99,
0x92, 0x82, 0xF8, 0x80, 0x90};
const uint exp10[4]={1, 10, 100, 1000};
uchar i, j;
display_data[1]=0xFF;
display_data[2]=0xFF;
display_data[3]=0xFF;
if(itg > 9999)
{
display_data[0]=0xBF;
return; //判断是否超过4位
}
j=1;
if(itg > 999)
j=4;
else if(itg > 99)
j=3;
else if(itg > 9)
j=2;
for(i=0;i<j;i++)
display_data = seg7[(itg % exp10[i+1] /exp10)];
}
void Delayms(uint MS)
{
uint i,j;
for( i=0;i<MS;i++)
for(j=0;j<2282. ;j++); //1141是在8MHz晶振下,通过软件仿真反复实验得到的数值
}
void port_init(void)
{
DDRD = 0x8F;
PORTD = 0xFF;
DDRB = 0xFF;
PORTB = 0xFF;
}
void timer0_init(void)
{
TCCR0 = 0x00;
TCNT0 = 128;
TCCR0 = 0x04; //start timer
}
#pragma interrupt_handler timer0:iv_TIMER0_OVF
void timer0(void)
{
static unsigned char i=0;
TCNT0 = 128; //reload counter value
if(i > 3)
i=0;
PORTD = BIT(i)|0b11110000;
PORTB = display_data;
i++;
}
//TIMER2 initialize - prescale:1
// WGM: PWM Fast
// desired value: 31250Hz
// actual value: 31250.000Hz (0.0%)
void timer2_init(void)
{
TCNT2 = 0x00; //setup
OCR2 = 127; //50%
TCCR2 = BIT(WGM20)|BIT(WGM21)|BIT(COM21)|BIT(CS20); //start
}
//call this routine to initialize all peripherals
void init_devices(void)
{
//stop errant interrupts until set up
CLI(); //disable all interrupts
port_init();
timer2_init();
timer0_init();
TIMSK = 0x01;
SEI(); //re-enable interrupts
//all peripherals are now initialized
}
void main(void)
{
uint percent=50;
Display_integer(50);
init_devices();
while(1)
{
if(!(BIT(BUT1)&PIND))
{
Delayms(10);
if(!(BIT(BUT1)&PIND))
{
if(percent == 100)
continue;
Delayms(200);
percent++;
OCR2 = PWM[percent];
Display_integer(percent);
}
}
if(!(BIT(BUT2)&PIND))
{
Delayms(10);
if(!(BIT(BUT2)&PIND))
{
if(percent == 0)
continue;
Delayms(200);
percent--;
OCR2 = PWM[percent];
Display_integer(percent);
}
}
if(!(BIT(BUT3)&PIND))
{
Delayms(10);
if(!(BIT(BUT3)&PIND))
{
Delayms(200);
percent = 50;
OCR2 = PWM[percent];
Display_integer(percent);
}
}
}
}