问题描述
使用MPLAB X IDE v5.40和编译器XC8 v2.30进行编程。这使用PICkit 4 ICSP对配置为采用以下输入的PIC18F47Q10器件进行编程:
PS / 2协议处于空闲状态,其中CLK和DATA线为高电平,这就是观察到的-在while(1)循环中对它们进行轮询,然后将其发送到LED进行检查。键盘已经过测试,可以正常工作。那么,为什么该程序从不进入readRoutine?当它检测到启动条件足够长的时间(CLK为低电平,DATA为低电平)时,应等待置信度计数器超过阈值。
在调试模式下,我可以看到它确实读取了一些低位和低位的信息,但是它的保存时间不够长。该振荡器为64MHz的HFINTOSC,因此它绝对应该能够读取5个以上的low和low实例。设置了置信度计数器的阈值,以便我可以尝试不同的值并查看有效的方法。它仅在低至5个实例时才进入例程,并且在没有按键按下时才进入例程,所以这只是噪音。再高一点,它就不会输入,但是键盘可以正常工作,怎么办?
当按下PS / 2键时,设备会在CLK开始产生脉冲之前将两条线都驱动为低电平,并且可以在低电平脉冲上读取DATA。我已经测试了带有逻辑开关的例程,所以我正在测试一个单词,将一个开关拨动以使时钟脉冲化。它从LSB到MSB构筑单词,并按照我期望的方式正确检查奇偶校验。但是当插入键盘时,我只是无法进入程序而已,这让我很沮丧……我将非常感谢任何人都可以提供的任何帮助。
顺便说一句,尽管这是一个普通的项目,但它不是针对类的。实际上,我是在学校里做的,但是那时候我当然有了GTA的帮助。
#include "mcc_generated_files/mcc.h"
#define PUSHED 1
#define NOT_PUSHED 0
#define WAIT_FOR_CLK_HI while(!CLOCK_PORT)
#define WAIT_FOR_CLK_LO while(CLOCK_PORT)
void strobe(void);
void assignLight(void);
void waitForCLK_HI(void);
void waitForCLK_LO(void);
void checkKeyboard(void);
void checkButtonS2(void);
void clearandBlink(void);
void checkStartCondition(void);
void clockConfidence(void);
uint8_t readRoutine(void);
bool dataIsValid = true;
bool confident = false;
bool startCond = false;
long confidence = 0;
long confLimit = 10;
uint8_t byteBuild = 0x00;
uint8_t zeroBits = 0;
uint8_t scanCode = 0;
uint8_t parityBit = 0;
uint8_t newScan = 0;
uint8_t lastScan = 0;
uint8_t currClock = 0;
uint8_t currData = 0;
uint8_t wordCount = 0;
uint8_t switch2Flag = 0;
uint8_t btn2State = 0;
long startConf = 0;
long counter = 0;
void main(void)
{
SYstem_Initialize();
while (1)
{
strobe(); //Light strobes
checkButtonS2(); //Check button
assignLight(); //LED on with button
checkStartCondition(); //wait for key-press
}
}
void checkKeyboard(void) //Print scan-code
{
newScan = readRoutine(); //Read scan code
if(newScan != lastScan) //Make sure it's a new key-press
{
if(newScan == 0xF0) L8_SetHigh(); //Turn on L8 if we see break-code
}
lastScan = newScan; //Set lastScan - F0 will have to be ignored (break code)
}
uint8_t readRoutine(void)
{
WAIT_FOR_CLK_LO; //Wait for START bit
WAIT_FOR_CLK_HI; //Read DATA on low CLK pulse (typical)
for(int i = 0; i<8; i++) //Enter the byteBuilding zone
{
__delay_us(15); //Poll halfway thru CLK pulse
if (DATA_PORT) byteBuild |= 0x01 << i; //Set the bit if DATA=1
else zeroBits++; //Count the zeros for PARITY
WAIT_FOR_CLK_HI; //Wait for next bit
if (i<7) WAIT_FOR_CLK_LO; //Wait for CLK to go LOW. After D7,EXIT LOOP
}
WAIT_FOR_CLK_LO; //PARITY BIT
__delay_us(15); //Poll halfway thru CLK pulse
parityBit = DATA_PORT; //Take the PARITY bit
//PARITY BIT CHECK///////////////////////////////////////////////////////////
//If odd 0s and parityBit=1,or if even 0s and parityBit=0,data is corrupted
/////////////////////////////////////////////////////////////////////////////
if((zeroBits%2 && parityBit) || (!(zeroBits%2) && !parityBit)) dataIsValid=false;
WAIT_FOR_CLK_HI;
WAIT_FOR_CLK_LO; //STOP BIT
__delay_us(15); //Poll halfway thru CLK pulse
if(!DATA_PORT) dataIsValid=false; //STOP bit must be 1
WAIT_FOR_CLK_HI;
scanCode = byteBuild; //Store the completed byte
clearandBlink(); //Clear variables,blink lights
return scanCode; //Return the keyboard scanCode
}
void clearandBlink(void)
{
byteBuild = 0; //Clear the byteBuild tool
zeroBits = 0; //Clear the zero bits counter
dataIsValid = true; //Reset dataIsValid for next
L15_SetHigh();
__delay_ms(250); //Blink L15
L15_SetLow();
}
void strobe(void) //Strobe L14,showing program is running
{
counter++; //Increment counter
if(counter>256000) //Manually set to be close to 1 second by stopwatch
{
L14_Toggle(); //L14 strobes to show it's running
counter=0; //Reset counter
}
}
void checkButtonS2(void) //RC3 sets btn2State,switch2Flag
{
if(btn2State == NOT_PUSHED) //We think the button is not pushed
{
if (RC3_GetValue() == LOW) //See if the button is pushed
{
__delay_ms(30); //De-bouncing
if (RC3_GetValue() == LOW) //If the button is still pressed
{
btn2State = PUSHED; //Switch on button state
switch2Flag = HIGH; //Raise the flag
}
}
}
else //We think the button is pushed
{
if (RC3_GetValue() == HIGH) //If the button is released
{
btn2State = NOT_PUSHED; //Set the button state
}
}
}
void assignLight(void) //L13 on when RC3 pressed down
{
if (switch2Flag) //If the switch has been pressed
{
switch2Flag=LOW; //Lower the flag
} //Add any other actions if desired
if(btn2State == PUSHED) L13_SetHigh(); //L13 ON
else L13_SetLow(); //L13 OFF
}
void checkStartCondition(void)
{
if(CLOCK_PORT) L12_SetHigh(); //display CLOCK
else L12_SetLow();
if(DATA_PORT) L11_SetHigh(); //display DATA
else L11_SetLow();
if(!CLOCK_PORT && !DATA_PORT)
{
L0_SetHigh(); //LED 0 INDICATOR
checkKeyboard(); //Begin when confident of START condition
}
}
void waitForCLK_HI(void) //DEBUG ONLY: Uses confidence to confirm LO-HI transition
{
while (!confident) //Wait for CLK to go HIGH
{
if(CLOCK_PORT) //If CLK is HIGH
{
confidence++; //Building confidence
if(confidence>confLimit)
{
confidence = 0; //Clear confidence counter
confident = true; //Assured of state change
}
}
else confidence = 0; //Reset confidence
} confident = false; //Reset for next check
}
void waitForCLK_LO(void) //DEBUG ONLY: Uses confidence to confirm HI-LO transition
{
while (!confident) //Wait for CLK to go LOW
{
if(!CLOCK_PORT) //If CLK is LOW
{
confidence++; //Building confidence
if(confidence>confLimit)
{
confidence = 0; //Clear confidence counter
confident = true; //Assured of state change
}
} else confidence = 0; //Reset confidence
} confident = false; //Reset for next check
}
void clockConfidence(void) //DEBUG ONLY: Uses confidence to confirm START condition
{ //When using this for debug,must revise to check for startCond
if(!currClock && !currData) //If CLK&DATA both LOW - Possible START Condition
{
startConf++; //Build Start Confidence
if (startConf > confLimit) //Need to hold condition past confLimit
{
startConf = 0; //Reset Start Confidence
startCond = true; //Set Start Condition
}
} else startConf = 0;
}
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)