Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1598431
  • 博文数量: 354
  • 博客积分: 8137
  • 博客等级: 中将
  • 技术积分: 5137
  • 用 户 组: 普通用户
  • 注册时间: 2009-11-26 15:40
文章分类

全部博文(354)

文章存档

2010年(300)

2009年(54)

分类: 嵌入式

2010-07-13 23:28:52

事无巨细,独立按键




这里是源文件所在,不过觉的这个在按键判断那里有点繁锁,我就改写了下。如下:
嗯,我对你写的程序改写了下。
如下三个文件:
文件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) |
给主人留下些什么吧!~~