|
|
View previous topic :: View next topic |
Author |
Message |
tyro
Joined: 25 May 2005 Posts: 10
|
|
Posted: Fri May 27, 2005 5:42 am |
|
|
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
|
|
Posted: Fri May 27, 2005 8:11 am |
|
|
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
|
|
Posted: Fri May 27, 2005 1:53 pm |
|
|
Ok I have PCWH version 3.203! |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri May 27, 2005 6:16 pm |
|
|
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
|
|
Posted: Sat May 28, 2005 8:53 am |
|
|
oh thank you, PCM programmer for testing this. I will give it a try. |
|
|
tyro
Joined: 25 May 2005 Posts: 10
|
|
Posted: Mon May 30, 2005 1:03 pm |
|
|
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
|
|
Posted: Mon May 30, 2005 1:54 pm |
|
|
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
|
|
Posted: Mon May 30, 2005 2:25 pm |
|
|
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
|
|
Posted: Mon May 30, 2005 2:49 pm |
|
|
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
|
|
Posted: Mon May 30, 2005 3:03 pm |
|
|
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
|
|
Posted: Mon May 30, 2005 3:14 pm |
|
|
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
|
|
Posted: Wed Jun 01, 2005 12:13 pm |
|
|
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
|
|
Posted: Fri Oct 07, 2005 11:20 pm |
|
|
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! |
|
|
|
|
|
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
|