实验一 STC8h1k28 熟悉开发环境和端口输出控制
参考原理图,设计闪烁灯程序,每次亮灭时间为500ms。 三色流转灯程序设计参考原理图,GRB三种颜色的LED轮流点亮,每次只点亮一盏,每次点亮时间为500ms。
(共阳)LED负极接单片机IO口(P00\P01\P02),当IO口输出低电平时LED被点亮,反之亦然。
/*程序代码及注释: ?项目1: 参考原理图,设计闪烁灯程序,每次亮灭时间为500ms。代码如下:*/ #include <stc8h.h> /*存储是定义好的寄存器地址。*/ #include<intrins.h>/*用到_nop_()这个函数必须包含这个头文件中对这个函数的定义*/ void Delay500ms() //@11.0592MHz延时函数 {
unsigned char i, j, k; _nop_();///使用它将使用这个头文件<intrins.h> _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 <stc8h.h>
/*存储的是定义好的寄存器地址。*/
#include<intrins.h>//用到_nop_()这个函数就得包含这个头文件里面有关于这个函数的定义
//用尖括号是用于包含标准库的头文件
//双引号一般用于包含用户自己编写的头文件
char i;//控制灯轮转的变量
void Delay500ms() //@11.0592MHz延时函数
{
unsigned char i, j, k;
_nop_();//用到它就要用到这个头文件<intrins.h>
_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控制
利用定时器产生周期为100ms的方波,并以此方波控制LED以相同频率闪烁(使用查询方式实现); 利用定时器控制流水灯流转时间,每盏灯每次点亮时长500ms(使用中断方式实现)。
(共阳)LED负极连接单片机IO口(P00\P01\P02).当IO口输出低电平时LED被点亮,反之熄灭。 定时/计数器工作原理 定时器定时时间计算公式(16bit):
/*程序代码及注释: 项目1: 利用定时器产生周期为100ms的方波,并以此方波控制LED以相同频率闪烁(使用查询方式实现);代码如下:*/ #include <stc8h.h> /*存储的是定义好的寄存器地址*/ 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 <stc8h.h> /*存储的是定义好的寄存器地址。*/ 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中断、查询与按键控制
每次按下按键,流水灯变化一种颜色,三种颜色循环变化,按键不按时颜色不变。(用外部中断实现)。 每次按下按键,流水灯变化一种颜色,三种颜色循环变化,按键不按时颜色不变。 (用普通查询实现)。 每次按下按键,流水灯变化一种颜色,三种颜色循环变化,按键不按时颜色不变。 (用定时器中断查询实现)。 (共阳)LED负极接单片机IO口(P00\P01\P02),当IO口输出低电平时LED被点亮,反之熄灭。 按键按下为低电平,扫描按键为低电平灯亮。 定时/计数器工作原理 定时器定时时间计算公式(16bit):
/*程序代码及注释: 项目1: 每次按下按键,流水灯变化一种颜色,三种颜色循环变化,按键不按时颜色不变。(用外部中断实现)。*/ //外部中断实现流水灯运转 #include <stc8h.h> #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 <stc8h.h> #include <intrins.h>//用到 _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 <stc8h.h>//头文件包含下面部分需要用到的语句定义 #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 <stc8h.h> #include<intrins.h>//用到_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); } 标签:
1n4007g二极管