一、原理图
二、源程序
/**
主控MCU:STC15F104W
开关:INT0(P3.2) 下降沿触发
亮度增加:INT2(P3.4) 下降沿触发
亮度减少:INT3(P3.5) 下降沿触发
PWM输出:P3.3
**/
#include #include //#define FOSC 24000000L //晶振频率 #define FOSC 6000000L //晶振频率 #define MACHINE_CYCLE (FOSC / 1000000) //时钟震荡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; //外部中断与时钟输出控制寄存器 sfr AUXR = 0x8e; //辅助寄存器 sfr P3M1 = 0xB1; //P3口寄存器 sfr P3M0 = 0xB2; signed int duty_cycle; //占空比,0-10,带符号 unsigned int init_value; //定时器初值 unsigned int count; //定时器中断次数 sbit pwm = P3 ^ 3; //PWM输出口 bit flag; //灯开关状态 //INT0初始化程序 void init_int0(void) { INT0 = 1; IT0 = 1; //设置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中断 } //初始化计时值 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; } } //定时器0初始化程序 /** 时钟周期 = 1 / FOSC = 1 / 6 MHz = 1/6us 机器周期 = 1 * 时钟周期 = 1/6us (1T模式) 定时100us: 100us = 100 / (1/6) = 600机器周期 **/ void init_timer0(void) { TMOD = 0x00; //设置定时器0为模式0(16位自动重装载) set_tm0_init_value(init_value); TR0 = 1; //定时器0开始计时 ET0 = 1; //使能定时器0中断 } /** 频率 = 1 / 周期 **/ void main(void) { P3M1 = 0x00; P3M0 = 0xFF; AUXR |= 0x80; //定时器0为1T模式 duty_cycle = 5; //初始占空比为50% count = 0; init_value = 100; //初始频率1kHz init_int0(); init_int2(); init_int3(); init_timer0(); //定时器初始值为0.1ms,初始频率为 1 / 0.001 = 1000Hz flag = 0; EA = 1; while(1); } //INT0中断服务程序 void ex_int0() interrupt 0 //INT0中断入口 { EA = 0; flag = !flag; if(flag) { //关灯 TR0 = 0; ET0 = 0; } else { TR0 = 1; ET0 = 1; } pwm = flag; EA = 1; } //INT2中断服务程序 void ex_int2() interrupt 10 //INT2中断入口 { EA = 0; if(++duty_cycle > 10) { duty_cycle = 10; } INT_CLKO &= 0xEF; //若需要手动清除中断标志,可先关闭中断,此时系统会自动清除内部的中断标志 INT_CLKO |= 0x10; //然后再开中断即可 EA = 1; } //INT3中断服务程序 void ex_int3() interrupt 11 //INT3中断入口 { EA = 0; if(--duty_cycle < 0) { duty_cycle = 0; } INT_CLKO &= 0xDF; //若需要手动清除中断标志,可先关闭中断,此时系统会自动清除内部的中断标志 INT_CLKO |= 0x20; //然后再开中断即可 EA = 1; } //定时器0中断服务程序 void tm0_isr() interrupt 1 using 1 { EA = 0; //初始化计时值 set_tm0_init_value(init_value); //pwm = !pwm; if(++count > 9) { count = 0; } if(count < duty_cycle) { pwm = 1; } else { pwm = 0; } EA = 1; }
上一篇:STC15F104W 使用 315/433 MHz 超再生模块发送/接收数据
下一篇:STC15F104W使用定时器0模拟串口
推荐阅读最新更新时间:2024-11-09 12:56
设计资源 培训 开发板 精华推荐
- 使用 Analog Devices 的 LT3467AES67 的参考设计
- AM1S-4824SZ 1W DC-DC转换器典型应用
- LF60ABDT-TR 6V 极低压降稳压器的典型应用,带开关
- L7815A 大电流稳压器的典型应用
- RT9161A 300/500mA 低压差线性稳压器典型应用
- 全向轮FPV三轮车V2
- DER-901 - 使用 HiperPFS-4 和基于 PowiGaN 的 LYTSwitch-6 的 125 W 2 级升压和隔离反激式 3 路可调光 LED 镇流器
- EV-ADF4360-0EB1Z,用于 ADF4360-0 集成 PLL 和 VCO 频率合成器的评估板
- LTC4240CGN 演示板,I2C 紧凑型 PCI 热插拔控制器
- 2021大学生电子设计竞赛J题国一作品(周期信号波形识别及参数测量装置)