We are extending our previous example where I show how to receive data from UART in PIC CCS Compiler for PIC16f887 microcontroller. We received Serial Data and then we display UART received data to 9 digit 7 segment display. In the current example we are extending that previous code by implementing the Serial Interrupt or UART Interrupt. We are shifting the total Receiving Code to The Interrupt based code and we will tell how to receive data from serial port in PIC16F887A microcontroller using PIC CCS Compiler and along with the timer 0 based 9 digit 7 segment display multiplexing. There is also RTOS based example for 9 digit 7 segment display multiplexing in our previous post.
The reason for shifting the serial received data is I faced a problem where I have to add another microcontroller to send data to the PIC16F887A microcontroller. In the previous code I tried this with simple polling based serial data receiving. But in the PIC16f887A microcontroller there is UART buffer which if got full, new data will be lost. I faced this problem because I implemented the Setting on digital Input via push buttons attached to the PORTA of PIC16F887A microcontroller.
So when I came back from the setting the new data from other microcontroller wasn’t able to be received. I changed that code and implemented a Serial Interrupt based receiving data from UART. After receiving the other display procedure is almost identical to previous.
Here is the complete code
#include <16F887.h>
#device *= 16 ADC=10
#fuses NOWDT, HS, PROTECT, CPD, NOWRT, BROWNOUT, NODEBUG, NOLVP, PUT
#use delay(clock=16000000)
#define OUT_SEG_CODE(CODE) output_b(CODE)
#use rs232(uart1, baud = 9600)
#define NUM_DIGITS 9
unsigned char seg_codes[] = {0x03, 0x9F, 0x25, 0x0D, 0x99, 0x49, 0x41, 0x1F, 0x01, 0x09, 0xFF, 0xE5, 0x91};
int seg_commons[] = {PIN_C0, PIN_C1, PIN_C2, PIN_C3, PIN_D0, PIN_D1, PIN_D2, PIN_D3, PIN_C4};
unsigned char allDigits[] = {11, 2, 3, 11, 5, 6, 12, 8, 9};
//====================================================================
// ISRs
//====================================================================
volatile boolean new_data_received = FALSE;
volatile char received_data;
#INT_TIMER0
void timer0_isr(void)
{
static int8 ms_counter=0,cur_segment=0;
if(cur_segment==0)output_high(seg_commons[NUM_DIGITS-1]);
else output_high(seg_commons[cur_segment-1]);
OUT_SEG_CODE(seg_codes[allDigits[cur_segment]]);
output_low(seg_commons[cur_segment]);
cur_segment++;
if(cur_segment>NUM_DIGITS)cur_segment=0;
clear_interrupt(INT_TIMER0);
set_timer0(999);
}
#INT_RDA
void uart1_isr() {
received_data = getc();
new_data_received = TRUE;
}
char i =0,count=0;
void main(){
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_8); // Prescaler of 8
set_timer0(999); // Set Timer0 reload value to 999 for 500 µs interval
clear_interrupt(INT_TIMER0);
enable_interrupts(INT_TIMER0);
enable_interrupts(INT_RDA);
enable_interrupts(GLOBAL);
putc(13); // Go to first column
printf("Hello world!");
while(TRUE){
int8 c =0;
if(!input(SW_SET)){
doSettings();
loadSettingState(0);do{delay_ms(10);}while(!input(SW_SET));
}
if (new_data_received) {
// Process the received data here
i = received_data;
putc(i);
if (i == '[') {
count = 0;
} else {
if (i == 'H') i = 12 + 48;
if (i == 'c') i = 11 + 48;
allDigits[count] = i - 48;
count++;
}
new_data_received = FALSE; // Clear the flag after processing
}
}
}
Code language: C++ (cpp)