CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

Problem with RS232 Communication

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
_olaf_



Joined: 24 Feb 2005
Posts: 32

View user's profile Send private message

Problem with RS232 Communication
PostPosted: Wed Jun 25, 2008 1:53 am     Reply with quote

Hello,

I have a problem with the RS232 communication in my program. I searched in the forum for similar problems, but anything I found was the same code as I use.

Code of timer_01.h
Code:

#use delay(clock=4000000)
#define LCD_DB4   PIN_A4
#define LCD_DB5   PIN_A5
#define LCD_DB6   PIN_C0
#define LCD_DB7   PIN_C1

#define LCD_E     PIN_B0
#define LCD_RS    PIN_B1
#define LCD_RW    PIN_B2

#define Tast_1   52
#define Tast_2   53
#define Tast_3   54
#define Tast_4   55
#define DB6   56
#define DB7   57
#define Beleuchtung   58
#define /Bel_an   59

#define Ausgang   60
#define RS232_XMIT   62
#define RS232_RCV   63
#use rs232(baud=19200,parity=N,xmit=RS232_XMIT,rcv=RS232_RCV)


C-Code of the program
Code:

#include <16f873.h>
#include "C:\timer_01.h"
#include <stdio.h>
#include <string.h>
#include "Flex_LCD420.c"

void PIC_Initialisierung(void);

#fuses HS,NOWDT,NOBROWNOUT,NOPROTECT
#reserve 0x00A0
#reserve 0x00B0:0x00B3
#reserve 0x00C0:0x00C3

char ISR_Flags=0x00;      // Flags für die Interruptroutinen
#Locate ISR_Flags = 0x00A0 //
#bit INTF_START = ISR_FLAGS.0
#bit INTF_RB = ISR_FLAGS.1
#bit INTF_DATOK = ISR_FLAGS.2
#bit INTF_Light = ISR_FLAGS.3
#bit INTF_TMREND = ISR_FLAGS.4

char RB_Taste=0x00;
#locate RB_Taste = 0x0A1
#bit Taste1=RB_Taste.0
#bit Taste2=RB_Taste.1
#bit Taste3=RB_Taste.2
#bit Taste4=RB_Taste.3

struct
{
   unsigned Zeiteinstellung:1; // 1 Bit für die Initialisierungsanforderung
   unsigned Konfiguration:1; // 1 Bit für die Manchester_Dekodierung
} Menu_Punkt;


unsigned int Timer2_Zaehlvariable=0x0000;
unsigned int Zehntel_Zaehler=0x0000;
unsigned int Sec_Zaehler=0x0000;
unsigned int Min_Zaehler=0x0000;
unsigned int STD_Zaehler=0x0000;
unsigned int Zehntelsekunde=0x0000;
unsigned int Sekunden=0x0000;
unsigned int Minuten=0x0000;
unsigned int Stunden=0x0000;

static int8 old_PortB;
#define first_bit(x) (x&0x1)
#define second_bit(x) (x&0x2)
#define third_bit(x) (x&0x4)
#define fourth_bit(x) (x&0x8)

#Locate Zehntel_Zaehler = 0x00B0
#Locate Sec_Zaehler = 0x00B1
#Locate Min_Zaehler = 0x00B2
#Locate STD_Zaehler = 0x00B3
#Locate Zehntel_Sekunde = 0x00C0
#Locate Sekunden = 0x00C1
#Locate Minuten = 0x00C2
#Locate Stunden = 0x00C3

void PIC_Initialisierung(void)
{
   int i=0;
     setup_adc_ports(NO_ANALOGS);
      setup_adc(ADC_CLOCK_DIV_2);
      setup_spi(FALSE);
      setup_counters(RTCC_INTERNAL,RTCC_DIV_64);
      setup_timer_1(T1_DISABLED);
      setup_timer_2(T2_DIV_BY_1,124,8);
      setup_ccp2(CCP_OFF);
      enable_interrupts(INT_RB);
     enable_interrupts(INT_RDA);
   lcd_init();
   lcd_putc("\Timer V1.0\n");
   lcd_putc("Taster   gedrueckt ");
   lcd_gotoxy(1,3);
   lcd_putc("Std.");
   lcd_gotoxy(6,3);
   lcd_putc("Min.");   
   lcd_gotoxy(11,3);
   lcd_putc("Sek.");   
   lcd_gotoxy(16,3);
   lcd_putc("1/10");   
   Menu_Punkt.Konfiguration=1;
    enable_interrupts(INT_TIMER2);
      enable_interrupts(global);
}   

#int_RB
RB_isr() {
   int new_PortB;
    int changes;
    new_PortB=input_b();
    INTF_RB=1;
    changes=new_PortB^old_PortB;
    changes=changes&new_PortB;
    changes=changes>>4;
    old_PortB=new_PortB; 

    if (first_bit(changes))
   {
        Taste1=1;
         lcd_gotoxy(8,2);
      lcd_putc("1");
       printf("Taste 1 gedrückt\n");

    }
    if (second_bit(changes))
   {
      Taste2=1;
         lcd_gotoxy(8,2);
      lcd_putc("2");
      printf("Taste 2 gedrückt\n");
    }
    if (third_bit(changes))
   {
      Taste3=1;
      lcd_gotoxy(8,2);
      lcd_putc("3");
      printf("Taste 3 gedrückt\n");
    }
    if (fourth_bit(changes))
   {
      Taste4=1;
      lcd_gotoxy(8,2);
      lcd_putc("4");
      printf("Taste 4 gedrückt\n");
    }
    return 0;
}

#int_TIMER2
TIMER2_isr() {
   Timer2_Zaehlvariable++;
   if (Timer2_Zaehlvariable==100)
   {
      Timer2_Zaehlvariable=0;
      Zehntel_Sekunde++;
      lcd_gotoxy(16,4);
      printf(lcd_putc,"%2d",Zehntel_Sekunde);
   }
   if (Zehntel_Sekunde==10)
   {
      Sekunden++;
      Zehntel_Sekunde=0;
      lcd_gotoxy(16,4);
      printf(lcd_putc,"%2d",Zehntel_Sekunde);
      lcd_gotoxy(11,4);
      printf(lcd_putc,"%2d",Sekunden);
   }
   if (Sekunden==60)
   {
      Minuten++;
      Sekunden=0;
      lcd_gotoxy(11,4);
      printf(lcd_putc,"%2d",Sekunden);
      lcd_gotoxy(6,4);
      printf(lcd_putc,"%2d",Minuten);
   }
   if (Minuten==60)
   {
      Minuten=0;
      Stunden++;
      lcd_gotoxy(6,4);
      printf(lcd_putc,"%2d",Minuten);
      lcd_gotoxy(1,4);
      printf(lcd_putc,"%2d",Stunden);
   }
   return 0;
}

void main()
{
   char i;
   int I_RB_Count=0;
   old_PortB=input_b();
   switch ( restart_cause() )
      {
         case WDT_FROM_SLEEP:    {
                              lcd_putc("\fFehlerfall\n");
   
                           }
         case WDT_TIMEOUT:      {
                           }
         case NORMAL_POWER_UP:    {
                                 PIC_Initialisierung();
                           }
      }
}




   delay_ms(100);
   SET_TRIS_A(0x00);
   SET_TRIS_B(0xf0);
   SET_TRIS_C(0x40);
   i=0;
    Menu_Punkt.Konfiguration=0;
    while(1);
}


Everything in the program works fine except the RS232 communication. I don't get any character on the PC. The only character I get is "<0>". What could be the problem? I tried it with Timer2 disabled and Baudrates down to 2400 baud. But this wasn't successful. I have checked the hardware but it should work.
Any other idea?

Best regards

Olaf
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Jun 25, 2008 11:19 am     Reply with quote

Quote:

setup_timer_2(T2_DIV_BY_1,124,8);
setup_ccp2(CCP_OFF);
enable_interrupts(INT_RB);
enable_interrupts(INT_RDA);

You are enabling RDA interrupts, but you don't have an #int_rda function.
This is very bad. Delete the line shown in bold.


Quote:
#define Tast_1 52
#define Tast_2 53
#define Tast_3 54
#define Tast_4 55
#define DB6 56
#define DB7 57
#define Beleuchtung 58
#define /Bel_an 59

#define Ausgang 60
#define RS232_XMIT 62
#define RS232_RCV 63

Here you have tons of magic numbers. This is a bad programming technique. It makes the program difficult to understand and to maintain.
Use the CCS pin numbers from the 16F873.h file. Example:
Code:
#define Tast_1  PIN_B4
#define Tast_2  PIN_B5
#define Tast_3  PIN_B6
#define Tast_4  PIN_B7
#define DB6     PIN_C0
etc.

With this method, it's very clear which pins are used by your program.
Here is an explanation of magic numbers:
http://c2.com/cgi/wiki?MagicNumber


Quote:
#Locate ISR_Flags = 0x00A0 //

char RB_Taste=0x00;
#locate RB_Taste = 0x0A1
#bit Taste1=RB_Taste.0
#bit Taste2=RB_Taste.1
#bit Taste3=RB_Taste.2
#bit Taste4=RB_Taste.3

#reserve 0x00A0
#reserve 0x00B0:0x00B3
#reserve 0x00C0:0x00C3

All of this "locate" and "reserve" stuff is unnecessary with CCS.
The CCS compiler will automatically put your variables in a suitable
location. You don't have to worry about it.


Quote:
#fuses HS,NOWDT,NOBROWNOUT,NOPROTECT

You need to add the NOLVP fuse to the list. If you don't have it,
the PIC can lock-up if pin B3 goes to a high level. In recent versions
of the CCS compiler, CCS automatically sets NOLVP even if you don't
specify it. But you didn't give your compiler version so I'm telling
you about the need for NOLVP, in case you have an older version.


Quote:
SET_TRIS_A(0x00);
SET_TRIS_B(0xf0);
SET_TRIS_C(0x40);

You are not using #fast_io() on any of those ports, so the compiler will
override those TRIS statements as needed. But you don't need to set
the tris, because the CCS compiler automatically sets the TRIS for you
if you use CCS pin i/o functions or CCS library functions. You can
delete the 3 lines shown above.


Quote:
#int_RB
RB_isr() {


return 0;
}

Interrupt service routines don't return anything. Delete the line shown in bold.



Quote:
unsigned int Timer2_Zaehlvariable=0x0000;
unsigned int Zehntel_Zaehler=0x0000;
unsigned int Sec_Zaehler=0x0000;
etc.

In CCS, an "unsigned int" is an 8-bit unsigned variable. Your code
implies that it is 16-bits, when you initialize it to 0x0000. If you want
16-bit unsigned variables, then declare them as "int16".


Finally, if you have an RS-232 problem, then first make a small test
program that only tests the RS-232 connection to the PC. Don't test
anything else in that program. See the 2nd post in the following link
for an example:
http://www.ccsinfo.com/forum/viewtopic.php?t=34127&highlight=putc+getc
_olaf_



Joined: 24 Feb 2005
Posts: 32

View user's profile Send private message

PostPosted: Wed Jun 25, 2008 12:18 pm     Reply with quote

I have forgotten to handle the RDA interrupts so I don't enable them, o.k.
The defining of the different ports was not fully done. As you see, some of them are defined with the names in the PIC-headerfiles. But at the beginning it is easier for me, to see what register address is used. Rolling Eyes

I know, that (nearly) every compiler can locate variables on his own. But I wanted these addresses and therefore I specified them. Neutral

The NOLVP fuse was set by the compiler (Version 3.223) so I didn't had it in the #fuse declaration.

That the Tris statement is not needed is new to me (and I did not see similar with other compilers, most need the "Tris" statement e.g. GCC for Atmel controller). And in many posts it is used. But what does the compiler do if he does not have the Tris statement. Is then the Tris register set and reset every time when I change the direction of the data I/O? Question

The "return 0;" I inserted, because without this I get the warning:
Function not void and does not return a value

With the returnvalue I don't get the warning Surprised

I had in mind that an int was 16bit. And as I have learned in the last few minutes, it can be nearly everything from 8bit to 32bit depending on what kind of compiler/software you use Smile

So I will now try a small simple program and test it. I thought, that I write my program in steps and ad every day a new part (yesterday it was the RS232-day Confused ).

Olaf
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Jun 25, 2008 12:40 pm     Reply with quote

Quote:
The NOLVP fuse was set by the compiler (Version 3.223) so I didn't had it in the #fuse declaration.

That's not true. Here is your #fuses statement:
Code:
#fuses HS,NOWDT,NOBROWNOUT,NOPROTECT


I compiled your program with vs. 3.223, and with that #fuses statement,
the .LST file shows these settings at the end of the file:
Quote:
Configuration Fuses:
Word 1: 3FBA HS NOWDT NOPUT NOPROTECT NOBROWNOUT LVP NOCPD NOWRT NODEBUG


To fix this, you must add the NOLVP fuse as shown in bold below:
Quote:
#fuses HS,NOWDT,NOBROWNOUT,NOPROTECT, NOLVP



Quote:
But what does the compiler do if he does not have the Tris statement.
Is then the Tris register set and reset every time when I change the direction of the data I/O?

Yes, it sets the TRIS everytime you use output_low() or output_high(),
or output_b(), or any other pin i/o function.


Quote:
The "return 0;" I inserted, because without this I get the warning:
Function not void and does not return a value

The correct way to get rid of the warning is to declare the function to
return 'void' as shown in bold below:
Quote:
#int_RB
void RB_isr() {
_olaf_



Joined: 24 Feb 2005
Posts: 32

View user's profile Send private message

PostPosted: Wed Jun 25, 2008 1:17 pm     Reply with quote

Quote:

Quote:
The NOLVP fuse was set by the compiler (Version 3.223) so I didn't had it in the #fuse declaration.


That's not true. Here is your #fuses statement: Code:
#fuses HS,NOWDT,NOBROWNOUT,NOPROTECT



I compiled your program with vs. 3.223, and with that #fuses statement,
the .LST file shows these settings at the end of the file: Quote:
Configuration Fuses:
Word 1: 3FBA HS NOWDT NOPUT NOPROTECT NOBROWNOUT LVP NOCPD NOWRT NODEBUG


Then we have a problem. If I compile the code without "NOLVP" and look at the Configuration Bits in MPLab, the LVP is disabled.

And the option for the configuration-bits window is set to "Configuration Bits set in code" in the MPlab (8.02) configuration bits window. Every change I make in the code e.g. change from HS to XT or change the Brownout-fuse is changed in the configuration bit window except the change of the NOLVP. This is unchanged. It still says "Low Voltage program" disabled Exclamation

Olaf
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Jun 25, 2008 4:47 pm     Reply with quote

I don't have MPLAB 8.02. I have 8.10 on another computer. I installed
PCM vs. 3.249 on that computer and compiled a test program without
the NOLVP fuse. The Configuration Bits menu in MPLAB shows:
Code:

Low Voltage Program   Enabled

That is correct.

This option is also enabled:
Code:
 [x]  Configuration bits set in code


I don't have a problem. I don't know what is causing your problem.
Maybe re-install everything or upgrade MPLAB. Or ask a question
about it on the MPLAB forum.
Ttelmah
Guest







PostPosted: Thu Jun 26, 2008 2:41 am     Reply with quote

Is it possible that some form of ICD is being used?.
I have seen MPLAB ignore the LVP fuse, when some types of ICE/ICD are being used.
It can be quite annoying, since if you forget to set the fuse the way it is needed, code that runs in the development environment, then doesn't work on the real chip...

Best Wishes
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group