【Proteus仿真】51单片机+lcd1602显示定时器实现PWM输出
【Proteus仿真】51单片机+lcd1602显示定时器实现PWM输出
- ✨lcd显示具体频率和占空比,通过按键调节占空比。
- 🎬LCD显示

📝主程序代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158
| #include <reg52.h> #include "LCD1602.H" #define uchar unsigned char #define uint unsigned int
unsigned int fr = 50; //频率 50hz unsigned char dc = 50; //50%占空比 uchar fr_g = 0; uchar fr_s = 0; uchar dc_g = 0; uchar dc_s = 0; /\* 配置并启动 PWM,fr-频率,dc-占空比 \*/
unsigned int high, low; unsigned long tmp; unsigned char HighRH = 0; //高电平重载值的高字节 unsigned char HighRL = 0; //高电平重载值的低字节 unsigned char LowRH = 0; //低电平重载值的高字节 unsigned char LowRL = 0; //低电平重载值的低字节
void ConfigPWM(); void ClosePWM();
sbit key1 = P3 ^ 1; //定义按键位置 加占空比 sbit key2 = P3 ^ 0; //定义按键位置 减占空比 sbit PWMOUT = P2 ^ 1;
/\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* //\* 名称 : Delay\_1ms() //\* 功能 : 延时子程序,延时时间为 1ms \* x //\* 输入 : x (延时一毫秒的个数) //\* 输出 : 无 //\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*/ void Delay\_1ms(uint i)//1ms延时 { uchar x, j; for(j = 0; j < i; j++) for(x = 0; x <= 148; x++); }
void key() {
if(!key1) //按下相应的按键,数码管显示相应的码值 { Delay\_1ms(10); if(!key1) { if(dc++ >= 100)dc = 100;
} while(!key1); }
if(!key2) { Delay\_1ms(10); if(!key2) { if(dc-- <= 0)dc = 100;
} while(!key2); } }
void ConfigPWM() { tmp = (11059200 / 12) / fr; //计算一个周期所需的计数值 high = (tmp \* dc) / 100; //计算高电平所需的计数值 low = tmp - high; //计算低电平所需的计数值 high = 65536 - high + 12; //计算高电平的重载值并补偿中断延时 low = 65536 - low + 12;//计算低电平的重载值并补偿中断延时
HighRH = (unsigned char)(high >> 8); //高电平重载值拆分为高低字节 HighRL = (unsigned char)high; LowRH = (unsigned char)(low >> 8); //低电平重载值拆分为高低字节 LowRL = (unsigned char)low;
TMOD &= 0xF0; //清零 T0 的控制位 TMOD |= 0x01; //配置 T0 为模式 1 TH0 = HighRH; //加载 T0 重载值 TL0 = HighRL; ET0 = 1; //使能 T0 中断 TR0 = 1; //启动 T0 PWMOUT = 1; //输出高电平 }
/\* 关闭 PWM \*/ void ClosePWM() { TR0 = 0; //停止定时器 ET0 = 0; //禁止中断 PWMOUT = 1; //输出高电平 }
void main() { uint i; LCD1602\_Init(1, 0, 0); //lcd1602初始化 Delay\_1ms(100);
LCD1602\_DisplayChar(1, 2, ':'); //显示e LCD1602\_DisplayChar(2, 1, 'd'); //显示p LCD1602\_DisplayChar(2, 2, ':'); //显示: LCD1602\_DisplayChar(1, 6, 'H'); //显示t LCD1602\_DisplayChar(1, 7, 'Z'); //显示e LCD1602\_DisplayChar(2, 6, '%'); //显示t LCD1602\_DisplayChar(1, 1, 'f'); //显示t TMOD = 0x00; TL1 = 0xD8; TH1 = 0xf0; TR1 = 1; //启动定时器 ET1 = 1; //使能定时器中断 EA = 1; //开总中断 while(1) { key(); ConfigPWM(); for(i = 0; i < 40000; i++); fr_g = fr % 10; fr_s = fr / 10; dc_g = dc % 10; dc_s = dc / 10; LCD1602\_DisplayChar(1, 4, fr_s + 48); //显示t LCD1602\_DisplayChar(1, 5, fr_g + 48); //显示e LCD1602\_DisplayChar(2, 4, dc_s + 48); //显示p LCD1602\_DisplayChar(2, 5, dc_g + 48); //显示:
}
}
/\* T0 中断服务函数,产生 PWM 输出 \*/ void InterruptTimer0() interrupt 1 {
if(PWMOUT == 1) { //当前输出为高电平时,装载低电平值并输出低电平 TH0 = LowRH; TL0 = LowRL; PWMOUT = 0; } else { //当前输出为低电平时,装载高电平值并输出高电平 TH0 = HighRH; TL0 = HighRL; PWMOUT = 1; } } void TM1\_Isr() interrupt 3 using 1 { key(); }
|
📚LCD显示驱动程序和仿真资源
1 2 3
| 链接: https://pan.baidu.com/s/1OotC289Ejxadayl200DjqA 提取码: piiy
|
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!