• AVR Freaks

Helpful ReplyHot!UART Read problem from a TFT screen by usig PIC16F877A microcontroller

Page: 12 > Showing page 1 of 2
Author
Ayman Morsy
New Member
  • Total Posts : 22
  • Reward points : 0
  • Joined: 2020/02/12 14:35:33
  • Location: 0
  • Status: offline
2020/07/27 13:23:13 (permalink)
0

UART Read problem from a TFT screen by usig PIC16F877A microcontroller

I hope you are well. I am using a TFT screen that communicates through UART. this screen sends and receives data by a known sequence in its datasheet. I used PIC16F877A to make an ISR function that reads data from it by adding each byte in an array, then the required byte is used for doing its function. the code did not run as expected. the first problem is that the code runs properly after pressing reset button. the second problem when I try to make bit shifting to add bytes together, I discover that the previous number is printed (i.e. if i write 125, 85 appears in the screen, which was the previous written number).
The third problem is that the UART ISR stops everything else just after it starts running. Are there any solutions for these bugs?
I am just A beginner in programming, so finding a solution by myself is a problem for me. I appropriate any help that could be offered. 
 
int n = 0, flag =0;
const int i = 12;
unsigned char* Read[i];
unsigned short up=0, down=0;
unsigned int max_value = 0;
//Timer 1 and UART ISR interrupt
   void interrupt() {
   char buffer;
   unsigned char test;
    if(PIR1.RCIF == 1){
    buffer = RCREG;
        Read[n] = buffer;
        n++;
         test = Read[0];
          if (test == 0xAA){
          flag = 1;
          }
        PIR1.RCIF = 0;
            }
 if (TMR1IF_bit) { // If bit TMR1IF = 1
      cnt++;
      TMR1IF_bit = 0;
      TMR1H = 0x3C;
      TMR1L = 0xB0; // reset register TMR1
               }
         }


void main() {
  TRISB.B2=0; //PortB2 is output
  PORTB.B2=0; //initial state is zero
  TRISC = 0x68;
  timer1init(); //timer 1 function
  UART1_Init(9600); //Uart baud at 115200
  Delay_ms(500); // Wait for UART module to stabilize
  SPI1_Init();
  PIE1.RCIE=1; //enable receive interrupt
  INTCON.PEIE = 1;
  INTCON.GIE = 1;


  
  while(1){ // Endless loop

//UART Read value
      if (flag ==1){
      up = Read[7];
      down = Read[8];
      max_value = ((down << 8)| up);
      HMT_WriteVPN16(0x080000, max_value);

      PORTB.B2 = 1;
      delay_ms(500);
      PORTB.B2 = 0;
      delay_ms(500);
      flag = 0;
      n = 0;
      }
}
}

#1
ric
Super Member
  • Total Posts : 28299
  • Reward points : 0
  • Joined: 2003/11/07 12:41:26
  • Location: Australia, Melbourne
  • Status: online
Re: UART Read problem from a TFT screen by usig PIC16F877A microcontroller 2020/07/27 13:30:22 (permalink)
+2 (2)
#1 mistake. That code does NOT contain an interrupt service.
Just naming a function "interrupt" doesn't make it an ISR.
How to declare an ISR depends upon which version of XC8 you are using (v1.xx? v2.xx?),
and if it is 2.xx, which mode it is in (C90?, C99?)
 
Once you have that sorted, if your interrupt code changes a value that you want to read in non-interrupt code, then you MUST add a "voilatile" qualifier when you define the variable.
(I'm particularly looking at your "flag" variable.)
Lastly, don't use "int" for variables that will fit into 8 bits. This is an 8 bit processor, it has to do a lot of extra work to handle 16 bit variables, which is pointless for most of your variables.
 

I also post at: PicForum
Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
NEW USERS: Posting images, links and code - workaround for restrictions.
To get a useful answer, always state which PIC you are using!
#2
Ayman Morsy
New Member
  • Total Posts : 22
  • Reward points : 0
  • Joined: 2020/02/12 14:35:33
  • Location: 0
  • Status: offline
Re: UART Read problem from a TFT screen by usig PIC16F877A microcontroller 2020/07/27 14:35:30 (permalink)
0
Thanks ric for your quick reply. I missed to mention in my post that I use MikroC, and this is the name of ISR in the program. 
About the volatile qualifier, it is supposed to be some type of variable that is not stored in a register, right?
if it is as i say, Could you please give me some types of these variables?
you are absolutely right about the int variables, I will change them directly.
 
Many thanks for your advises for improving this code.  
#3
Ayman Morsy
New Member
  • Total Posts : 22
  • Reward points : 0
  • Joined: 2020/02/12 14:35:33
  • Location: 0
  • Status: offline
Re: UART Read problem from a TFT screen by usig PIC16F877A microcontroller 2020/07/27 14:40:16 (permalink)
0
another question if i do not disturb you. can (n) variable be volatile too?
 
#4
ric
Super Member
  • Total Posts : 28299
  • Reward points : 0
  • Joined: 2003/11/07 12:41:26
  • Location: Australia, Melbourne
  • Status: online
Re: UART Read problem from a TFT screen by usig PIC16F877A microcontroller 2020/07/27 15:00:49 (permalink)
+2 (2)
Ayman Morsy
Thanks ric for your quick reply. I missed to mention in my post that I use MikroC, and this is the name of ISR in the program.

Do mention that in future. If you don't, folks are going to assume you're using XC8.

About the volatile qualifier, it is supposed to be some type of variable that is not stored in a register, right?

Wrong.
It tells the compiler not to make assumptions about the variable holding its value.
When it can be changed by an interrupt, the value can change without the running code doing it.
Without volatile, any optimisation of the C code will see the "flag" variable is never changed by the running code, and just not bother reading it.
 

if it is as i say, Could you please give me some types of these variables?

Any variable can have a "volatile" qualifier added to it. This really is a very basic feature of the C language.
 
 

I also post at: PicForum
Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
NEW USERS: Posting images, links and code - workaround for restrictions.
To get a useful answer, always state which PIC you are using!
#5
Ayman Morsy
New Member
  • Total Posts : 22
  • Reward points : 0
  • Joined: 2020/02/12 14:35:33
  • Location: 0
  • Status: offline
Re: UART Read problem from a TFT screen by usig PIC16F877A microcontroller 2020/07/27 15:10:14 (permalink)
0
Great. I will try your advises and post the code if it works. Many thanks for your help and I am sorry for my mistakes.
#6
Ayman Morsy
New Member
  • Total Posts : 22
  • Reward points : 0
  • Joined: 2020/02/12 14:35:33
  • Location: 0
  • Status: offline
Re: UART Read problem from a TFT screen by usig PIC16F877A microcontroller 2020/07/28 13:38:39 (permalink)
0
Hi Ric, I have tried your advises in the code but the results are the same
#7
upand_at_them
Super Member
  • Total Posts : 634
  • Reward points : 0
  • Joined: 2005/05/16 07:02:38
  • Location: Pennsylvania
  • Status: online
Re: UART Read problem from a TFT screen by usig PIC16F877A microcontroller 2020/07/28 14:31:42 (permalink)
0
Post your new code.
#8
Ayman Morsy
New Member
  • Total Posts : 22
  • Reward points : 0
  • Joined: 2020/02/12 14:35:33
  • Location: 0
  • Status: offline
Re: UART Read problem from a TFT screen by usig PIC16F877A microcontroller 2020/07/28 14:36:58 (permalink)
0
 
 
volatile char flag = 0;
volatile char n = 0;
volatile const i = 12;
unsigned char* Read [i];
unsigned int max_value = 0;

 

//Timer 1 and UART ISR interrupt
void interrupt() {
char buffer;
if(PIR1.RCIF == 1){
buffer = RCREG;
if (n< i) {
Read[n++] = buffer;
}
if (n >= i){
n = 0;
flag = 1;
}
RCREG = 0;
RCIF_bit = 0;
}
if (TMR1IF_bit) { // If bit TMR1IF = 1
cnt++;
TMR1IF_bit = 0;
TMR1H = 0x3C;
TMR1L = 0xB0; // reset register TMR1
}
}

 

//main routine
void main() {
TRISB.B2=0; //PortB2 is output
PORTB.B2=0; //initial state is zero
TRISC = 0x68;
timer1init(); //timer 1 function
UART1_Init(9600); //Uart baud at 115200
Delay_ms(500); // Wait for UART module to stabilize
SPI1_Init();
PIE1.RCIE=1; //enable receive interrupt
INTCON.PEIE = 1;
INTCON.GIE = 1;



while(1){ // Endless loop

//UART Read value
if (flag ==1){
HMT_WriteVPN16(0x080000, Read[0]);
delay_ms(100);
HMT_WriteVPN16(0x080002, Read[1]);
delay_ms(100);
HMT_WriteVPN16(0x080004, Read[2]);
delay_ms(100);
HMT_WriteVPN16(0x080006, Read[3]);
delay_ms(100);
HMT_WriteVPN16(0x080008, Read[4]);
delay_ms(100);
HMT_WriteVPN16(0x08000A, Read[5]);
delay_ms(100);
HMT_WriteVPN16(0x08000C, Read[6]);
delay_ms(100);
HMT_WriteVPN16(0x08000E, Read[7]);
delay_ms(100);
HMT_WriteVPN16(0x080010, Read[8]);
delay_ms(100);
HMT_WriteVPN16(0x080012, Read[9]);
delay_ms(100);
HMT_WriteVPN16(0x080014, Read[10]);
delay_ms(100);
HMT_WriteVPN16(0x080016, Read[11]);
delay_ms(100);
PORTB.B2 = 1;
delay_ms(500);
PORTB.B2 = 0;
delay_ms(500);
flag = 0;
}

post edited by Ayman Morsy - 2020/07/28 14:38:31
#9
ric
Super Member
  • Total Posts : 28299
  • Reward points : 0
  • Joined: 2003/11/07 12:41:26
  • Location: Australia, Melbourne
  • Status: online
Re: UART Read problem from a TFT screen by usig PIC16F877A microcontroller 2020/07/28 14:56:53 (permalink)
+1 (1)
Not your problem, but get rid of these two lines
RCREG = 0;
RCIF_bit = 0;

In both cases you are trying to write to read only bits.
 
What baud rate are you actually trying to use?
UART1_Init(9600); //Uart baud at 115200

 
It's far easier to start by transmitting a known character (usually 0x55), and checking what comes out to see if you have the baud rate set correctly.
 
Does your screen send TTL serial, or RS232 voltages?
If it's RS232, you need inverting buffers on the TX and RX signals.
 
 

I also post at: PicForum
Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
NEW USERS: Posting images, links and code - workaround for restrictions.
To get a useful answer, always state which PIC you are using!
#10
Ayman Morsy
New Member
  • Total Posts : 22
  • Reward points : 0
  • Joined: 2020/02/12 14:35:33
  • Location: 0
  • Status: offline
Re: UART Read problem from a TFT screen by usig PIC16F877A microcontroller 2020/07/28 15:21:51 (permalink)
0
 
 
What baud rate are you actually trying to use?
 
UART1_Init(9600); //Uart baud at 115200


I am now using 9600 baud rate, 115200 baud results in empty bytes at start. the baud rate of both the microcontroller and the TFT are set equally, so no problem about it.
 
 Does your screen send TTL serial, or RS232 voltages?
If it's RS232, you need inverting buffers on the TX and RX signals.

 it is an RS232. But how can I invert the buffer?
 
There is also something I read about uart read, which is adding the received bytes in a circular buffer. However this is a bit hard for me as I still don't have this knowledge, but is this a preferred method in receiving bytes in uart?
and how can this be coded? 
post edited by Ayman Morsy - 2020/07/28 15:22:58
#11
ric
Super Member
  • Total Posts : 28299
  • Reward points : 0
  • Joined: 2003/11/07 12:41:26
  • Location: Australia, Melbourne
  • Status: online
Re: UART Read problem from a TFT screen by usig PIC16F877A microcontroller 2020/07/28 15:29:31 (permalink)
0
Ayman Morsy
 it is an RS232. But how can I invert the buffer?

Are you sure?
RS232 idles at a negative voltage, somewhere between -3V and -9V, and pulses to between +3V and +9V when sending a "0" bit.
TTL idles at 5V, and switches down to ground when sending a "0".
If it is really RS232, then you MUST NOT connect it directly to your PIC. You need an RS232 buffer, something like a MAX232 chip.
 
[quoute]
There is also something I read about uart read, which is adding the received bytes in a circular buffer. However this is a bit hard for me as I still don't have this knowledge, but is this a preferred method in receiving bytes in uart?
and how can this be coded?

Yes, that is the standard way to handle it. You need to create an array to hold the received data, and "read" and "write" pointers to record where in the array you are writing to and reading from.
In the interrupt service, you just add the received character to the buffer, and you do all your logic interpreting the read data in non interrupt code, reading from the buffer as required.
However, that is just one way to do it, and not your immediate problem.
Do you have an oscilloscope to watch the signals?
 

I also post at: PicForum
Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
NEW USERS: Posting images, links and code - workaround for restrictions.
To get a useful answer, always state which PIC you are using!
#12
Ayman Morsy
New Member
  • Total Posts : 22
  • Reward points : 0
  • Joined: 2020/02/12 14:35:33
  • Location: 0
  • Status: offline
Re: UART Read problem from a TFT screen by usig PIC16F877A microcontroller 2020/07/28 15:36:29 (permalink)
0
ric
Are you sure?
 
RS232 idles at a negative voltage, somewhere between -3V and -9V, and pulses to between +3V and +9V when sending a "0" bit.
 
TTL idles at 5V, and switches down to ground when sending a "0".
 
If it is really RS232, then you MUST NOT connect it directly to your PIC. You need an RS232 buffer, something like a MAX232 chip.

  Oh, this was the first step that I have done to interface the TFT with the MCU, so no problem about this. I though that the buffer was inverted in the software. 
 
 
Do you have an oscilloscope to watch the signals?

you mean the logic analyzer? I have one, but I am not very professional at using it.
 





post edited by Ayman Morsy - 2020/07/28 15:39:29
#13
ric
Super Member
  • Total Posts : 28299
  • Reward points : 0
  • Joined: 2003/11/07 12:41:26
  • Location: Australia, Melbourne
  • Status: online
Re: UART Read problem from a TFT screen by usig PIC16F877A microcontroller 2020/07/28 15:45:48 (permalink)
0
Ayman Morsy
Oh, this was the first step that I have done to interface the TFT with the MCU, so no problem about this. I though that the buffer was inverted in the software.

So you DO have an RS232 buffer connected?
It's hard to know what you are doing when you don't mention crucial details like this.
You mention you are a beginner, so I don't know what I can assume you have done correctly.
Have you connected the ground as well?
A schematic or photo of what you are doing would help.
 
 


Do you have an oscilloscope to watch the signals?

you mean the logic analyzer? I have one, but I am not very professional at using it.


An oscilloscope is better, as it shows the actual voltages.
A logic analyser connected to Tx and Rx would at least let you check if the baud rate is correct.
 
post edited by ric - 2020/07/28 15:46:49

I also post at: PicForum
Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
NEW USERS: Posting images, links and code - workaround for restrictions.
To get a useful answer, always state which PIC you are using!
#14
Ayman Morsy
New Member
  • Total Posts : 22
  • Reward points : 0
  • Joined: 2020/02/12 14:35:33
  • Location: 0
  • Status: offline
Re: UART Read problem from a TFT screen by usig PIC16F877A microcontroller 2020/07/28 16:17:11 (permalink)
0
Trust me I am a beginner mr green: mr green. I am now learning many things that I didn't learn when I started programming by Arduino.
Anyway, This is the connection that I have used. I am sorry that I could not upload the real connections. the photo size is too large
 
 
 
 

#15
Ayman Morsy
New Member
  • Total Posts : 22
  • Reward points : 0
  • Joined: 2020/02/12 14:35:33
  • Location: 0
  • Status: offline
Re: UART Read problem from a TFT screen by usig PIC16F877A microcontroller 2020/07/28 16:20:31 (permalink)
0
sorry about mr green. It is attached with the the smile face 
#16
ric
Super Member
  • Total Posts : 28299
  • Reward points : 0
  • Joined: 2003/11/07 12:41:26
  • Location: Australia, Melbourne
  • Status: online
Re: UART Read problem from a TFT screen by usig PIC16F877A microcontroller 2020/07/28 16:24:35 (permalink)
+1 (1)
Your connections look ok.
The secret to efficient debugging is to minimise the number of unknown factors. i.e. only test one thing at a time, assuming that everything else does not work yet.
In this case, throw away most of the code, don't use interrupts, and just get your PIC to transmit character 0x55 ("U") once per second, and confirm that the PC receives it.
Once that works, get the PIC to echo back any characters it receives. Again, that can all be done without interrupts.
 

I also post at: PicForum
Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
NEW USERS: Posting images, links and code - workaround for restrictions.
To get a useful answer, always state which PIC you are using!
#17
Ayman Morsy
New Member
  • Total Posts : 22
  • Reward points : 0
  • Joined: 2020/02/12 14:35:33
  • Location: 0
  • Status: offline
Re: UART Read problem from a TFT screen by usig PIC16F877A microcontroller 2020/07/28 16:35:27 (permalink)
0
Good Idea I will try it directly and send my results. 
by the way, this is the link of the datasheet of the screen 
https://www.topwaydisplay.com/sites/default/files/2020-02/HMT050ATA-2C.pdf 
#18
LdB_ECM
Super Member
  • Total Posts : 434
  • Reward points : 0
  • Joined: 2019/04/16 22:01:25
  • Location: 0
  • Status: offline
Re: UART Read problem from a TFT screen by usig PIC16F877A microcontroller 2020/07/28 20:28:39 (permalink)
+1 (1)
I would guess you have a very basic problem, consider what happens when you receive the 12th byte.
You set flag = 1 which is for the normal loop to pickup
However process in the loop when flag = 1 has a huge number of 100ms delays
 
So my question to you is what happens when it receives an interrupt (and it will) while doing those delays???
Hint: walk thru thru the interrupt code with n == 0 and flag = 1. Really the interrupt could catch n at any 0..11 value. 
 
AFAIK you need to make a choice from
1.) Clear the buffer a hell of a lot faster
2.) disable the interrupt while flag = 1
3.) handshake the screen off so it doesn't keep sending characters.
post edited by LdB_ECM - 2020/07/28 20:39:56
#19
Ayman Morsy
New Member
  • Total Posts : 22
  • Reward points : 0
  • Joined: 2020/02/12 14:35:33
  • Location: 0
  • Status: offline
Re: UART Read problem from a TFT screen by usig PIC16F877A microcontroller 2020/07/29 04:14:14 (permalink)
0
LdB_ECM
I would guess you have a very basic problem, consider what happens when you receive the 12th byte.
You set flag = 1 which is for the normal loop to pickup
However process in the loop when flag = 1 has a huge number of 100ms delays
 
So my question to you is what happens when it receives an interrupt (and it will) while doing those delays???
Hint: walk thru thru the interrupt code with n == 0 and flag = 1. Really the interrupt could catch n at any 0..11 value. 
 
AFAIK you need to make a choice from
1.) Clear the buffer a hell of a lot faster
2.) disable the interrupt while flag = 1
3.) handshake the screen off so it doesn't keep sending characters.


About the 100 ms delays, I added them at first because I thought that the transmission required stabilization, but I found lately that they are a load to the MCU and they are of no use, so I removed them. 
But still the problem are in the field without any change. 
 
I tried to disable the interrupt by PIR1.RCIF = 0, at flag = 1, but still the UART interrupt locks everything up.
 
About the Handshake, I didn't try out this out. but to do it, I think that I should transmit the handshake address to the screen, Right?
this is the last code

 
 
 
volatile char flag = 0;
volatile char n = 0;
volatile const i = 12;
unsigned char* Read[i];
unsigned int max_value = 0;
 
 
 
 
 
 
 
//Timer 1 and UART ISR interrupt
void interrupt() {
char buffer;
if(PIR1.RCIF == 1){
buffer = RCREG;
if (n< i) {
Read[n++] = buffer;
}
if (n >= i){
n = 0;
flag = 1;
}
}
if (TMR1IF_bit) { // If bit TMR1IF = 1
cnt++;
TMR1IF_bit = 0;
TMR1H = 0x3C;
TMR1L = 0xB0; // reset register TMR1
}
}
 
 
 
 
 
 
 
 
 
 
 
//main routine
void main() {
TRISB.B2=0; //PortB2 is output
PORTB.B2=0; //initial state is zero
TRISC = 0x68;
timer1init(); //timer 1 function
UART1_Init(9600); //Uart baud at 115200
Delay_ms(500); // Wait for UART module to stabilize
SPI1_Init();
PIE1.RCIE=1; //enable receive interrupt
INTCON.PEIE = 1;
INTCON.GIE = 1;
 
 
 

while(1){ // Endless loop
//UART Read value
if (flag ==1){
 
HMT_WriteVPN16(0x080000, Read[0]);
HMT_WriteVPN16(0x080002, Read[1]);
HMT_WriteVPN16(0x080004, Read[2]);
HMT_WriteVPN16(0x080006, Read[3]);
HMT_WriteVPN16(0x080008, Read[4]);
HMT_WriteVPN16(0x08000A, Read[5]);
HMT_WriteVPN16(0x08000C, Read[6]);
HMT_WriteVPN16(0x08000E, Read[7]);
HMT_WriteVPN16(0x080010, Read[8]);
HMT_WriteVPN16(0x080012, Read[9]);
HMT_WriteVPN16(0x080014, Read[10]);
HMT_WriteVPN16(0x080016, Read[11]);
 
 
 
PORTB.B2 = 1;
delay_ms(500);
PORTB.B2 = 0;
delay_ms(500);
flag = 0;
 
 
 
}
 
 
 
 
post edited by Ayman Morsy - 2020/07/29 04:25:43
#20
Page: 12 > Showing page 1 of 2
Jump to:
© 2020 APG vNext Commercial Version 4.5