蓝桥杯
基础实验阶段
跑马灯
实验目的
在CT107D单片机综合训练平台上实现LED的基本控制,首先让8路LED指示灯闪烁3遍然后熄灭,接着依次点亮LED指示灯,最后依次熄灭指示灯,程序循环实现上述功能。
使用芯片
- 74HC573 锁存器
- 74HC138 译码器
- 74HC02 或非门
编写思路
首先根据LED的亮灭由74HC573控制,LE低电平时输出不变,LE高电平时候,Q1-8输出P00-P07相同值。根据LED的摆放,低电平亮,高电平灭。
LE由Y4C控制,连接在或非门的输出端。Y4或WR任意为高电平,输出为低电平,Y4和WR均为低电平时,输出为高电平。控制LED时需要输出为高电平,所以Y4与WR均应为低电平。
其中 WR 通过 J13 跳帽23连接,已经为低电平,则只需要 Y4 为低电平。
Y4 连接在 74HC138 的输出端,需要控制 CBA(P27P26P25) 为100时,输出Y4即为低电平。
至此可以控制LED的亮灭,后续LED的亮灭控制可以通过 P0 引脚直接控制。
程序
main.c
#include <reg52.h>
sbit HC138_A = P2^5;
sbit HC138_B = P2^6;
sbit HC138_C = P2^7;
void Delay(unsigned int t)
{
while(t--);
while(t--);
}
void LED_init(){
HC138_C = 1;
HC138_B = 0;
HC138_A = 0;
}
void LED_running(){
int i=0;
for(i=0;i<3;i++)
{
P0 = 0x00;
Delay(60000);
Delay(60000);
P0 = 0xff;
Delay(60000);
Delay(60000);
}
for(i=1;i<9;i++)
{
P0 = 0xff<<i;
Delay(60000);
Delay(60000);
}
for(i=1;i<9;i++)
{
P0 = ~(0xff<<i);
Delay(60000);
Delay(60000);
}
}
int main()
{
LED_init();
while(1){
LED_running();
}
}
蜂鸣器与继电器
实验目的
在CT107D单片机综合训练平台上实现蜂鸣器与继电器的基本控制,首先让8路LED指示灯闪烁3遍后熄灭,接着依次点亮LED指示灯,继电器吸合一会后断开,然后依次熄灭LED指示灯,蜂鸣器鸣叫一会后关闭,程序循环实现上述功能。
使用芯片
-
74HC573 锁存器
-
74HC138 译码器
-
74HC02 或非门
-
ULN2003 达林顿管
起到增大功率作用,非门输出
编写思路
蜂鸣器由网络标签 N_BUZZ 控制,输出低电平蜂鸣器鸣叫,高电平不发声。继电器由网络标签 N_RELAY 控制,输入低电平 m2 接低,高电平 m1 接低,根据 L10 可知,**N_RELAY **为低电平时LED亮,高电平时灭。
N_BUZZ 和 N_RELAY 连接在ULN2003的输出5、7两个引脚上,由输入引脚5、7反相控制。进一步由Y5C为高电平时,P04(继电器) 和 P06(蜂鸣器)控制。
Y5C 与 Y5 的控制与第一个实验中类似,不再赘述。
程序
main.c
#include <reg52.h>
sbit HC138_A = P2^5;
sbit HC138_B = P2^6;
sbit HC138_C = P2^7;
sbit Relay_LED = P0^4;
sbit BUZZ = P0^6;
void Delay(unsigned int t){
while(t--);
while(t--);
while(t--);
while(t--);
}
void HC138_Set(unsigned char n)
{
switch(n)
{
case 4:
HC138_C = 1;
HC138_B = 0;
HC138_A = 0;
break;
case 5:
HC138_C = 1;
HC138_B = 0;
HC138_A = 1;
break;
}
}
void Relay(unsigned char n){
//控制继电器 参数 n=1 时候继电器闭合,n=0时继电器打开。
if(n){
HC138_Set(5);
Relay_LED = 1;
}
else{
HC138_Set(5);
Relay_LED = 0;
}
}
void BUZZ_Alarm(unsigned char n){
//控制蜂鸣器 参数 n=1 时候蜂鸣器发声,n=0时蜂鸣器不发声。
if(n){
HC138_Set(5);
BUZZ = 1;
}
else{
HC138_Set(5);
BUZZ = 0;
}
}
void LED_running(){
int i=0;
//闪烁3次
HC138_Set(4);
for(i=0;i<3;i++)
{
P0 = 0x00;
Delay(60000);
P0 = 0xff;
Delay(60000);
}
//依次点亮LED
for(i=1;i<9;i++)
{
P0 = 0xff<<i;
Delay(60000);
}
//继电器闭合 LED亮
Relay(1);
Delay(60000);
Relay(0);
//依次熄灭LED
HC138_Set(4);
for(i=1;i<9;i++)
{
P0 = ~(0xff<<i);
Delay(60000);
}
//蜂鸣器报警
BUZZ_Alarm(1);
Delay(60000);
BUZZ_Alarm(0);
}
void System_Init(){
HC138_Set(5);
P0 = 0x00;
}
int main()
{
System_Init();
while(1){
LED_running();
}
}
共阳数码管的静态显示
实验目的
在CT107D单片机综合训练平台上,8个数码管分别单独依次显示0~9的值,然后所有数码管一起同时显示0~F的值,如此往复。
使用外设
- 共阳数码管
编写思路
共阳数码管的显示需要选择两个变量,一个是位置(由Y6C所在的573锁存器控制)一个是内容(由Y7C所在的锁存器控制)。在显示的时候,先选择位置,再选择显示内容即可使用数码管。
共阳数码管的段码表:
unsigned char table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};
程序
main.c
#include <reg52.h>
unsigned char code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};
void Delay(unsigned int t){
while(t--);
while(t--);
}
void InitHC138(unsigned char n){
switch(n)
{
case 4:
P2 = (P2 & 0x1f) | 0x80;
break;
case 5:
P2 = (P2 & 0x1f) | 0xa0;
break;
case 6:
P2 = (P2 & 0x1f) | 0xc0;
break;
case 7:
P2 = (P2 & 0x1f) | 0xe0;
break;
}
}
void NixieTube_Show(){
unsigned char i,j;
for(i=0;i<8;i++)
{
InitHC138(6);
P0 = 0x01 << i;
for(j=0;j<10;j++)
{
InitHC138(7);
P0 = table[j];
Delay(6000);
Delay(6000);
}
}
InitHC138(6);
P0 = 0xff;
for(j=0;j<16;j++)
{
InitHC138(7);
P0 = table[j];
Delay(6000);
Delay(6000);
Delay(6000);
Delay(6000);
}
}
void main ()
{
InitHC138(5);
P0 = 0x00;
while(1)
{
NixieTube_Show();
}
}
共阳数码管动态显示
实验目的
在CT107D单片机综合训练平台上,实现数码管的动态显示,在8位数码管中,前面4位显示年份“2018”,接着2位是分隔符“-”,最后两位是月份,从1月份开始,每隔一段时间加1个月,到12月之后又从1月开始递增,如此往复。
使用外设
- 共阳数码管
编写思路
-
动态显示实质上就是轮流点亮单个数码管实现多位数码管整体显示的效果。
-
在轮流显示过程中,每位数码管点亮时间为1~2ms,由于人的视觉暂留现象及发光二极管的余辉效应,尽管实际上各位数码管并非同时点亮,但只要扫描的速度足够快,给人的印象就是一组稳定的显示数据,不会有闪烁感,效果和静态显示是一样的,能够节省大量的IO端口,而且功耗更低。
-
对于一组4位数码管来说,静态显示和动态显示都能实现同样的效果,但需要的I/O端口是不同的。
静态显示需要I/O端口:8个段码*4+4个COM端=36个lO引脚动态显示需要l/O端口:8个段码+4个COM端=12个I/O引脚
程序
main.c
#include <reg52.h>
unsigned char mouth=1;
unsigned char code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xbf,0x7f};
void SetHC138(unsigned char n){
switch(n)
{
case 4:
P2 = (P2 & 0x1f) | 0x80;
break;
case 5:
P2 = (P2 & 0x1f) | 0xa0;
break;
case 6:
P2 = (P2 & 0x1f) | 0xc0;
break;
case 7:
P2 = (P2 & 0x1f) | 0xe0;
break;
}
}
void NixieTube_Show(unsigned char pos,unsigned value){
SetHC138(6);
P0 = 0x01 << pos;
SetHC138(7);
P0 = value;
}
void Delay_NixieTube(unsigned t){
while (t--);
}
void NixieTube_Dynamic(){
NixieTube_Show(0,table[2]);
Delay_NixieTube(500);
NixieTube_Show(1,table[0]);
Delay_NixieTube(500);
NixieTube_Show(2,table[0]);
Delay_NixieTube(500);
NixieTube_Show(3,table[2]);
Delay_NixieTube(500);
NixieTube_Show(4,table[16]);
Delay_NixieTube(500);
NixieTube_Show(5,table[16]);
Delay_NixieTube(500);
NixieTube_Show(6,table[mouth/10]);
Delay_NixieTube(500);
NixieTube_Show(7,table[mouth%10]);
Delay_NixieTube(500);
}
void Delay(unsigned int t)
{
while(t--)
{
NixieTube_Dynamic();
}
}
int main(){
while (1){
NixieTube_Dynamic();
Delay(200);
mouth++;
if(mouth>12)
mouth-=12;
}
}