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

PROBLEMS with SOFTWARE USART ON PIC16F876! PLEASE HELP!
Goto page Previous  1, 2
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
tyro



Joined: 25 May 2005
Posts: 10

View user's profile Send private message Send e-mail Visit poster's website ICQ Number

PostPosted: Fri May 27, 2005 5:42 am     Reply with quote

ahmm shift_right out to the pin is right at put_char, cause LSB is first. And in get_char() the bits are shifted left in, so the LSB is the first who is in. I think that is right. I have tried it with the CCS functions and it doesn�t work.
But I think the problem is the timing differences because of the instruction cycles like Ttelmah said.
I�m working on it.
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Fri May 27, 2005 8:11 am     Reply with quote

Quote:
ahmm shift_right out to the pin is right at put_char, cause LSB is first. And in get_char() the bits are shifted left in, so the LSB is the first who is in. I think that is right.
I agree the put_char function is correct. In get_char() however you should use the shift_right i.s.o. shift_left or the received bits will be stored in reversed sequence order.

Quote:
But I think the problem is the timing differences because of the instruction cycles like Ttelmah said.
I'm sure this is one of the problems, see my first posting.

Quote:
I have tried it with the CCS functions and it doesn�t work.
Yes, you told so before but many other people are using these functions and have no problems. If you tell us which CCS version you are using I will create a test program and have a look at the generated code.
tyro



Joined: 25 May 2005
Posts: 10

View user's profile Send private message Send e-mail Visit poster's website ICQ Number

PostPosted: Fri May 27, 2005 1:53 pm     Reply with quote

Ok I have PCWH version 3.203!
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri May 27, 2005 6:16 pm     Reply with quote

I don't think the compiler calculates the bit timing correctly for 115.2
kbaud with a soft UART. I measured a baud rate of 123.468 KHz when
sending "UUUUUU".

I had to adjust the baud value to 108000 in the #use rs232() statement
to make it work. Then I measured a baud rate of 114.952 KHz.
This is close enough to 115200 to work OK with TeraTerm.
I can see "UUUUUUUUU" properly displayed on the screen.

I know that a 20 MHz crystal will not give the exact baud rate in this
case, but it's only expected to be off by 1%. The CCS calculation
is off by more than 5%. There's no reason for it, because at 20 MHz
one instruction cycle is 200 ns. One bit time at 115.2 Kbaud is 8.68 us.
So the instructions are short enough to easily build a bit-output routine
which will have accurate bit timing.

I tested this with PCM vs. 3.203 and with vs. 3.225 (the latest) and
got the same results.

Code:
#include <16F877.H>
#fuses HS, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock = 20000000)
#use rs232(baud=109000, xmit=PIN_C6, rcv=PIN_C7, FORCE_SW)

void main()
{

while(1)
  {
   putc(0x55);
  }   
 
}
tyro



Joined: 25 May 2005
Posts: 10

View user's profile Send private message Send e-mail Visit poster's website ICQ Number

PostPosted: Sat May 28, 2005 8:53 am     Reply with quote

oh thank you, PCM programmer for testing this. I will give it a try.
tyro



Joined: 25 May 2005
Posts: 10

View user's profile Send private message Send e-mail Visit poster's website ICQ Number

PostPosted: Mon May 30, 2005 1:03 pm     Reply with quote

OK, PCM programmer. Now I have tested it, like you said, with 20MHz crystal and 109000 baud. With PIC16F876 <--> HYPERTERMINAL putc() and getc() are working fantastic, BUT with communication to Nokia Handy nothing is working, although I made the same adjustments. Here is a code snippet:

Code:

#include<16F876.h> // Standard header for PIC16F876
#include<stdlib.h> // Standard header for std input/output
//#include<string.h> // Standard header for string handling

#fuses HS,NOWDT,NOPROTECT,NOBROWNOUT,NOLVP,PUT
/* Highspeed Mode, no Watchdog Timer, no code-protection, no brownout detection,
   no low voltage programming, powerup-timer on */

#use delay(clock=20000000)
#use rs232(baud=109000,xmit=PIN_C6,rcv=PIN_C7,parity=n,bits=8,errors,STREAM=PHONE_STREAM,FORCE_SW)
#use i2c(master,sda=PIN_C4,scl=PIN_C3)

#define PORTA   0x05
#define PORTB  0x06
#define PORTC   0x07

#define low 0
#define high 1

//#include <lcd16x2.c> // For driving a 16x2 LCD over I2C

struct port_a{ // PORT A structure for relay outputs
BOOLEAN hex_out_enable;
BOOLEAN unused;
BOOLEAN out_1; // -> optocoupler -> relay -> output 1
BOOLEAN out_2; // -> optocoupler -> relay -> output 2
BOOLEAN unused_2:2;}a;
#byte a=PORTa

struct port_b{ // PORT B structure for status led�s
BOOLEAN interrupt;
BOOLEAN rxtx_success;
BOOLEAN success;
BOOLEAN sys_ready_busy; // High = System ready, Low = Busy
BOOLEAN rxtx_error;
BOOLEAN error;
BOOLEAN unused:2;}b;
#byte b=PORTb

int i=0, d=0, e; // Global variables & byte-strings, no constants

byte send_acks[10] = {0x1E,0x00,0x0C,0x7F,0x00,0x02,0xD2,0x00,0xC0,0x00}; // Only for HW/SW acknowledgement
byte send_acks2[10] = {0x1E,0x00,0x0C,0x7F,0x00,0x02,0x02,0x00,0x10,0x00}; // Prepared for SMS handling
byte send_acks3[30]; // ACK 3rd string from phone after message sending
byte send_acks4[10] = {0x1E,0x00,0x0C,0x7F,0x00,0x02,0x14,0x00,0x06,0x00}; // Prepared for SMS deleting

byte received_acks[10]; // Acks from HW/SW info,sent sms & delete
byte received_big[60]; // For receiving HW/SW info and sms

byte message_sending[14]; // While message sending
byte message_sent[30]; // For message sent string
byte message_delete[16] = {0x1E,0x00,0x0C,0x14,0x00,0x08,0x00,0x01,0x00,
0x0A,0x02,0x00,0x01,0x00,0x00,0x00}; // For message deleting

void usart_sync(){ // USART <-> phone syncronization

b.sys_ready_busy = 0;

for(i=0;i<=31;i++)
putc(0x55); // U
putc(0xC1);
delay_ms(500);}


void hwsw(){ // Getting HW/SW info

byte CONST send_frame_hwswinfo[16] = {0x1E,0x00,0x0C,0xD1,0x00,0x07,0x00,0x01,
0x00,0x03,0x00,0x01,0x60,0x00,0x72,0xD5}; // Get HW/SW information

byte CONST hwswinfo_analyze[31] = {0x56,0x20,0x30,0x35,0x2E,0x34,0x32,0x0A,
0x30,0x34,0x2D,0x30,0x38,0x2D,0x30,0x33,0x0A,0x4E,0x48,0x4D,0x2D,0x32,0x0A,
0x28,0x63,0x29,0x20,0x4E,0x4D,0x50,0x2E}; // V 05.42 04-08-03 NHM-2 (c) NMP.

b.sys_ready_busy = 0;

for(i=0;i<=15;i++)
putc(send_frame_hwswinfo[i]);

for(i=0;i<=9;i++){
//if(kbhit()){
received_acks[i]=getc();} //}

for(i=0;i<=45;i++){
//if(kbhit()){
received_big[i]=getc();} //}

//..................................

send_acks[7]=received_big[43]-0x40; // Sequence Nr. & ACK calculation
send_acks[9]=0x7F^0x02^send_acks[7];

for(i=0;i<=9;i++)
putc(send_acks[i]);

//..................................

for(i=10;i<=40;i++){ // Analyzing the received HW/SW string
if(received_big[i] != hwswinfo_analyze[i-10]){
error();
reset_cpu();}}}


void sms_delete(){

b.sys_ready_busy = 0;

//message_delete[11]=received_big[11];  // Sequence nr. & message calculation
message_delete[11] = 0x01; // SMS store location is always 0x01
//message_delete[13] = send_acks3[26]+0x01;
//message_delete[13] = 0x41; // Seq. nr. is now 0x41
message_delete[13] = received_big[43]+0x01;
message_delete[14] = 0x1E^0x0C^0x02^0x01;
message_delete[15] = 0x14^0x08^0x01^0x0A^message_delete[11]^message_delete[13];

for(i=0;i<=15;i++)
putc(message_delete[i]);

//..................................

for(i=0;i<=9;i++)
received_acks[i]=getc();

//..................................

for(i=0;i<=13;i++) // Using send_acks3 string to ACK 2nd string from phone
send_acks3[i]=getc();

//..................................

send_acks4[7]=send_acks3[11]-0x40; // Sequence nr. & ACK calculation
send_acks4[9]=0x7F^0x02^send_acks4[7];

for(i=0;i<=9;i++)
putc(send_acks4[i]);}


#INT_EXT
void ext_isr(){ // A real reset by INT, �cause reset_cpu() doesn�t reset relays

while(!input(PIN_B0)){

delay_ms(500);
b.sys_ready_busy = 0;

output_a(0); // Interrupt is doing a reset of the relays and PIC
reset_cpu();}}



///////////////////////////////////////////////////////////////////////////////
////////////////////////////// MAIN FUNCTION //////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

void main(){

setup_adc_ports(NO_ANALOGS); // Make PORT A digital

set_tris_a(0x31); // PIN A0, A4 & A5 are inputs, PIN A1, A2 & A3 are outputs
set_tris_b(0x01); // Only PIN B0 is input (Interrupt input)
set_tris_c(0x80); // Only PIN C7 is input (USART RX input)

output_b(0x09); // Only PIN B0 & B3 are high

//------------------------ Interrupt handling ---------------------------------

ext_int_edge(H_TO_L); // Interrupt on falling edge
enable_interrupts(INT_EXT); // Enabling extern interrupt
enable_interrupts(GLOBAL);

b.interrupt = 1;

//if(kbhit()) fgetc(PHONE_STREAM); // Clears the 2-deep FIFO RX buffer "RCREG"
//if(kbhit()) fgetc(PHONE_STREAM);

usart_sync(); // Syncronize the USART from PIC & Phone

hwsw();

sms_delete();

reset_cpu(); // Resetting to begin again
} // End main
 
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon May 30, 2005 1:54 pm     Reply with quote

Actually, I didn't mean to imply that you had to use a 20 MHz crystal.
I just wanted to show that an adjustment factor was needed, and maybe
a different adjustment would work with your 11.059 MHz crystal.

Also, I haven't done a Nokia project, so someone else will have to help
you with the communications protocol.

I can help with compiler or coding errors, and I do see one.
You're setting the TRIS for ports A, B, and C. But you don't have
#use fast_io() statements for those ports. As a consequence,
when you do "output_b(0x09)", it changes the TRIS for port B to
all outputs. Pin RB0 is no longer an input. Look at the .LST file
to see this. The lines that set TRISB to all outputs are in bold:

Quote:

Note: Upon entering this code, RAM bank 1 is already selected.

........... output_b(0x09); // Only PIN B0 & B3 are high
0272: MOVLW 00
0273: MOVWF 06 // Write 0x00 to 0x86 (TRISB)
0274: MOVLW 09
0275: BCF 03.5
0276: MOVWF 06


You need to put these lines near the start of your program,
right after the #fuses statement, to prevent the output_x()
functions from changing the TRIS.
#use fast_io(A)
#use fast_io(B)
#use fast_io(C)
tyro



Joined: 25 May 2005
Posts: 10

View user's profile Send private message Send e-mail Visit poster's website ICQ Number

PostPosted: Mon May 30, 2005 2:25 pm     Reply with quote

Ok, the protocol is right, cause it works with HW USART. I have put in the fast_io thing. the output_b(0x09) doesn�t matter for communication, it�s only relay reset and LED control. Maybe the Nokia is more sensitive. I will try to adjust the baud-value!
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon May 30, 2005 2:49 pm     Reply with quote

In the earlier posts in this thread, there is a huge back and forth
discussion of using the INVERT option. You say that you must use it.
Then people suggest that you should use it, but then you insist that
you can't.

I think you may want to do the following with the Nokia, but I'm
really not sure.

#use rs232(baud=109000,xmit=PIN_C6,rcv=PIN_C7, INVERT ,STREAM=PHONE_STREAM,FORCE_SW)
tyro



Joined: 25 May 2005
Posts: 10

View user's profile Send private message Send e-mail Visit poster's website ICQ Number

PostPosted: Mon May 30, 2005 3:03 pm     Reply with quote

i must use it on the board with IR transceiver on. now i�m using a board with wired comm to nokia. as i explained, wired comm needs no invert. and if it�s not running here with software uart, i don�t have to try the IR thing!!!!
tyro



Joined: 25 May 2005
Posts: 10

View user's profile Send private message Send e-mail Visit poster's website ICQ Number

PostPosted: Mon May 30, 2005 3:14 pm     Reply with quote

I have noticed that phone reacts if baud is greater than 112k. But the wrong chars are coming in. I think i�m close.
tyro



Joined: 25 May 2005
Posts: 10

View user's profile Send private message Send e-mail Visit poster's website ICQ Number

PostPosted: Wed Jun 01, 2005 12:13 pm     Reply with quote

YIIIIIIIIIIIIPPPPPPPPPPPPIIIIIIEEEEEEEEEEEEEEE!!!!

Got it. With 123000 baud at 20MHz.

Everything works fine. Now i can invert.
Thanks to all.


Code:

#include<16F876.h> // Standard header for PIC16F876
#include<stdlib.h> // Standard header for std input/output
//#include<string.h> // Standard header for string handling

#fuses HS,NOWDT,NOPROTECT,NOBROWNOUT,NOLVP,PUT
/* Highspeed Mode, no Watchdog Timer, no code-protection, no brownout detection,
   no low voltage programming, powerup-timer on */

#use fast_io(A)
#use fast_io(B)
#use fast_io(C)

#use delay(clock=20000000)
#use rs232(baud=123000,xmit=PIN_C6,rcv=PIN_C7,parity=n,bits=8,errors,FORCE_SW,STREAM=PHONE_STREAM)
#use i2c(master,sda=PIN_C4,scl=PIN_C3)

#define PORTA   0x05
#define PORTB  0x06
#define PORTC   0x07

#define low 0
#define high 1

//#include <lcd16x2.c> // For driving a 16x2 LCD over I2C
#include <numeric.c> // For driving the numeric displays of HEXOUT-board over I2C


//------------------------ Structures -----------------------------------------

struct port_a{ // PORT A structure for relay outputs
BOOLEAN hex_out_enable;
BOOLEAN unused;
BOOLEAN out_1; // -> optocoupler -> relay -> output 1
BOOLEAN out_2; // -> optocoupler -> relay -> output 2
BOOLEAN unused_2:2;}a;
#byte a=PORTa

struct port_b{ // PORT B structure for status led�s
BOOLEAN interrupt;
BOOLEAN rxtx_success;
BOOLEAN success;
BOOLEAN sys_ready_busy; // High = System ready, Low = Busy
BOOLEAN rxtx_error;
BOOLEAN error;
BOOLEAN unused:2;}b;
#byte b=PORTb


//------------------------ Global variables -----------------------------------

int i=0, d=0, e; // Global variables & byte-strings, no constants

byte send_acks[10] = {0x1E,0x00,0x0C,0x7F,0x00,0x02,0xD2,0x00,0xC0,0x00}; // Only for HW/SW acknowledgement
byte send_acks2[10] = {0x1E,0x00,0x0C,0x7F,0x00,0x02,0x02,0x00,0x10,0x00}; // Prepared for SMS handling
byte send_acks3[30]; // ACK 3rd string from phone after message sending
byte send_acks4[10] = {0x1E,0x00,0x0C,0x7F,0x00,0x02,0x14,0x00,0x06,0x00}; // Prepared for SMS deleting

byte received_acks[10]; // Acks from HW/SW info,sent sms & delete
byte received_big[60]; // For receiving HW/SW info and sms

byte message_sending[14]; // While message sending
byte message_sent[30]; // For message sent string
byte message_delete[16] = {0x1E,0x00,0x0C,0x14,0x00,0x08,0x00,0x01,0x00,
0x0A,0x02,0x00,0x01,0x00,0x00,0x00}; // For message deleting


//--------------------------- Functions ---------------------------------------

void success(){ // Success

b.success = 1;
delay_ms(1000);
b.success = 0;
delay_ms(50);}


//-----------------------------------------------------------------------------

void error(){ // Error

b.error = 1;
delay_ms(1000);
b.error = 0;
delay_ms(50);}


//-----------------------------------------------------------------------------

void usart_sync(){ // USART <-> phone syncronization

b.sys_ready_busy = 0;

for(i=0;i<=31;i++)
putc(0x55); // U
putc(0xC1);
delay_ms(500);}


//-----------------------------------------------------------------------------

void hwsw(){ // Getting HW/SW info

byte CONST send_frame_hwswinfo[16] = {0x1E,0x00,0x0C,0xD1,0x00,0x07,0x00,0x01,
0x00,0x03,0x00,0x01,0x60,0x00,0x72,0xD5}; // Get HW/SW information

byte CONST hwswinfo_analyze[31] = {0x56,0x20,0x30,0x35,0x2E,0x34,0x32,0x0A,
0x30,0x34,0x2D,0x30,0x38,0x2D,0x30,0x33,0x0A,0x4E,0x48,0x4D,0x2D,0x32,0x0A,
0x28,0x63,0x29,0x20,0x4E,0x4D,0x50,0x2E}; // V 05.42 04-08-03 NHM-2 (c) NMP.

b.sys_ready_busy = 0;

for(i=0;i<=15;i++)
fputc(send_frame_hwswinfo[i],PHONE_STREAM);

for(i=0;i<=9;i++){

//while(!kbhit()){}
received_acks[i]=fgetc(PHONE_STREAM);} //}

for(i=0;i<=45;i++){

//while(!kbhit()){}
received_big[i]=fgetc(PHONE_STREAM);} //}

//..................................

send_acks[7]=received_big[43]-0x40; // Sequence Nr. & ACK calculation
send_acks[9]=0x7F^0x02^send_acks[7];

for(i=0;i<=9;i++)
fputc(send_acks[i],PHONE_STREAM);

//..................................

for(i=10;i<=40;i++){ // Analyzing the received HW/SW string
if(received_big[i] != hwswinfo_analyze[i-10]){
error();
reset_cpu();
}}}


//-----------------------------------------------------------------------------

void sms_delete(){

b.sys_ready_busy = 0;

//message_delete[11]=received_big[11];  // Sequence nr. & message calculation
message_delete[11] = 0x01; // SMS store location is always 0x01
//message_delete[13] = send_acks3[26]+0x01;
//message_delete[13] = 0x41; // Seq. nr. is now 0x41
message_delete[13] = received_big[43]+0x01;
message_delete[14] = 0x1E^0x0C^0x02^0x01;
message_delete[15] = 0x14^0x08^0x01^0x0A^message_delete[11]^message_delete[13];

for(i=0;i<=15;i++)
fputc(message_delete[i],PHONE_STREAM);

//..................................

for(i=0;i<=9;i++){
//while(!kbhit()){}

received_acks[i]=fgetc(PHONE_STREAM);}

//..................................

for(i=0;i<=13;i++){ // Using send_acks3 string to ACK 2nd string from phone
//while(!kbhit()){}

send_acks3[i]=fgetc(PHONE_STREAM);}

//..................................

send_acks4[7]=send_acks3[11]-0x40; // Sequence nr. & ACK calculation
send_acks4[9]=0x7F^0x02^send_acks4[7];

for(i=0;i<=9;i++)
fputc(send_acks4[i],PHONE_STREAM);}


//-----------------------------------------------------------------------------

#INT_EXT
void ext_isr(){ // A real reset by INT, �cause reset_cpu() doesn�t reset relays

while(!input(PIN_B0)){

delay_ms(500);
b.sys_ready_busy = 0;

output_a(0); // Interrupt is doing a reset of the relays and PIC
reset_cpu();}}



///////////////////////////////////////////////////////////////////////////////
////////////////////////////// MAIN FUNCTION //////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

void main(){

setup_adc_ports(NO_ANALOGS); // Make PORT A digital

set_tris_a(0x31); // PIN A0, A4 & A5 are inputs, PIN A1, A2 & A3 are outputs
set_tris_b(0x01); // Only PIN B0 is input (Interrupt input)
set_tris_c(0x80); // Only PIN C7 is input (USART RX input)

output_b(0x09); // Only PIN B0 & B3 are high

i2c_num_reset();


//------------------------ Interrupt handling ---------------------------------

ext_int_edge(H_TO_L); // Interrupt on falling edge
enable_interrupts(INT_EXT); // Enabling extern interrupt
enable_interrupts(GLOBAL);

b.interrupt = 1;


//-------------------------- Clearing USART -----------------------------------

//if(kbhit()) fgetc(PHONE_STREAM); // Clears the 2-deep FIFO RX buffer "RCREG"
//if(kbhit()) fgetc(PHONE_STREAM);


//------------------------ USART Syncronization -------------------------------

usart_sync(); // Syncronize the USART from PIC & Phone


//--------------------------- Get HW/SW info ----------------------------------

hwsw();
success();


//--------------------------- Deleting SMS ------------------------------------

sms_delete();
success();


reset_cpu(); // Resetting to begin again
} // End main
Guest








PostPosted: Fri Oct 07, 2005 11:20 pm     Reply with quote

tyro wrote:
Ok, the protocol is right, cause it works with HW USART. I have put in the fast_io thing. the output_b(0x09) doesn�t matter for communication, it�s only relay reset and LED control. Maybe the Nokia is more sensitive. I will try to adjust the baud-value!
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 Previous  1, 2
Page 2 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