Task 1:
基于51核心板设计一个按键计数器。要求:判断KEY1按下,每次按下按键后记录按动次数加1,并且能在数码管上显示,能够从0计数至99。
#include <STC89C5xRC.H>
void DelayNums(unsigned int xms) //@11.0592MHz
{
while(xms--)
{
unsigned char i, j;
i = 2;
j = 199;
do
{
while (--j);
} while (--i);
}
} //标配的延时函数
sbit SegmentG1 = P2^3;//位定义数码管1
sbit SegmentG2 = P2^2;//位定义数码管2
sbit SegmentG3 = P2^1;//位定义数码管3
sbit SegmentG4 = P2^0;//位定义数码管4
sbit KEY1 = P3^2;//位定义按键1
static unsigned char s_arrNUmber[]={0x03,0x9f,0x25,0x0d,0x99,0x49,0x41,0x1f,0x01,0x09};//数码管显示0~9
void main()
{
unsigned int i=1,j;//i=1 数码管从数字1开始
while(1)
{
if(0==KEY1)
{
DelayNums(220);//按键去抖,时间依据数码管实际响应时间做调整
if(0==KEY1&&i<=9) { //次数小于9次时
P0 = s_arrNUmber[i];
SegmentG1 = 0; //点亮数码管1
DelayNums(30);
SegmentG1=1;
i++; //累加次数
}
else if((0==KEY1)&&(i>9&&i<100))//次数大于9时
{
P0 = s_arrNUmber[i/10]; //取按键次数的十位数并记录在数码管1
SegmentG1 = 0; //点亮数码管1
DelayNums(5);
SegmentG1=1;
P0 = s_arrNUmber[i%10]; //取按键次数的个位数并记录在数码管2
SegmentG2 = 0; //点亮数码管2
DelayNums(5);
SegmentG2=1;
i++; //累加次数
}
}
}
}
Task 2:
LED倒序流水
#include <STC89C5xRC.H>
static void DelayNums(int nums)
{
unsigned int i=0,j=0;
for( j=0; j<nums; j++)
for( i=0; i<123; i++);
}
sbit LED1 = P2^4;
sbit LED2 = P2^5;
sbit LED3 = P2^6;
sbit LED4 = P2^7;
void main()
{
unsigned int t;
while(1)
{
P2=0x7F;
for(t=0; t<4; t++)
{
DelayNums(500);
P2=P2>>1;
}
}
}
Chapter 7 外部中断
7.1中断概念
当CPU在正常运行时,如果外部发生了紧急事件请求,CPU则会先暂停当前的工作,转而调用特定的程序来处理这个紧急事件。处理完毕后再回到原来中断发生的地方继续工作。
7.2 中断系统框架
中断源:请示中断的请求源。STC89 C52系列微控制器有8个中断源(4个外部中断,3个定时器/计数器中断,1个串口中断)
中断触发条件
1)低电平触发
当外部中断输入引脚检测到低电平时中断触发,并且在低电平保持的时间内持续触发中断,直到引脚变为高电平。
2)下降沿触发
引脚电平从高电平到低电平跳变的瞬间,称为下降沿。当外部中断输入引脚检测到下降沿时,中断触发。当引脚保持低电平时,中断不会再次触发。
中断触发相关寄存器
//设置外部中断0触发方式为下降触发
ITO = 1;
中断允许控制
中断允许分为各中断源的允许和总中断允许,决定着中断能否被CPU响应。只有对应中断源的中断允许以及总中断允许打开后,CPU才能够响应该中断。
中断优先级
中断处理
//软件查询
if (1==IE0)
{
......//中断处理
IE0 = 0;//清零外部中断0请求标志位
}
//硬件查询
函数类型 函数名()interrupt 中断号 using 工作寄存器组号
void External_0Handler() interrupt 0
#include <STC89C5xRC.H>
sbit LED1 = P2^4;
sbit LED2 = P2^5;
static void IniInterrupt(void);
static void InitInterrupt()
{
IT0 = 1;//设置外部中断0的触发方式为下降沿触发
EX0 = 1;//打开外部中断0的中断允许
IT1 = 1;//设置外部中断1的触发方式为下降沿触发
EX1 = 1;//打开外部中断1的中断允许
EA = 1;//打开总中断允许
}
void main()
{
InitInterrupt();//配置中断
while(1);
}
void External0_Handler() interrupt 0
{
LED1 = ~LED1;//翻转LED1的亮灭状态
void External1_Handler() interrupt 2
{
LED2 = ~LED2;//翻转LED2的亮灭状态
}
Chapter 8定时器/计时器
8.1 时钟周期和机器周期
1)时钟周期
51核心板采用的是12MHz晶振,因此一个时钟周期为
2)机器周期
指单片机执行一个操作所需的最短时间。在汇编语言中,执行一条指令所需的时间为机器周期的整数倍。传统的51单片机1个机器周期等于12个时钟周期,而STC89C52RC单片机的机器周期是可变的,为6或12个时钟周期,简称为6T或12T。在12MHz晶振下,机器周期分别为0.5μs和1μs。
8.2 工作原理
定时器/计数器所有累加的操作是通过计数寄存器实现的。单片机上电复位后其初值均为0,一旦定时器/计数器0开始工作,则从设定的计数初值开始,每接收到1个脉冲时计数值加1。当计数寄存器的高位与低位都计满至0xFFFF时,再接收1个脉冲后定时器溢出,产生中断请求,并且自动清零。
8.3 定时器/计时器框架
8.4实践
1)计数器控制LED
#include <STC89C52xRC.H>
sbit LED1 = P2^4;
static void InitInterrupt()
{
ET0 = 1;//打开定时器/计数器0的中断允许
EA = 1;//打开总中断允许
}
static void InitTimer0()
{
TMOD = 0x05;//设置计数器0为工作模式1
TH0 = 0xFF;//设置计数器0计数初值的高8位
TL0 = 0xFD;//设置计数器0计数初值的低8位,计数至3位后溢出
TR0 = 1;//打开计数器0
}
void main()
{
InitInterrupt();//配置中断
InitTimer0 ();//配置计数器0
while(1);
}
void Timer_Handler() interrupt 1
{
TH0 = 0XFF;//重新设置计数器0计数初值的高8位
TL0 = 0XFD;//重新设置计数器0计数初值的低8位,计数至3后溢出
LED1 = ~LED1;//翻转LED1的亮灭状态
}
2)定时器控制LED
#include <STC89C52cC.H>
sbit LED1 = P2^4;
static void InitInterrupt()
{
ET0 = 1;//打开定时器/计数器0的中断允许
EA = 1;//打开总中断允许
}
static void InitTimer0()
{
TMOD = 0x01;//设置定时器0为模式工作1
TH0 = 0xFC;//设置定时器0计数初值的高8位
TL0 = 0x18;//设置定时器0计数初值的低8位,定时1ms后溢出
TR0 = 1;//打开定时器0
}
void main()
{
InitInterrupt();//配置中断
InitTimer0();//配置定时器0
while(1);
}
void Timer0_Handler() interrupt 1
{
static unsigned int s_iCounter;//定义静态变量作为计数变量
TH0 = 0XFC;//重新设置定时器0计数初值的高8位
TL0 = 0X18;//重新设置定时器0计数初值的低8位,定时1ms后溢出
s_iCounter++;//每次进入一次中断,计数变量加1
if(s_iCounter>=1000)//当计数变量达到1000时,即1000ms
{
s_iCounter = 0;//计数变量清零
LED1 = ~LED1;//翻转LED1的亮灭状态
}
}
标签:STC89,LED1,定时器,C52RC,计数,中断,void,单片机,计数器
From: https://blog.csdn.net/2301_79706774/article/details/137236281