Микрочип 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 всегда вызывает головную боль.