|
|
View previous topic :: View next topic |
Author |
Message |
hwryu
Joined: 25 Sep 2013 Posts: 18
|
UART2 Problem: Please help me |
Posted: Thu Sep 26, 2013 10:50 pm |
|
|
Device :18f46k22
compiler version : 4.108
My goal:
I want to use UART2 to communicate with PC.
problem :
1. When sending a charcter vai pic tx2 pin, PIC is shut down and freezing.
2. Rx2 interrupt is not working.
Help me, Please
Code: |
#include <18f46k22.h>
#device *=16 adc=10
//#device pass_strings=in_ram
#FUSES H4
#use delay(internal=16Mhz,clock=64Mhz,RESTART_WDT,clock_out))
#use rs232(UART2,baud=19200,stop=1,parity=N,xmit=PIN_D6,rcv=PIN_D7,bits=8,restart_WDT,errors,stream=SER2)
#ZERO_RAM
#include <stdio.h>
#use fast_io(a)
#use fast_io(b)
#use fast_io(c)
int32 gtemp1=1234567;
long int Delay_time=1000;
int Serial_1=0;
int Serial_2=0;
int Rx1Flag=0;
char RecvChar=null;
#int_rda2
void rda_isr2(void)
{
RecvChar = getc();
Delay_time = 100;
Rx1Flag = 1;
}
#int_ext
Void ext_isr(){
if(Delay_time==100)
Delay_time=1000;
else
Delay_time=100;
}
void main()
{
SET_TRIS_A(0b00000000);
SET_TRIS_B(0b11000001);
SET_TRIS_C(0b11000000);
SET_TRIS_C(0b11000000);
// Port_B_Pullups(TRUE);
disable_interrupts(INT_RB);
disable_interrupts(INT_AD);
disable_interrupts(INT_TBE);
disable_interrupts(INT_CCP1);
disable_interrupts(INT_CCP2);
disable_interrupts(INT_EEPROM);
enable_interrupts(INT_EXT);
enable_interrupts(INT_RDA2);
enable_interrupts(GLOBAL);
while(true){
#byte ANSELA = 0xF38
#byte ANSELB = 0xF39
#byte ANSELC = 0xF3A
#byte ANSELD = 0xF3B
#byte ANSELE = 0xF3C
ANSELA = 0;
ANSELB = 0;
ANSELC = 0;
ANSELD = 0;
ANSELE = 0;
delay_ms(500);
gtemp1+=1;
fprintf(SER2,"UART2=%lu \r\n", gtemp1);
fputs("----------------",SER2);
if(Rx1Flag==1)
{
fprintf(SER2,"%c \r\n",RecvChar);
Rx1Flag = 0;
}
output_bit(pin_b1,1);
// led=0b000000010;
delay_ms(Delay_time);
output_bit(pin_b1,0);
// led=0b00000000;
delay_ms(Delay_time);
// Delay_time +=50;
}
} |
|
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9226 Location: Greensville,Ontario
|
|
Posted: Fri Sep 27, 2013 5:23 am |
|
|
First, have you confirmed that the pIC is running correctly using the '1Hz flashing LED' program?
If so, here's some suggestions...
1) delete this line ...#device *=16 adc=10
not needed with PIC18 series devices
2) delete these lines ...
#use fast_io(a)
#use fast_io(b)
#use fast_io(c)
Let the compiler handle the I/O settings automatically
3)delete these lines...
SET_TRIS_A(0b00000000);
SET_TRIS_B(0b11000001);
SET_TRIS_C(0b11000000);
SET_TRIS_C(0b11000000);
again, let the compiler handle the I/O settings automatically
4) this is 'messy'....
output_bit(pin_b1,1);
// led=0b000000010;
delay_ms(Delay_time);
output_bit(pin_b1,0);
// led=0b00000000;
delay_ms(Delay_time);
// Delay_time +=50;
use the 'toggle' function CCS supplies to 'flash the LED'.At least for test purposes.
5) What is the INT_EXT input ? It could be falsely triggering,causing the PIC to stay in the ISR...I'd disable it ,for test purposes,until you get the serial port running correctly.
The 'trick' is to make the program as small as possible so you can easily work on one section at a time,get it working, then add the next section.
I do use the 46k22 and know the 2nd serial works fine.
Make the changes,maybe more...,test and repost with what happens,we can then help you further.
hth
jay |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Fri Sep 27, 2013 6:17 am |
|
|
A few more hints for improving your code:
1) Code: | #byte ANSELA = 0xF38
#byte ANSELB = 0xF39
#byte ANSELC = 0xF3A
#byte ANSELD = 0xF3B
#byte ANSELE = 0xF3C
ANSELA = 0;
ANSELB = 0;
ANSELC = 0;
ANSELD = 0;
ANSELE = 0; | It is bad practice to have the #byte defines inside the while loop. Move them to the top of your program where you declare the global variables.
Or even better, use: Code: | setup_adc_ports(NO_ANALOGS); | This single line replaces your 10 lines above, is portable to other processors and a lot easier to read.
2) Code: | #use rs232(UART2,baud=19200,stop=1,parity=N,xmit=PIN_D6,rcv=PIN_D7,bits=8,errors,stream=SER2) | Tricky. The pins to use are now defined two times. Just declaring 'UART2' is enough information to specify the 2nd uart. Declaring the xmit and rcv pins is double information with possible future problems when you change 1 item and forget to change the other. Remove either 'UARTx' or remove the pin specifications.
3) Remove all watchdog code. Hardly any device ever requires a watchdog. From experience I can tell you that watchdogs can create hard to find problems. Don't make your programming task harder than it already is. Removing the watchdog also saves someenergy, makes your program smaller and easier to read.
4) Always specify the UART you want to access.This works as long as you have one #RS232 line. But with two RS232 lines it depends on the sequence of declaration.
Better replace by: Code: | rlRecvChar = getc(SER2); |
5) For debugging it helps to make your program as small as possible. Remove all parts not related to the issue at hand so you can make sure not multiple problems are interacting and you can focus on one problem at a time.
For example, the INT_EXT could be interfering. We can't tell as we don't know your hardware connections. Remove it and see if things improve.
Post your improved and cleaned up code here. It should be at least half the size of what you posted now. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Sep 27, 2013 12:34 pm |
|
|
Quote: | setup_adc_ports(NO_ANALOGS);
This single line replaces your 10 lines above, is portable to other processors and a lot easier to read.
|
Not in his version. He has vs. 4.108 and it produces this code for the 18F46K22:
Code: |
.................... setup_adc_ports(NO_ANALOGS);
00026: MOVLW 00
00028: MOVWF F7E // PIR5 register
0002A: BCF FC1.0 // ADCON1.0 bit = 0
0002C: BCF FC1.1
0002E: BCF FC1.2
00030: BCF FC1.3
00032: MOVWF F7F // IPR5 register
|
That's not correct code. FC1 is the ADCON1 register. In the 18F46K22,
bits 0 to 3 do not control the analog/digital settings for the ADC ports.
It's done with the ANSELx registers.
Here is the result when it's compiled with vs. 5.012. It's correct:
Code: |
.................... setup_adc_ports(NO_ANALOGS);
0002E: MOVF FC1,W
00030: ANDLW F0
00032: MOVWF FC1
00034: MOVLW 00
00036: MOVLB F
00038: MOVWF x38 // ANSELA
0003A: MOVWF x3C // ANSELE
0003C: MOVWF x39 // ANSELB
0003E: MOVWF x3A // ANSELC
00040: MOVWF x3B // ANSELD
|
So he does need a work-around for his version.
Quote: |
It is bad practice to have the #byte defines inside the while loop. Move
them to the top of your program where you declare the global variables. |
I gave him an example of the work-around that shows it as a routine.
http://www.ccsinfo.com/forum/viewtopic.php?t=43961&start=6
He changed it to inline code. |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Fri Sep 27, 2013 12:56 pm |
|
|
PCM programmer wrote: | Quote: | setup_adc_ports(NO_ANALOGS);
This single line replaces your 10 lines above, is portable to other processors and a lot easier to read.
|
Not in his version. He has vs. 4.108 and it produces this code for the 18F46K22:
< cut>
I gave him an example of the work-around that shows it as a routine.
http://www.ccsinfo.com/forum/viewtopic.php?t=43961&start=6
He changed it to inline code. | Alright, now makes sense to me. I don't have v4.108 and in v4.141 it looked al-right.
Then here another hint for the original topic starter:
Always write comments in your code! Especially when you have created some code with a special extra condition like here.
By the way: why did Hwryu make the function inline? The version as posted by PCM was way more easy to read. |
|
|
hwryu
Joined: 25 Sep 2013 Posts: 18
|
Thank you for your help |
Posted: Mon Sep 30, 2013 7:22 pm |
|
|
I struggled to solve this problem. Finally I updated compiler to new version 5.012 so that all these problems are solved.
Thank you for your advice. |
|
|
|
|
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
|