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 CCS Technical Support

UART Problem
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
TargetBusy



Joined: 07 Jan 2012
Posts: 6

View user's profile Send private message

UART Problem
PostPosted: Sat Jan 21, 2012 2:52 pm     Reply with quote

My first post and is a problem... oh well.

I'm new to CCS, not to microcontrollers.
But I've found a brick wall trying to figure out what is wrong here.

Just trying to make the PIC12F1840 with the UART library is impossible.
The same Header of the 12F1840.h declares:


Code:

////////////////////////////////////////////////////////////////// UART
// Constants used in setup_uart() are:
// FALSE - Turn UART off
// TRUE  - Turn UART on
#define UART_ADDRESS           2
#define UART_DATA              4
///////////////////////////////////


and trying to compile :
setup_uart(TRUE); /// gave me the error:

*** Error 12 "1840_EUSART.c" Line 19[12,13]: Undefined identifier --setup_uart

Commenting out there is no error, but the code just doesn't works.
Code:

#include <12F1840.h>
#device adc=16

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES INTRC_IO                 //Internal RC Osc, no CLKOUT
#FUSES NOMCLR                   //Master Clear pin used for I/O
#FUSES NOBROWNOUT               //No brownout reset

#use delay(int=8000000)

#use rs232(baud=9600,xmit=PIN_A0,rcv=PIN_A1)
#define LED PIN_A4
#define DELAY 60


void main()
{

 //setup_uart(TRUE);

   while(true)
   {
      output_low(LED);
      delay_ms(DELAY);
      output_high(LED);
      delay_ms(DELAY);

      printf("This is a test \n\r  ");
           
   }

}


I had no problems with PIC12F675 of PIC12F683, I just don't understand why the PIC12F1840 doesn't works.

By the way I am lifting UART with PICKIT 2, but I've been testing with oscilloscope and nothing happens.

What I am doing wrong?
(I'm done Editing this post Smile )
Ttelmah



Joined: 11 Mar 2010
Posts: 19504

View user's profile Send private message

PostPosted: Sat Jan 21, 2012 3:49 pm     Reply with quote

First try defining the pins for the UART using the #pin select function.
Then, in the #use RS232 use 'UART1', rather than the pin numbers. This way the code is generated to talk to the hardware UART.
This should setup the pin mapping, and then generate the code to talk to the UART.
Make sure you turn off the ADC on these pins - the ADC overrides the UART.

However haven't tested with the 1840 (have done with some of it's earlier cousins). The 1840, is very new. CCS quite commonly has problems with getting the settings right for the first few versions with a new chip. If it doesn't work, leave the #use RS232 talking to UART1, and manually add your own settings for the APFCON register, with code like:
Code:

#byte APFCON=getenv(SFR:APFCON)

//Then in your initialisation code
bit_clear(APFCON,7);
bit_clear(APFCON,2);

//And again make sure you turn off the ADC on these pins.


Best Wishes
TargetBusy



Joined: 07 Jan 2012
Posts: 6

View user's profile Send private message

PostPosted: Sat Jan 21, 2012 5:31 pm     Reply with quote

Thank you Ttelmah,
Worth the effort but I'm in square zero again. It didn't work.

The fact that this PIC has its own EUSART module is the clue that this feature works in a different way than using UART defines.

Is hard to debug something when there is no examples codes around. I guess that I jumped to this PIC too early and I'm not that good on assembly anyway.

I only hope to find something around or at least that someone will post a working code on this thread some day.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sat Jan 21, 2012 7:29 pm     Reply with quote

Post your compiler version, because as Ttelmah said, there may be
problems in your version. The version is a 4 digit number, like 4.128, etc,
and it's given at the top of the .LST file, which will be in your project
directory after a successful compilation.
TargetBusy



Joined: 07 Jan 2012
Posts: 6

View user's profile Send private message

PostPosted: Sat Jan 21, 2012 11:44 pm     Reply with quote

PCM programmer wrote:
Post your compiler version, because as Ttelmah said, there may be
problems in your version. The version is a 4 digit number, like 4.128, etc,
and it's given at the top of the .LST file, which will be in your project
directory after a successful compilation.


This is it. Not sure if the last try, but at least covers the version debug.
Code:

CCS PCM C Compiler, Version 4.128, xxxxx          21-Jan-12 21:33

               Filename: C:\Projects\PCW\1840-UART\1840-UART.lst

               ROM used: 186 words (5%)
                         Largest free fragment is 2048
               RAM used: 5 (2%) at main() level
                         25 (10%) worst case
               Stack:    2 locations

*
0000:  MOVLP  00
0001:  GOTO   08F
0002:  NOP
.................... #include <12F1840.h>
.................... //////// Standard Header file for the PIC12F1840 device ////////////////
.................... #device PIC12F1840
.................... #list
.................... 
.................... #device adc=16
.................... 
.................... #FUSES NOWDT                    //No Watch Dog Timer
.................... #FUSES INTRC_IO                 //Internal RC Osc, no CLKOUT
.................... #FUSES WDT_SW                   //No Watch Dog Timer, enabled in Software
.................... #FUSES NOMCLR                   //Master Clear pin used for I/O
.................... #FUSES NOBROWNOUT               //No brownout reset
.................... #FUSES NOIESO                   //Internal External Switch Over mode disabled
.................... #FUSES NOFCMEN                  //Fail-safe clock monitor disabled
.................... #FUSES NOSTVREN                 //Stack full/underflow will not cause reset
.................... #FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
.................... 
.................... 
.................... #use delay(int=8000000)
*
000D:  MOVLW  20
000E:  MOVWF  05
000F:  MOVLW  05
0010:  MOVWF  04
0011:  MOVF   00,W
0012:  BTFSC  03.2
0013:  GOTO   021
0014:  MOVLW  02
0015:  MOVWF  21
0016:  CLRF   20
0017:  DECFSZ 20,F
0018:  GOTO   017
0019:  DECFSZ 21,F
001A:  GOTO   016
001B:  MOVLW  97
001C:  MOVWF  20
001D:  DECFSZ 20,F
001E:  GOTO   01D
001F:  DECFSZ 00,F
0020:  GOTO   014
0021:  RETURN
.................... #use rs232(baud=9600,xmit=PIN_A1,rcv=PIN_A0,bits=8,stream=UART1)
0022:  MOVLB  01
0023:  BCF    0C.1
0024:  MOVLB  02
0025:  BCF    0C.1
0026:  MOVLW  08
0027:  MOVLB  00
0028:  MOVWF  21
0029:  GOTO   02A
002A:  NOP
002B:  BSF    21.7
002C:  GOTO   03F
002D:  BCF    21.7
002E:  RRF    29,F
002F:  MOVLB  02
0030:  BTFSC  03.0
0031:  BSF    0C.1
0032:  BTFSS  03.0
0033:  BCF    0C.1
0034:  MOVLB  00
0035:  BSF    21.6
0036:  GOTO   03F
0037:  BCF    21.6
0038:  DECFSZ 21,F
0039:  GOTO   02E
003A:  GOTO   03B
003B:  NOP
003C:  MOVLB  02
003D:  BSF    0C.1
003E:  MOVLB  00
003F:  MOVLW  3E
0040:  MOVWF  04
0041:  DECFSZ 04,F
0042:  GOTO   041
0043:  GOTO   044
0044:  BTFSC  21.7
0045:  GOTO   02D
0046:  BTFSC  21.6
0047:  GOTO   037
0048:  RETURN
.................... #define LED PIN_A4
.................... #define DELAY 200
.................... 
.................... 
.................... void main()
.................... {
*
008F:  CLRF   05
0090:  CLRF   04
0091:  MOVLW  1F
0092:  ANDWF  03,F
0093:  MOVLW  72
0094:  MOVLB  01
0095:  MOVWF  19
0096:  BCF    0C.1
0097:  MOVLB  02
0098:  BSF    0C.1
0099:  MOVLB  03
009A:  CLRF   0C
009B:  MOVLB  02
009C:  CLRF   12
009D:  CLRF   11
009E:  CLRF   14
009F:  CLRF   13
.................... 
.................... // setup_uart(TRUE); 
.................... // set_uart_speed(9600); 
.................... 
.................... 
....................    //Example blinking LED program
....................    while(true)
....................    { // while
....................       output_low(LED);
00A0:  MOVLB  01
00A1:  BCF    0C.4
00A2:  MOVLB  02
00A3:  BCF    0C.4
....................       delay_ms(DELAY);
00A4:  MOVLW  C8
00A5:  MOVLB  00
00A6:  MOVWF  25
00A7:  CALL   00D
....................       output_high(LED);
00A8:  MOVLB  01
00A9:  BCF    0C.4
00AA:  MOVLB  02
00AB:  BSF    0C.4
....................       delay_ms(DELAY);
00AC:  MOVLW  C8
00AD:  MOVLB  00
00AE:  MOVWF  25
00AF:  CALL   00D
.................... 
....................       printf("This is a test /n  ");
00B0:  MOVLW  03
00B1:  MOVLB  03
00B2:  MOVWF  11
00B3:  MOVLW  00
00B4:  MOVWF  12
00B5:  MOVLB  00
00B6:  GOTO   049
....................     } // elihw
00B7:  MOVLB  02
00B8:  GOTO   0A0
.................... 
.................... }
00B9:  SLEEP

Configuration Fuses:
   Word  1: 098C   INTRC_IO WDT_SW PUT NOMCLR NOPROTECT NOCPD NOBROWNOUT NOCLKOUT NOIESO NOFCMEN
   Word  2: 1CFF   NOWRT PLL_SW NOSTVREN BORV19 NODEBUG NOLVP

Ttelmah



Joined: 11 Mar 2010
Posts: 19504

View user's profile Send private message

PostPosted: Sun Jan 22, 2012 2:52 am     Reply with quote

Seriously, I don't see anywhere in the code you post, where you are trying what I suggested!....
I suspect you have misunderstood slightly, switching to a stream, rather than telling the compiler to use the UART.

The problem is that A0, and A1, are _not_ automatically the hardware UART pins.
Your #use RS232 needs to use:
Code:

#PIN_SELECT U1TX=PIN_A1
#PIN_SELECT U1RX=PIN_A0
#use rs232(baud=9600,UART1,bits=8,ERRORS)

This tells the compiler that A0, and A1, are to be selected for 'UART1', and the serial code that it is to talk to UART1.
Then if this fails set the APFCON bits manually.

Best Wishes
Douglas Kennedy



Joined: 07 Sep 2003
Posts: 755
Location: Florida

View user's profile Send private message AIM Address

PostPosted: Sun Jan 22, 2012 7:35 am     Reply with quote

Hopefully to help a bit.
A pic can have more than one hardware uart and then there are always software uarts. Stream is useful when there is more than one uart since it names each uart configuration and in conjuction with fprintf your output can be directed to the appropriate uart. Now UART1 ..UART2 identify the hardware uart. Sure you could specify the pins by why bother the compiler when it sees UART1 will use the hardware pins for that specific device. For the software uart you have to specify the pins to the compiler. Some PIC's allow for the hardware ports to be remapped. This is where pin select comes in....it allows you to choose another pin than the default pin for the uart.
Not all pins are remappable so check the PIC device spec sheet. The compiler will error the pin select if you choose a non remappable pin but it is still best to check the specs. Oh and notice how Ttelmah added ERRORS this is very useful ( it allows the uart to continue after an error occurs) since it can avoid head scratching if the uart hangs glitches.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Jan 22, 2012 4:45 pm     Reply with quote

I tested all four combinations of the Tx/Rx pins on the 12F1840, and
the compiler generated a software UART for all of them. I also tried
using "UART1" instead of specifying the pins. It still made a soft UART.
This is with vs. 4.128.

Work-around code can be done, but how important is it to you to use a
H/W UART on this PIC, right now ?
TargetBusy



Joined: 07 Jan 2012
Posts: 6

View user's profile Send private message

PostPosted: Sun Jan 22, 2012 6:08 pm     Reply with quote

PCM programmer wrote:
I tested all four combinations of the Tx/Rx pins on the 12F1840, and the compiler generated a software UART for all of them. I also tried using "UART1" instead of specifying the pins. It still made a soft UART.
This is with vs. 4.128.


It will be very helpful if you can share the simplest code to understand what I am doing wrong.

I've been trying all night without messing SFR's by hand, because again, I'm not good at assembler.

I had success on the other hand with mikroC PRO compiler, and they have a hardware library for EUSART and it works.
Looks like the software library is not compatible with the hardware library (that makes sense), but I don't see an alternative on CCS. This is the code after configuration if you guys are interested to see the difference:

Code:

// MikroC Pro Code:

void main(){

UART1_Init(9600);                         // initialize UART1 module
Delay_ms(100);

while (1) {

 UART1_Write_Text("Start");
 UART1_Write(10);

}

}


As you can see, there is no pin initialization since I'm using the default UART1 or UART2 option. I am not sure if MikroC Pro has the ability to remap the pins, but is working so far.

Quote:

Work-around code can be done, but how important is it to you to use a
H/W UART on this PIC, right now ?


Is not a big issue the use of hardware EUSART. The only reason why I'm choosing this chip is the XLP capabilities and pricing, but if is going to give me more problems I will probably go with the 12F683 instead.

I need "setup_uart(TRUE)" & "setup_uart(FALSE); " to be functional, or I might not be able to work on this chip.

Most of my code is done, I am just adopting this new chip (and new compiler at the same time). Rebuilding code for CCS was really easy and the main reason why I bought PCW after 5 hours of using the IDE. This is the only problem that I had with CCS so far, but I understand that new chips are always a problem.
Problems like this force me to get out of my C-omfort zone and getting dirty with binary control I guess.
TargetBusy



Joined: 07 Jan 2012
Posts: 6

View user's profile Send private message

PostPosted: Sun Jan 22, 2012 6:37 pm     Reply with quote

Update on the troubleshooting to Ttelmah's suggestions.

This code:
Code:

#byte APFCON=getenv(SFR:APFCON)

gave me an "Expression must evaluate to a constant" error.

Code:

bit_clear(APFCON,7);
bit_clear(APFCON,2);

gave me "Expecting an identifier" & "Expecting a declaration" error.

Code:

// /////////////////////////
#PIN_SELECT U1TX=PIN_A1
#PIN_SELECT U1RX=PIN_A0
//////////////////////////////

This code gave me "Invalid Pre-Processor directive Invalid PIN ID" error.

Looks like this PIC manage UART in a different way and the common UART library doesn't works on this PIC, althought I might be wrong (and probalby I am).
MikroC Pro compiler uses a different library to work with hardware EUSART instead a software UART, so we might need a new library to deal with this PIC, and I would love to work on that, but first I need to understand where is the problem.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Jan 22, 2012 6:53 pm     Reply with quote

I just don't think CCS has it all working on the 12F1840. If you have
4.128, and you recently bought it, then you should be able to ask CCS to
add hardware UART support, and #pin select support in the next version.

Here's an example of how to add support with code, but why bother,
if you can get CCS do it all for you in the next release ?
http://www.ccsinfo.com/forum/viewtopic.php?t=26631&start=8


Quote:
#byte APFCON=getenv(SFR:APFCON)

gave me an "Expression must evaluate to a constant" error.


You have to put quotes around the text inside the parentheses.
This is in the manual, in the examples for the getenv() section.
http://www.ccsinfo.com/downloads/ccs_c_manual.pdf
TargetBusy



Joined: 07 Jan 2012
Posts: 6

View user's profile Send private message

PostPosted: Sun Jan 22, 2012 10:05 pm     Reply with quote

PCM programmer wrote:
I just don't think CCS has it all working on the 12F1840. If you have
4.128, and you recently bought it, then you should be able to ask CCS to
add hardware UART support, and #pin select support in the next version.

Here's an example of how to add support with code, but why bother,
if you can get CCS do it all for you in the next release ?
http://www.ccsinfo.com/forum/viewtopic.php?t=26631&start=8


Quote:
#byte APFCON=getenv(SFR:APFCON)

gave me an "Expression must evaluate to a constant" error.


You have to put quotes around the text inside the parentheses.
This is in the manual, in the examples for the getenv() section.
http://www.ccsinfo.com/downloads/ccs_c_manual.pdf


This is a good fix. Looks good, but I might have to do a lot of debug for this project that was working flawless on the 12F683.

Thank you guys.

Last thing... I don't know why I had a truncated "Version 4.128, xxxx" on the last .LST, here is the compiler version:


+++++++++++++++++
Ye olde Mod kindly hid yer user number.

Again.

- Forum Moderator
+++++++++++++++++


Code:

CCS PCM C Compiler, Version 4.128, xxxxx             22-Jan-12 19:58

               Filename: c:\projects\pcw\1840-uart\1840-UART.lst

               ROM used: 184 words (4%)
                         Largest free fragment is 2048
               RAM used: 6 (2%) at main() level
                         25 (10%) worst case
               Stack:    2 locations

*
0000:  MOVLP  00
0001:  GOTO   08F
0002:  NOP
.................... #include <12F1840.h>
Mike



Joined: 16 Jul 2009
Posts: 4

View user's profile Send private message

Working PIC12F1822 UART
PostPosted: Mon Jan 23, 2012 11:01 pm     Reply with quote

Guys,
Thanks for the post. I "wasted" 5+ hours on this UART until Google discovered your posts. Thanks it was very helpful.

I upgraded from v4.109 of the compiler where FORCE_SW seemed to work but delay_ms() was broken. I can take the same code and compile for PIC12F675 and put in place of the PIC12F1822 and it works. However for v4.128 the following doesn't work at all!

There is no TX output for any of the following serial port definitions:
Code:

#use rs232(baud=9600, parity=N, UART1, stream=PORT1)   
#use rs232(baud=9600, parity=N, xmit=PIN_A0, rcv=PIN_A5, bits=8,FORCE_SW)

If you define it this way it works:
Code:

#use rs232(baud=9600, parity=N, UART2, stream=PORT1)

I know there is only one UART and for the TX pin I'm using the reset default values so why does UART2 works?
BTW,
Code:

setup_uart(19200);

results in an "Undefined Identifier" even though the F1822 has an advanced uart as defined by CCS, see main.h.

I have serial RX on GP5 and TX on GP0 here is my code.
main.c
Code:

#include <main.h>
#include <stdio.h>

void main() {
   unsigned char c;
   setup_comparator(NC_NC);   // works w/o it
   setup_oscillator(OSC_8MHZ|OSC_INTRC|OSC_PLL_OFF,0);
   // setup_uart(19200);  // results in Undefined Identifier
   setup_adc_ports(NO_ANALOGS);  // works w/o it
   setup_adc(ADC_OFF);           // works w/o it

   APFCON = 0x80;
// lets keep reset defaults but RX needs to be on RA5 instead of RA1 for my design,  TX is on RA0
   output_a(PORTA_INIT);   // lets make the inactive pin states play
   set_tris_a(TRISA_INIT);   // nice with host UART want it isn't enabled.
   printf("\n\r     ****** Hello World\n\r");
   while(true){
      c=getchar();
      if (c) putc(c+1);
      output_low(LED);    // toggle LED
      delay_ms(10);
      output_high(LED);
      delay_ms(10);
   }

}

main.h
Code:

#include <12F1822.h>
#device adc=10

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES INTRC_IO                 //Internal RC Osc, no CLKOUT
#FUSES WDT_SW                   //No Watch Dog Timer, enabled in Software
#FUSES PUT                      //Power Up Timer
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOIESO                   //Internal External Switch Over mode disabled
#FUSES NOFCMEN                  //Fail-safe clock monitor disabled
#FUSES BORV25                   //Brownout reset at 2.5V
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O

#use delay(int=8000000)

#use rs232(baud=9600, parity=N, UART2, stream=PORT1, TIMEOUT=1)    // This works
// #use rs232(baud=9600, parity=N, UART1, stream=PORT1, TIMEOUT=1)    // This doesn't work, No TXD output
// #use rs232(baud=9600, parity=N, xmit=PIN_A0, rcv=PIN_A5, bits=8, stream=PORT1, TIMEOUT=1,  FORCE_SW)  // This doesn't work.  No TXD output
// #use rs232(baud=9600, parity=N, xmit=PIN_A0, rcv=PIN_A5, bits=8,  FORCE_SW)  // This doesn't work.  No TXD output

#use FAST_IO(A)

#define LED PIN_A4
#define PORTA_INIT 0x01
#define TRISA_INIT 0x28

#BYTE APFCON  = 0x11D
#BYTE APFCON2  = getenv("SFR:APFCON")

#if (getenv("SFR:APFCON") == 0x11D )
#warning "APFCON is equal, just checking"
#else
#warning "APFCON is not equal"
#endif

#if (getenv("UART") == 1)
#warning "one uart"
#endif

#if (getenv("AUART") == 1)
#warning "one adv uart"
#endif

The toggling of "LED" is to see activity on the d-scope. I was also exercising the timeout capability so you should see continued LED activity even w/o serial input. The program receives a char from RX and adds one and sends it back.

Hope this helps.
Mike L.
RF_Developer



Joined: 07 Feb 2011
Posts: 839

View user's profile Send private message

PostPosted: Tue Jan 24, 2012 11:18 am     Reply with quote

There is only one UART on this PIC, but it can work through either of two pairs of IO pins. UART1 selects the first, default pair, UART2 selects the second pair. You must have your serial hardware wired to the second pair: RA4 & RA5. UART1, the default, selects RA0 & 1.

If you force AFPCON by writing to it after setting up the UART then that may or may not have the effect you are expecting as you are implementing a software UART, which is not steered by AFPCON, just the availability of the relevant IO pins.

If you specify a timeout that will force a software UART as the hardware UART doesn't have that functionality.

RF Developer
Mike



Joined: 16 Jul 2009
Posts: 4

View user's profile Send private message

PostPosted: Tue Jan 24, 2012 5:06 pm     Reply with quote

Sure. I as I stated in the post it has only one UART, but the PU/reset value of APFCON is 0, which from the datasheet maps TXD to RA0, see Register 12-1. I'm saying is that UART1 doesn't select the default pin assignments for TXD.

Sure it makes some sense to have UART1 and UART2 specify the different default configurations but RXD and TXD can be individually assigned. Regardless, setting UART1 or UART2 should access the same SFR's to control the sole UART and setting APFCON.2 to 1 (TXCKSEL) still doesn't fix it when UART1 is selected. What I mean is by d-scope monitoring on both RA0 and RA4 there is no activity when UART1 is selected. It seems with UART2 you can then select which pin has TXD activity. Which means it is UART code is broken with UART1 selected.

For me FORCE_SW option didn't work on the 12F1822 at all. It did on my previous version 4.109 and it worked with a 12F675 but I upgraded yesterday to 4.128 and then it was broken on the 12F1822 but not on 12F675. I would say it is a compiler or library issue.

I don't think you are correct about the timeout option, see page 141 of 7-14-2011 PCB-PCWH compiler manual and CCS F1 help file. Also, there is a 34 instruction word difference btw compiling w. and w/o FORCE_SW.

Thanks.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
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