实验一:利用PWM实现LED1 呼吸灯
学习视频:[15-2] LED呼吸灯&直流电机调速_哔哩哔哩_bilibili
#include "reg51.h"
typedef unsigned int u16;
typedef unsigned char u8;
sbit LED1 = P2^0; // 位定义LED灯
void delay10us(u16 ten_us) // 延时程序
{
while(ten_us--);
}
void main()
{
u8 t=0,i=0;
while(1)
{
for(t=0;t<100;t++) // 设置占空比 从小变大
{
for(i=0;i<20;i++) // 每个状态循环20次
{
LED1 = 0; // 循环内4条代码是让LED灯的亮度大小维持在一个状态 亮度由t决定
delay10us(t);
LED1 = 1;
delay10us(100-t);
}
}
for(t=100;t>0;t--) // 设置占空比 从大变小
{
for(i=0;i<20;i++)
{
LED1 = 0;
delay10us(t);
LED1 = 1;
delay10us(100-t);
}
}
}
}
实验二:利用PWM实现对直流电机的调速:
[15-2] LED呼吸灯&直流电机调速_哔哩哔哩_bilibili
主程序 main.c :
#include <REGX52.H>
#include "Delay.h"
#include "Key.h"
#include "Nixie.h"
#include "Timer0.h"
sbit Motor=P1^0;
unsigned char Counter,Compare; // Counter为定时器计数值,Compare为比较值,两者结合来设置PWM
unsigned char KeyNum,Speed;
void main()
{
Timer0_Init();
while(1)
{
KeyNum=Key(); // Key( )来判断哪个按键被按下
if(KeyNum==1)
{
Speed++; // 设置4种模式0、1、2、3
Speed%=4;
if(Speed==0){Compare=0;} // 设置比较值,改变PWM占空比
if(Speed==1){Compare=50;}
if(Speed==2){Compare=75;}
if(Speed==3){Compare=100;}
}
Nixie(1,Speed); // 在第几位晶体管显示数值,即Speed的4种模式
}
}
void Timer0_Routine() interrupt 1
{
TL0 = 0x9C; //设置定时初值
TH0 = 0xFF; //设置定时初值
Counter++;
Counter%=100; //计数值变化范围限制在0~99
if(Counter<Compare) //计数值小于比较值
{
Motor=1; //输出1
}
else //计数值大于比较值
{
Motor=0; //输出0
}
}
延时程序 Delay.c 和 Delay.h:
// Delay.c
void Delay(unsigned int xms)
{
unsigned char i, j;
while(xms--)
{
i = 2;
j = 239;
do
{
while (--j);
} while (--i);
}
}
// Delay.h
#ifndef __DELAY_H__
#define __DELAY_H__
void Delay(unsigned int xms);
#endif
定时器程序 Timer0.c 和 Timer0.h:
//Timer0.c
#include <REGX52.H>
/**
* @brief 定时器0初始化,100us@12.000MHz
* @param 无
* @retval 无
*/
void Timer0_Init(void)
{
TMOD &= 0xF0; //设置定时器模式
TMOD |= 0x01; //设置定时器模式
TL0 = 0x9C; //设置定时初值
TH0 = 0xFF; //设置定时初值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
ET0=1;
EA=1;
PT0=0;
}
/*定时器中断函数模板
void Timer0_Routine() interrupt 1
{
static unsigned int T0Count;
TL0 = 0x9C; //设置定时初值
TH0 = 0xFF; //设置定时初值
T0Count++;
if(T0Count>=1000)
{
T0Count=0;
}
}
*/
//Timer0.h
#ifndef __TIMER0_H__
#define __TIMER0_H__
void Timer0_Init(void);
#endif
按键程序 Key.c 和 Key.h:
// Key.c
#include <REGX52.H>
#include "Delay.h"
/**
* @brief 获取独立按键键码
* @param 无
* @retval 按下按键的键码,范围:0~4,无按键按下时返回值为0
*/
unsigned char Key()
{
unsigned char KeyNumber=0;
if(P3_1==0){Delay(20);while(P3_1==0);Delay(20);KeyNumber=1;}
if(P3_0==0){Delay(20);while(P3_0==0);Delay(20);KeyNumber=2;}
if(P3_2==0){Delay(20);while(P3_2==0);Delay(20);KeyNumber=3;}
if(P3_3==0){Delay(20);while(P3_3==0);Delay(20);KeyNumber=4;}
return KeyNumber;
}
// Key.h
#ifndef __KEY_H__
#define __KEY_H__
unsigned char Key();
#endif
数码管显示程序 Key.c 和 Key.h:
// Nixie.c
#include <REGX52.H>
#include "Delay.h"
//数码管段码表
unsigned char NixieTable[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
/**
* @brief 数码管显示
* @param Location 要显示的位置,范围:1~8
* @param Number 要显示的数字,范围:段码表索引范围
* @retval 无
*/
void Nixie(unsigned char Location,Number)
{
switch(Location) //位码输出
{
case 1:P2_4=1;P2_3=1;P2_2=1;break;
case 2:P2_4=1;P2_3=1;P2_2=0;break;
case 3:P2_4=1;P2_3=0;P2_2=1;break;
case 4:P2_4=1;P2_3=0;P2_2=0;break;
case 5:P2_4=0;P2_3=1;P2_2=1;break;
case 6:P2_4=0;P2_3=1;P2_2=0;break;
case 7:P2_4=0;P2_3=0;P2_2=1;break;
case 8:P2_4=0;P2_3=0;P2_2=0;break;
}
P0=NixieTable[Number]; //段码输出
Delay(1); //显示一段时间
P0=0x00; //段码清0,消影
}
// Nixie.h
#ifndef __NIXIE_H__
#define __NIXIE_H__
void Nixie(unsigned char Location,Number);
#endif
以上内容,学习所用。侵删。