星期日, 十二月 30, 2007

我写的spi按键的驱动程序

由于工作需要,学着写了工作以来第一个真正能用的基于spi通信的按键程序,至于为什么,优缺点之类的就不是我要考虑的了,因为硬件工程师已经给设计成这样了,所以我只管写就好了

下面是arm主程序:
主要是参考了网上大家的一些方法,至于很多东西自己也不是很清楚,毕竟做linux驱动才几个月,还有就是在选择按键码的部分,后来对应得键码换了好多次,所以注释和代码不一致,这部分是为了对应单片机所以一改再改,反正最后能用最重要,键码的修改也比较简单,放在这就当个备份吧,呵呵

/********************************************************************/
/********************************************************************/
/*********Description: SPI keyboard driver ***************/
/*********Author: Kenshinxf <xuefengwang101@gmail.com> ***************/
/*********Date: 2007/11/12 **************/
/********************************************************************/
/********************************************************************/

#include <linux/kernel.h>
#include <linux/miscdevice.h>
#include <linux/sched.h>
#include <linux/poll.h>
#include <linux/spinlock.h>
#include <linux/irq.h>
#include <linux/input.h>

#include <asm/irq.h>
#include <asm/io.h>

#include <asm/hardware.h>

#include <linux/module.h>
#include <linux/config.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/iobuf.h>
#include <linux/highmem.h>
#include <linux/in.h>
#include <linux/vmalloc.h>
#include <asm/io.h>
#include <linux/errno.h>
#include <linux/tqueue.h>
#include <linux/wait.h>
#include <linux/interrupt.h>
#include <asm/irq.h>
#include <linux/delay.h>
#include <asm/uaccess.h>
#include <asm/keyboard.h>

#ifdef CONFIG_DEVFS_FS
#include <linux/devfs_fs_kernel.h>
#endif
#include <linux/kbd_kern.h>

devfs_handle_t MegaKbd_devfs_dir;
//#define spi_debug

void input_register_device (struct input_dev *);

void input_unregister_device (struct input_dev *);

void input_register_handler (struct input_handler *);
void input_unregister_handler (struct input_handler *);

int input_open_device (struct input_handle *);
void input_close_device (struct input_handle *);

devfs_handle_t input_register_minor (char *name, int minor, int minor_base);
void input_unregister_minor (devfs_handle_t handle);

void input_event (struct input_dev *dev, unsigned int type, unsigned int code,
int value);

#define input_report_key(a,b,c) input_event(a, EV_KEY, b, !!(c))

#define DEVICE_NAME "MegaKbd"
#define MegaKbd_MAJOR 232

#define U8 unsigned char
#define U32 unsigned int

#define rSPCON0 (*(volatile unsigned long *)r_SPCON0) /*SPI control Register */
#define rSPSTA0 (*(volatile unsigned long *)r_SPSTA0) /*SPI status Register */
#define rSPPIN0 (*(volatile unsigned long *)r_SPPIN0) /* SPI pin control Register */
#define rSPPRE0 (*(volatile unsigned long *)r_SPPRE0) /*SPI Baud Rate Prescaler Register */
#define rSPTDAT0 (*(volatile unsigned long *)r_SPTDAT0) /*SPI Tx Data Register */
#define rSPRDAT0 (*(volatile unsigned long *)r_SPRDAT0) /*SPI Rx Data Register */

#define rGPECON (*(volatile unsigned long *)r_GPECON) /*Configure the pins of port E */
#define rGPEUP (*(volatile unsigned long *)r_GPEUP) /*Pull-up disable register for port E */
#define rGPGCON (*(volatile unsigned long *)r_GPGCON) /*Configure the pins of port G */
#define rGPGUP (*(volatile unsigned long *)r_GPGUP) /*Pull-up disable register for port G */
#define rGPGDAT (*(volatile unsigned long *)r_GPGDAT) /*The data register for port G */
unsigned long r_SPCON0, r_SPSTA0, r_SPPIN0, r_SPPRE0, r_SPTDAT0, r_SPRDAT0;
unsigned long r_GPECON, r_GPEUP;
unsigned long r_GPGCON, r_GPGUP, r_GPGDAT;

static struct input_dev *button_dev;

static void spi_poll_done (void);
void spi_tx_data (U8 data);

static int keycode = 0;
static DECLARE_WAIT_QUEUE_HEAD (key_wait);

/*address_map*/
int
address_map (void)
{
//SPI registers
r_SPCON0 = ioremap (0x59000000, 4);
r_SPSTA0 = ioremap (0x59000004, 4);
r_SPPIN0 = ioremap (0x59000008, 4);
r_SPPRE0 = ioremap (0x5900000C, 4);
r_SPTDAT0 = ioremap (0x59000010, 4);
r_SPRDAT0 = ioremap (0x59000014, 4);
//I/O registers
r_GPECON = ioremap (0x56000040, 4);
r_GPEUP = ioremap (0x56000048, 4);
r_GPGCON = ioremap (0x56000060, 4);
r_GPGUP = ioremap (0x56000068, 4);
r_GPGDAT = ioremap (0x56000064, 4);


return 0;
}

/**********************************************************/
static void spi_poll_done (void)
{
int j = 0;

while (!(rSPSTA0 & 0x01))
{
j++;
if (j >= 5000)
{
printk ("SPI state poll failed\n");
break;
}
} //endwhile
}

/**********************************************************/
void spi_tx_data (U8 data)
{
spi_poll_done ();
rSPTDAT0 = data; //transmit data
spi_poll_done ();
}

/**********************************************************/
void Init_SPI (void)
{
int i, config, value;
#ifdef spi_debug
printk ("************************\n*");
printk ("spi open program begin..\n");
printk ("now,GPE AND GPG port init...\n");
#endif

rSPPRE0 = 0xff;

#ifdef spi_debug
value = rSPPRE0;
printk ("rSPPRE0=0x%x\n", value);
#endif

for (i = 0; i < 10; i++)
{
rSPTDAT0 = 0xff;
}
rGPECON = (rGPECON & 0xf03fffff) | 0x0a800000; //GPECON-11,12,13=10
#ifdef spi_debug
value = rGPECON;
printk ("GPECON=0x%x\n", value);
#endif
rGPEUP |= 0x3800; //GPE11,12,13 pull-up disable

#ifdef spi_debug
value = rGPEUP;
printk ("GPEUP=0x%x\n", value);
#endif

rGPGCON = (rGPGCON & 0xffffffde) | 0x00000032;
#ifdef spi_debug
value = rGPGCON;
printk ("rGPGCON=0x%x\n", value);
#endif

rGPGUP |= 0x4; //GPG2 pull-up disable;
#ifdef spi_debug
value = rGPGUP;
printk ("rGPGUP=0x%x\n", value);
#endif

//select the chip
set_gpio_ctrl (GPIO_G2 | GPIO_PULLUP_EN | GPIO_MODE_OUT);
write_gpio_bit (GPIO_G2, 0);

#ifdef spi_debug
printk ("GPE AND GPG port init end!\n");
printk ("**************************\n");
#endif

}

/*********************Drive********************************/

static void megakbd_irq (int irq, void *dev_id, struct pt_regs *reg)
{
int i = 0;
int down = 0, keycode = 0;
int config;
char string;
#ifdef spi_debug
printk ("**************************\n");
printk ("\nThis is MegaKbd irq service\n");
printk ("SPI polling TX/RX Test...\n");
#endif
rSPCON0 = (1 << 5) | (1 << 4) | (1 << 3) | (0 << 2) | (0 << 1) | (0 << 0);
#ifdef spi_debug
config = (int) rSPCON0;
printk ("rSPCON0=0x%x\n", config);
#endif
//polling,en-sck,master,low,format A,nomal
rSPPIN0 = (0 << 2) | (1 << 1) | (0 << 0);
//Multi Master error detect disable,reserved,release
#ifdef spi_debug
config = (int) rSPPIN0;
printk ("rSPPIN0=0x%x\n", config);
#endif
spi_tx_data (0xff);
#ifdef spi_debug
string = rSPTDAT0;
printk ("transmit char=0x%x\n", string);
printk ("transmit char=%c\n", string);

string = rSPRDAT0;
printk ("receive char=%c\n", string);
printk ("receive char=0x%x\n", string);
#endif

keycode = rSPRDAT0;
#ifdef spi_debug
printk ("\nkeycode is %d\n", keycode);
#endif
switch (keycode)
{
case 255:
break;
/*
case 12: //1 down
keycode = KEY_1; //2;
down = 1;
break;
case 11: //1 up
keycode = KEY_1; //2;
break;
*/
case 42: //2 down
keycode = KEY_2; //3;
down = 1;
break;
case 41: //2 up
keycode = KEY_2; //3;
break;
/*
case 72: //3 down
keycode = KEY_3; //4;
down = 1;
break;
case 71: //3 up
keycode = KEY_3; //4;
break;
*/
//key #


case 9: //4 down
keycode = KEY_ENTER; //5;
down = 1;
break;
case 8: //4 up
keycode = KEY_ENTER; //5;
break;

case 39: //5 down
keycode = KEY_9; //6;
down = 1;
break;
case 38: //5 up
keycode = KEY_9; //6;
break;

case 69: //6 down
keycode = KEY_3; //7;
down = 1;
break;
case 68: //6 up
keycode = KEY_3; //7;
break;
case 6: //7 down
keycode = KEY_0; //8;
down = 1;
break;
case 5: //7 up
keycode = KEY_0; //8;
break;
case 36: //8 down
keycode = KEY_8; //9;
down = 1;
break;
case 35: //8 up
keycode = KEY_8; //9;
break;
case 66: //9 down
keycode = KEY_2; //10;
down = 1;
break;
case 65: //9 up
keycode = KEY_2; //10;
break;
case 33: //0 down
keycode = KEY_7; //11;
down = 1;
break;
case 32: //0 up
keycode = KEY_7; //11;
break;

//key *
case 3: //asterisk down shift+8
keycode = KEY_KPASTERISK; //55;
// keycode = KEY_LEFTSHIFT;
down = 1;
// input_report_key(&button_dev, keycode, down);
// input_sync(&button_dev);
// keycode = KEY_8;
// keycode = KEY_KPASTERISK; //55;
// down = 1;
break;
case 2: //asterisk up 8+shift
keycode = KEY_KPASTERISK; //55;
// keycode = KEY_8;
// input_report_key(&button_dev, keycode, down);
// input_sync(&button_dev);
// keycode = KEY_LEFTSHIFT;
// keycode = KEY_KPASTERISK; //55;
break;

case 63: //numbersign down shift+3
keycode = KEY_1;
// keycode = KEY_LEFTSHIFT;
down = 1;
// input_report_key(&button_dev, keycode, down);
// input_sync(&button_dev);
// keycode = KEY_3;
// keycode = KEY_KPPLUS;
// down = 1;
break;
case 62: //numbersign up 3+shift
keycode = KEY_1;
// input_report_key(&button_dev, keycode, down);
// input_sync(&button_dev);
// keycode = KEY_LEFTSHIFT;
// keycode = KEY_KPPLUS;
break;

case 27: //enter down
keycode = KEY_ENTER; //28;
down = 1;
break;
case 26: //enter up
keycode = KEY_ENTER; //28;
break;
case 57: //esc down
keycode = KEY_BACKSPACE; //1;
down = 1;
break;
case 56: //esc up
keycode = KEY_BACKSPACE; //1;
break;
case 15: //backspace down
keycode = KEY_S;
down = 1;
break;
case 14: //backspace up
keycode = KEY_S;
break;
case 75: //left down
keycode = KEY_LEFT;
down = 1;
break;
case 74: //left up
keycode = KEY_LEFT;
break;
case 60: //right down
keycode = KEY_L;
down = 1;
break;
case 59: //right up
keycode = KEY_L;
break;
case 30: //up down
keycode = KEY_UP;
down = 1;
break;
case 29: //up up
keycode = KEY_UP;
break;
/*
case 45: //down down
keycode = KEY_4;
down = 1;
break;
case 44: //down up
keycode = KEY_4;
break;
*/
case 24: //f1 down
keycode = KEY_F1;
down = 1;
break;
case 23: //f1 up
keycode = KEY_F1;
break;
case 54: //f2 down
keycode = KEY_6;
down = 1;
break;
case 53: //f2 up
keycode = KEY_6;
break;
case 21: //f3 down
keycode = KEY_F3;
down = 1;
break;
case 20: //f3 up
keycode = KEY_F3;
break;
case 51: //f4 down
keycode = KEY_5;
down = 1;
break;
case 50: //f4 up
keycode = KEY_5;
break;
case 18: //f5 down
keycode = KEY_F5;
down = 1;
break;
case 17: //f5 up
keycode = KEY_F5;
break;
case 48: //f6 down
keycode = KEY_4;
down = 1;
break;
case 47: //f6 up
keycode = KEY_4;
break;

default:;
}
#ifdef spi_debug
printk("keycode=0x%x\n",keycode);
#endif
if (keycode)
{
input_report_key (&button_dev, keycode, down);
// input_sync(&button_dev);
// printk("*********************[%d]", keycode);
}

// printk ("\nkeycode=[0x%x]\n", keycode);
// printk ("\nkeycode=[%d]\n", keycode);

handle_scancode (keycode, down);
tasklet_schedule (&keyboard_tasklet);
wake_up_interruptible (&key_wait);
}

//Read for megaKbd
static ssize_t megaKbd_read (struct file *file, char *buf, size_t count, loff_t * offset)
{
static int key;
key = keycode;
copy_to_user (buf, &key, sizeof key);
return sizeof keycode;

}


//Write to megaKbd
ssize_t megaKbd_write (struct file *file, char *buf, size_t count, loff_t * offset)
{

int i = 0;
int config;
int string;
#ifdef spi_debug
printk ("SPI polling TX/RX Test...\n");
printk ("Connet SPIMOSI0 into SPIMISO\n");
#endif
rSPCON0 = (1 << 5) | (1 << 4) | (1 << 3) | (0 << 2) | (0 << 1) | (0 << 0);
// config = (int) rSPCON0;
// printk ("rSPCON0=0x%x\n", config);

//polling,en-sck,master,low,format A,nomal
rSPPIN0 = (0 << 2) | (1 << 1) | (0 << 0);

//Multi Master error detect disable,reserved,release
// config = (int) rSPPIN0;
// printk ("rSPPIN0=0x%x\n", config);
spi_tx_data (*buf);
string = rSPTDAT0;
#ifdef spi_debug
printk ("\ntransmit char=%c\n", string);
printk ("transmit char=0x%x\n", string);
#endif
string = rSPRDAT0;
#ifdef spi_debug
printk (" receive char=%c\n\n\n", string);
printk (" receive char=0x%x\n\n\n", string);
printk ("****************\n");
printk ("****************\n");
printk ("****************\n");
printk ("****************\n");
printk ("****************\n");
printk ("****************\n");
#endif
return 0;

}

/**********************************************************/
//Open the megaKbd device
static int megaKbd_open (struct inode *inode, struct file *file)
{
return 0;
}

/**********************************************************/
//Close the megaKbd device
static int megaKbd_close (struct inode *inode, struct file *file)
{
return 0;
}

/**********************************************************/
static struct file_operations megaKbd_fops = {
owner:THIS_MODULE,
llseek:no_llseek,
read:megaKbd_read,
write:megaKbd_write,
open:megaKbd_open,
release:megaKbd_close,
};

static int __init HW_kbd_init (void)
{
unsigned int result;

// set_external_irq (IRQ_EINT8, EXT_FALLING_EDGE, GPIO_PULLUP_DIS);
set_external_irq (IRQ_EINT8, EXT_RISING_EDGE, GPIO_PULLUP_DIS);
disable_irq (IRQ_EINT8);
enable_irq (IRQ_EINT8);
result = request_irq (IRQ_EINT8, &megakbd_irq, SA_INTERRUPT, DEVICE_NAME, &megakbd_irq);
if (result)
{
printk ("Can't get assigned irq %d,result=%d\n", IRQ_EINT8, result);
return result;
}
}

static int mega_kbd_translate (U8 scancode, U8 * keycode, char raw_mode)
{
int Result = 1;
printk ("my transleate\n");
*keycode = (scancode & 0x7f);
return 1;
}


static int __init megaKbd_code (void)
{

/*
button_dev = input_allocate_device();
if (!button_dev) {
printk(KERN_ERR "input: not enough memory for input device\n");
return -ENOMEM;
}
*/
// input_register_device(&button_dev);
button_dev->name = "Spi Keyboard";
// button_dev->phys = "input/input0";
button_dev->evbit[0] = BIT (EV_KEY);
// button_dev->keybit[LONG(KEY_NUMLOCK)] = BIT(KEY_NUMLOCK);
set_bit (KEY_0, button_dev->keybit);
set_bit (KEY_1, button_dev->keybit);
set_bit (KEY_2, button_dev->keybit);
set_bit (KEY_3, button_dev->keybit);
set_bit (KEY_4, button_dev->keybit);
set_bit (KEY_5, button_dev->keybit);
set_bit (KEY_6, button_dev->keybit);
set_bit (KEY_7, button_dev->keybit);
set_bit (KEY_8, button_dev->keybit);
set_bit (KEY_9, button_dev->keybit);

set_bit (KEY_F1, button_dev->keybit);
set_bit (KEY_F2, button_dev->keybit);
set_bit (KEY_F3, button_dev->keybit);
set_bit (KEY_F4, button_dev->keybit);
set_bit (KEY_F5, button_dev->keybit);
set_bit (KEY_F6, button_dev->keybit);

set_bit (KEY_ENTER, button_dev->keybit);
set_bit (KEY_ESC, button_dev->keybit);
set_bit (KEY_UP, button_dev->keybit);
set_bit (KEY_DOWN, button_dev->keybit);
set_bit (KEY_LEFT, button_dev->keybit);
set_bit (KEY_RIGHT, button_dev->keybit);

set_bit (KEY_BACKSPACE, button_dev->keybit);
set_bit (KEY_LEFTSHIFT, button_dev->keybit);
set_bit (KEY_KPASTERISK, button_dev->keybit);
set_bit (KEY_KPPLUS, button_dev->keybit);

input_register_device (&button_dev);
return 0;
}


/**********************************************************/
// Install the megaKbd driver
static int __init megaKbd_init (void)
{
unsigned int result;

//Init Spi Device
address_map ();
Init_SPI ();

result = HW_kbd_init ();
if (result)
return result;

//k_translate = mega_kbd_translate;

megaKbd_code ();
result = register_chrdev (MegaKbd_MAJOR, DEVICE_NAME, &megaKbd_fops);
if (result < 0)
{
printk (DEVICE_NAME "cannot register maor number\n");
return result;
}

//Register device
MegaKbd_devfs_dir = devfs_mk_dir (NULL, "MegaKbd", NULL);

devfs_register (MegaKbd_devfs_dir, DEVICE_NAME, DEVFS_FL_AUTO_DEVNUM, 0, 0, S_IFCHR | S_IRUGO | S_IWUGO, &megaKbd_fops, NULL);
printk ("megaKbd driver installed OK\n");

return 0;
}

/**********************************************************/
// Remove the megaKbd driver
static void megaKbd_exit (void)
{
//Disable Interrupt
// disable_irq (IRQ_EINT8);
free_irq (IRQ_EINT8, NULL);

devfs_unregister (MegaKbd_devfs_dir);
input_unregister_device (&button_dev);
printk ("megaKbd driver uninstalled OK\n");
}

module_init (megaKbd_init);
module_exit (megaKbd_exit);

MODULE_LICENSE ("GPL");
MODULE_AUTHOR ("Kenshinxf <xuefengwang101@gmail.com>");
MODULE_DESCRIPTION ("keyboard driver with spi S3C2410 board");

本来说只写arm就好了,谁知道最后单片机也得我写,真是。。。。

那就写吧,说写,其实就是改改一个师哥以前的单片机程序,不知道其他人为什么就不会呢?自己也没搞过单片机,工作后就直接arm了,其实还是比较简单的

下面是单片机程序:

/**key.c***/

#include <mega88.h>
#include "key.h"

#define INT PORTC.2
unsigned char ScanState = 0;
unsigned char KeyDelay[25];
unsigned char temp0;
bit flag0 = 0;

void SendKeyChar(unsigned char KeyValue)
{
PINC.5 = 1;
//SpiPutChar(KeyValue);
//I2cSendChar(KeyValue);
temp0 = SPSR;
SPDR = KeyValue;
#asm("nop")
#asm("nop")
#asm("nop")
#asm("nop")
INT = 1;
flag0 = 1;
}

// Timer 0 overflow interrupt service routine
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
TCNT0=0x80;
switch(ScanState)
{
case 0:
if(Col1Row1 == ROW1)
{
if(Col1Row1 == 0)
{
if(++KeyDelay[0] == 7)
{
KeyDelay[0] = 0;
if(ColRow11)
{
ColRow11 = 0;
SendKeyChar(1);
}
}
}
}
else
{
if(Col1Row1 == 0) SendKeyChar(2);
else
{
KeyDelay[0] = 0;
ColRow11 = 1;
SendKeyChar(3);
}
}
Col1Row1 = ROW1;
if(Col1Row2 == ROW2)
{
if(Col1Row2 == 0)
{
if(++KeyDelay[1] == 7)
{
KeyDelay[1] = 0;
if(ColRow12)
{
ColRow12 = 0;
SendKeyChar(4);
}
}
}
}
else
{
if(Col1Row2 == 0) SendKeyChar(5);
else
{
KeyDelay[1] = 0;
ColRow12 = 1;
SendKeyChar(6);
}
}
Col1Row2 = ROW2;
if(Col1Row3 == ROW3)
{
if(Col1Row3 == 0)
{
if(++KeyDelay[2] == 7)
{
KeyDelay[2] = 0;
if(ColRow13)
{
ColRow13 = 0;
SendKeyChar(7);
}
}
}
}
else
{
if(Col1Row3 == 0) SendKeyChar(8);
else
{
KeyDelay[2] = 0;
ColRow13 = 1;
SendKeyChar(9);
}
}
Col1Row3 = ROW3;
if(Col1Row4 == ROW4)
{
if(Col1Row4 == 0)
{
if(++KeyDelay[3] == 7)
{
KeyDelay[3] = 0;
if(ColRow14)
{
ColRow14 = 0;
SendKeyChar(10);
}
}
}
}
else
{
if(Col1Row4 == 0) SendKeyChar(11);
else
{
KeyDelay[3] = 0;
ColRow14 = 1;
SendKeyChar(12);
}
}
Col1Row4 = ROW4;
if(Col1Row5 == ROW5)
{
if(Col1Row5 == 0)
{
if(++KeyDelay[4] == 7)
{
KeyDelay[4] = 0;
if(ColRow15)
{
ColRow15 = 0;
SendKeyChar(13);
}
}
}
}
else
{
if(Col1Row5 == 0) SendKeyChar(14);
else
{
KeyDelay[4] = 0;
ColRow15 = 1;
SendKeyChar(15);
}
}
Col1Row5 = ROW5;
COL1 = 0;
COL2 = 1;
break;
case 1:
if(Col2Row1 == ROW1)
{
if(Col2Row1 == 0)
{
if(++KeyDelay[5] == 7)
{
KeyDelay[5] = 0;
if(ColRow21)
{
ColRow21 = 0;
SendKeyChar(16);
}
}
}
}
else
{
if(Col2Row1 == 0) SendKeyChar(17);
else
{
KeyDelay[5] = 0;
ColRow21 = 1;
SendKeyChar(18);
}
}
Col2Row1 = ROW1;
if(Col2Row2 == ROW2)
{
if(Col2Row2 == 0)
{
if(++KeyDelay[6] == 7)
{
KeyDelay[6] = 0;
if(ColRow22)
{
ColRow22 = 0;
SendKeyChar(19);
}
}
}
}
else
{
if(Col2Row2 == 0) SendKeyChar(20);
else
{
KeyDelay[6] = 0;
ColRow22 = 1;
SendKeyChar(21);
}
}
Col2Row2 = ROW2;
if(Col2Row3 == ROW3)
{
if(Col2Row3 == 0)
{
if(++KeyDelay[7] == 7)
{
KeyDelay[7] = 0;
if(ColRow23)
{
ColRow23 = 0;
SendKeyChar(22);
}
}
}
}
else
{
if(Col2Row3 == 0) SendKeyChar(23);
else
{
KeyDelay[7] = 0;
ColRow23 = 1;
SendKeyChar(24);
}
}
Col2Row3 = ROW3;
if(Col2Row4 == ROW4)
{
if(Col2Row4 == 0)
{
if(++KeyDelay[8] == 7)
{
KeyDelay[8] = 0;
if(ColRow24)
{
ColRow24 = 0;
SendKeyChar(25);
}
}
}
}
else
{
if(Col2Row4 == 0) SendKeyChar(26);
else
{
KeyDelay[8] = 0;
ColRow24 = 1;
SendKeyChar(27);
}
}
Col2Row4 = ROW4;
if(Col2Row5 == ROW5)
{
if(Col2Row5 == 0)
{
if(++KeyDelay[9] == 7)
{
KeyDelay[9] = 0;
if(ColRow25)
{
ColRow25 = 0;
SendKeyChar(28);
}
}
}
}
else
{
if(Col2Row5 == 0) SendKeyChar(29);
else
{
KeyDelay[9] = 0;
ColRow25 = 1;
SendKeyChar(30);
}
}
Col2Row5 = ROW5;
COL2 = 0;
COL3 = 1;
break;
case 2:
if(Col3Row1 == ROW1)
{
if(Col3Row1 == 0)
{
if(++KeyDelay[10] == 7)
{
KeyDelay[10] = 0;
if(ColRow31)
{
ColRow31 = 0;
SendKeyChar(31);
}
}
}
}
else
{
if(Col3Row1 == 0) SendKeyChar(32);
else
{
KeyDelay[10] = 0;
ColRow31 = 1;
SendKeyChar(33);
}
}
Col3Row1 = ROW1;
if(Col3Row2 == ROW2)
{
if(Col3Row2 == 0)
{
if(++KeyDelay[11] == 7)
{
KeyDelay[11] = 0;
if(ColRow32)
{
ColRow32 = 0;
SendKeyChar(34);
}
}
}
}
else
{
if(Col3Row2 == 0) SendKeyChar(35);
else
{
KeyDelay[11] = 0;
ColRow32 = 1;
SendKeyChar(36);
}
}
Col3Row2 = ROW2;
if(Col3Row3 == ROW3)
{
if(Col3Row3 == 0)
{
if(++KeyDelay[12] == 7)
{
KeyDelay[12] = 0;
if(ColRow33)
{
ColRow33 = 0;
SendKeyChar(37);
}
}
}
}
else
{
if(Col3Row3 == 0) SendKeyChar(38);
else
{
KeyDelay[12] = 0;
ColRow33 = 1;
SendKeyChar(39);
}
}
Col3Row3 = ROW3;
if(Col3Row4 == ROW4)
{
if(Col3Row4 == 0)
{
if(++KeyDelay[13] == 7)
{
KeyDelay[13] = 0;
if(ColRow34)
{
ColRow34 = 0;
SendKeyChar(40);
}
}
}
}
else
{
if(Col3Row4 == 0) SendKeyChar(41);
else
{
KeyDelay[13] = 0;
ColRow34 = 1;
SendKeyChar(42);
}
}
Col3Row4 = ROW4;
if(Col3Row5 == ROW5)
{
if(Col3Row5 == 0)
{
if(++KeyDelay[14] == 7)
{
KeyDelay[14] = 0;
if(ColRow35)
{
ColRow35 = 0;
SendKeyChar(43);
}
}
}
}
else
{
if(Col3Row5 == 0) SendKeyChar(44);
else
{
KeyDelay[14] = 0;
ColRow35 = 1;
SendKeyChar(45);
}
}
Col3Row5 = ROW5;
COL3 = 0;
COL4 = 1;
break;
case 3:
if(Col4Row1 == ROW1)
{
if(Col4Row1 == 0)
{
if(++KeyDelay[15] == 7)
{
KeyDelay[15] = 0;
if(ColRow41)
{
ColRow41 = 0;
SendKeyChar(46);
}
}
}
}
else
{
if(Col4Row1 == 0) SendKeyChar(47);
else
{
KeyDelay[15] = 0;
ColRow41 = 1;
SendKeyChar(48);
}
}
Col4Row1 = ROW1;
if(Col4Row2 == ROW2)
{
if(Col4Row2 == 0)
{
if(++KeyDelay[16] == 7)
{
KeyDelay[16] = 0;
if(ColRow42)
{
ColRow42 = 0;
SendKeyChar(49);
}
}
}
}
else
{
if(Col4Row2 == 0) SendKeyChar(50);
else
{
KeyDelay[16] = 0;
ColRow42 = 1;
SendKeyChar(51);
}
}
Col4Row2 = ROW2;
if(Col4Row3 == ROW3)
{
if(Col4Row3 == 0)
{
if(++KeyDelay[17] == 7)
{
KeyDelay[17] = 0;
if(ColRow43)
{
ColRow43 = 0;
SendKeyChar(52);
}
}
}
}
else
{
if(Col4Row3 == 0) SendKeyChar(53);
else
{
KeyDelay[17] = 0;
ColRow43 = 1;
SendKeyChar(54);
}
}
Col4Row3 = ROW3;
if(Col4Row4 == ROW4)
{
if(Col4Row4 == 0)
{
if(++KeyDelay[18] == 7)
{
KeyDelay[18] = 0;
if(ColRow44)
{
ColRow44 = 0;
SendKeyChar(55);
}
}
}
}
else
{
if(Col4Row4 == 0) SendKeyChar(56);
else
{
KeyDelay[18] = 0;
ColRow44 = 1;
SendKeyChar(57);
}
}
Col4Row4 = ROW4;
if(Col4Row5 == ROW5)
{
if(Col4Row5 == 0)
{
if(++KeyDelay[19] == 7)
{
KeyDelay[19] = 0;
if(ColRow45)
{
ColRow45 = 0;
SendKeyChar(58);
}
}
}
}
else
{
if(Col4Row5 == 0) SendKeyChar(59);
else
{
KeyDelay[19] = 0;
ColRow45 = 1;
SendKeyChar(60);
}
}
Col4Row5 = ROW5;
COL4 = 0;
COL5 = 1;
break;
case 4:
if(Col5Row1 == ROW1)
{
if(Col5Row1 == 0)
{
if(++KeyDelay[20] == 7)
{
KeyDelay[20] = 0;
if(ColRow51)
{
ColRow51 = 0;
SendKeyChar(61);
}
}
}
}
else
{
if(Col5Row1 == 0) SendKeyChar(62);
else
{
KeyDelay[20] = 0;
ColRow51 = 1;
SendKeyChar(63);
}
}
Col5Row1 = ROW1;
if(Col5Row2 == ROW2)
{
if(Col5Row2 == 0)
{
if(++KeyDelay[21] == 7)
{
KeyDelay[21] = 0;
if(ColRow52)
{
ColRow52 = 0;
SendKeyChar(64);
}
}
}
}
else
{
if(Col5Row2 == 0) SendKeyChar(65);
else
{
KeyDelay[21] = 0;
ColRow52 = 1;
SendKeyChar(66);
}
}
Col5Row2 = ROW2;
if(Col5Row3 == ROW3)
{
if(Col5Row3 == 0)
{
if(++KeyDelay[22] == 7)
{
KeyDelay[22] = 0;
if(ColRow53)
{
ColRow53 = 0;
SendKeyChar(67);
}
}
}
}
else
{
if(Col5Row3 == 0) SendKeyChar(68);
else
{
KeyDelay[22] = 0;
ColRow53 = 1;
SendKeyChar(69);
}
}
Col5Row3 = ROW3;
if(Col5Row4 == ROW4)
{
if(Col5Row4 == 0)
{
if(++KeyDelay[23] == 7)
{
KeyDelay[23] = 0;
if(ColRow54)
{
ColRow54 = 0;
SendKeyChar(70);
}
}
}
}
else
{
if(Col5Row4 == 0) SendKeyChar(71);
else
{
KeyDelay[23] = 0;
ColRow54 = 1;
SendKeyChar(72);
}
}
Col5Row4 = ROW4;
if(Col5Row5 == ROW5)
{
if(Col5Row5 == 0)
{
if(++KeyDelay[24] == 7)
{
KeyDelay[24] = 0;
if(ColRow55)
{
ColRow55 = 0;
SendKeyChar(73);
}
}
}
}
else
{
if(Col5Row5 == 0) SendKeyChar(74);
else
{
KeyDelay[24] = 0;
ColRow55 = 1;
SendKeyChar(75);
}
}
Col5Row5 = ROW5;
COL5 = 0;
COL1 = 1;
break;
default:
break;
}
ScanState++;
if(ScanState == 5) ScanState = 0;

}


// Declare your global variables here


void main(void)
{
#pragma optsize-
CLKPR=0x80;
CLKPR=0x00;
#ifdef _OPTIMIZE_SIZE_
#pragma optsize+
#endif


PORTB=0x00;
DDRB=0x11;


PORTC=0x00;
DDRC=0x24;


PORTD=0x1F;
DDRD=0x60;
// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 7.813 kHz
// Mode: Normal top=FFh
// OC0A output: Disconnected
// OC0B output: Disconnected TCCR0A=0x00;
TCCR0B=0x05;
TCNT0=0x80;
OCR0A=0x00;
OCR0B=0x00;


// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer 1 Stopped
// Mode: Normal top=FFFFh
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer 1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;


// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer 2 Stopped
// Mode: Normal top=FFh
// OC2A output: Disconnected
// OC2B output: Disconnected
ASSR=0x00;
TCCR2A=0x00;
TCCR2B=0x00;
TCNT2=0x00;
OCR2A=0x00;
OCR2B=0x00;


// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
// Interrupt on any change on pins PCINT0-7: Off
// Interrupt on any change on pins PCINT8-14: Off
// Interrupt on any change on pins PCINT16-23: Off
EICRA=0x00;
EIMSK=0x00;
PCICR=0x00;


// Timer/Counter 0 Interrupt(s) initialization
TIMSK0=0x01;
// Timer/Counter 1 Interrupt(s) initialization
TIMSK1=0x00;
// Timer/Counter 2 Interrupt(s) initialization
TIMSK2=0x00;


// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
ADCSRB=0x00;


// SPI initialization
// SPI Type: Slave
// SPI Clock Rate: 125.000 kHz
// SPI Clock Phase: Cycle Half
// SPI Clock Polarity: Low
// SPI Data Order: MSB First
SPCR=0x42;
SPSR=0x00;


// Global enable interrupts
#asm("sei")


while (1)
{
if(flag0)
{
#asm("nop")
#asm("nop")
#asm("nop")
#asm("nop")
#asm("nop")
#asm("nop")
#asm("nop")
#asm("nop")
#asm("nop")
#asm("nop")
#asm("nop")
#asm("nop")
#asm("nop")
flag0 = 0;
INT = 0;
#asm("nop")
#asm("nop")
#asm("nop")
#asm("nop")
#asm("nop")
#asm("nop")
#asm("nop")
INT = 1;
#asm("nop")
#asm("nop")
#asm("nop")
#asm("nop")
#asm("nop")
#asm("nop")
#asm("nop")
INT = 0;
}
};
}


/***key.h****/

#define COL1 DDRB.0
#define COL2 DDRB.1
#define COL3 DDRD.7
#define COL4 DDRD.6
#define COL5 DDRD.5

#define ROW1 PIND.0
#define ROW2 PIND.1
//#define KEY1 PIND.2
//#define KEY2 PIND.3
#define ROW3 PIND.2
#define ROW4 PIND.3
#define ROW5 PINB.6

bit Col1Row1 = 1;
bit Col1Row2 = 1;
bit Col1Row3 = 1;
bit Col1Row4 = 1;
bit Col1Row5 = 1;

bit Col2Row1 = 1;
bit Col2Row2 = 1;
bit Col2Row3 = 1;
bit Col2Row4 = 1;
bit Col2Row5 = 1;

bit Col3Row1 = 1;
bit Col3Row2 = 1;
bit Col3Row3 = 1;
bit Col3Row4 = 1;
bit Col3Row5 = 1;

bit Col4Row1 = 1;
bit Col4Row2 = 1;
bit Col4Row3 = 1;
bit Col4Row4 = 1;
bit Col4Row5 = 1;

bit Col5Row1 = 1;
bit Col5Row2 = 1;
bit Col5Row3 = 1;
bit Col5Row4 = 1;
bit Col5Row5 = 1;

bit ColRow11 = 1;
bit ColRow12 = 1;
bit ColRow13 = 1;
bit ColRow14 = 1;
bit ColRow15 = 1;

bit ColRow21 = 1;
bit ColRow22 = 1;
bit ColRow23 = 1;
bit ColRow24 = 1;
bit ColRow25 = 1;

bit ColRow31 = 1;
bit ColRow32 = 1;
bit ColRow33 = 1;
bit ColRow34 = 1;
bit ColRow35 = 1;

bit ColRow41 = 1;
bit ColRow42 = 1;
bit ColRow43 = 1;
bit ColRow44 = 1;
bit ColRow45 = 1;

bit ColRow51 = 1;
bit ColRow52 = 1;
bit ColRow53 = 1;
bit ColRow54 = 1;
bit ColRow55 = 1;

2 意見:

KenShinXF 说...

嗯,还不错,后生可畏啊,必定会前途无量的,呵呵,再接再厉

匿名 说...

丢人了吧,自己夸自己,皮皮真厚,呵呵