锐单电子商城 , 一站式电子元器件采购平台!
  • 电话:400-990-0325

STC8h1k28六个基本实验

时间:2023-11-13 00:37:02 1n4007g二极管

实验一 STC8h1k28 熟悉开发环境和端口输出控制

实验内容:
项目1:
参考原理图,设计闪烁灯程序,每次亮灭时间为500ms。
项目2:
三色流转灯程序设计参考原理图,GRB三种颜色的LED轮流点亮,每次只点亮一盏,每次点亮时间为500ms。

原理图:
在这里插入图片描述
实验原理:
(共阳)LED负极接单片机IO口(P00\P01\P02),当IO口输出低电平时LED被点亮,反之亦然。

/*程序代码及注释: ?项目1: 参考原理图,设计闪烁灯程序,每次亮灭时间为500ms。代码如下:*/ #include  /*存储是定义好的寄存器地址。*/ #include/*用到_nop_()这个函数必须包含这个头文件中对这个函数的定义*/ void Delay500ms()  //@11.0592MHz延时函数 { 
          unsigned char i, j, k;   _nop_();///使用它将使用这个头文件  _nop_();  i = 22;  j = 3;  k = 227;  do  { 
           do   { 
            while (--k);   } while (--j);  } while (--i); } void initialize()//初始化io口工作模式 { 
          P0M1 &=0xf8; //设置P双向口模式为0口低三位。  P0M0 &=0xf8;//设置P双向口模式为0口低三位。 //设置IO口工作模式00(共阳)P00,P01,P02为准双向口模式(可输出或/输入) //01推拉输出(共阴)(A/D转换时),11泄漏输出(电平匹配时) }  void LED() { 
           P00=0;//因为是共阳LED所以给低电平它亮,给高电平它灭   Delay500ms();//延时500ms再灭,不能太快灭和亮,不然人眼看不出变化
		P00=1;//灭灯//或以上两行用它代替P00!=P00;
		Delay500ms();
}
 
void main()//万年不变三段式:初始化,循环体,循环内容
{ 
        
		initialize();//初始化用到哪个io口就先设置工作模式
		while(1)
		{ 
        
			LED();//放大循环里让灯不停运转
		}
}
/*项目2: 参考原理图,设计三色流转灯程序,GRB三种颜色的LED轮番点亮,每次只亮一盏,每次点亮时长为500ms。代码如下:*/
#include 
/*存储的是定义好的寄存器地址。*/
#include//用到_nop_()这个函数就得包含这个头文件里面有关于这个函数的定义
//用尖括号是用于包含标准库的头文件
//双引号一般用于包含用户自己编写的头文件
char i;//控制灯轮转的变量
void Delay500ms()		//@11.0592MHz延时函数
{ 
        
	unsigned char i, j, k;
	_nop_();//用到它就要用到这个头文件
	_nop_();
	i = 22;
	j = 3;
	k = 227;
	do
	{ 
        
		do
		{ 
        
			while (--k);
		} while (--j);
	} while (--i);
}
void initialize()//IO口工作模式初始化
{ 
        
	P0M1 &=0xf8;
	P0M0 &=0xf8;/*设置IO口工作模式00(共阳),设置P00,P01,P02为准双向口模式(既可以输//出也可以输入)*/
	//01推挽输出(共阴),10高祖输入(adc),11开漏输出
}
void LED()//LED轮转函数
{ 
        
	for(i=0;i<3;i++)
	{ 
        
		P0=~(1<<i);//利用i变量进行左移位,每次1移动i位后取反,电平为0的那一位
//亮,也就是先蓝灯亮500ms再红灯亮500ms再绿灯亮500ms
		Delay500ms();
	}
	i=0;//当i等于3时,也就是完成一轮亮灯(蓝红绿)i清零
}


void main()
{ 
        
	initialize();//初始化用到哪个io口就先设置工作模式
	while(1)
	{ 
        
		LED();//放大循环里让灯不停运转
	}
}


实验二 STC8h1k28基于定时器的LED控制

实验内容:
项目1:
利用定时器产生周期为100ms的方波,并以此方波控制LED以相同频率闪烁(使用查询方式实现);
项目2:
利用定时器控制流水灯流转时间,每盏灯每次点亮时长500ms(使用中断方式实现)。
原理图:

实验原理:
(共阳)LED负极连接单片机IO口(P00\P01\P02).当IO口输出低电平时LED被点亮,反之熄灭。
定时/计数器工作原理
定时器定时时间计算公式(16bit):

/*程序代码及注释: 项目1: 利用定时器产生周期为100ms的方波,并以此方波控制LED以相同频率闪烁(使用查询方式实现);代码如下:*/
#include 
/*存储的是定义好的寄存器地址*/
void Timer0Init (void)    //50毫秒延时@11.0592MHz
{ 
        
 	AUXR &= 0x7F;    //定时器时钟12T模式
	/*T0x12=0定时计数脉冲与传统8051单片机的计数脉冲完去全一样 计数脉冲周期位系统周期的12倍,即12分频;当=1,与系统周期一致,即无分频。*/
TMOD &= 0xF0;    /*设置定时器模式,设置定时器0,GATE=0,TR0=1/0可直接通过软件设置定时器开关,当它等于1时不仅通过软件设置TR0开关还有引脚P32 P33参与,C/T非=0的定时器模式=1计数器模式,M1=0M0=0,16位自动重装初始值*/
 	TL0 = 0xB0;   //设置定时初值低8位
 	TH0 = 0x3C;   //设置定时初值高8位
 	TF0= 0;   //清空溢出标志位
 	TR0= 1;   //开启定时器0 
}
void initialize()//初始化IO口模式
{ 
        
	P0M1 &=0xf8; //P0低三位IO设置为准双向口模式
	P0M0 &=0xf8;// P0低三位IO设置为准双向口模式
//设置IO口工作模式00(共阳),设置P00,P01,P02为准双向口模式(既可以输出也可以输入)
	//01推挽输出(共阴),10高祖输入(adc),11开漏输出
}
void LED()//查询方式实现灯以相同频率闪烁函数
{ 
        
	if(TF0)//判断是否到50ms
	{ 
        
		TF0=0;//到50ms进入if,后清零
		P00=~P00;//控制灯的亮灭
	}
}
void main()//万年不变主函数三段式:初始化,循环体,循环内容
{ 
        
	initialize();//初始化定时器
	Timer0Init ();//初始化io口
	P0=0xff;//初始化P00先灭灯
	while(1)
	{ 
        
		LED();//放大循环里让灯循环运转
	}
}
/*项目2: 利用定时器控制流水灯流转时间,每盏灯每次点亮时长500ms(使用中断方式实现)。代码如下:*/
#include 
/*存储的是定义好的寄存器地址。*/
char i,j=0;//j为满50ms加一,加满10次满500ms,flag=1,j=0。I是控制灯移位变量。
bit flag;//500ms标志变量
void Timer0Init (void)    //50毫秒@11.0592MHz
{ 
        
 	AUXR &= 0x7F;    //定时器时钟12T模式
	/*T0x12=0定时计数脉冲与传统8051单片机的计数脉冲完去全一样 计数脉冲周期位系统周期的12倍,即12分频;当=1,与系统周期一致,即无分频。*/
 	TMOD &= 0xF0;    /*设置定时器模式,设置定时器0,GATE=0,TR0=1/0可直接通过软件设置定时器开关,当它等于1时不仅通过软件设置TR0开关还有引脚P32 P33参与,C/T非=0的定时器模式=1计数器模式,M1=0M0=0,16位自动重装初始值*/
 	TL0 = 0xB0;   //设置定时初值低8位
 	TH0 = 0x3C;   //设置定时初值高8位
 	TF0= 0;   //清除TF0标志
 	TR0= 1;   //定时器0开始计时
}
void initialize()
{ 
        
	P0M1 &=0xf8; //P0低三位准双向口模式
	P0M0 &=0xf8;// P0低三位准双向口模式
//设置IO口工作模式00(共阳),设置P00,P01,P02为准双向口模式(既可以输出也可以输入)
	//01推挽输出(共阴),10高祖输入(adc),11开漏输出
	EA=1;
	ET0=1;
}
void ET0_LED() interrupt 1
{ 
        
	j++;//每50ms加一
	if(j==10)//满500ms进入
	{ 
        
		j=0;//清零保证下一个500ms正常定时
		flag=1;//自己定义的标志位,等于一代表500ms到了
	}
}
void LED()//LED轮转函数
{ 
        
	if(flag)//只有500ms到了才能进入流水的运转
	{ 
        
		flag=0;//清零保证下一次500ms正常进行亮灯不然你会看到混彩灯
		P0=~(1<<i);//用i实现位移控制轮流500ms亮灯
		i++;//在之前基础上位移到下一位
		if(i>2)
		{ 
        
			i=0;//蓝红绿进行一轮后i清零保证下一轮亮灯正常进行
		}
		
	}
}
void main()
{ 
        
	initialize();//初始化定时器
	Timer0Init ();//初始化io口
	while(1)
	{ 
        
		LED();//放大循环里让流水灯运转
	}
}
 


实验三 STC8h1k28中断、查询与按键控制

实验内容:
项目1:
每次按下按键,流水灯变化一种颜色,三种颜色循环变化,按键不按时颜色不变。(用外部中断实现)。
项目2:
每次按下按键,流水灯变化一种颜色,三种颜色循环变化,按键不按时颜色不变。
(用普通查询实现)。
项目3:
每次按下按键,流水灯变化一种颜色,三种颜色循环变化,按键不按时颜色不变。
(用定时器中断查询实现)。
原理图:


实验原理:
(共阳)LED负极接单片机IO口(P00\P01\P02),当IO口输出低电平时LED被点亮,反之熄灭。
按键按下为低电平,扫描按键为低电平灯亮。
定时/计数器工作原理
定时器定时时间计算公式(16bit):

/*程序代码及注释: 项目1: 每次按下按键,流水灯变化一种颜色,三种颜色循环变化,按键不按时颜色不变。(用外部中断实现)。*/

//外部中断实现流水灯运转
#include 
#define KEY1 P32//预处理,还没开始前把下面出现过的KEY1用P32代替
#define KEY2 P33//预处理,还没开始前把下面出现过的KEY2用P33代替
bit key_flag=0;//自定义按键一标志位先清零,按键按下置1
unsigned char i;//控制灯移位变量
void setup()//外部中断0和io口初始化变量
{ 
        
	EA=1;//打开总中断
	EX0=1;//外部中断0中断允许位,它打开等会才能进入中断服务子函数
	EX1=1;//外部中断1中断允许位,它打开等会才能进入中断服务子函数
	IE0=0;//外部中断0中断请求标志位,它等于1进入中断服务子函数
	IE1=0;//外部中断1中断请求标志位,它等于1进入中断服务子函数
	IT0=1;//外部中断0下降沿触发,就是按键按下才触发,抬起不触发
	IT1=1;//外部中断1下降沿触发,就是按键按下才触发,抬起不触发
	P0M1 &=0xf8;//设置P0口低三位为准双向口模式
	P0M0 &=0xf8;//设置P0口低三位为准双向口模式
	P0 &=0xff;//先把灯都灭了;
}
void INT0_IE0() interrupt 0//外部中断0的中断服务子函数
{ 
        
	key_flag=1;//自定义按键一标志位,按键按下置1
	while(!KEY1);//等待按键抬起
}
void INT0_IE1() interrupt 2//外部中断1的中断服务子函数
{ 
        
	key_flag=1;//自定义按键一标志位,按键按下置1
	while(!KEY2);//等待按键抬起
}
void LED_turn()//led流转函数
{ 
        
	if(key_flag)//确认按键按下才进入亮灯
	{ 
        
		key_flag=0;//自定义按键一标志位清零
		P0=~(1<<i);//按键按下一次亮一种灯
		i++;//移位量比前一次多一
		if(i>2)//灯循环一次后i清零
			i=0;
	}
}

void loop()//循环题里面的内容
{ 
        
	LED_turn();//调用led流转函数
}
void main()//万年不变主函数三段式
{ 
        
	setup();//初始化
	while(1)//循环体
	{ 
        
		loop();//亮灯程序
	}
}

/*项目2: 每次按下按键,流水灯变化一种颜色,三种颜色循环变化,按键不按时颜色不变。 (用普通查询实现)。*/

//普通查询按键流转灯
#include 
#include //用到 _nop_()就要这个头文件
#define KEY1 P32//预处理,还没开始前把下面出现过的KEY1用P32代替
#define KEY2 P33//预处理,还没开始前把下面出现过的KEY1用P33代替
bit key_flag=0;//自定义按键一标志位先清零,按键按下置1
unsigned char i;//控制灯移位变量
void Delay20ms()  //@11.0592MHz
{ 
        
 unsigned char i, j, k;

 _nop_();
 _nop_();
 i = 1;
 j = 216;
 k = 35;
 do
 { 
        
  do
  { 
        
   while (--k);
  } while (--j);
 } while (--i);
}

void setup()//外部中断0和io口初始化变量
{ 
        
 	P0M1 &=0xf8;//设置P0口低三位为准双向口模式
 	P0M0 &=0xf8;//设置P0口低三位为准双向口模式
 P0 &=0xff;//先把灯都灭了;
}
void key_see_about()//按键查询,看按键1或二是否按下
{ 
        
 	if(KEY1==0)//如果按键1按下
 	{ 
        
  		Delay20ms();//延时20ms按键1消抖环节
  		if(KEY1==0)//按键1还是低电平则标志为置1,以上为按键1消抖环节
  		{ 
        
  	 		key_flag=1;//按键标志位置1
  		}
 	} 
 	if(KEY2==0)//如果按键2按下
 	{ 
        
  		Delay20ms();//延时20ms
  		if(KEY2==0)//以上为按键2消抖环节
  		{ 
        
   			key_flag=1;//标志位置1
  		}
 	}
}
void LED_turn()//led流转函数
{ 
        
 	if(key_flag)//确认按键按下才进入亮灯
 	{ 
        
  		key_flag=0;//自定义按键一标志位清零
  		P0=~(1<<i);//按键按下一次亮一种灯
  		i++;//移位量笔前一次多一
  		if(i>2)//灯循环一次后i清零
    			i=0;
 	}
}

void loop()//循环题里面的内容
{ 
        
key_see_about();
 	LED_turn();//调用led流转函数
}
void main()
{ 
        
 	setup();//初始化
 while(1)//循环体
 	{ 
        
  		loop();//亮灯程序
 	}
}
/*项目3: 每次按下按键,流水灯变化一种颜色,三种颜色循环变化,按键不按时颜色不变。 (用定时器中断查询实现)。*/
//定时器查询按键流转灯
#include //头文件包含下面部分需要用到的语句定义
#define KEY1 P32//预处理,还没开始前把下面出现过的KEY1用P32代替
#define KEY2 P33//预处理,还没开始前把下面出现过的KEY2用P33代替
bit flag=0;//按键标志位,为1表示按键被按下
unsigned char I;//控制灯颜色转变的移位自定义变量
void time0_setup()//定时器一初始化
{ 
        
	TMOD &=0xf0;//定时器模式tr0=1启动定时器,工作方式0
	AUXR &=0x7f;//定时器0为12分频
	TL0=0xb0;//设置定时器初值
	TH0=0x3c;//设置定时器初值
	TR0=1;//启动定时器0
	TF0=0;//中断请求标志为清零
}
void setup()//初始化io空口和中断
{ 
        
	P0M1 &=0xf8;//设置为p00-p02为准双向口
	P0M0 &=0xf8;//设置为p00-p02为准双向口
	EA=1;//打开总中断开关
	ET0=1;//打开中断允许位
}
void et0_time0() interrupt 1//定时器0中断服务子函数
{ 
        
	if(KEY1==0||KEY2==0)
		flag=1;//按键按下标志变量置1
}
void led_turn()
{ 
        
	if(flag)
	{ 
        
		flag=0;//标志变量清零
		P0=~(1<<I);//灯变化下一种颜色
		I++;//移位变量加一
		if(I>2)//灯三种颜色循环一次就移位变量清零,方便下次灯循环
			I=0;
	}
}
void loop()//循环体里面包含的内容
{ 
        
	led_turn();
}
void main()//万年不变主函数三段式
{ 
        
	time0_setup();//定时器0初始化
	setup();//io口,中断初始化,即要用到的东西都先初始化设置一次
	while(1)//循环体
	{ 
        
		loop();
	}
} 


实验四 STC8h1k28数码管秒表程序设计

实验内容:
项目:

采用数码管、按键和内部定时实现秒计时功能,最大计时9999秒,超时9999秒则计数清零。外部按键KEY1控制秒表启停,按键KEY2清零秒表计时。
原理图:

实验原理:
数码管显示和动态扫描
按键按下为低电平,扫描按键为低电平灯亮。
(共阳)数码管负极接单片机IO口,当IO口输出低电平时对应段选或位选被点亮,反之熄灭。

//程序代码及注释:
#include 
#include//用到_nop_();
#define font_PORT P2//段选
#define position_PORT P1//位选
sbit key1=P3^2;//sbit定义一个引脚,sfr定义一个并行口
sbit key2=P3^3;
typedef unsigned char uchar;
typedef unsigned int uint;

uchar code LED_SMG[]={ 
        0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff};//字形码控制//段选
uchar code Scan_bit[]={ 
        0xfe,0xfd,0xfb,0xf7};//控制位选
uchar data Dis_buf[]={ 
        0,10,10,10};//控制显示内容
uint moment = 0;//ms变量
uint second = 0;//s变量
bit start = 1;
void Delay20ms()		//@12.000MHz
{ 
        
	unsigned char i, j, k;

	_nop_();
	_nop_();
	i = 1;
	j = 234;
	k = 113;
	do
	{ 
        
		do
		{ 
        
			while (--k);
		} 元器件数据手册IC替代型号,打造电子元器件IC百科大全!
          

相关文章