Микрочип PIC светодиодная вспышка ИЛИ операция редкое поведение

Я новичок с Microchip PIC UC. У меня есть некоторый опыт работы с AVR, но несколько недель назад я решил узнать о PIC.

Ну, проблема в следующем. Я пытаюсь сделать свою первую программу с двумя мигающими светодиодами, это очень просто. RA1 и RA2 мигают.

Когда я набираю код 1 и код 2, программа работает отлично. Код 1: работает нормально.

//Code 1. OK.

main(){

while(1){
  __delay_ms(1000); //wait 1 second
  PORTA |= 0b00000110; //RA1 & RA2 on
  __delay_ms(1000); //wait 1 second
  PORTA &= 0b00000000; //RA1 & RA2 off
}
}

Код 2: работает нормально.

//Code 2. OK

main(){

while(1){
  __delay_ms(1000); //wait 1 second
  PORTA |= (1 << 1) | (1 << 2); //RA1 & RA2 on
  __delay_ms(1000); //wait 1 second
  PORTA &= ~(1 << 1) & ~(1 << 2); //RA1 & RA2 off
}
}

Код 3: этот код не работает. Только 1 светодиодная вспышка. Я использую это с AVR, и код работает отлично. В чем проблема? ИЛИ операция не должна влиять на работу RA1.

//Code 3. Don't work. Only RA2 flash.

main(){

while(1){
  __delay_ms(1000); //wait 1 second
  PORTA |= (1 << 1); //RA1 on
  PORTA |= (1 << 2); //RA2 on

  __delay_ms(1000); //wait 1 second
  PORTA &= ~(1 << 1); //RA1 off
  PORTA &= ~(1 << 2); //RA2 off
}
}

Большое спасибо за Вашу помощь.

С наилучшими пожеланиями

2 ответа

Решение

Регистры ввода / вывода PIC используют чтение-изменение-запись. В некоторых случаях это может привести к повторному считыванию напряжения с выводов вместо логического значения, которое вы ожидали в своей программе. Это особенно верно, если выходной контакт имеет некоторую емкость, которая заставляет его менять значение медленнее, чем то, что указывается в последовательности инструкций для контакта.

В вашем случае третий случай пытается изменить контакты на PORTA очень быстро подряд. Это может привести к тому, что второе значение зафиксирует фактическое напряжение на выходе, а не то, что вы предполагали с помощью своего кода.

В таких случаях вам нужно использовать переменную для тени регистра PORTA:

main(){

unsigned char output = 0;

while(1){
  __delay_ms(1000); //wait 1 second
  output |= (1 << 1); //RA1 on 
  PORTA = output;
  output |= (1 << 2); //RA2 on 
  PORTA = output;

  __delay_ms(1000); //wait 1 second
  output &= ~(1 << 1); //RA1 off
  PORTA = output;
  output &= ~(1 << 2); //RA2 off
  PORTA = output;
}
}

Всегда пишите в порты LATx (выходные защелки) и читайте из PORTx.

Письмо в PORTx всегда вызывает головную боль.

Другие вопросы по тегам