DAY1 初始化/LED/矩阵键盘/共阳极数码管 模块

芯片型号(STC15F2K60S2)

关闭所有外设

电路逻辑

蜂鸣器:达林顿管IN = ~OUT

P0口全部写0,就是关闭

代码模板Init.c

#include <Init.h> //先引用自身.h文件

/**
  * @brief介绍  系统初始化函数,关闭LED和蜂鸣器
  * @param参数  无
  * @retval返回值 无
  */

void System_Init()
{
	P0 = 0xff;  //关闭LED
	P2 = P2 & 0x1f | 0x80;    //把P0数据放入Y4锁存器   &与0001 1111(0x1f) 再|或1000 0000(0x80)只改变前三位
	P2 &= 0x1f;    //高三位关上
	
	P0 = 0x00;  //关闭蜂鸣器
	P2 = P2 & 0x1f | 0xa0;    //选Y5
	P2 &= 0x1f;    //高三位关上
}

LED模块

电路逻辑

P25~P27选中Y4 ---使其置0---从而使Y4C置1

---Y4C 置1使数据通过锁存器

M74HC573锁存器:

参考数据手册
模式配置:(配置Y4C)
OE 默认接地
LE置1 数据传输(开门 Y4C = 0)
LE置0 数据锁存(关门 Y4C = 1)
或非门 WR默认接地

74HC138译码器

查看数据手册
功能表
用P25~P27去控制Y0~Y7
8421编码
举例
 8 4 2 1 
   C B A
   0 1 1 = 0+2+1=3 //选中Y3
   1 1 0 = 4+2+0= 6 //选中Y6

代码模板LED.c

#include <Led.h>

/**
  * @brief介绍  点亮LED
  * @param参数  addr选择亮哪个灯
                enable使能标志位 0--使能/1--不使能
  * @retval返回值 无
  */


void Led_Disp(unsigned char addr,enable)
{
	static unsigned char temp = 0x00;    //定义两个中间变量,局部静态变量:静态局部变量存放在内存的全局数据区。函数结束时,静态局部变量不会消失,每次该函数调用时,也不会为其重新分配空间。它始终驻留在全局数据区,直到程序运行结束。静态局部变量的初始化与全局变量类似.如果不为其显式初始化,则C++自动为其初始化为。虽然静态局部变量在函数调用结束后仍然存在,但其他函数是不能引用它的,也就是说,在其他函数中它是“不可见”的。
	static unsigned char temp_old = 0xff;    //两个变量表示对于LED灯设置的新旧状态进行比较
	if(enable)
		temp |= 0x01 << addr;    // 打开第addr个灯(|=或等于 :全0为0,有1就为1)
	else
		temp &= ~(0x01 << addr);    // 关闭第addr个灯(&=与等于 :全1为1,有0就为0)
	if(temp != temp_old)    //新旧状态不一样,则扫描新状态及改变LED状态
	{
		P0 = ~temp;    //改变状态
		P2 = P2 & 0x1f | 0x80;    //开锁存
		P2 &= 0x1f;    //关
		temp_old = temp;    //刷新旧状态,防止出现电流声(避免多次刷新产生电流声)
	}
}

矩阵键盘模块

跳线帽插在23上为独立按键,插在12上为矩阵键盘

注意是P36 P37 还是P42 P44

按键扫描 代码模板

/**
  * @brief介绍  按键扫描函数
  * @param参数  无
  * @retval返回值 返回按键键码
  */

unsigned char Key_Read()
{
    unsigned char temp = 0;    //局部变量必须初始化

    P44 = 0;    //选中第一列扫描(s4-s7)
    P42 = 1;
    P35 = 1;
    P34 = 1; 
    if (P33 == 0)
        temp = 4;
    if (P32 == 0)
        temp = 5;
    if (P31 == 0)
        temp = 6;
    if (P30 == 0)
        temp = 7;

    P37 = 1;    //选中第二列扫描(s8-s11)
    P36 = 0;
    P35 = 1;
    P34 = 1;
    if (P33 == 0)
        temp = 8;
    if (P32 == 0)
        temp = 9;
    if (P31 == 0)
        temp = 10;
    if (P30 == 0)
        temp = 11;

    P44 = 1;    //选中第三列扫描(s12-s15)
    P42 = 1;
    P35 = 0;
    P34 = 1;
    if (P33 == 0)
        temp = 12;
    if (P32 == 0)
        temp = 13;
    if (P31 == 0)
        temp = 14;
    if (P30 == 0)
        temp = 15;

    P44 = 1;    //选中第一列扫描(s16-s19)
    P42 = 1;
    P35 = 1;
    P34 = 0;
    if (P33 == 0)
        temp = 16;
    if (P32 == 0)
        temp = 17;
    if (P31 == 0)
        temp = 18;
    if (P30 == 0)
        temp = 19;

    return temp;
}

疑问:消抖?

共阳极数码管模块

代码模板Seg.c

//.h文件
void Seg_Disp(unsigned char wela,dula,point);
//.c文件
#include <Seg.h>

/**
  * @brief介绍  打开数码管
  * @param参数  wela位选 选择哪一个数码管亮
                dula段选 选择亮哪个数
                point小数点标志位 
  * @retval返回值 无
  */

unsigned char seg_dula[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff};//段选,0xff表示熄灭
unsigned char seg_wela[] = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};//位选

void Seg_Disp(unsigned char wela,dula,point)
{
	P0 = 0xff;    //段选消隐 全灭
	P2 = P2 & 0x1f | 0xe0;    //锁存器打开
	P2 &= 0x1f;    //锁存器关闭

	P0 = seg_wela[wela];    //位选
	P2 = P2 & 0x1f | 0xc0;
	P2 &= 0x1f;
	
	P0 = seg_dula[dula];    //段选
	if(point)    //加小数点标志
		P0 &= 0x7f;    //小数点点亮:0x7f 0111 1111
	P2 = P2 & 0x1f | 0xe0;
	P2 &= 0x1f;	
}

大模板框架

/*头文件声明区域*/
#include <STC15F2K60S2.H>	 //15单片机寄存器专属头文件
#include <Key.h>	//按键底层专属头文件
#include <Seg.h>	//数码管底层专属头文件
#include <Init.h>	 //初始化底层专属头文件
#include <Led.h>	//Led专属头文件



/*变量声明区域*/
unsigned char Key_Slow_ Down;	//按键专属减速函数
unsigned char Key_Val,Key_Old,Key_Down,Key_Up;	//按键扫描专用变量
unsigned int Seg_Slow_Down;	//数码管减速专用变量(因为此变量数值一般为500,所以用int型)
unsigned char Seg_Pos;	//数码管扫描专用变量
unsigned char Seg_Buf[8] = {10,10,10,10,10,10,10,10,};	//数码管数据显示数组,默认全部熄灭
unsigned char Seg_Point[8] = {0,0,0,0,0,0,0,0};  //数码管小数点数组,默认熄灭
unsigned char ucLed[8] = {0,0,0,0,0,0,0,0}; 	//Led数据存放数组



/*按键处理函数*/
void Key_Proc()
{
	if(Key_Slow_Down) return;
	Key_Slow_Down = 1;	//按键减速程序
	
	Key_Val = Key_Read();
	Key_Down = Key_Val & (Key_Old ^ Key_Val);	//读取按键下降沿
	Key_Up = ~Key_Val & (Key_Old ^ Key_Val);	//读取按键上升沿
	Key_Old = Key_Val;	//辅助扫描变量
	
}




/*信息处理函数*/
void Seg_Proc()
{
	if(Seg_Slow_Down) return;
	Seg_Slow_Down = 1;
	
	
}


/*其他显示函数*/
void Led_Proc()
{
	
}




/*定时器0初始化函数*/
void Timer0Init(void)		//1毫秒@12.000MHz
{
	AUXR &= 0x7F;		//定时器时钟12T模式
	TMOD &= 0xF0;		//设置定时器模式
	TL0 = 0x18;		//设置定时初值
	TH0 = 0xFC;		//设置定时初值
	TF0 = 0;		//清除TF0标志
	TR0 = 1;		//定时器0开始计时
	
	ET0 = 1;	//自己打开定时器中断
	EA = 1;	 //自己打开总中断
}




/*定时器0中断服务函数*/
void Timer0Server() interrupt 1
{
	if(++Key_Slow_Down = 10) Key_Slow_Down = 0;  //一般是10,可自定义
	if(++Seg_Slow_Down = 500) Seg_Slow_Down = 0;	//一般是500,可自定义
	if(==Seg_Pos = 8) Seg_Pos = 0;	//在0-8之间循环,动态扫描
	Seg_Disp(Seg_Pos,Seg_Buf[Seg_Pos],Seg_Point[Seg_Pos]);	//调用Seg_Disp()函数,在第几个位选处出现什么样的数字以及有没有点号	
	Led_Disp(Seg_Pos,ucLed[Seg_Pos]);	
	
}



/*Main函数*/
void main()
{
	Sys_Init();	//引用系统初始化函数
	Timer0Init();	//引用定时器0初始化函数
	while(1)
	{
		Key_Proc();
		Seg_Proc();
		Led_Proc();
	}
}

  • 7
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值