我使用的是带有mplabv8.70的pic16F690、Pickit2和高科技的PICC编译器。
我的问题是,这个中断是否能够使用其中的getch函数,因为getch函数使用RCIF标志,该标志也是用于触发EUSART中断的标志。
这是我的代码,很抱歉它很长,但这里的人似乎不喜欢放片段/部分,而不是整个东西。它多路复用了一个4位数的7段LED显示屏,并获得了RPM值的EUSART信号,但是我希望它即使在没有接收到EUSART的情况下也能继续显示,然后在接收到EUSART时有效地“更新”,从而产生中断和全局变量。如果有一个明显更好的方法,那么我很高兴被告知我的方法是错误的。
//#include _LEGACY_HEADERS //Added for compiler versions 9.81+
#include <stdio.h> //For the printf function
#include <htc.h> //Compiler header file
//#include "usart.h" //USART header file
//#include "pause.h"
//#include "SerialIn.h"
//#include "Display.h"
__CONFIG(INTIO & WDTDIS & PWRTEN & MCLRDIS & UNPROTECT & UNPROTECT & BORDIS & IESODIS & FCMDIS); //Configure the PIC with generic set up
#define BAUD 2400
#define FOSC 4000000L
#define baudsetting ((int)(FOSC/(64UL * BAUD) -1))
#define RX_PIN TRISB5
#define TX_PIN TRISB7
#define dig0 0b01111110
#define dig1 0b00110000
#define dig2 0b01101101
#define dig3 0b01111001
#define dig4 0b00110011
#define dig5 0b01011011
#define dig6 0b01011111
#define dig7 0b01110000
#define dig8 0b01111111
#define dig9 0b01111011
unsigned char byte1;
unsigned char byte2;
unsigned char byte3;
unsigned char byte4;
unsigned char byte5;
unsigned char byte6;
unsigned char byte7;
unsigned char byte8;
unsigned char byte9;
unsigned RPMleft;
unsigned RPMright;
#define units 0b000001
#define tens 0b000010
#define hundreds 0b000100
#define thousands 0b001000
unsigned char RPM_unit;
unsigned char RPM_ten;
unsigned char RPM_hund;
unsigned char RPM_thou;
void interrupt isr(void);
void display_digit(unsigned char digit);
void multiplex(unsigned RPM);
void pause(unsigned usvalue);
unsigned char getch(void);
void init_comms(void);
void interrupt isr(void)
{
if (RCIF == 1)
{
byte2 = getch(); //Receive 8 bytes from the PICAXE
byte3 = getch();
byte4 = getch();
byte5 = getch();
byte6 = getch();
byte7 = getch();
byte8 = getch();
byte9 = getch();
byte2 = byte2 - 30; //Convert the ASCII to equivilent integer
byte3 = byte3 - 30;
byte4 = byte4 - 30;
byte5 = byte5 - 30;
byte6 = byte6 - 30;
byte7 = byte7 - 30;
byte8 = byte8 - 30;
byte9 = byte9 - 30;
////////Depending on which PIC is being used comment one of the following lines///////////////////////////////
RPMleft = byte2*1000 + byte3*100 + byte4*10 + byte5; //Save the RPM of the left prop shaft
// RPMright = byte6*1000 + byte7*100 + byte8*10 + byte9; //Save the RPM of the right prop shaft
}
}
void main(void)
{
/* General Setup */
PORTA = 0; //Clear PortA
PORTB = 0; //Clear PortB
PORTC = 0; //Clear PortC
TRISA = 0; //All PortA outputs
TRISB = 0xFF; //All PortB inputs
TRISC = 0; //All PortC outputs
CM1CON0 = 0; //Comparators off
CM2CON0 = 0;
ANSEL = 0; //A/D module off
INTCON = 0b11000000; //Enable interrupts GIE = 1 (global interrupts), PEIE = 1 (periphaeral interrupts)
PIE1 = 0b00100000; //Enable bit 5 RCIE = 1 (EUSART receive interrupt enable bit)
init_comms(); //Set up the USARTh
while(1==1) //Loop Forever
{
////////Depending on which PIC is being used comment one of the following lines////////////////////////////////////
multiplex(RPMleft);
// multiplex(RPMright);
}//End while
}//End main
unsigned char getch(void) {
/* retrieve one byte */
while(!RCIF) /* set when register is not empty */
continue;
return RCREG;
}
void init_comms(void)
{
RX_PIN = 1;
TX_PIN = 0;
SPBRG = baudsetting;
//Continuous 8 bit asynchronous non inverted low speed communication
RCSTA = 0x90; // SPEN and CREN bit = 1, RX9EN = 0
TXSTA = 0x20;//TXEN = 1, BRGH, SYNC = 0
BAUDCTL = 0; //BRG16 = 0
}
void multiplex(unsigned RPM)
{
RPM_unit = RPM / 1000; //Split the Left RPM value into 4 digits
RPM_ten = (RPM / 100) % 10;
RPM_hund = (RPM / 10) % 10;
RPM_thou = RPM % 10;
//Start Multiplexing
PORTA = thousands;
display_digit(RPM_thou);
PORTA = hundreds;
display_digit(RPM_hund);
PORTA = tens;
display_digit(RPM_ten);
PORTA = units;
display_digit(RPM_unit);
}
void display_digit(unsigned char digit)
{
switch (digit)
{
case 0:
PORTC = dig0; //zero
break;
case 1:
PORTC = dig1; //one
break;
case 2:
PORTC = dig2; //two
break;
case 3:
PORTC = dig3; //three
break;
case 4:
PORTC = dig4; //four
break;
case 5:
PORTC = dig5; //five
break;
case 6:
PORTC = dig6; //six
break;
case 7:
PORTC = dig7; //seven
break;
case 8:
PORTC = dig8; //eight
break;
case 9:
PORTC = dig9; //nine
break;
}
}发布于 2015-08-22 00:37:18
在PIC16架构中,中断不能中断自身。即使您提前清除该标志,ISR也会继续运行,直到它返回为止。
如果需要嵌套中断,请切换到PIC18。
发布于 2015-08-22 01:57:25
我喜欢保持中断服务例程尽可能简短,避免延迟或代码处理时间过长。这样,程序就可以尽可能快地处理新的中断。
如果在为另一个中断提供服务时发生中断,微处理器将在您退出ISR后立即重新进入ISR,因为中断标志已设置。
在您的代码中,我认为您可以在读取第一个字符后退出ISR,然后继续执行,直到下次设置RCIF标志。因为在通过USART发送另一个字节之前,您可以执行相当多的代码。如果您创建了一个类似byte9的缓冲区和一个静态指针来记住您在ISR调用之间接收的是哪个字符,那么这应该是可行的。
下面是一个示例:
void interrupt isr(void)
{
static char pointer = 0;
if (RCIF == 1)
{
byte[pointer]=getch(); // stores the incoming data in byte[0]-byte[8]
pointer++;
if(pointer==9)
{
pointer=0; // Reset pointer
// Other operations or flags that signal the expected data was received
}
}
}编辑:我还认为你需要在软件中清除RCIF标志,检查数据表,看看你是否需要手动执行此操作,或者如果缓冲区为空,该标志是否自动清除。
https://stackoverflow.com/questions/32144623
复制相似问题