完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
扫一扫,分享给好友
不能实现预期功能,何解?
附件去掉后缀 .doc,是proteus8工程文件 main.ino #include "Arduino.h" #include #include "USART.h" #define ADDR 0x20 // pcf8574 I2C地址 #define setbit(x,y) (x|=(1<<(y))) #define clrbit(x,y) (x&=~(1<<(y))) #define reversebit(x,y) (x^=(1<<(y))) #define getbit(x,y) ((x)>>(y)&1) // pcf8574上电时所有数据口为高电平 volatile uint8_t ioBits = 0xf0; unsigned char key[4][4]={ {'1','2','3','A'}, {'6','5','4','B'}, {'7','8','9','C'}, {'*','0','#','D'} }; char prompt[] = "Press one key:"; volatile unsigned char lastKey; volatile unsigned int prevMillis = 0; void setup() { USART_begin(2400); USART_putString(prompt); Wire.begin(); writeIoBits(); //readIoBits(); // 设置中断 pinMode(2, INPUT_PULLUP); // pcf8574平时高电平,中断信号为低电平,按下和释放button会触发两次CHANGE // 因此使用FALLING,高电平转低电平时触发中断 attachInterrupt(digitalPinToInterrupt(2), keyISR, FALLING); } void loop() { if(lastKey){ USART_transmit(lastKey); lastKey = 0x00; ioBits = 0xf0; writeIoBits(); //readIoBits(); } delay(100); } // 按键中断处理函数,仅设置标志 void keyISR() { USART_transmit('K'); if ((millis() > prevMillis + 100) && (lastKey == 0)) { checkKey(); prevMillis = millis(); } } // 扫描按键 void checkKey(){ int row, col; for(col = 0; col < 4; col++){ ioBits = 0xff; clrbit(ioBits, col); writeIoBits(); for(row = 0; row < 4; row++){ readIoBits(); if(!getbit(ioBits, row+4)){ lastKey = key[row][col]; return; } } } } void writeIoBits(){ // 写入数据 Wire.beginTransmission(ADDR); Wire.write(ioBits); Wire.endTransmission(); } void readIoBits(){ // 重新读入 Wire.requestFrom(ADDR, 1); if (Wire.available()) { ioBits = Wire.read(); } } usart.h #ifndef USART_H #define USART_H void USART_begin(unsigned int baud) { unsigned int ubrr = F_CPU/16/baud - 1; UBRR0H = (unsigned char)(ubrr>>8); UBRR0L = (unsigned char)(ubrr); UCSR0B = (1 << RXEN0)|(1 << TXEN0); UCSR0C = (1 << UCSZ00)|(1 << UCSZ01); } void USART_start(unsigned int baud,uint8_t dataBits,uint8_t stopBits){ UCSR0C = (stopBits==2) ? (1< case 5: // Char size 5 bit UCSR0C &= ~((1< case 6: // Char size 6 bit UCSR0C |= (1< case 7: // Char size 7 bit UCSR0C |= (1< default: // Char size 8 bit UCSR0C |= (1< } } void USART_transmit(unsigned char data) { while(!(UCSR0A & (1 << UDRE0))); UDR0 = data; } void USART_putString(char* str) { while(*str != 0x00){ USART_transmit(*str); str++; } } unsigned char USART_receive() { while(!(UCSR0A & (1 << RXC0))); return UDR0; } #endif
|
|
相关推荐
1个回答
|
|
我知道了,中断内不能使用I2C通讯!
|
|
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
6268 浏览 3 评论
7532 浏览 1 评论
7773 浏览 0 评论
Protues中自己封装的芯片元件无Program File、Clock Frequency选项怎么解决,求求大神了!
9581 浏览 1 评论
基于51单片机的车辆倒车雷达报警系统,HC-SR04超声波测距,全套资料
1282 浏览 0 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-27 05:09 , Processed in 0.464050 second(s), Total 43, Slave 35 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号