Следуя this tutorial, я хотел отправить и получить данные с PIC18f4520 на свой компьютер. Отправка данных на компьютер с использованием последовательного порта работает для меня отлично. Теперь я пытаюсь получить данные с моего компьютера с помощью последовательного порта. Я отправляю данные из приложения C#, которое было создано моим учителем (он отлично работает для других студентов), поэтому это не может быть проблемой.PIC 18f4520 - Получение данных из последовательного интерфейса с использованием прерывания Rx
Чтобы получать данные, мне нужно сделать это с помощью прерываний. Я изменил USART_RX_INT_OFF на USART_RX_INT_ON и включил периферийное прерывание.
Используя инструмент отладки, я заметил, что моя программа никогда не вводилась, это прерывание (я должен использовать высокоприоритетный).
Что моя программа делает в основном (это работает отлично):
- Я сбора аналоговых данных с выводами RA5 с помощью АЦП
- Отправка ВЫСОКИЙ или НИЗКИЙ приколоть RE2, чтобы зажечь лампочку или повернуть это от
- Использование пин RA1 для управления сервомотором
- Использование ЖК-экран для печати информации на нем
Init_Inte Предполагается, что прерывания() должны инициировать прерывания. ADC_Init() должен инициировать ADC
Вот мой код, я попытался добавить как можно больше комментариев, чтобы быть ясными. Дайте мне знать, если вы можете мне помочь, это было бы очень оценено.
#include <stdio.h>
#include <stdlib.h>
#include "p18f4520.h"
#include <stdio.h>
#include <stdlib.h>
#include <plib/adc.h>
#include <plib/usart.h>
#include <plib/portb.h>
#include <plib/delays.h>
#include <plib/timers.h>
#include <plib/pwm.h>
#include <string.h>
#include <xc.h>
#include <stdlib.h>
#include "config.h"
#include "hd44780/hd44780.h"
#define delay1S for(uint8_t i = 0 ; i < 20 ; i++) __delay_ms(50)
int counter;
unsigned char textTx[10];
unsigned char JourMSG[]= "jour";
unsigned char NuitMSG[]= "nuit";
/*char chaine[10]= "";
char buffer[10];
char * s1, * s2;
unsigned int i, j;*/
//Servo motor signal sending functions
void turn_middle() { //0°
PORTAbits.RA1 = 1;
__delay_us(1500);
PORTAbits.RA1 = 0;
__delay_us(18500);
}
void turn_left() { //-90°
PORTAbits.RA1 = 1;
__delay_us(1000);
PORTAbits.RA1 = 0;
__delay_us(19000);
}
void turn_right() { //90°
PORTAbits.RA1 = 1;
__delay_us(2000);
PORTAbits.RA1 = 0;
__delay_us(18000);
}
//////////////////////////////////////
//Delay functions
void DelayxmSecond(unsigned int tempo_ms)
{
for(int i=0;i<tempo_ms;i++)
__delay_ms(1);
}
void DelayxSecond(unsigned int tempo_s)
{
for(int j=0;j<tempo_s;j++)
DelayxmSecond(1000);
}
////////////////////////////////////////
void Init_Timer1(void)
{
OpenTimer1(TIMER_INT_ON & T1_16BIT_RW & T1_SOURCE_EXT & T1_PS_1_1 & T1_OSC1EN_ON & T1_SYNC_EXT_ON);
IPR1bits.TMR1IP=0;
WriteTimer1(32768);
}
void Init_Interruptions(void)
{
PIR1bits.RCIF = 0; //reset RX pin flag
IPR1bits.RCIP = 1; //high priority
PIE1bits.RCIE = 1; //Enable RX interrupt
INTCONbits.PEIE = 1; //Enable pheripheral interrupt (serial port is a pheripheral)
RCONbits.IPEN = 1;
INTCONbits.GIEH = 1;
INTCONbits.GIEL = 1;
}
void interrupt high_priority Int_haute()
{
//check if the interrupt is caused by RX pin
if(PIR1bits.RCIF == 1)
{
INTCONbits.GIEH = 0;
getsUSART(textTx,10);
PIR1bits.RCIF = 0; // clear rx flag
INTCONbits.GIEH = 1;
}
}
void interrupt low_priority Int_basse() //Not doing anything here
{
INTCONbits.GIEL = 0;
INTCONbits.GIEL = 1;
}
void ADC_Init() //ADC init
{
ADCON1bits.VCFG1 = 0; //-Vref VSS
ADCON1bits.VCFG0 = 0; //+Vref VDD
ADCON1bits.PCFG3 = 1110;
ADCON1bits.PCFG2 = 1110;
ADCON1bits.PCFG1 = 1110;
ADCON1bits.PCFG0 = 1110;
ADCON0bits.CHS3 = 0000;
ADCON0bits.CHS2 = 0000;
ADCON0bits.CHS1 = 0000;
ADCON0bits.CHS0 = 0000;
ADCON0bits.GODONE = 0;
ADCON0bits.ADON = 1;
ADCON2bits.ADFM = 0;
ADCON2bits.ACQT2 = 101;
ADCON2bits.ACQT1 = 101;
ADCON2bits.ACQT0 = 101;
ADCON2bits.ADCS2 = 010;
ADCON2bits.ADCS2 = 010;
ADCON2bits.ADCS2 = 010;
ADCON0bits.ADON = 1; //TURN ON AD MODULE
ADCON1 = 0xC0; //All pins as Analog Input
//With reference voltages VDD and VSS
}
void main(){
TRISCbits.TRISC7 = 1;
TRISCbits.TRISC6 = 0;
OpenUSART(USART_TX_INT_OFF &USART_RX_INT_ON &USART_ASYNCH_MODE &USART_EIGHT_BIT &USART_BRGH_HIGH,12);
Init_Interruptions();
//Set LCD pins to output
TRISD=0x00;
//PIC2DEMPLUS related stuffs. Not needed on board without LCD power control and with R/W wired to ground
LATDbits.LD7 = 1; // LCD power on
__delay_ms(50); // LCD power up delay
LATDbits.LD5 = 0; // R/W set to W
//LCD init
LCDinit(LCD_INIT_CURSOR_DISABLED);
__delay_ms(2);
ADC_Init();
TRISAbits.TRISA5 = 1; // configure RA5 as analog input
ADCON0 = 0b01100000; // Set channel select to AN5
ADCON1 = 0b00001011; // Configure RA5/AN5 as analogue
ADCON2 = 0b10101010; // Right justified result
// configure voltage reference
//ADCON1bits.VCFG1 = 0; // -ve ref = Vss
//ADCON1bits.VCFG0 = 1; // +ve ref = Vdd
// select ADC input channel
ADCON0bits.CHS = 100; // input = AN5
ADCON2bits.ACQT = 100; // input = AN5
ADCON2bits.ADCS = 100; // input = AN5
ADCON2bits.ADFM = 1;
ADCON0bits.ADON = 1; // turn on ADC module
TRISAbits.TRISA1 = 0; //RA1 output -> SERVOMOTOR
TRISEbits.TRISE2 = 0; //RB1 output -> BULB
PORTBbits.RB1 = 1;
int compteur=0;
int modejour=1; //Starting with day mode
unsigned int N;
while(1)
{
ADCON0bits.GO_DONE = 1; //LAUNCH CONVERSION
while(ADCON0bits.GO_DONE != 0);
LCDpos(0,3);
N=(ADRESH<<8)+ADRESL;
putsUSART(textTx);
if(N>800 && modejour==0)
{
LCDpos(0,3);
LCDprintConst("PLEIN JOUR");
putsUSART(JourMSG);
PORTEbits.RE2 = 0;
modejour=1;
compteur=0;
while(compteur<20)
{
turn_right();
compteur++;
}
}
if(N<800 && modejour==1)
{
LCDpos(0,3);
LCDprintConst("MODE NUIT ");
putsUSART(NuitMSG);
PORTEbits.RE2 = 1;
modejour=0;
compteur=0;
while(compteur<20)
{
turn_left();
compteur++;
}
}
}
}
такие цифры: 'ADCON2bits.ADCS2 = 010;' - восьмеричные значения, это то, что вы на самом деле хотите? – user3629249
опубликованный код не инициализирует периферийное устройство часов, я бы подумал, что этот шаг необходим для получения точных скоростей передачи, таймингов задержки и т. Д. – user3629249
Указанный учебник включает в себя соответствующий код для использования PIC81 в качестве эхо-устройства. Помимо всего прочего, периферийное устройство ADC необходимо отключить, чтобы иметь возможность использовать соответствующий вывод ввода-вывода для бит данных «rx». Я не вижу, чтобы этот шаг выполнялся в коде. – user3629249