Светодиодная вспышка микрочипа 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
}
}

Спасибо большое за помощь.

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


person Juan Luis    schedule 02.10.2016    source источник


Ответы (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;
}
}
person slebetman    schedule 02.10.2016
comment
Многие PIC также имеют регистры-защелки вывода, которые лучше подходят для управления выводами, поскольку они содержат только те значения, которые вы записываете в них. АКА. ЛАТА против ПОРТЫ - person Mathieu L.; 02.10.2016
comment
Спасибо за ответ, оба решения сработали для меня. На AVR регистр PORTX не имеет такой проблемы. - person Juan Luis; 02.10.2016
comment
@JuanLuis На любом микроконтроллере, кроме PIC, это не проблема. Почему люди будут использовать PIC в новых проектах, я понятия не имею. - person Lundin; 03.10.2016

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

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

person EBlake    schedule 03.10.2016
comment
Большое тебе спасибо! Я сделаю это! - person Juan Luis; 03.10.2016