有pic写的矩阵键盘与数码管和单片机C语言的程序吗?

有pic写的矩阵键盘与数码管和单片机C语言的程序吗?,第1张

#include<pic.h>//矩阵键盘与数码管:当s1按下时6个显示全0,当s2按下时6个显示全1,......当s16按下时6个显示全F

#define uchar unsigned char//宏定义

#define uint unsigned int

__CONFIG(0x3b31)//设置配置位

const uchar table[]={0x3f,0x06,0x5b,0x4f,//注意code是用在51单片机中的程序储存器中,const是一个常量,pic和51的单片机也可以共用的常量,但要写在前头

0x66,0x6d,0x7d,0x07,

0x7f,0x6f,0x77,0x7c,

0x39,0x5e,0x79,0x71,0x20}//数码管数字表从0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f,无显示

uchar key_num//先定义一个变量为RB口低4位的检测

void delay(uint x)//声明

void init()

void scan()

void didi(uchar)

void disp()//在这里用的是静态显示全部管是一样的,所以不用加动态扫描时的变量

void main()

{

init()//调用初始化

while(1)//因为要不断地循环扫描键盘检测是否按下所以要进行死循环

{

scan()//调用键盘扫描程序

disp()//在调用键盘扫描的同时调用数码管

}

}

void delay(uint x)//延迟函数x表示毫秒

{

uint a,b

for(a=xa>0a--)

for(b=110b>0b--)//嵌套

}

void init()

{

TRISB=0x0f//因为RB口的高4位RB4-RB7为输出状态,低4位RB0-RB3为输入状态

TRISD=0//因为RD接的是数码管段选设置全为输出状态

TRISE0=0//设置RE0蜂鸣器为输出状态

TRISA=0//设置数码管的位选为全输出状态

RE0=0//先设置蜂鸣器为关闭不响

PORTD=0//设置数码管的输出先全部关闭

PORTA=0xff//设置数码管全部打开

}

void scan()//键盘扫描程序

{

/*检测最后一行RB7是否有键按下*/

uchar key_tem//定义一个松手后才有变化的变量,可不加,但按下时漏肆简数码管就会变化

PORTB=0x7f//01111111先从最高位RB7开始,又因为低4位是输入状态,所以写什么都不影响,因为是不能输出的

key_num=PORTB//将RB端口读回来

key_num=key_num&0x0f//与00001111比较判断如果RB7这行的s13-s16是否有键按下,如果按下则RB低4位其中一个为0,再附给回key_num,这是判断哪一列

if(key_num!=0x0f)//判定运算与之后如果不等0x0f,则有按键按下

{

delay(10)//去抖,再判断多一次

key_num=PORTB//将RB端口读回来附给key_num

key_num=key_num&0x0f//与00001111比较判断如果RB7这行的s13-s16是否有键按下,如果按下则RB低4位其中一个为0,再附给回key_num,这是判断哪一列

if(key_num!=0x0f)//确定不等于0x0f,有键按下但未知是哪一列

{ //////////////////////////////////////////////雹烂/////返裤///松手后才有变化,可不加

key_tem=key_num//将key_num也同时附给tem,这样就不影响松手后才能读到key_num的附回的值了,为作松手后才有变化

didi(1)//调用蜂鸣器

while(key_tem!=0x0f)//这个是松手检测,如果不加则按下的同时数码管就会有变化

{

key_tem=PORTB//将RB端口读回来附给key_tem

key_tem=key_tem&0x0f//与00001111比较

}//////////////////////////////////////////////////////松手后才有变化,可不加

key_num=key_num|0x70//和01110000运算或比较,到这里0x7f先是和0x0f与运算但未知是哪一列,再和0x70或运算判断哪一列得出了具体的按键,再附给回key_num

}

}

/*检测第三行RB6是否有键按下*/

else

{

PORTB=0xbf//10111111检测第三行RB6因为低4位是输入状态,所以写什么都不影响,因为是不能输出的

key_num=PORTB//将RB端口读回来

key_num=key_num&0x0f//与00001111比较判断如果RB6这行的s9-s12是否有键按下,如果按下则RB低4位其中一个为0,再附给回key_num,这是判断哪一列

if(key_num!=0x0f)//判定运算与之后如果不等0x0f,则有按键按下

{

delay(10)//去抖,再判断多一次

key_num=PORTB//将RB端口读回来附给key_num

key_num=key_num&0x0f//与00001111比较判断如果RB6这行的s9-s12是否有键按下,如果按下则RB低4位其中一个为0,再附给回key_num,这是判断哪一列

if(key_num!=0x0f)//确定不等于0x0f,有键按下但未知是哪一列

{ //////////////////////////////////////////////////////松手后才有变化,可不加

key_tem=key_num//将key_num也同时附给tem,这样就不影响松手后才能读到key_num的附回的值了,为作松手后才有变化

didi(1)//调用蜂鸣器

while(key_tem!=0x0f)//这个是松手检测,如果不加则按下的同时数码管就会有变化

{

key_tem=PORTB//将RB端口读回来附给key_tem

key_tem=key_tem&0x0f//与00001111比较

}//////////////////////////////////////////////////////松手后才有变化,可不加

key_num=key_num|0xb0//和10110000运算或比较,到这里0xbf先是和0x0f与运算但未知是哪一列,再和0xb0或运算判断哪一列得出了具体的按键,再附给回key_num

}

}

/*在第一个else里继续第二个else检测第二行RB5是否有键按下*/

else

{

PORTB=0xdf//11011111检测第二行RB5因为低4位是输入状态,所以写什么都不影响,因为是不能输出的

key_num=PORTB//将RB端口读回来

key_num=key_num&0x0f//与00001111比较判断如果RB5这行的s5-s8是否有键按下,如果按下则RB低4位其中一个为0,再附给回key_num,这是判断哪一列

if(key_num!=0x0f)//判定运算与之后如果不等0x0f,则有按键按下

{

delay(10)//去抖,再判断多一次

key_num=PORTB//将RB端口读回来附给key_num

key_num=key_num&0x0f//与00001111比较判断如果RB5这行的s5-s8是否有键按下,如果按下则RB低4位其中一个为0,再附给回key_num,这是判断哪一列

if(key_num!=0x0f)//确定不等于0x0f,有键按下但未知是哪一列

{ //////////////////////////////////////////////////////松手后才有变化,可不加

key_tem=key_num//将key_num也同时附给tem,这样就不影响松手后才能读到key_num的附回的值了,为作松手后才有变化

didi(1)//调用蜂鸣器

while(key_tem!=0x0f)//这个是松手检测,如果不加则按下的同时数码管就会有变化

{

key_tem=PORTB//将RB端口读回来附给key_tem

key_tem=key_tem&0x0f//与00001111比较

}//////////////////////////////////////////////////////松手后才有变化,可不加

key_num=key_num|0xd0//和11010000运算或比较,到这里0xdf先是和0x0f与运算但未知是哪一列,再和0xd0或运算判断哪一列得出了具体的按键,再附给回key_num

}

}

/*在第二个else里继续第三个else检测第一行RB4是否有键按下*/

else

{

PORTB=0xef//11101111检测第一行RB4因为低4位是输入状态,所以写什么都不影响,因为是不能输出的

key_num=PORTB//将RB端口读回来

key_num=key_num&0x0f//与00001111比较判断如果RB4这行的s1-s4是否有键按下,如果按下则RB低4位其中一个为0,再附给回key_num,这是判断哪一列

if(key_num!=0x0f)//判定运算与之后如果不等0x0f,则有按键按下

{

delay(10)//去抖,再判断多一次

key_num=PORTB//将RB端口读回来附给key_num

key_num=key_num&0x0f//与00001111比较判断如果RB4这行的s1-s4是否有键按下,如果按下则RB低4位其中一个为0,再附给回key_num,这是判断哪一列

if(key_num!=0x0f)//确定不等于0x0f,有键按下但未知是哪一列

{ //////////////////////////////////////////////////////松手后才有变化,可不加

key_tem=key_num//将key_num也同时附给tem,这样就不影响松手后才能读到key_num的附回的值了,为作松手后才有变化

didi(1)//调用蜂鸣器

while(key_tem!=0x0f)//这个是松手检测,如果不加则按下的同时数码管就会有变化

{

key_tem=PORTB//将RB端口读回来附给key_tem

key_tem=key_tem&0x0f//与00001111比较

}//////////////////////////////////////////////////////松手后才有变化,可不加

key_num=key_num|0xe0//和11100000运算或比较,到这里0xef先是和0x0f与运算但未知是哪一列,再和0xe0或运算判断哪一列得出了具体的按键,再附给回key_num

}

}

}

}

}

}

void didi(uchar num)//蜂鸣器程序,num表示响多少声

{

uchar di_num

for(di_num=numdi_num>0di_num--)

{

RE0=1//蜂鸣器响

delay(100)//响100ms

RE0=0//蜂鸣器关闭

delay(50)//关闭50ms

}

}

void disp()//数码管

{

switch(key_num)//多选择语句,这前提要知道它的值再相应输出相对应的数

{

case 0xee:PORTD=table[0]break//0xee(01110111)表示第一个键按下时,段选显示0字,位选在初始化中已打开

case 0xed:PORTD=table[1]break

case 0xeb:PORTD=table[2]break

case 0xe7:PORTD=table[3]break

case 0xde:PORTD=table[4]break

case 0xdd:PORTD=table[5]break

case 0xd7:PORTD=table[6]break

case 0xbe:PORTD=table[7]break

case 0xbd:PORTD=table[8]break

case 0xbb:PORTD=table[10]break

case 0xb7:PORTD=table[11]break

case 0x7e:PORTD=table[12]break

case 0x7d:PORTD=table[13]break

case 0x7b:PORTD=table[14]break

case 0x77:PORTD=table[15]break

}

}

简单的可肢桐差以设置一个变量,比如a=1,2,3,4,按一下可以增加一下,即a=1 if (a>4) a=1 else a=a+1

这样再判断a是什么值,然后确定相应的灯轮谨的历皮亮就可以了

1

static

volatile

unsigned

TMR1

@

0x0E

0x0E

是寄存器地址。

表示这个TMR1是寄存器0x0E的值。陵升

具体这个寄存器是做什么用的,需要看你芯片的datasheet,比如

16F874A

16F877A

这个都是计数寄存器的地址。

2

PopQueue应该是一个d出队列的函数。岩汪清

将队列首d出到粗前msg中,

返回值

为PopSuccess表示取数据成功,取到的数据会存在msg中。

一般用于中断传数据给

主线程

。这个在主线程中接收。

3

__CONFIG(x)

一般是配置寄存器的。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/8275278.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-14
下一篇 2023-04-14

发表评论

登录后才能评论

评论列表(0条)

保存