永发信息网

单片机课程设计以89C51为基础设计SPWM波发生器

答案:1  悬赏:50  手机版
解决时间 2021-04-23 12:42
  • 提问者网友:嘚啵嘚啵
  • 2021-04-23 03:40
单片机课程设计以89C51为基础设计SPWM波发生器
最佳答案
  • 五星知识达人网友:鱼忧
  • 2021-04-23 04:56


#include


//键值表-----------------------------------------------------------------------
#define NOKEY 0
#define KEY1 128
#define KEY2 129
#define KEY3 131
#define KEY4 135
#define KEY5 64
#define KEY6 65
#define KEY7 67
#define KEY8 71
#define KEY9 32
#define KEY10 33
#define KEY11 35
#define KEY12 39
#define KEY13 16
#define KEY14 17
#define KEY15 19
#define KEY16 23

//数码管位驱动-----------------------------------------------------------------
#define DIG0 0xfe
#define DIG1 0xfd
#define DIG2 0xfb
#define DIG3 0xf7
#define DIG4 0xef
#define DIG5 0xdf
#define DIG6 0xbf
#define DIG7 0x7f

//字符表-----------------------------------------------------------------------
#define CODE0 0xc0
#define CODE1 0xf9
#define CODE2 0xa4
#define CODE3 0xb0
#define CODE4 0x99
#define CODE5 0x92
#define CODE6 0x82
#define CODE7 0xf8
#define CODE8 0x80
#define CODE9 0x90
#define CODEA 0x88
#define CODEB 0x83
#define CODEC 0xc6
#define CODED 0xa1
#define CODEE 0x86
#define CODEF 0x8e
#define CODEH 0x89
#define CODEP 0x8c
#define POINT 0x7f
#define CODE_ 0xf7
#define CODENO 0xff

//LED控制位(PWM模块接口定义,根据自已的需要更改)------------------------
sbit LED = P1^2;


code const unsigned char NUMBER_CODE[10] =
{CODE0,CODE1,CODE2,CODE3,CODE4,CODE5,CODE6,CODE7,CODE8,CODE9};
code const unsigned char LED_DIG[8] =
{DIG0,DIG1,DIG2,DIG3,DIG4,DIG5,DIG6,DIG7};
unsigned char LED_SEG[8] = {0}; //显示缓冲区

unsigned char flag_10ms = 0; //10ms标志位
unsigned char last_key = 0;
unsigned char key = 0;

unsigned char PWM_CYCLE = 0; //PWM的周期
unsigned char PWM_ON = 0; //PWM的占空比


void Delay1ms(unsigned int count)
{
unsigned int i=0;
unsigned int j=0;

for(i=0;i for(j=0;j<120;j++);
}


void DisplayCode(unsigned int x)
{
unsigned char m=0;

LED_SEG[7]=CODEF;
LED_SEG[6]=CODE_;
LED_SEG[5]=CODE_;
while(x>=10000){x=x-10000;m++;}LED_SEG[4]=NUMBER_CODE[m];m=0;
while(x>=1000) {x=x-1000;m++;} LED_SEG[3]=NUMBER_CODE[m];m=0;
while(x>=100) {x=x-100;m++;} LED_SEG[2]=NUMBER_CODE[m];m=0;
while(x>=10) {x=x-10;m++;} LED_SEG[1]=NUMBER_CODE[m];m=0;
while(x>=1) {x=x-1;m++;} LED_SEG[0]=NUMBER_CODE[m];m=0;
}


unsigned char ReadKey(void)
{
unsigned char cord_x=0; //定义行和列
unsigned char cord_y=0;

P3 = 0x0f; //行扫描,高四位输出低电平,低四位高电平输入状态,进行行扫描
cord_x = (P3 & 0x0f); //行扫描值送入cord_x
if(cord_x == 0x0f)
return (0); //无键按下,返回0

else //有键按下,则继续进行按键扫描
{
P3 = (cord_x | 0xf0); //列扫描,高四位高电平输入状态,低四位扫描到的行进行回扫,那一行输出低电平
cord_y = P3 & 0xf0; //列扫描值送入cord_y
return (~cord_x + ~cord_y); //返回组合码
}
}


void Play(void)
{
unsigned char i=0;

while(!flag_10ms); //有标志位则退出循环
flag_10ms = 0; //标志位清零

for(i=0;i<8;i++) //数码管显示
{
P2 = LED_DIG[i]; //位驱动
P0 = LED_SEG[i]; //段驱动
Delay1ms(1); //延时1ms
}
P2 = 0xff; //清显示
P0 = 0xff;

last_key = key; //记住上次键值
key = ReadKey(); //读新键值
}


void timer1(void) interrupt 3
{
static unsigned char pwm=0;

pwm++;
if(pwm==PWM_ON)
LED=1; //灯灭
if(pwm==PWM_CYCLE)
{
pwm=0;
if(PWM_ON!=0)
LED=0; //灯亮
}
}


void Timer0(void) interrupt 1
{
TH0 = 0xd8; //定时10ms
TL0 = 0xf0;
flag_10ms = 1; //设定标志位
}


void main (void)
{
TMOD = 0x21; //time0方式1,timer1方式2
EA = 1; //开总中断
ET0 = 1; //开定时器0中断
TR0 = 1; //启动定时器0
ET1 = 1; //开定时器1中断
TR1 = 1; //启动定时器1
TH1 = 0x9c; //定时0.1ms
TL1 = 0x9c;

PWM_ON= 1; //设定占空比为1/10;
PWM_CYCLE = 10; //周期为10*0.1ms,可调,随便设置
P2 = 0x00;

for(;;)
{
Play();
DisplayCode(PWM_ON);
if((last_key == NOKEY) && (key == KEY1))
{
PWM_ON++;
if(PWM_ON>=10)
PWM_ON=0; //调占空比
}
}
}
我要举报
如以上回答内容为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
点此我要举报以上问答信息
大家都在看
推荐资讯