事无巨细,独立按键
这里是源文件所在,不过觉的这个在按键判断那里有点繁锁,我就改写了下。如下:
嗯,我对你写的程序改写了下。如下三个文件:文件1:main.c[code]/********************************************************/**********************************************************************
* 文件名称: main.c/独立按键
* 程序作者: Kevin Chin
* 电子邮件:kevinchin@qq.com
* 程序版本: V1.0
* 编制日期: 2010/07/13
* 功能描述: 按下四个独立按键,分别在数码管上显示1~4
* 编译器:WinAVR-20090313
* 芯片:ATmega16,外部11.0592MHZ晶振
* 技术支持:
**********************************************************************/
#include
#include
#include "hc595.h"
#define KeyState ((PINB & (1 << PB0)) | (PIND & (1 << PD2)) | (PIND & (1 << PD6)) | (PIND & (1 << PD7)))
uint8_t const LedData[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xF8, //数码管段选端数据表
0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};
uint8_t const LedPos[] = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80}; //数码管位选端数据表
void Init(void);
void Display(uint8_t pos,uint8_t dat);
uint8_t Keyscan(void);
int main(void)
{
uint8_t returndata;
Init();
while(1)
{
returndata = Keyscan(); //按键扫描,返回值存于全局变量X中
if(returndata)
{
Display(0,returndata); //显示扫描值
}
}
}
void Init(void)
{
PORTB &= ~(_BV(PB4) | _BV(PB5) | _BV(PB7));
DDRB |= (_BV(PB4) | _BV(PB5) | _BV(PB7));
PORTB |= _BV(PB0); //PB0上拉
DDRB &= ~(_BV(PB0));//PB口为0,输入
PORTD |= (_BV(PD2) | _BV(PD6) | _BV(PD7));
DDRD &= ~(_BV(PD2) | _BV(PD6) | _BV(PD7));
}
uint8_t Keyscan(void) //键盘扫描函数,返回值对应按键
{
uint8_t temp = 0,datanum = 0, keydata;
if( KeyState != 0xc5 )
{
keydata = KeyState;
_delay_ms(20);
if(KeyState == keydata)
{
temp = keydata;
}
}
switch (temp)
{
case 0xc4: datanum = 1; break;
case 0xc1: datanum = 2; break;
case 0x85: datanum = 3; break;
case 0x45: datanum = 4; break;
default: break;
}
return datanum;
}
void Display(uint8_t pos,uint8_t dat)
{
HC595Send(LedP[/code]文件2:hc595.c
[code]#include
#include
#include "hc595.h"
/*************
*HC595发送子函数
*要发送的数据通过形参x传递。
——————————————
*HC595的工作原理:
74HC595是具有8位移位寄存器和一个存储器,三态输出功能。 移位寄存器和存储器是分别的时钟。
数据在SHcp的上升沿输入,在STcp的上升沿进入的存储寄存器中去。
如果两个时钟连在一起,则移位寄存器总是比存储寄存器早一个脉冲。
移位寄存器有一个串行移位输入(Ds),和一个串行输出(Q7’),和一个异步的低电平复位。
存储寄存器有一个并行8位的,具备三态的总线输出,当使能 OE时(为低电平),存储寄存器的数据输出到总线。
引脚说明:
QA--QH: 八位并行输出端,可以直接控制数码管的8个段。
QH': 级联输出端。我将它接下一个595的SI端。
SER(DS): 串行数据输入端。
74595的控制端说明:
/SCLR(MR)(10脚): 低点平时将移位寄存器的数据清零。通常我将它接Vcc。
SCK(SHCP)(11脚):上升沿时数据寄存器的数据移位。QA-->QB-->QC-->...-->QH;下降沿移位寄存器数据不变。
(脉冲宽度:5V时,大于几十纳秒就行了。我通常都选微秒级)
RCK(STCP)(12脚):上升沿时移位寄存器的数据进入数据存储寄存器,下降沿时存储寄存器数据不变。
通常我将RCK置为低电平,当移位结束后,在RCK端产生一个正脉冲(5V时,大于几十纳秒就行了。我通常都选微秒级),更新显示数据。
*************/
void HC595Send(uint8_t x)//HC595发送子函数
{
uint8_t n; //定义两个局部变量n,temp
for(n = 0;n < 8; n++)
{
if(x & 0x80)//如果x最高位不为0,则为1
{
SER_PORT |= (1 << SER_DS); //PB5口输出1
}
else
{
SER_PORT &= ~(1< }
HC595Shift();//调用移位子函数
x <<= 1; //x右移一位,位原来的第七位,成为第8位,最后一位补0
}
}
void HC595Shift(void) //HC595移位子函数
{
SER_PORT |= (1 << SER_SHCP);//PB7输出1
_delay_us(5);
SER_PORT &= ~(1 << SER_SHCP);//PB7输出0
}
void HC595Store(void) //HC595储存子函数
{
SER_PORT |= (1 << SER_STCP); //PB4输出1
_delay_us(5);
SER_PORT &= ~(1 << SER_STCP); //PB4输出0
}
[/code]
文件3:hc595.h
[code]#ifndef __HC595_H__
#define __HC595_H__
#define SER_PORT PORTB
#define SER_DS PB5
#define SER_STCP PB4
#define SER_SHCP PB7
extern void HC595Send(uint8_t x);
extern void HC595Shift(void);
extern void HC595Store(void);
#endif
[/code]
|
文件: | 独立按键.zip |
大小: | 27KB |
下载: | 下载 |
|
阅读(1675) | 评论(0) | 转发(0) |