Приветствую!
Пытаюсь с pic18f2550 общаться с WiFi-модулем ESP8266 (на скорости 115200 kbps). В ответах от него бывают и нули и переводы каретки, терминировать строку символом не получилось. Поэтому организовал таймер. И таймер и хардварный USART организованы на прерываниях.
С другой стороны для отладки сделал ещё и software UART (9600 kbps, работает на delay). Соответственно, хардварный вариант намного быстрее софтварного, и чтобы напечатать в debug полученную информацию нужно организовать буфер и как-то их между собой синхронизировать (потом буфер всё-равно будет нужен). Вот тут то я и запутался.
Достаточно ли в прерывании выставить булевскую переменную gotString, а в главном цикле просто её проверять?
Раньше для отладки планировал использовать LCD 1602, но он слишком маленький. Тем не менее, как средство верификации он остался. Так вот, на экране есть такая последовательность символов: "AT+RST\r\n\0\nOK\r\n13,rst cause:4". В putty же по дебагу я получаю только вот такое:
Код:
Debug messages started...
AT+RST
OK
ets Jan ▒
Прилагаю исходники проекта. Функции printf, printn - вывод на LCD; putcuart, dbgprintn - отладочный вывод; putcuSart - общение с WiFi. Компилятор XC8. Код:
Спойлер
Код:
#define _XTAL_FREQ (20000000ULL)
#define USE_AND_MASKS
#pragma config FOSC = HS
#pragma config DEBUG = ON
#pragma config PWRT = OFF // Power-up Timer Enable bit (PWRT disabled)
#pragma config WDT = OFF // Watchdog Timer Enable bit (WDT disabled (control is placed on the SWDTEN bit))
#pragma config LVP = OFF // Single-Supply ICSP Enable bit (Single-Supply ICSP disabled)
#pragma config MCLRE = ON // MCLR Pin Enable bit (MCLR pin enabled; RE3 input pin disabled)
#pragma config PBADEN = OFF // PORTB A/D Enable bit (PORTB<4:0> pins are configured as analog input channels on Reset)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <xc.h>
#include <delays.h>
#include <plib/usart.h>
#include <plib/sw_uart.h>
#include "flex_lcd.c"
#define WAITCONST 10000
#define LED_PIN PORTCbits.RC2
#define BUFSIZE 100
unsigned char buffer[BUFSIZE];
static unsigned int writeIndex = 0;
static int getString = 0;
void DelayTXBitUART(void){
_delay(509); //9600 baud:
}
void DelayRXHalfBitUART(void){
_delay(252); //9600 baud:
}
void DelayRXBitUART(){
_delay(507); //9600 baud:
}
void dxDelayMs(int ms){
int n = ms/10;
if( ms <= 10 ) __delay_ms( 10 );
for(int i = 0; i < n; i++ )
__delay_ms( 10 );
}
void someDelay(){
dxDelayMs(500);
}
/*static void clearBuffer(void){
unsigned long i;
for(i=0;i<BUFSIZE ;i++)
buffer[i] = 0;
writeIndex=0;
}*/
void dbgprintn(const char* s, int n){
int i;
for(i=0; i<n; i++){
putcUART(s[i]);
}
}
/*
*
*/
int main(int argc, char** argv) {
//Setup Timer0
T0PS0=0; //Prescaler is divide by 256
T0PS1=1;
T0PS2=0;
PSA=0; //Timer Clock Source is from Prescaler
T0CS=0; //Prescaler gets clock from FCPU (5MHz = 20MHz/4)
T08BIT=1; //8 BIT MODE?
TMR0IE=1; //Enable TIMER0 Interrupt
PEIE=1; //Enable Peripheral Interrupt
GIE=1; //Enable INTs globally
TMR0ON = 0;
//USART
TRISCbits.RC6 = 0; //TX pin set as output
TRISCbits.RC7 = 1; //RX pin set as input
//LED
TRISCbits.RC2 = 0;
LED_PIN = 1; //LED ON
unsigned char Rxdata[20];
unsigned char Txdata[] = "AT+RST\r\n";
unsigned char Tx2[] = "AT+GMR\r\n";
unsigned char Cdata;
int i, n;
//LCD pins
TRISAbits.TRISA0 = 0;
TRISAbits.TRISA1 = 0;
TRISBbits.TRISB3 = 0;
TRISBbits.TRISB2 = 0;
TRISBbits.TRISB1 = 0;
TRISBbits.TRISB0 = 0;
lcd_init();
LED_PIN = 0; //LED on/off
printf("LCD init...\nBegin USART");
someDelay();
OpenUART();
putsUART("\r\nDebug messages started...\r\n");
OpenUSART( USART_TX_INT_OFF &
USART_RX_INT_ON &
USART_ASYNCH_MODE &
USART_EIGHT_BIT &
USART_CONT_RX &
USART_BRGH_HIGH,
10 ); // SPBRG = 129 for 9600 Baud rate at 20 MHz and 51 for 8Mhz,
//SPBRG = 20 for 57600 on 20 MHz, = 10 for 115200 on 20 MHz
//16(X+1) = Fosc/Baud Rate
printf("\fUSART opened");
putsUSART((char *)Txdata); // transmit the string
printf("\nWrite");
someDelay();
printf("\f");
while(1){
if( getString ){
//printf("\fGot string");
printn(buffer, writeIndex);
dbgprintn(buffer, writeIndex);
getString = 0;
writeIndex = 0;
}
;
}
return 0;
}
//Main Interrupt Service Routine (ISR)
void interrupt ISR(){
//Check if it is TMR0 Overflow ISR
if(TMR0IE && TMR0IF){
//TMR0 Overflow ISR
getString = 1;
TMR0ON = 0;
//TMR0IE = 0;
//Clear Flag
TMR0IF=0;
}
//check if the interrupt is caused by RX pin
if(PIR1bits.RCIF == 1){
if( writeIndex<BUFSIZE ){
//our buffer size
buffer[writeIndex] = getcUSART();
writeIndex++;
TMR0H = 0;
TMR0L = 0;
TMR0 = 0;
TMR0ON = 1;
}
}
}