По сути, я хочу запрограммировать PIC16F917, чтобы конкретный int увеличивался на единицу каждый раз, когда я нажимаю кнопку.
Теперь я запустил и запустил АЦП, у меня есть циклы для подсчета, но мне, похоже, не хватает знаний и опыта, чтобы поставить его полностью и зафиксировать ввод обратно в ноль до того, как int увеличится на число больше единицы.
Следующий код — это то, что я написал до сих пор. Проблема с ним в том, что он увеличивается несколько раз за одно нажатие (столько циклов задержки, в течение которых удерживалась кнопка), и я бы хотел, чтобы он учитывался только на единицу. Я думал о создании новой функции и int, но я просто не могу собрать ее вместе - нужна большая помощь.
Спасибо за помощь, Эзра
#include <xc.h>
#include "config-bits.h"
#define _XTAL_FREQ 4000000
int result;
int output;
void delay()
{
int i;
for(i=0; i<100; i++)
{
/*Timer Stuff*/
}
}
int main()
{
TRISA=1; //Set all pins to input
TRISB=1;
TRISC=1;
TRISD=1;
TRISE=1;
TRISDbits.TRISD0 = 0; //LED output
ANSELbits.ANS0 = 1; //Select ADC input
ADCON0bits.ADFM = 1; //ADC result is right justified
ADCON0bits.VCFG = 0; //Vdd is the +ve reference
ADCON1bits.ADCS = 0b001; //Fosc/8 is the conversion clock
//This is selected because the conversion
//clock period (Tad) must be greater than 1.5us.
//With a Fosc of 4MHz, Fosc/8 results in a Tad
//of 2us.
ADCON0bits.CHS = 0; //select analog input, AN2
ADCON0bits.ADON = 1; //Turn on the ADC
while(1)
{
delay(); //Wait the acquisition time (about 5us).
ADCON0bits.GO = 1; //start the conversion
while(ADCON0bits.GO==1){}; //wait for the conversion to end
result = (ADRESH<<8)+ADRESL; //combine the 10 bits of the conversion
if(result > 512)
{
PORTD=output++;
delay();
}
else
{
NOP();
}
}
}
Используйте переменную, чтобы запомнить, был ли последний результат < 512. Перед увеличением выходной переменной проверьте, был ли предыдущий результат < 512. Могли бы вы использовать цифровой вход, а не аналоговый?
Хорошо, сначала несколько вещей. TRISA=1
не помещает все PORTA в качестве входных данных, как написано в комментарии, это эквивалентно тому, 0b00000001
чтобы поместить все порты в качестве входных данных, которые вы должны сделать TRISA=255
, или TRISA=0xFF
которые равны 0b11111111
.
Я не знаю, как вы подключили кнопку к микроконтроллеру, но, глядя на вашу программу, это должно быть примерно так:
смоделируйте эту схему - схема, созданная с помощью CircuitLab
Таким образом, это должно работать, вы получаете 5 В, когда кнопка нажата, и 0 В, когда она открыта. Однако вы все еще можете получить некоторое нестабильное напряжение в момент нажатия кнопки (называемое дребезгом), это выглядит так:
Таким образом, может показаться, что кнопка нажимается несколько раз из-за этого эффекта подпрыгивания, чтобы решить эту проблему, вам нужно взять больше образцов и усреднить их, а затем использовать средний результат, чтобы решить, что делать.
Но есть и другой способ, который в этом случае проще, вы просто хотите прочитать, нажат ли переключатель ('1') или нет ('0'), поэтому вам не нужен и АЦП, вы можете сделать это просто с помощью цифровой вход, аналоговый не нужен. Схема будет такой же, но программа на C будет примерно такой (предположим, что коммутатор подключен к RA0):
int main() {
TRISA=1; // Set RA0 as input
TRISD=0x00;
PORTD=0x00;
while(1){
if(TRISAbits.RA0) {
PORTD += 1;
delay(); // We use the delay to avoid the bouncing effect (some milliseconds)
while(TRISAbits.RA0);
}
}
}
Аналоговые входы иногда полезны, когда вам нужно прочитать много кнопок и вы хотите сохранить некоторые входы MCU:
В этой схеме каждая кнопка создает разное напряжение на входе АЦП. Таким образом, с помощью аналогового входа вы считываете это напряжение и определяете, какая кнопка была нажата.
if(TRISAbits.RA0)
это то же самое, что if(TRISAbits.RA0 == 1)
таким же образом, if(!TRISAbits.RA0)
это то же самое, что if(TRISAbits.RA0 == 0)
. Это просто некоторые вещи C :)
Роджер Роуленд
ezra_vdj
Голаж
Роджер Роуленд
ezra_vdj
ezra_vdj
Роджер Роуленд