1、烧录软件
(1)单片机型号:IAP15F2K61S2
(2)输入用户程序运行时的IRC频率:11.0592MHz
2、CT107D单片机综合实训平台
CT107D:单片机芯片(全I/O兼容8051系列,为保留P3.6,P3.7的WR,RD功能由P4.2,P4.4替换。);显示模块;输入/输出模块;传感模块;存储/AD、DA/时钟模块;USB转TTLIO扩展。
跳线:红外功能选择(J2);USB功能选择(J4);按键功能选择(J5);外设访问方式选择(J13);外设访问方式选择(J15)
功能:片上功能(定时器、中断、捕获、串口、外部中断、EEPROM、ADC);重点外设功能(键盘、数码管、LED、继电器、蜂鸣器、DS1302、AT24C02、DS18B20、PCF8591);额外功能(串口通信、LCD1602、红外收发、霍尔元件频率测算、超声波测距)
**
选通端(G1)为高电平,另两个选通端((G2A)和(G2B))为低电平时,可将地址端(A、B、C)的二进制编码在一个对应的输出端以低电平译出。
A、B、C 译码地址输入端(接单片机IO口)
G1 选通端(接电源或单片机IO口)
(G2A)、(G2B) 选通端(低电平有效)
Y0~Y7 译码输出端(接受控器件)
在该平台A、B、C 译码地址输入端接入单片机P2寄存器中的P25、P26、P27三个端口。
//如果需要使用P20~P25端口建议如下写法
P2 = ((P2&0x1f)|0xA0); //这种写法只改变后P2高三位的状态,不改变前面低五位的状态。
//P2&0x1f的操作是保留低五位状态将高三位置0,0x1f = 00011111 和 0xA0 = 10100000进行或运算
//最终 P2 = 0xBF = 10111111
P2 = 0xA0; //如无需使用P20~P25端口可直接对P2寄存器进行操作
其中G2* =(G2A) + (G2B)、L = 低电平、H = 高电平、X = 任意
引出端符号:
A1-A4或非门输入端(接单片机IO口或GND)
B1-B4或非门输入端(接单片机IO口或GND)
Y1~Y4 或非门输出端(接受控器件)
在该平台A1-A4或非门输入端接入GND或P36(通过跳线选择),B1-B4或非门输入端接入GND,Y1~Y4 或非门输出端接四片573(LE)锁存使能端。
可以通过J13的跳帽选择是WR还是GND作为74HC02的输入。如果译码器的Y4输出低电平,那么74HC02的输出Y4C将为高电平。
3、八进制3态非反转透明锁存器 —— 74HC573
LE为高电平时,Q1~ Q8输出和D1~D8输入是一样的;
LE为低电平时,Q1~ Q8输出不受D1~D8输入的变化影响。
引出端符号:
D1-D8输入端(接单片机IO口)
Q1-Q8输出端(接受控器件)
LE锁存使能端(接控制器件)
OE输出使能端(接GND)
在该平台D1-D8输入端接入单片机P0,Q1-Q8输出端接受控元器件,LE锁存使能端接四2或非门输出端。
P2 = ((P2&0x1f)|0xA0); //操作138译码器ABC输入端为 101,Y0~Y7输出为 11111011,其中Y5为 L
/*
CT107D实验平台中 Y4 ~ Y7分别对应控制或非门输出端Y1 ~ Y4
通过或非门选择分别控制以下四部份的573锁存器
①LED发光二极管
②达林顿管——(电机、继电器、蜂鸣器)
③8位8段数码管段选
④8位8段数码管位选
*/
P0 = 0x00; //控制②号573锁存器驱动,达林顿管ULN2003输出0xff,控制电机、继电器、蜂鸣器等原件
void InitHC138(unsigned char n)
{
switch(n)
{
case 4:
P2 = (P2 & 0X1f) | 0x80; //LED,低电平亮
break;
case 5:
P2 = (P2 & 0X1f) | 0xa0; //蜂鸣器(0x40)继电器(0x10),
break; //高电平使能
case 6:
P2 = (P2 & 0X1f) | 0xc0; //数码管位置
break;
case 7:
P2 = (P2 & 0X1f) | 0xe0; //数码管内容
break;
}
}
#include “stc15f2k60s2.h”
void main()//消音、关闭继电器程序
{
while(1)
{
P2 = ((P2&0x1f)|0xA0); //选中控制蜂鸣器、继电器的573芯片
P0 = 0X00; //输入0000 0000,通过ULN2003取非,输出1111 1111,
//使受控源两端电势差为0
}
}
2、流水灯
(1)方法一:位运算的左右移符号“<<”、“>>”符号
#include “stc15f2k60s2.h”
#include “intrins.h”//因为延时函数中含有_nop_指令,
//需要用到这个头文件,同时流水灯2
//中的左右移函数也是从中调用的
void main()//流水灯1程序
{
unsigned char i;
P2 = ((P2&0x1f)|0xA0);
P0 = 0X00; //先进行消音处理,蜂鸣器声音刺耳。
P2 = ((P2&0x1f)|0x80);//选择控制LED的573
P0 = 0x00;//点亮八个LED
while(1)//循环条件永远为真,以下程序一直执行下去。
{
for(i = 0; i < 8; i++)
(2)方法二:调用左右移函数“crol”、“cror”
<span style="font-family: Tahoma, "Microsoft Yahei", Simsun;">#include</span><span style="font-family: Tahoma, "Microsoft Yahei", Simsun;"> </span><span style="font-family: Tahoma, "Microsoft Yahei", Simsun; white-space: normal;">“stc15f2k60s2.h”</span>
3、独立按键和矩阵键盘
比赛使用的是IAP15的转接板,该开发板不可使用按键处罚外部中断的方式检测按键,不做讨论,同时IAP15芯片的WR/RD功能不是P36/P37引脚功能,故用P42/P44引脚代替。
(1)方法一:使用reg52.h开头的程序
#include “stc15f2k60s2.h”
void main()//消音、关闭继电器程序
{
while(1)
{
P2 = ((P2&0x1f)|0xA0); //选中控制蜂鸣器、继电器的573芯片
P0 = 0X00; //输入0000 0000,通过ULN2003取非,输出1111 1111,
//使受控源两端电势差为0
}
}
(2)方法二:使用stc15f2k60s2.h开头的程序
#include “stc15f2k60s2.h”//该文件已定义P4寄存器故下方无需重复定义
sbit P3_6 = P4^2;//位定义用 P3_6 在程序中替换 P4^2的功能
sbit P3_7 = P4^4;//同上
以stc15为开头的程序为例。
1ms延时程序(11.0592M晶振)
void Delay_1_ms(unsigned int n)//@11.0592MHz
{
unsigned char i,j;
for(i = 0;i > n;i--)
{
_nop_();
_nop_();
_nop_();
i = 11;
j = 190;
do
{
while (--j);
} while (--i);
}
}
(1)独立按键
#include “stc15f2k60s2.h”
#include “intrins.h”
#define LED P0 //宏定义,在程序中可用LED代替P0使用
sbit key0 = P3^0; //对S7按键所接端口进行位定义
void Delay_1_ms(unsigned int n);
void main()
{
P2 = ((P2&0x1f)|0xA0); //不再重复解释,前两章已解释多次
P0 = 0X00;
P2 = ((P2&0x1f)|0x80); //因为要使用LED故选择到该区域
P0 = 0Xff;//先关闭LED
while(1)
{
if(key0 == 0)//档S7按键按下GND与P30导通P30得到低电平的信号
{
Delay_1_ms(10);//延时消抖,去除按键机械抖动带来的干扰因素
if(key0 == 0)//再次确认按键按下
{
LED = 0X00;//按键按下 点亮所有LED
while(!key0);//判断按键是否松开,如果为松开则停在此处等待
}
LED = 0xff;//按键松开,熄灭所有LED
}
}
}
(2)矩阵按键
a. 扫描函数
void keyscan()
{
BUFFER = 0X0F; P3_6 = 0; P3_7 = 0;
/*首先我们进行列扫描,将P34~P37都置零,其中要注意,开发板上用
P42、P44替换了P36、P37故我们要单独将这两个IO置零*/
if(BUFFER != 0X0F)// “!=”表示档P3不等于0x0f时条件为真
{
Delay_1_ms(10); //延时消抖
if(BUFFER != 0X0F)//再次判断
{
switch(BUFFER)
/*当按键按下行中值发生变化得到一个BUFFER,
生成一个新的标志位*/
{
case 0X07: key_value = 1; break;
case 0X0B: key_value = 5; break;
case 0X0D: key_value = 9; break;
case 0X0E: key_value = 13; break;
}
BUFFER = 0XF0; P3_6 = 1; P3_7 = 1;
/*我们在进行行扫描,原理同上下方进行判断第几行
按键按下,结合列标志位生成新的行列标志位。*/
if(P3_7 == 0) key_value += 0; while(P3_7 == 0);
if(P3_6 == 0) key_value += 1; while(P3_6 == 0);
if(BUFFER == 0XD0) key_value += 2; while(BUFFER == 0XD0);
if(BUFFER == 0XE0) key_value += 3; while(BUFFER == 0XE0);
}
}
}
b. 主函数
#include “stc15f2k60s2.h”
#include “intrins.h”
#define LED P0 //宏定义,在程序中可用LED代替P0使用
#define BUFFER P3 //宏定义,在程序中用BUFFER代替P3端口
sbit P3_6 = P4^2;//位定义用 P3_6 在程序中替换 P4^2的功能
sbit P3_7 = P4^4;//同上
void Delay_1_ms(unsigned int n);
void keyscan();//键盘扫描函数
void main()
{
P2 = ((P20x1f)|0xA0); //选中控制蜂鸣器、继电器的573芯片
P0 = 0X00;
P2 = ((P20x1f)|0x80); //因为要使用LED故选择到该区域
P0 = 0Xff;//先关闭LED
while(1)
{
keyscan();//键盘扫描函数
switch(key_value)
{
case 1: LED = 0x00; break;
case 2: LED = 0x12; break;
case 3: LED = 0xab; break;
case 4: LED = 0xfe; break;
case 5: LED = 0x08; break;
case 6: LED = 0x0c; break;
case 7: LED = 0xa5; break;
case 8: ; break;
case 9: ; break;
case 10: ; break;
case 11: ; break;
case 12: ; break;
case 13: ; break;
case 14: ; break;
case 15: ; break;
case 16: ; break;//只定义了一部分按键功能
case 17: ; break;//功能不限于点灯
}
}
}
习题:用四个独立按键和八个LED做一个八位二进制加法器,一个按键表示“+1”,一个按键表示“-1”,一个按键表示“清零”,一个按键表示“清零前最后一次显示的数”。
void InitHC138(unsigned char n)
{
switch(n)
{
case 4:
P2 = (P2 & 0X1f) | 0x80; //LED,低电平亮
break;
case 5:
P2 = (P2 & 0X1f) | 0xa0; //蜂鸣器(0x40)继电器(0x10),
break; //高电平使能
case 6:
P2 = (P2 & 0X1f) | 0xc0; //数码管位置
break;
case 7:
P2 = (P2 & 0X1f) | 0xe0; //数码管内容
break;
}
}
1、&
2、流水灯方法二:调用左右移函数“crol”、“cror”
3、使用stc15f2k60s2.h开头的程序
说明:本文根据 http://www.51hei.com/bbs/forum.php?mod=viewthread&tid=107373 内容,加入部分自己补充的内容和思考。