|
/**
主控MCU:STC15F104W
開關(guān):INT0(P3.2) 下降沿觸發(fā)
亮度增加:INT2(P3.4) 下降沿觸發(fā)
亮度減少:INT3(P3.5) 下降沿觸發(fā)
PWM輸出:P3.3
**/
#include <reg51.h>
#include <intrins.h>
//#define FOSC 24000000L //晶振頻率
#define FOSC 6000000L //晶振頻率
#define MACHINE_CYCLE (FOSC / 1000000) //時(shí)鐘震蕩6次1μs
#define _1US 1 //1us
#define _50US 50 //50us
#define _100US 100 //100us
#define _150US 150 //150us
#define _200US 200 //200us
#define _250US 250 //250us
sfr INT_CLKO = 0x8f; //外部中斷與時(shí)鐘輸出控制寄存器
sfr AUXR = 0x8e; //輔助寄存器
sfr P3M1 = 0xB1; //P3口寄存器
sfr P3M0 = 0xB2;
signed int duty_cycle; //占空比,0-10,帶符號(hào)
unsigned int init_value; //定時(shí)器初值
unsigned int count; //定時(shí)器中斷次數(shù)
sbit pwm = P3 ^ 3; //PWM輸出口
bit flag; //燈開關(guān)狀態(tài)
//INT0初始化程序
void init_int0(void)
{
INT0 = 1;
IT0 = 1; //設(shè)置INT0的中斷類型 (1:僅下降沿 0:上升沿和下降沿)
EX0 = 1; //使能INT0中斷
}
//INT2初始化程序
void init_int2(void)
{
INT_CLKO |= 0x10; //(EX2 = 1)使能INT2中斷
}
//INT3初始化程序
void init_int3(void)
{
INT_CLKO |= 0x20; //(EX3 = 1)使能INT3中斷
}
//初始化計(jì)時(shí)值
void set_tm0_init_value(unsigned int value) reentrant
{
switch(value) {
case 50:
TL0 = (65536 - (_50US * MACHINE_CYCLE)) % 256;
TH0 = (65536 - _50US * MACHINE_CYCLE) / 256;
break;
case 100:
TL0 = (65536 - _100US * MACHINE_CYCLE) % 256;
TH0 = (65536 - _100US * MACHINE_CYCLE) / 256;
break;
case 150:
TL0 = (65536 - _150US * MACHINE_CYCLE) % 256;
TH0 = (65536 - _150US * MACHINE_CYCLE) / 256;
break;
case 200:
TL0 = (65536 - _200US * MACHINE_CYCLE) % 256;
TH0 = (65536 - _200US * MACHINE_CYCLE) / 256;
break;
case 250:
TL0 = (65536 - _250US * MACHINE_CYCLE) % 256;
TH0 = (65536 - _250US * MACHINE_CYCLE) / 256;
break;
default:
TL0 = (65536 - value * MACHINE_CYCLE) % 256;
TH0 = (65536 - value * MACHINE_CYCLE) / 256;
break;
}
}
//定時(shí)器0初始化程序
/**
時(shí)鐘周期 = 1 / FOSC = 1 / 6 MHz = 1/6us
機(jī)器周期 = 1 * 時(shí)鐘周期 = 1/6us (1T模式)
定時(shí)100us:
100us = 100 / (1/6) = 600機(jī)器周期
**/
void init_timer0(void)
{
TMOD = 0x00; //設(shè)置定時(shí)器0為模式0(16位自動(dòng)重裝載)
set_tm0_init_value(init_value);
TR0 = 1; //定時(shí)器0開始計(jì)時(shí)
ET0 = 1; //使能定時(shí)器0中斷
}
/**
頻率 = 1 / 周期
**/
void main(void)
{
P3M1 = 0x00;
P3M0 = 0xFF;
AUXR |= 0x80; //定時(shí)器0為1T模式
duty_cycle = 5; //初始占空比為50%
count = 0;
init_value = 100; //初始頻率1kHz
init_int0();
init_int2();
init_int3();
init_timer0(); //定時(shí)器初始值為0.1ms,初始頻率為 1 / 0.001 = 1000Hz
flag = 0;
EA = 1;
while(1);
}
//INT0中斷服務(wù)程序
void ex_int0() interrupt 0 //INT0中斷入口
{
EA = 0;
flag = !flag;
if(flag) { //關(guān)燈
TR0 = 0;
ET0 = 0;
} else {
TR0 = 1;
ET0 = 1;
}
pwm = flag;
EA = 1;
}
//INT2中斷服務(wù)程序
void ex_int2() interrupt 10 //INT2中斷入口
{
EA = 0;
if(++duty_cycle > 10) {
duty_cycle = 10;
}
INT_CLKO &= 0xEF; //若需要手動(dòng)清除中斷標(biāo)志,可先關(guān)閉中斷,此時(shí)系統(tǒng)會(huì)自動(dòng)清除內(nèi)部的中斷標(biāo)志
INT_CLKO |= 0x10; //然后再開中斷即可
EA = 1;
}
//INT3中斷服務(wù)程序
void ex_int3() interrupt 11 //INT3中斷入口
{
EA = 0;
if(--duty_cycle < 0) {
duty_cycle = 0;
}
INT_CLKO &= 0xDF; //若需要手動(dòng)清除中斷標(biāo)志,可先關(guān)閉中斷,此時(shí)系統(tǒng)會(huì)自動(dòng)清除內(nèi)部的中斷標(biāo)志
INT_CLKO |= 0x20; //然后再開中斷即可
EA = 1;
}
//定時(shí)器0中斷服務(wù)程序
void tm0_isr() interrupt 1 using 1
{
EA = 0;
//初始化計(jì)時(shí)值
set_tm0_init_value(init_value);
//pwm = !pwm;
if(++count > 9) {
count = 0;
}
if(count < duty_cycle) {
pwm = 1;
} else {
pwm = 0;
}
EA = 1;
}
|
|