实验一 STC8h1k28 熟悉开发环境及端口输出控制
实验内容:
项目1:
参考原理图,设计1位闪烁灯程序,每次亮、灭时长均为500ms。
项目2:
参考原理图,设计三色流转灯程序,GRB三种颜色的LED轮番点亮,每次只亮一盏,每次点亮时长为500ms。
原理图:
实验原理:
(共阳)LED负极接单片机IO口(P00\P01\P02),当IO口输出低电平时LED被点亮,反之熄灭。
/*程序代码及注释:
项目1:
参考原理图,设计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; //设置P0口低三位为准双向口模式。
P0M0 &=0xf8;//设置P0口低三位为准双向口模式。
//设置IO口工作模式00(共阳),设置P00,P01,P02为准双向口模式(既可以输出也可//以输入)
//01推挽输出(共阴),10高祖输入(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控制
实验内容:
项目1:
利用定时器产生周期为100ms的方波,并以此方波控制LED以相同频率闪烁(使用查询方式实现);
项目2:
利用定时器控制流水灯流转时间,每盏灯每次点亮时长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中断、查询与按键控制
实验内容:
项目1:
每次按下按键,流水灯变化一种颜色,三种颜色循环变化,按键不按时颜色不变。(用外部中断实现)。
项目2:
每次按下按键,流水灯变化一种颜色,三种颜色循环变化,按键不按时颜色不变。
(用普通查询实现)。
项目3:
每次按下按键,流水灯变化一种颜色,三种颜色循环变化,按键不按时颜色不变。
(用定时器中断查询实现)。
原理图:
实验原理:
(共阳)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);
} while (--j);
} while (--i);
}
void Timer0Init(void)//1000微秒@12.000MHz(定时器0,16位自动重装12t模式12.000MHz)
{
AUXR &= 0x7F; //定时器时钟12T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0x18; //设置定时初值
TH0 = 0xFC; //设置定时初值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
}void Display_Init()//初始化中断、IO口
{
P2M1 = 0;//P2口设置为准双向口
P2M0 = 0; //P2口设置为准双向口
P1M1 &=0xF0; //P1口低4位设置为准双向口
P1M0 &=0xF0; //P1口低4位设置为准双向口
EA=1;//打开总中断
ET0=1;//打开定时器0中断允许位
TimerOInit();//初始化定时器0
}
void Dis_figure(unsigned int dd)
{
if(dd<10)
{
Dis_buf[0] = dd;//右边第一个数码管亮的数字
Dis_buf[1] = 10; //左边第三个数码管不亮
Dis_buf[2] = 10; //左边第二个数码管不亮
Dis_buf[3] = 10; //左边第一个数码管不亮
}
else if(10<=dd<100)
{
Dis_buf[0] = dd%10; //右边第一个数码管亮的数字
Dis_buf[1] = dd/10%10; //右边第二个数码管亮的数字
Dis_buf[2] = 10; //左边第二个数码管不亮
Dis_buf[3] = 10; //左边第一个数码管不亮
}
else if(100<=dd<1000)
{
Dis_buf[0] = dd%10; //右边第一个数码管亮的数字
Dis_buf[1] = dd/10%10; //右边第二个数码管亮的数字
Dis_buf[2] = dd/100%10; //右边第三个数码管亮的数字
Dis_buf[3] = 10; //左边第一个数码管不亮
}
else if(1000<=dd<9999)
{
Dis_buf[0] = dd%10; //右边第一个数码管亮的数字
Dis_buf[1] = dd/10%10; //右边第二个数码管亮的数字
Dis_buf[2] = dd/100%10; //右边第三个数码管亮的数字
Dis_buf[3] = dd/1000%10; //右边第四个数码管亮的数字
}
}
void dis_second()//每1ms进一次
{
if(start)
moment++;//每1毫秒加一
if(moment == 1000)//满一秒进入
{
moment = 0;//满1000ms清零
second++;//加一秒变量
Dis_figure(second);//数码管显示
}
}
void T0_Int() interrupt 1//定时器0外部中断服务子函数
{
static uchar i;//控制数码管对应段选位选亮的变量
position_PORT = 0xff;//先把数码管灭了,消影
font_PORT = LED_SMG[Dis_buf[i]];//数码管管段选亮字形码
position_PORT = Scan_bit[3-i];//控制位选亮
i++;
if(i>3)
i=0;//以上两行保证数码动态显示
dis_second();//数码管显示
}
void INT0() interrupt 0//外部中断0中断服务子函数
{
Delay20ms();
if(!key1)//按键消抖
start = !start;//每按一次取标志位取非一次,控制启停
}
void INT1() interrupt 2//外部中断1中断服务子函数
{
second = 0;//计时清零
Dis_buf[0] = 0;//数码管清零
}
void setup()
{
EA=1;//打开中断总开关
IT0=1;//外部中断0下降沿触发,=0上升沿下降沿都触发
EX0=1;//外部中断0中断允许位打开
IT1=1; //外部中断1下降沿触发
EX1=1; //外部中断1中断允许位打开
Display_Init();
}
void main(void)//万年不变主函数,三段式
{
setup();//初始化
while(1);//循环体,啥也不执行在这耗时,保证个定时器功能瞬时间流逝时执行
}
实验五 STC8h1k28单片机与 PC 串口通信
实验内容:
项目:
PC 机通过串口调试助手发送字符指令给单片机。单片机接到指令后,按照指令点亮或熄灭对应的 LED,并将指令回传给 PC 机,并在串口调试助手的接收缓冲区显示出来。指令对照表如下:
R——红灯亮; G——绿灯亮; B——蓝灯亮; A——所有灯亮; O——所有灯灭。
实验原理:
1.单片机与PC机间采用电平转换模块连接, 实现单片机串口与PC机USB接口的物理连接和电平转换。单片机与PC之间采用异步串口通信。 波特率9600, 信息格式为8个数据位, 1个停止位,无奇偶校验位。 PC机可采用STC-ISP软件内嵌的“串口调试助手”进行调试。
2.波特率计算公式
3.STC-ISP 在线编程工具中内嵌的串口助手。
原理图:
文章来源:https://www.toymoban.com/news/detail-440148.html
//程序代码及注释:
#include<stc8h.h>
char s_data='x';//初始化变量
void UartInit(void) //9600bps@11.0592MHz
{
SCON = 0x50; //8位数据,可变波特率
AUXR |= 0x40; //定时器1时钟为Fosc,即1T
AUXR &= 0xFE; //串口1选择定时器1为波特率发生器
TMOD &= 0x0F; //设定定时器1为16位自动重装方式
TL1 = 0xE0; //设定定时初值
TH1 = 0xFE; //设定定时初值
ET1 = 0; //禁止定时器1中断
TR1 = 1; //启动定时器1
}
void UART_R(void) interrupt 4 using 1//串口1中断服务子函数
{
if(RI)//接受成功时进入if
{
s_data = SBUF;//接收数据,CPU从SBUF读数据
RI =0;//接受成功清零标志位,保证下次接收
switch(s_data)
{
case 'b'://发送‘b’蓝灯亮
P00=0;
break; //跳出整个循环
case 'r': //发送‘r’红灯亮
P01=0;
break; //跳出整个循环
case 'g': //发送‘g’绿灯亮
P02=0;
break; //跳出整个循环
case 'o': //发送‘o’灯不亮
P0=0xff;
break; //跳出整个循环
case 'a': //发送‘a’灯都亮
P0=0;
break; //跳出整个循环
default: //除了以上情况外,
SBUF = 'n'; //发送数据‘n’。CPU向SBUF写入数据
while(!TI); //等待发送成功
break;//跳出整个循环
}
SBUF =s_data ; //发送数据。CPU向SBUF写入数据
while(!TI);//等待发送成功
}
if(TI)//发送成功进入if
TI=0;//发送标志位清零
}
void setup()
{
P0M1 &=0xF8;//(P0M1=0x00)//P0低三位设置为准双向口模式
P0M0 &=0XF8;//(P0M0=0x00)//P0低三位设置为准双向口模式
ES=1;//打开串口1中断允许控制位
EA=1; //打开总中断
}
void main(void)//万年不变主函数三段式
{
setup();//初始化函数
UartInit();初始化串口1
while(1);//耗时
}
实验六 STC8h1k28基于 ADC 的模拟按键识别与控制
实验内容:
项目:
将模拟按键键值通过串口发送至 PC 机的串口调试助手, 并通过四个模拟按键控制评估版上的发光二极管亮灭。 控制方式如下: 1 键按下蓝灯亮, 2 键按下红灯亮, 3 键按下绿灯亮,
4 键按下三种颜色的灯均亮, 没有按键按下时所有灯均熄灭。
原理图:
实验原理:
按下不同模拟按键模拟通道口得到不同模拟数值,ADC转换成对应数值给cpu,在通过switc—case循环选择控制灯亮灭;
(共阳)LED 负极连接单片机 IO 口(P00\P01\P02), 当 IO 口输出低电平时 LED 被点亮,反之
熄灭;
PC 机的串口调试助手。文章来源地址https://www.toymoban.com/news/detail-440148.html
//程序代码及注释:
#include <stc8h.h>
#include<intrins.h>//用到了_nop_();
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
uchar adc_data;//读取结果高八位放于此变量
void Delay20ms() //@24.000MHz
{
unsigned char i, j, k;
_nop_();
_nop_();
i = 2;
j = 211;
k = 231;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
void UartInit(void) //9600bps@11.0592MHz
{
SCON = 0x50; //8位数据,可变波特率
AUXR |= 0x40; //定时器1时钟为Fosc,即1T
AUXR &= 0xFE; //串口1选择定时器1为波特率发生器
TMOD &= 0x0F; //设定定时器1为16位自动重装方式
TL1 = 0xE0; //设定定时初值
TH1 = 0xFE; //设定定时初值
ET1 = 0; //禁止定时器1中断
TR1 = 1; //启动定时器1
}
void adc_init()
{
ADC_CONTR |=1<<7;//打开ADC 电源
}
uint adc_read()
{
uint adc_value; //存放ADC转换结果高八位的自定义变量
ADC_CONTR &=(0xf0);//清除ADC_CHS[3:0]
ADC_CONTR |=7;//设置ADC模拟通道选择P1.7
P1M1 |=0x80;//P1.7高阻输入
P1M0 &=0x7f;//P1.7高阻输入
ADC_CONTR |=0x40;//启动ADC转换
while(!ADC_CONTR & 0x20);//等待转换成功
ADC_CONTR &=~0x20;//清零完成标志位
adc_value = ADC_RES;//ADC转换结果高八位给变量
ADC_RES=0;//高八位寄存器清零
ADC_RESL = 0;//低八位寄存器清零
return adc_value; //返还高八位值,返回值必须与函数类型一致
}
void UART_R(void) interrupt 4 using 1
{
if(TI)//发送成功则进入if
TI = 0;//发送成功,ti清零
}
void adc_uart()
{
SBUF = adc_data;//发送数据。CPU向SBUF写入数据
Delay20ms();//延时20ms
}
void adc_led()//按下不同模拟键得到不同ADC转换值,亮相应灯
{
switch(adc_data)
{
case 0: P00 = 0; break;//转换数值高八位为0,亮蓝灯
case 0x2A: P01 = 0; break;//转换数值高八位为2a,亮红灯
case 0x51: P02 = 0; break;//转换数值高八位为51,亮绿灯
case 0x7F: P0 &= 0xF8; break;//转换数值高八位为7f,亮混彩灯
default: P0 |= 0x07; break;//转换数值高八位除了以上情况,灯灭
}
}
void main()//万年不变主函数三段式
{
EA=1;//打开中断总开关
ES=1;//打开串口1中断允许控制位
adc_init();//初始化ADC
UartInit();//初始化串口1
P0M1 &=0xf8;//设置P0低三位为准双向
P0M0 &=0xf8;//设置P0低三位为准双向
while(1)
{
adc_data = adc_read();//读dac转换值取出高八位转换值
adc_uart();//发送数据。CPU向SBUF写入数据 函数
adc_led();//ADC值控制亮灯函数
}
}
到了这里,关于STC8h1k28六个基本实验的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!