本文最后更新于 2024-07-30,文章内容可能已经过时。

郭天祥2023全新51单片机教程-入门+提高——仿真模块

制作仿真模块

类似于不同芯片的移植,由于STC89C52和STC8H是同一个51架构

所以只需要修改头文件,添加IO口的内容

移植:更改头文件,添加与不同芯片的架构内的文件以便于修改

制作流水灯仿真模块

/**
*功能:制作流水灯仿真模块
*依据lesson4-4进行修改移植
*/
#include<stc8h.h>
#define uchar unsigned char
#define uint unsigned int
uchar j,k,m;
void delay_ms(uint c);
void main(void)
{
	  P0M0 = 0x00; P0M1 = 0x00; 
    P1M0 = 0x00; P1M1 = 0x00; 
    P2M0 = 0x00; P2M1 = 0x00; 
    P3M0 = 0x00; P3M1 = 0x00; 
    P4M0 = 0x00; P4M1 = 0x00; 
    P5M0 = 0x00; P5M1 = 0x00; 
    P6M0 = 0x00; P6M1 = 0x00; 
    P7M0 = 0x00; P7M1 = 0x00; 

		while(1)
		{
			//左移流水灯
			for(m=3;m>0;m--)
			{
				k=0x01;
				for(j=8;j>0;j--)
				{
					P1=~k;//取反后赋给P1口
					k=k<<1;
					delay_ms(5);
				}
			}
			
			//右移流水灯
			for(m=3;m>0;m--)
			{
				k=0x80;
				for(j=8;j>0;j--)
				{
					P1=~k;//取反后赋给P1口
					k=k>>1;
					delay_ms(5);
				}
			}
		}
}

void delay_ms(uint c)
{
		uint a,b;
		for(a=c;a>0;a--)
			for(b=11400;b>0;b--);
}

制作按键检测仿真模块

/**
*功能:制作按键检测仿真模块
*依据lesson8-2进行修改移植
*/
#include<stc8h.h>
#include<intrins.h>
#define uint  unsigned int 
#define uchar unsigned char 
#define beep P23
#define dula P26
#define wela P27
//uchar num,temp;
uint num,num1,dis,bm;
uchar code table[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};
void DelayMs(uint c);
void Display(uint shu);
void Init();
void main ()
{
	  P0M0 = 0x00; P0M1 = 0x00; 
    P1M0 = 0x00; P1M1 = 0x00; 
    P2M0 = 0x00; P2M1 = 0x00; 
    P3M0 = 0x00; P3M1 = 0x00; 
    P4M0 = 0x00; P4M1 = 0x00; 
    P5M0 = 0x00; P5M1 = 0x00; 
    P6M0 = 0x00; P6M1 = 0x00; 
    P7M0 = 0x00; P7M1 = 0x00; 
	while(1)
	{
		if(P34==0)
		{
			Display(5);
			if(P34==0)
			{
				while(!P34)
					 Display(num);
				P1=~P1;
				num++;
			}
		}
		
		if(P35==0)
		{
			Display(5);
			if(P35==0)
			{
				while(!P35)
					 Display(num);
				P1=~P1;
				num--;
			}
		}
		
		if((P36==0)&&(P37==0))
		{
			Display(5);
			if((P36==0)&&(P37==0))
			{
				//while(!P36||!P37)
				while(!(P36==1)&&(P37==1))
					 Display(num);
				P1=~P1;
				num--;
			}
		}
	  Display(num);
	}
}
void Init()
{
	TMOD=0x11;//配置定时器0工作模式1
	TH0=(65536-46296)/256;
	TL0=(65536-46296)%256;//装初值
	TH1=(65536-45296)/256;
	TL1=(65536-45296)%256;//装初值
	EA=1;//打开总中断
	ET0=1;//打开定时器0的中断
	ET1=1;//打开定时器1的中断
	TR0=1;//启动定时器0;
	TR1=1;//启动定时器1;
	EX0=1;//打开外部中断
	IT0=1;//设置中断类型为下降沿
}
void Int0() interrupt 0
{
	beep=~beep;
}
void Time0()interrupt 1
{
	TH1=(65536-46296)/256;
	TL1=(65536-46296)%256;//装初值
	num++;//自加
}

void Time1()interrupt 3
{
	TH0=(65536-45296)/256;
	TL0=(65536-45296)%256;//装初值
	num1--;//自减
}
void DelayMs(uint c)
{
	uint a,b;
	for(a=c;a>0;a--)
		for(b=11;b>0;b--);
}
void Display(uint shu)
{			
		wela=1;//位选打开(打开数码管有几位)
		P0=0xfe;
		wela=0;
		P0=0;//消除影子
		dula=1;//段选打开【指表示这一位显示数字/字母/小数点】
		P0=table[shu/100];
		dula=0;
		DelayMs(20);

		wela=1;//位选打开(打开数码管有几位)
		P0=0xfd;
		wela=0;
		P0=0;//消除影子
		dula=1;//段选打开【指表示这一位显示数字/字母/小数点】
		P0=table[shu/10%10];
		dula=0;
		DelayMs(20);
	
		wela=1;//位选打开(打开数码管有几位)
		P0=0xfb;
		wela=0;
		P0=0;//消除影子
		dula=1;//段选打开【指表示这一位显示数字/字母/小数点】
		P0=table[shu%10];
		dula=0;
		DelayMs(20);
}

制作数码管仿真模块

/**
*功能:制作数码管仿真模块
*/
#include<stc8h.h>
#include<intrins.h>
#define uint  unsigned int 
#define uchar unsigned char 
#define beep P23
#define dula P26
#define wela P27
//uchar num,temp;
uint num,num1,dis,bm;
uchar code table[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};
void DelayMs(uint c);
void Display(uint shu);
void Init();
void main ()
{
	  P0M0 = 0x00; P0M1 = 0x00; 
    P1M0 = 0x00; P1M1 = 0x00; 
    P2M0 = 0x00; P2M1 = 0x00; 
    P3M0 = 0x00; P3M1 = 0x00; 
    P4M0 = 0x00; P4M1 = 0x00; 
    P5M0 = 0x00; P5M1 = 0x00; 
    P6M0 = 0x00; P6M1 = 0x00; 
    P7M0 = 0x00; P7M1 = 0x00; 
	while(1)
	{
		if(P34==0)
		{
			Display(5);
			if(P34==0)
			{
				while(!P34)
					 Display(num);
				P1=~P1;
				num++;
			}
		}
		
		if(P35==0)
		{
			Display(5);
			if(P35==0)
			{
				while(!P35)
					 Display(num);
				P1=~P1;
				num--;
			}
		}
		
		if((P36==0)&&(P37==0))
		{
			Display(5);
			if((P36==0)&&(P37==0))
			{
				//while(!P36||!P37)
				while(!(P36==1)&&(P37==1))
					 Display(num);
				P1=~P1;
				num=0;
			}
		}
	  Display(456);
	}
}
void Init()
{
	TMOD=0x11;//配置定时器0工作模式1
	TH0=(65536-46296)/256;
	TL0=(65536-46296)%256;//装初值
	TH1=(65536-45296)/256;
	TL1=(65536-45296)%256;//装初值
	EA=1;//打开总中断
	ET0=1;//打开定时器0的中断
	ET1=1;//打开定时器1的中断
	TR0=1;//启动定时器0;
	TR1=1;//启动定时器1;
	EX0=1;//打开外部中断
	IT0=1;//设置中断类型为下降沿
}
void Int0() interrupt 0
{
	beep=~beep;
}
void Time0()interrupt 1
{
	TH1=(65536-46296)/256;
	TL1=(65536-46296)%256;//装初值
	num++;//自加
}

void Time1()interrupt 3
{
	TH0=(65536-45296)/256;
	TL0=(65536-45296)%256;//装初值
	num1--;//自减
}
void DelayMs(uint c)
{
	uint a,b;
	for(a=c;a>0;a--)
		for(b=11;b>0;b--);
}
void Display(uint shu)
{			
		wela=1;//位选打开(打开数码管有几位)
		P0=0xfe;
		wela=0;
		P0=0;//消除影子
		dula=1;//段选打开【指表示这一位显示数字/字母/小数点】
		P0=table[shu/100];
		dula=0;
		DelayMs(20);

		wela=1;//位选打开(打开数码管有几位)
		P0=0xfd;
		wela=0;
		P0=0;//消除影子
		dula=1;//段选打开【指表示这一位显示数字/字母/小数点】
		P0=table[shu/10%10];
		dula=0;
		DelayMs(20);
	
		wela=1;//位选打开(打开数码管有几位)
		P0=0xfb;
		wela=0;
		P0=0;//消除影子
		dula=1;//段选打开【指表示这一位显示数字/字母/小数点】
		P0=table[shu%10];
		dula=0;
		DelayMs(20);
}