|
|
View previous topic :: View next topic |
Author |
Message |
TargetBusy
Joined: 07 Jan 2012 Posts: 6
|
UART Problem |
Posted: Sat Jan 21, 2012 2:52 pm |
|
|
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 ) |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19504
|
|
Posted: Sat Jan 21, 2012 3:49 pm |
|
|
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
|
|
Posted: Sat Jan 21, 2012 5:31 pm |
|
|
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
|
|
Posted: Sat Jan 21, 2012 7:29 pm |
|
|
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
|
|
Posted: Sat Jan 21, 2012 11:44 pm |
|
|
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
|
|
Posted: Sun Jan 22, 2012 2:52 am |
|
|
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
|
|
Posted: Sun Jan 22, 2012 7:35 am |
|
|
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
|
|
Posted: Sun Jan 22, 2012 4:45 pm |
|
|
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
|
|
Posted: Sun Jan 22, 2012 6:08 pm |
|
|
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
|
|
Posted: Sun Jan 22, 2012 6:37 pm |
|
|
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
|
|
Posted: Sun Jan 22, 2012 6:53 pm |
|
|
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
|
|
Posted: Sun Jan 22, 2012 10:05 pm |
|
|
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
|
Working PIC12F1822 UART |
Posted: Mon Jan 23, 2012 11:01 pm |
|
|
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,
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
|
|
Posted: Tue Jan 24, 2012 11:18 am |
|
|
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
|
|
Posted: Tue Jan 24, 2012 5:06 pm |
|
|
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. |
|
|
|
|
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
|