仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
单片机源程序如下:
- #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();
- }
复制代码
全部资料51hei下载地址:
lcd1602显示PWM频率和占空比1.rar
(66.36 KB, 下载次数: 100)
|