USART崩溃(如何同时管理用户输入和printfs

时间:2013-10-29 17:21:33

标签: buffer interrupt pic usart

嘿所有我有我的usart设置来读取键盘的中断并使用我的pic从我的面包板传输ADC读数。中断是用户可以输入的键盘命令,它将改变我的模拟面包板温度传感器的上限和下限。

我的问题有时候我的usart只会随机崩溃。它冻结并停止传输。这种情况发生在我进入我的键盘输入时,甚至有时当它在句子中间发送某些内容时(例如在printf的中途)然后我按下输入并且中断似乎使usart崩溃导致像下面的图像

http://imageshack.us/photo/my-images/5/ftfk.png/

看一下突出显示的行,即我按下回车键,输出我通过缓冲区收集的字符流,它似乎只是将输出切成两半,然后跳过中断输出好。

这里可能出现什么问题,我应该寻找什么?

请查找以下代码的示例

void mainNema( char *nemaSentence) //this function processes my output and prints it out
{
int i;
for (i = 0; i< 20; i++) {
   GPGGA_Tokens[i] = '\0';
}

parseNemaSentence(nemaSentence);

i = 0;
while (strcmp(GPGGA_Tokens[i], msgEndOfSentence)!=0) {
   printf("\r\ntoken %i: %s\r\n",i, GPGGA_Tokens[i]);
    i++;
}
evaluateTokens();
changeNema(token1,token2,token3);

if (token2 == 1)
    printf("your new upper limit for channel %i is %i", token1, token3);
else
    printf("your new lower limit for channel %i is %i", token1, token3);


}

在从ADC转换器读取的函数片段下方,并通过usart打印出“读数”给用户

ConvertADC(); //take value from potentiometer

while(BusyADC() == TRUE) 

Delay1TCY();//wait until value is received

sampledValue = ReadADC(); //store value as sampledValue

setCurrentTemperatureForChannel(channelsel, sampledValue); //call function with channelsel and sampledValue

readSwitches(channelsel); //read inputs from pushbuttons

    printf ("\n\rcurrent Temp of channel %i is %#x, highlimit is %i, low limit is %i \n\r", (channelsel+1), getCurrentTemperatureForChannel(channelsel), 
getUpperLimitForChannel(channelsel),getLowerLimitForChannel(channelsel));       

1 个答案:

答案 0 :(得分:0)

候选人问题:无法阻止无限循环和UB。

注意:GPGGA_Tokens[i] = '\0'strcmp(GPGGA_Tokens[i], ...错误。如果GPGGA_Tokens[i]char,则第一个有意义。第二个如果是char *。我假设后者。我认为OP想要GPGGA_Tokens[i] = NULL

无法保证任何GPGGA_Tokens[i]都匹配msgEndOfSentence。你需要一些限制来防止前往lala land。

i = 0;
while ((i < 20) && (GPGGA_Tokens[i] != NULL) && 
    (strcmp(GPGGA_Tokens[i], msgEndOfSentence)!=0)) {
  printf("\r\ntoken %i: %s\r\n",i, GPGGA_Tokens[i]);
  i++;
}

也许在您中断输入处理期间,GPGGA_Tokens会在while循环中发生变化。建议中断保护GPGGA_Tokens访问。

disable_interrupts();
i = 0;
while ((i < 20) && (GPGGA_Tokens[i] != NULL) && 
    (strcmp(GPGGA_Tokens[i], msgEndOfSentence)!=0)) {
  printf("\r\ntoken %i: %s\r\n",i, GPGGA_Tokens[i]);
  i++;
}
enable_interrupts();