完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
扫一扫,分享给好友
本帖最后由 herochenzhao 于 2012-10-25 19:37 编辑 |
|
相关推荐
19个回答
|
|
|
|
|
|
云里雾里
|
|
|
|
|
|
|
|
|
|
{:soso_e117:}
|
|
|
|
|
|
|
|
看看看
|
|
|
|
|
|
zhichixia!
|
|
|
|
|
|
谢谢你的点拨,顿时豁然开朗起来!希望有机会能再次获得你的帮助!谢谢{:soso_e100:} |
|
|
|
k看看
|
|
|
|
这个就是先选中第一个74L 在开始扫描 再选中第二个74L 再扫描
|
|
|
|
这个算是在做4*4键盘中最省的一种方法了,如果你有更好的方法,希望你能共享下哈! |
|
|
|
你可以做矩阵键盘啊,以前看到过一个很节约io口的矩阵键盘。。。
|
|
|
|
这个程序的目标是每发送一个时钟(P1.0)后,立即检查一次P1.2的状态;
这里要注意两点: 1、由于74LS164不能清零,所以扫描检查之前,必须先发送16个零脉冲,即P1.1保持为0时连发16个时钟信号; 2、扫描过程中,第一个时钟使P1.1为1,然后的15个时钟P1.1应为零,同时CPU内部应该有时钟计数器,该计数值是与按键号相对应的,这样才能知道扫描到的是哪一个键的状态。 |
|
|
|
/*****************************************************
* main.c 中如此这般: *****************************************************/ kd_init(); // ...... while (1) { if( should_update_kd ) { kd_update(); } // Other code // ...... } 再看显示、键扫源代码: /****************************************************** * key_disp-config.h ******************************************************/ #ifndef _KEY_DISP_CFG_H_ #define _KEY_DISP_CFG_H_ #define DIGIT1 B, 0 #define DIGIT2 B, 1 #define DIGIT3 B, 2 #define DIGIT4 B, 3 #define KEY_FB D, 6 #define KD_CLR D, 7 #define KD_CLK B, 5 #define KD_DAT B, 4 #define KEY_NONE (uint8_t)(0xFF) #define KEY_S1 (uint8_t)(0x01<<0) #define KEY_S2 (uint8_t)(0x01<<1) #define KEY_S3 (uint8_t)(0x01<<2) #define KEY_S4 (uint8_t)(0x01<<3) #define KEY_S5 (uint8_t)(0x01<<4) #define KEY_S6 (uint8_t)(0x01<<5) #define KEY_S7 (uint8_t)(0x01<<6) #define KEY_S8 (uint8_t)(0x01<<7) #endif /*_KEY_DISP_CFG_H_*/ /****************************************************** * key_disp.h ******************************************************/ #ifndef _KEY_DISP_H_ #define _KEY_DISP_H_ #include #include "key_disp-config.h" #define KD_CODE_NONE 10 #define KD_CODE_PAUSED 11 #define KD_CODE_CW 12 #define KD_CODE_CCW 13 #define KD_CODE_SET_RUN 14 #define KD_CODE_SET_SLEEP 15 #define KD_CODE_TIMER_RUN 16 #define KD_CODE_TIMER_SLEEP 17 #define KD_CODE_EXTERN_TRIG 18 #define KD_CODE_EXTERN_CTRL 19 #define KD_CODE_H 20 #define KD_CODE_M 21 #define KD_CODE_S 22 // Initialize key & display void kd_init(); // Update key & display, MUST be called periodically, eg., in timer void kd_update(); // Get key code uint8_t kd_get_key(); // Set mode to display void kd_display_code(uint8_t digit_id, uint8_t code_id); // Set display digits, dp_pos=-1 means no dp displayed void kd_display(uint16_t value, uint8_t max_digits, const int8_t dp_pos); #endif /*_KEY_DISP_H_*/ /****************************************************** * key_disp.c ******************************************************/ #include "avr/io.h" #include "key_disp.h" #include "config.h" #include "util.h" #define NOP() asm volatile ("nop") static const uint8_t seg_code[] = { 0x3F/*0*/, 0x06/*1*/, 0x5B/*2*/, 0x4F/*3*/, 0x66/*4*/, 0x6D/*5*/, 0x7D/*6*/, 0x07/*7*/, 0x7F/*8*/, 0x6F/*9*/, 0x00/*KD_CODE_NONE*/, 0x73/*KD_CODE_PAUSED*/, 0x21/*KD_CODE_CW*/, 0x03/*KD_CODE_CCW*/, 0x50/*KD_CODE_SET_RUN*/, 0x6D/*KD_CODE_SET_SLEEP*/, 0x09/*KD_CODE_TIMER_RUN*/, 0x36/*KD_CODE_TIMER_SLEEP*/, 0x79/*KD_CODE_EXTERN_TRIG*/, 0x39/*KD_CODE_EXTERN_CTRL*/, 0x76/*KD_CODE_H*/, 0x20/*KD_CODE_M*/, 0x22/*KD_CODE_S*/, }; #define SEG_DP 0x80 static volatile uint8_t _key_code = 0xFF; static volatile uint8_t _digits[4]; void kd_init() { PORT_DDR_SET(DIGIT1); PORT_DDR_SET(DIGIT2); PORT_DDR_SET(DIGIT3); PORT_DDR_SET(DIGIT4); PORT_DDR_CLR(KEY_FB); // Input PORT_DDR_SET(KD_CLR); PORT_PIN_CLR(DIGIT1); PORT_PIN_CLR(DIGIT2); PORT_PIN_CLR(DIGIT3); PORT_PIN_CLR(DIGIT4); PORT_PIN_SET(KEY_FB); // Internal pull-up PORT_PIN_SET(KD_CLR); _digits[0] = _digits[1] = _digits[2] = _digits[3] = 0; } /* Takes about 50 us @ 8MHz */ void kd_update() { static uint8_t turn = 0; uint8_t i; if( turn++ & 0x01 ) return; // Disable all digits first PORT_PIN_CLR(DIGIT1); PORT_PIN_CLR(DIGIT2); PORT_PIN_CLR(DIGIT3); PORT_PIN_CLR(DIGIT4); if( turn++ & 0x02 ) { // // trun for key scan // uint8_t shift_data; static uint8_t last_scan_code = 0; static uint8_t last_code_count = 0; // // Scan key PORT_PIN_CLR(KD_CLK); PORT_PIN_CLR(KD_CLR); PORT_PIN_SET(KD_CLR); // // All output 1 shift_data = 0xFF; PORT_PIN_SET(KD_DAT); while( shift_data ) { // Pulse out PORT_PIN_SET(KD_CLK); PORT_PIN_CLR(KD_CLK); shift_data >>= 1; } shift_data = 0x01; while( shift_data ) { if( (~shift_data) & 0x01 ) PORT_PIN_SET(KD_DAT); else PORT_PIN_CLR(KD_DAT); // Pulse out PORT_PIN_SET(KD_CLK); PORT_PIN_CLR(KD_CLK); // Delay for( i=0; i<16; i++ ) NOP(); // Check feedback if( PORT_PIN_VALUE(KEY_FB) == 0 ) { if( last_scan_code == shift_data ) { // Same as last scan result, that's the key! if( last_code_count > 4 ) _key_code = shift_data; if( last_code_count < 255 ) last_code_count++; } else { last_scan_code = shift_data; last_code_count = 1; _key_code = KEY_NONE; } break; } shift_data <<= 1; } if( shift_data == 0 ) { _key_code = KEY_NONE; last_scan_code = KEY_NONE; last_code_count = 1; } } else { // // Turn for display // static uint8_t curr_digit = 0; uint8_t curr_code = 0; // // Display digits PORT_PIN_CLR(KD_CLK); PORT_PIN_CLR(KD_CLR); PORT_PIN_SET(KD_CLR); curr_code = _digits[curr_digit]; for( i=0; i<8; i++ ) { // MSB first if( curr_code & 0x80 ) PORT_PIN_SET(KD_DAT); else PORT_PIN_CLR(KD_DAT); curr_code <<= 1; // Pulse out PORT_PIN_SET(KD_CLK); PORT_PIN_CLR(KD_CLK); } switch( curr_digit ) // 位控制pin可能不连续,所以不能够用移位之类的 { case 0: PORT_PIN_SET(DIGIT4); break; case 1: PORT_PIN_SET(DIGIT3); break; case 2: PORT_PIN_SET(DIGIT2); break; case 3: PORT_PIN_SET(DIGIT1); break; } // For next trun curr_digit++; curr_digit %= 4; } } uint8_t kd_get_key() { return _key_code; } void kd_display_code(uint8_t digit_id, uint8_t code_id) { _digits[digit_id] = seg_code[code_id]; } void kd_display(uint16_t value, uint8_t max_digits, const int8_t dp_pos/*=-1*/) { // // Prepare seg code for LED _digits[0] = seg_code[value % 10]; value /= 10; _digits[1] = seg_code[value % 10]; if(max_digits > 2) { value /= 10; _digits[2] = seg_code[value % 10]; if(max_digits > 3) { value /= 10; _digits[3] = seg_code[value % 10]; } } if( dp_pos >=0 && dp_pos<3 ) _digits[dp_pos] |= SEG_DP; } |
|
|
|
坐等大神,万分期盼,不甚感激!
|
|
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
【RA-Eco-RA2E1-48PIN-V1.0开发板试用】(第三篇)ADC采集+PWM输出
489 浏览 0 评论
《DNK210使用指南 -CanMV版 V1.0》第四十五章 人脸识别实验
498 浏览 0 评论
655 浏览 0 评论
如何用OpenCV的相机捕捉视频进行人脸检测--基于米尔NXP i.MX93开发板
1329 浏览 0 评论
《DNK210使用指南 -CanMV版 V1.0》第四十章 YOLO2人手检测实验
558 浏览 0 评论
【youyeetoo X1 windows 开发板体验】少儿AI智能STEAM积木平台
11752 浏览 31 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-20 13:20 , Processed in 0.954863 second(s), Total 108, Slave 91 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号