|
View:
New views
13 Messages
—
Rating Filter:
Alert me
|
|
|
Dragon Board 12 Serial Communication C code HelpHello all, I am hoping someone has some incite as to what I am doing wrong here, I figure it is a small problem but I am out of ideas. This is just a test to figure out how to pass char * through methods. The code should print Hello World to the serial port which it does, then print tes repeatedly, which it does not, rather the output is as follows:
Hello World""""""""""""""""""""""""""""""""""""""""""""""""""""""" """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" Here is the code, also below is the sci.c and sci.h that do the actually serial communication. Thank You in advanced ! Zach Long MAIN: #include "sci.h" int main(void); void encode(char *out); int main(void) { char* head = "Hello World"; // declare first print statement char* outData =(char*) malloc (sizeof (char*)* 5); // make room for 5 char SCI_Init(9600,0); //Startup serial port 0(under LCD) at 9600 BAUD SCI_OutStatus(1); // Is it clear to send (buffer empty) SCI_OutString(head,0); // print "Hello World" to serial port (WORKS !!) while(1) { if(SCI_OutStatus(0))// Is it clear to send (buffer empty) { encode(outData);//,out.throt,out.heading); // build output SCI_OutString(outData,0); // print out put to serial port } } return 0; } void encode(char *out) // take in pointer and fill with chars { out[0] = 't'; out[1] = 'e'; out[2] = 's'; out[3] = 0; } SCI include: // filename ******************* SCI.H ************************** // Jonathan W. Valvano 1/29/04 // This example accompanies the books // "Embedded Microcomputer Systems: Real Time Interfacing", // Brooks-Cole, copyright (c) 2000, // "Introduction to Embedded Microcomputer Systems: // Motorola 6811 and 6812 Simulation", Brooks-Cole, copyright (c) 2002 // Copyright 2004 by Jonathan W. Valvano, valvano@... // You may use, edit, run or distribute this file // as long as the above copyright notice remains // Modified by EE345L students Charlie Gough && Matt Hawk // Modified by EE345M students Agustinus Darmawan + Mingjie Qiu // Modified by Zachary Long Oct 16, 2009 (setup for Dragon Board 12 9600 BAUD, use of both serial ports enabled) //How To /* Each method has an unsigned int port parameter, this specifices the serial port the method will act on. Dragon Board 12: Serial port under LCD (top) = 0, Serial port near power plug (bottom) = 1 */ // standard ASCII symbols #define CR 0x0D #define LF 0x0A #define BS 0x08 #define ESC 0x1B #define SP 0x20 #define DEL 0x7F //-------------------------SCI_Init------------------------ //-------------------------SCI_Init------------------------ // Initialize Serial port SCI // Input: baudRate is tha baud rate in bits/sec // Output: none // SCIBDL = 24000000/(16 x BR) // baudRate = 2400 bits/sec SCIBDL=625 // baudRate = 4800 bits/sec SCIBDL=313 // baudRate = 9600 bits/sec SCIBDL=156 // baudRate = 19200 bits/sec SCIBDL=78 // assumes a module clock frequency of 4 MHz // sets baudRate to 9600 void SCI_Init(unsigned short baudRate,unsigned int port); //-------------------------SCI_InStatus-------------------------- // Checks if new input is ready, TRUE if new input is ready // Input: unsigned int port // Output: TRUE if a call to InChar will return right away with data // FALSE if a call to InChar will wait for input char SCI_InStatus(unsigned int port); //-------------------------SCI_InChar------------------------ // Wait for new serial port input, busy-waiting synchronization // Input: unsigned int port // Output: ASCII code for key typed char SCI_InChar(unsigned int port); void SCI_InString(char* string,unsigned short max,unsigned int port); // Reads in a String of max length //----------------------SCI_InUDec------------------------------- // InUDec accepts ASCII input in unsigned decimal format // and converts to a 16 bit unsigned number // valid range is 0 to 65535 // Input: unsigned int port // Output: 16-bit unsigned number // If you enter a number above 65535, it will truncate without an error // Backspace will remove last digit typed unsigned short SCI_InUDec(unsigned int port); //---------------------SCI_InUHex---------------------------------------- // Accepts ASCII input in unsigned hexadecimal (base 16) format // Input: unsigned int port // Output: 16-bit unsigned number // No '$' or '0x' need be entered, just the 1 to 4 hex digits // It will convert lower case a-f to uppercase A-F // and converts to a 16 bit unsigned number // value range is 0 to FFFF // If you enter a number above FFFF, it will truncate without an error // Backspace will remove last digit typed unsigned short SCI_InUHex(unsigned int port); //-----------------------SCI_OutStatus---------------------------- // Checks if output data buffer is empty, TRUE if empty // Input: unsigned int port // Output: TRUE if a call to OutChar will output and return right away // FALSE if a call to OutChar will wait for output to be ready char SCI_OutStatus(unsigned int port); //-------------------------SCI_OutChar------------------------ // Wait for buffer to be empty, output 8-bit to serial port // busy-waiting synchronization // Input: 8-bit data to be transferred, unsigned int port // Output: none void SCI_OutChar(char data,unsigned int port); //-----------------------SCI_OutUDec----------------------- // Output a 16-bit number in unsigned decimal format // Input: 16-bit number to be transferred, unsigned int port // Output: none // Variable format 1-5 digits with no space before or after void SCI_OutUDec(unsigned short,unsigned int port); //-------------------------SCI_OutString------------------------ // Output String (NULL termination), busy-waiting synchronization // Input: pointer to a NULL-terminated string to be transferred, unsigned int port // Output: none void SCI_OutString(char *pt,unsigned int port); //--------------------------SCI_OutUHex---------------------------- // Output a 16 bit number in unsigned hexadecimal format // Input: 16-bit number to be transferred, unsigned int port // Output: none // Variable format 1 to 4 digits with no space before or after void SCI_OutUHex(unsigned short,unsigned int port); // filename *************** SCI.C ****************************** // Simple I/O routines to 9S12C32 serial port // Jonathan W. Valvano 1/29/04 // This example accompanies the books // "Embedded Microcomputer Systems: Real Time Interfacing", // Brooks-Cole, copyright (c) 2000, // "Introduction to Embedded Microcomputer Systems: // Motorola 6811 and 6812 Simulation", Brooks-Cole, copyright (c) 2002 // Copyright 2004 by Jonathan W. Valvano, valvano@... // You may use, edit, run or distribute this file // as long as the above copyright notice remains // Modified by EE345L students Charlie Gough && Matt Hawk // Modified by EE345M students Agustinus Darmawan + Mingjie Qiu // Modified by Steven Lamb April 28, 2004 (minor changes for g++) // Modified by Zachary Long Oct 16, 2009 (serial init (9600)updated, use of both serial ports enabled) //How To /* */ #include "hcs12.h" // io register map #include "SCI.h" #define RDRF 0x20 // Receive Data Register Full Bit #define TDRE 0x80 // Transmit Data Register Empty Bit //-------------------------SCI_Init------------------------ // Initialize Serial port SCI // Input: baudRate is tha baud rate in bits/sec // Output: none // SCIBDL = 24000000/(16 x BR) // baudRate = 2400 bits/sec SCIBDL=625 // baudRate = 4800 bits/sec SCIBDL=313 // baudRate = 9600 bits/sec SCIBDL=156 // baudRate = 19200 bits/sec SCIBDL=78 // assumes a module clock frequency of 4 MHz // sets baudRate to 9600 void SCI_Init(unsigned short baudRate, unsigned int port) { switch(port) { case 0: { SCI0BDH = 0; switch(baudRate) { case 2400: SCI0BDL=625; break; case 4800: SCI0BDL=313; break; case 9600: SCI0BDL=156; break; case 19200: SCI0BDL=78; break; default: SCI0BDL = 156 ; // 9600 } break; SCI0CR1 = 0; /* bit value meaning 7 0 LOOPS, no looping, normal 6 0 WOMS, normal high/low outputs 5 0 RSRC, not appliable with LOOPS=0 4 0 M, 1 start, 8 data, 1 stop 3 0 WAKE, wake by idle (not applicable) 2 0 ILT, short idle time (not applicable) 1 0 PE, no parity 0 0 PT, parity type (not applicable with PE=0) */ SCI0CR2 = 0x0C; /* bit value meaning 7 0 TIE, no transmit interrupts on TDRE 6 0 TCIE, no transmit interrupts on TC 5 0 RIE, no receive interrupts on RDRF 4 0 ILIE, no interrupts on idle 3 1 TE, enable transmitter 2 1 RE, enable receiver 1 0 RWU, no receiver wakeup 0 0 SBK, no send break */ break; } case 1: { SCI1BDH = 0; switch(baudRate) { case 2400: SCI1BDL=625; break; case 4800: SCI1BDL=313; break; case 9600: SCI1BDL=156; break; case 19200: SCI1BDL=78; break; default: SCI1BDL = 156 ; // 9600 } break; SCI1CR1 = 0; /* bit value meaning 7 0 LOOPS, no looping, normal 6 0 WOMS, normal high/low outputs 5 0 RSRC, not appliable with LOOPS=0 4 0 M, 1 start, 8 data, 1 stop 3 0 WAKE, wake by idle (not applicable) 2 0 ILT, short idle time (not applicable) 1 0 PE, no parity 0 0 PT, parity type (not applicable with PE=0) */ SCI1CR2 = 0x0C; /* bit value meaning 7 0 TIE, no transmit interrupts on TDRE 6 0 TCIE, no transmit interrupts on TC 5 0 RIE, no receive interrupts on RDRF 4 0 ILIE, no interrupts on idle 3 1 TE, enable transmitter 2 1 RE, enable receiver 1 0 RWU, no receiver wakeup 0 0 SBK, no send break */ break; } } } //-------------------------SCI_InChar------------------------ // Wait for new serial port input, busy-waiting synchronization // Input: int port // Output: ASCII code for key typed char SCI_InChar(unsigned int port) { switch(port) { case 0: while((SCI0SR1 & RDRF) == 0){}; return(SCI0DRL); break; case 1: while((SCI1SR1 & RDRF) == 0){}; return(SCI1DRL); break; } } //-------------------------SCI_OutChar------------------------ // Wait for buffer to be empty, output 8-bit to serial port // busy-waiting synchronization // Input: 8-bit data to be transferred // Output: none void SCI_OutChar(char data,unsigned int port) { switch(port) { case 0: while((SCI0SR1 & TDRE) == 0){}; SCI0DRL = data; break; case 1: while((SCI1SR1 & TDRE) == 0){}; SCI1DRL = data; break; } } //-------------------------SCI_InStatus-------------------------- // Checks if new input is ready, TRUE if new input is ready // Input: unsigned int port // Output: TRUE if a call to InChar will return right away with data // FALSE if a call to InChar will wait for input char SCI_InStatus(unsigned int port) { switch(port) { case 0: return(SCI0SR1 & RDRF);break; case 1: return(SCI1SR1 & RDRF);break; } } //-----------------------SCI_OutStatus---------------------------- // Checks if output data buffer is empty, TRUE if empty // Input: unsigned int port // Output: TRUE if a call to OutChar will output and return right away // FALSE if a call to OutChar will wait for output to be ready char SCI_OutStatus(unsigned int port) { switch(port) { case 0: return(SCI0SR1 & TDRE); break; case 1: return(SCI1SR1 & TDRE); break; } } //-------------------------SCI_OutString------------------------ // Output String (NULL termination), busy-waiting synchronization // Input: pointer to a NULL-terminated string to be transferred, unsigned int port // Output: none void SCI_OutString(char *pt,unsigned int port) { while(*pt){ SCI_OutChar(*pt,port); pt++; } } //----------------------SCI_InUDec------------------------------- // InUDec accepts ASCII input in unsigned decimal format // and converts to a 16 bit unsigned number // valid range is 0 to 65535 // Input: unsigned int port // Output: 16-bit unsigned number // If you enter a number above 65535, it will truncate without an error // Backspace will remove last digit typed unsigned short SCI_InUDec(unsigned int port) { unsigned short number=0, length=0; char character; character = SCI_InChar(port); while(character!=CR) // accepts until carriage return input { // The next line checks that the input is a digit, 0-9. // If the character is not 0-9, it is ignored and not echoed if((character>='0') && (character<='9')) { number = 10*number+(character-'0'); // this line overflows if above 65535 length++; SCI_OutChar(character,port); } // If the input is a backspace, then the return number is // changed and a backspace is outputted to the screen else if((character==BS) && length) { number /= 10; length--; SCI_OutChar(character,port); } character = SCI_InChar(port); } return number; } //-----------------------SCI_OutUDec----------------------- // Output a 16-bit number in unsigned decimal format // Input: 16-bit number to be transferred, unsigned int port // Output: none // Variable format 1-5 digits with no space before or after void SCI_OutUDec(unsigned short n,unsigned int port) { // This function uses recursion to convert decimal number // of unspecified length as an ASCII string if(n >= 10){ SCI_OutUDec(n/10,port); n = n%10; } SCI_OutChar(n+'0',port); /* n is between 0 and 9 */ } //---------------------SCI_InUHex---------------------------------------- // Accepts ASCII input in unsigned hexadecimal (base 16) format // Input: unsigned int port // Output: 16-bit unsigned number // No '$' or '0x' need be entered, just the 1 to 4 hex digits // It will convert lower case a-f to uppercase A-F // and converts to a 16 bit unsigned number // value range is 0 to FFFF // If you enter a number above FFFF, it will truncate without an error // Backspace will remove last digit typed unsigned short SCI_InUHex(unsigned int port){ unsigned short number=0, digit, length=0; char character; character = SCI_InChar(port); while(character!=CR){ digit = 0x10; // assume bad if((character>='0') && (character<='9')){ digit = character-'0'; } else if((character>='A') && (character<='F')){ digit = (character-'A')+0xA; } else if((character>='a') && (character<='f')){ digit = (character-'a')+0xA; } // If the character is not 0-9 or A-F, it is ignored and not echoed if(digit<=0xF ){ number = number*0x10+digit; length++; SCI_OutChar(character,port); } // Backspace outputted and return value changed if a backspace is inputted else if(character==BS && length){ number /=0x10; length--; SCI_OutChar(character,port); } character = SCI_InChar(port); } return number; } //--------------------------SCI_OutUHex---------------------------- // Output a 16 bit number in unsigned hexadecimal format // Input: 16-bit number to be transferred, unsigned int port // Output: none // Variable format 1 to 4 digits with no space before or after void SCI_OutUHex(unsigned short number,unsigned int port){ // This function uses recursion to convert the number of // unspecified length as an ASCII string if(number>=0x10) { SCI_OutUHex(number/0x10,port); SCI_OutUHex(number%0x10,port); } else if(number<0xA){ SCI_OutChar(number+'0',port); } else{ SCI_OutChar((number-0x0A)+'A',port); } } //------------------------SCI_InString------------------------ // This function accepts ASCII characters from the serial port // and adds them to a string until a carriage return is inputted // or until max length of the string is reached. // It echoes each character as it is inputted. // If a backspace is inputted, the string is modified // and the backspace is echoed // InString terminates the string with a null character // -- Modified by Agustinus Darmawan + Mingjie Qiu -- void SCI_InString(char *string,unsigned short max,unsigned int port) { int length=0; char character; character = SCI_InChar(port); while(character!=CR) { if(character==BS) { if(length) { string--; length--; SCI_OutChar(BS,port); } } else if(length<max) { *string++=character; length++; SCI_OutChar(character,port); } character = SCI_InChar(port); } *string = 0; } |
|
|
Re: Dragon Board 12 Serial Communication C code HelpProbably malloc didn't succeed
char* outData =(char*) malloc (sizeof (char*)* 5); // make room for 5 char BTW comment is wrong, should be make room for 5 pointers to char Edward ----- Original Message ----- From: <zach.r.long@...> To: <68hc12@...> Sent: Monday, October 26, 2009 10:26 PM Subject: [68HC12] Dragon Board 12 Serial Communication C code Help > Hello all, I am hoping someone has some incite as to what I am doing wrong > here, I figure it is a small problem but I am out of ideas. This is just a > test to figure out how to pass char * through methods. The code should > print Hello World to the serial port which it does, then print tes > repeatedly, which it does not, rather the output is as follows: > > Hello World""""""""""""""""""""""""""""""""""""""""""""""""""""""" > """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" > > Here is the code, also below is the sci.c and sci.h that do the actually > serial communication. > > Thank You in advanced ! > > Zach Long > > MAIN: > > #include "sci.h" > > int main(void); > void encode(char *out); > > int main(void) > { > char* head = "Hello World"; // declare first print statement > char* outData =(char*) malloc (sizeof (char*)* 5); // make room for 5 char > > SCI_Init(9600,0); //Startup serial port 0(under LCD) at 9600 BAUD > SCI_OutStatus(1); // Is it clear to send (buffer empty) > SCI_OutString(head,0); // print "Hello World" to serial port (WORKS !!) > > while(1) > { > if(SCI_OutStatus(0))// Is it clear to send (buffer empty) > { > encode(outData);//,out.throt,out.heading); // build output > SCI_OutString(outData,0); // print out put to serial port > } > } > return 0; > } > > void encode(char *out) // take in pointer and fill with chars > { > out[0] = 't'; > out[1] = 'e'; > out[2] = 's'; > out[3] = 0; > } > > SCI include: > > // filename ******************* SCI.H ************************** > // Jonathan W. Valvano 1/29/04 > > // This example accompanies the books > // "Embedded Microcomputer Systems: Real Time Interfacing", > // Brooks-Cole, copyright (c) 2000, > // "Introduction to Embedded Microcomputer Systems: > // Motorola 6811 and 6812 Simulation", Brooks-Cole, copyright (c) 2002 > > // Copyright 2004 by Jonathan W. Valvano, valvano@... > // You may use, edit, run or distribute this file > // as long as the above copyright notice remains > // Modified by EE345L students Charlie Gough && Matt Hawk > // Modified by EE345M students Agustinus Darmawan + Mingjie Qiu > // Modified by Zachary Long Oct 16, 2009 (setup for Dragon Board 12 9600 > BAUD, use of both serial ports enabled) > > //How To > /* > Each method has an unsigned int port parameter, this specifices the > serial port > the method will act on. Dragon Board 12: Serial port under LCD (top) = > 0, Serial port near power plug (bottom) = 1 > */ > > // standard ASCII symbols > #define CR 0x0D > #define LF 0x0A > #define BS 0x08 > #define ESC 0x1B > #define SP 0x20 > #define DEL 0x7F > > //-------------------------SCI_Init------------------------ > //-------------------------SCI_Init------------------------ > // Initialize Serial port SCI > // Input: baudRate is tha baud rate in bits/sec > // Output: none > // SCIBDL = 24000000/(16 x BR) > // baudRate = 2400 bits/sec SCIBDL=625 > // baudRate = 4800 bits/sec SCIBDL=313 > // baudRate = 9600 bits/sec SCIBDL=156 > // baudRate = 19200 bits/sec SCIBDL=78 > // assumes a module clock frequency of 4 MHz > // sets baudRate to 9600 > void SCI_Init(unsigned short baudRate,unsigned int port); > > //-------------------------SCI_InStatus-------------------------- > // Checks if new input is ready, TRUE if new input is ready > // Input: unsigned int port > // Output: TRUE if a call to InChar will return right away with data > // FALSE if a call to InChar will wait for input > char SCI_InStatus(unsigned int port); > > //-------------------------SCI_InChar------------------------ > // Wait for new serial port input, busy-waiting synchronization > // Input: unsigned int port > // Output: ASCII code for key typed > char SCI_InChar(unsigned int port); > > void SCI_InString(char* string,unsigned short max,unsigned int port); // > Reads in a String of max length > > //----------------------SCI_InUDec------------------------------- > // InUDec accepts ASCII input in unsigned decimal format > // and converts to a 16 bit unsigned number > // valid range is 0 to 65535 > // Input: unsigned int port > // Output: 16-bit unsigned number > // If you enter a number above 65535, it will truncate without an error > // Backspace will remove last digit typed > unsigned short SCI_InUDec(unsigned int port); > > //---------------------SCI_InUHex---------------------------------------- > // Accepts ASCII input in unsigned hexadecimal (base 16) format > // Input: unsigned int port > // Output: 16-bit unsigned number > // No '$' or '0x' need be entered, just the 1 to 4 hex digits > // It will convert lower case a-f to uppercase A-F > // and converts to a 16 bit unsigned number > // value range is 0 to FFFF > // If you enter a number above FFFF, it will truncate without an error > // Backspace will remove last digit typed > unsigned short SCI_InUHex(unsigned int port); > > //-----------------------SCI_OutStatus---------------------------- > // Checks if output data buffer is empty, TRUE if empty > // Input: unsigned int port > // Output: TRUE if a call to OutChar will output and return right away > // FALSE if a call to OutChar will wait for output to be ready > char SCI_OutStatus(unsigned int port); > > //-------------------------SCI_OutChar------------------------ > // Wait for buffer to be empty, output 8-bit to serial port > // busy-waiting synchronization > // Input: 8-bit data to be transferred, unsigned int port > // Output: none > void SCI_OutChar(char data,unsigned int port); > > //-----------------------SCI_OutUDec----------------------- > // Output a 16-bit number in unsigned decimal format > // Input: 16-bit number to be transferred, unsigned int port > // Output: none > // Variable format 1-5 digits with no space before or after > void SCI_OutUDec(unsigned short,unsigned int port); > > //-------------------------SCI_OutString------------------------ > // Output String (NULL termination), busy-waiting synchronization > // Input: pointer to a NULL-terminated string to be transferred, unsigned > int port > // Output: none > void SCI_OutString(char *pt,unsigned int port); > > //--------------------------SCI_OutUHex---------------------------- > // Output a 16 bit number in unsigned hexadecimal format > // Input: 16-bit number to be transferred, unsigned int port > // Output: none > // Variable format 1 to 4 digits with no space before or after > void SCI_OutUHex(unsigned short,unsigned int port); > > > > // filename *************** SCI.C ****************************** > // Simple I/O routines to 9S12C32 serial port > // Jonathan W. Valvano 1/29/04 > > // This example accompanies the books > // "Embedded Microcomputer Systems: Real Time Interfacing", > // Brooks-Cole, copyright (c) 2000, > // "Introduction to Embedded Microcomputer Systems: > // Motorola 6811 and 6812 Simulation", Brooks-Cole, copyright (c) 2002 > > // Copyright 2004 by Jonathan W. Valvano, valvano@... > // You may use, edit, run or distribute this file > // as long as the above copyright notice remains > // Modified by EE345L students Charlie Gough && Matt Hawk > // Modified by EE345M students Agustinus Darmawan + Mingjie Qiu > // Modified by Steven Lamb April 28, 2004 (minor changes for g++) > // Modified by Zachary Long Oct 16, 2009 (serial init (9600)updated, use > of both serial ports enabled) > > > //How To > /* > > */ > > #include "hcs12.h" // io register map > #include "SCI.h" > #define RDRF 0x20 // Receive Data Register Full Bit > #define TDRE 0x80 // Transmit Data Register Empty Bit > > > //-------------------------SCI_Init------------------------ > // Initialize Serial port SCI > // Input: baudRate is tha baud rate in bits/sec > // Output: none > // SCIBDL = 24000000/(16 x BR) > // baudRate = 2400 bits/sec SCIBDL=625 > // baudRate = 4800 bits/sec SCIBDL=313 > // baudRate = 9600 bits/sec SCIBDL=156 > // baudRate = 19200 bits/sec SCIBDL=78 > // assumes a module clock frequency of 4 MHz > // sets baudRate to 9600 > void SCI_Init(unsigned short baudRate, unsigned int port) > { > switch(port) > { > case 0: > { > SCI0BDH = 0; > switch(baudRate) > { > case 2400: SCI0BDL=625; break; > case 4800: SCI0BDL=313; break; > case 9600: SCI0BDL=156; break; > case 19200: SCI0BDL=78; break; > default: SCI0BDL = 156 ; // 9600 > } > break; > > SCI0CR1 = 0; > /* bit value meaning > 7 0 LOOPS, no looping, normal > 6 0 WOMS, normal high/low outputs > 5 0 RSRC, not appliable with LOOPS=0 > 4 0 M, 1 start, 8 data, 1 stop > 3 0 WAKE, wake by idle (not applicable) > 2 0 ILT, short idle time (not applicable) > 1 0 PE, no parity > 0 0 PT, parity type (not applicable with PE=0) > */ > > SCI0CR2 = 0x0C; > /* bit value meaning > 7 0 TIE, no transmit interrupts on TDRE > 6 0 TCIE, no transmit interrupts on TC > 5 0 RIE, no receive interrupts on RDRF > 4 0 ILIE, no interrupts on idle > 3 1 TE, enable transmitter > 2 1 RE, enable receiver > 1 0 RWU, no receiver wakeup > 0 0 SBK, no send break > */ > break; > } > case 1: > { > SCI1BDH = 0; > switch(baudRate) > { > case 2400: SCI1BDL=625; break; > case 4800: SCI1BDL=313; break; > case 9600: SCI1BDL=156; break; > case 19200: SCI1BDL=78; break; > default: SCI1BDL = 156 ; // 9600 > } > break; > > SCI1CR1 = 0; > /* bit value meaning > 7 0 LOOPS, no looping, normal > 6 0 WOMS, normal high/low outputs > 5 0 RSRC, not appliable with LOOPS=0 > 4 0 M, 1 start, 8 data, 1 stop > 3 0 WAKE, wake by idle (not applicable) > 2 0 ILT, short idle time (not applicable) > 1 0 PE, no parity > 0 0 PT, parity type (not applicable with PE=0) > */ > > SCI1CR2 = 0x0C; > /* bit value meaning > 7 0 TIE, no transmit interrupts on TDRE > 6 0 TCIE, no transmit interrupts on TC > 5 0 RIE, no receive interrupts on RDRF > 4 0 ILIE, no interrupts on idle > 3 1 TE, enable transmitter > 2 1 RE, enable receiver > 1 0 RWU, no receiver wakeup > 0 0 SBK, no send break > */ > break; > } > } > } > > > //-------------------------SCI_InChar------------------------ > // Wait for new serial port input, busy-waiting synchronization > // Input: int port > // Output: ASCII code for key typed > char SCI_InChar(unsigned int port) > { > switch(port) > { > case 0: > while((SCI0SR1 & RDRF) == 0){}; > return(SCI0DRL); > break; > case 1: > while((SCI1SR1 & RDRF) == 0){}; > return(SCI1DRL); > break; > } > } > > //-------------------------SCI_OutChar------------------------ > // Wait for buffer to be empty, output 8-bit to serial port > // busy-waiting synchronization > // Input: 8-bit data to be transferred > // Output: none > void SCI_OutChar(char data,unsigned int port) > { > switch(port) > { > case 0: > while((SCI0SR1 & TDRE) == 0){}; > SCI0DRL = data; > break; > case 1: > while((SCI1SR1 & TDRE) == 0){}; > SCI1DRL = data; > break; > } > } > > //-------------------------SCI_InStatus-------------------------- > // Checks if new input is ready, TRUE if new input is ready > // Input: unsigned int port > // Output: TRUE if a call to InChar will return right away with data > // FALSE if a call to InChar will wait for input > char SCI_InStatus(unsigned int port) > { > switch(port) > { > case 0: > return(SCI0SR1 & RDRF);break; > case 1: > return(SCI1SR1 & RDRF);break; > } > } > //-----------------------SCI_OutStatus---------------------------- > // Checks if output data buffer is empty, TRUE if empty > // Input: unsigned int port > // Output: TRUE if a call to OutChar will output and return right away > // FALSE if a call to OutChar will wait for output to be ready > char SCI_OutStatus(unsigned int port) > { > switch(port) > { > case 0: > return(SCI0SR1 & TDRE); > break; > case 1: > return(SCI1SR1 & TDRE); > break; > } > } > > > //-------------------------SCI_OutString------------------------ > // Output String (NULL termination), busy-waiting synchronization > // Input: pointer to a NULL-terminated string to be transferred, unsigned > int port > // Output: none > void SCI_OutString(char *pt,unsigned int port) > { > while(*pt){ > SCI_OutChar(*pt,port); > pt++; > } > } > > //----------------------SCI_InUDec------------------------------- > // InUDec accepts ASCII input in unsigned decimal format > // and converts to a 16 bit unsigned number > // valid range is 0 to 65535 > // Input: unsigned int port > // Output: 16-bit unsigned number > // If you enter a number above 65535, it will truncate without an error > // Backspace will remove last digit typed > unsigned short SCI_InUDec(unsigned int port) > { > unsigned short number=0, length=0; > char character; > character = SCI_InChar(port); > while(character!=CR) // accepts until carriage return input > { > // The next line checks that the input is a digit, 0-9. > // If the character is not 0-9, it is ignored and not echoed > if((character>='0') && (character<='9')) > { > number = 10*number+(character-'0'); // this line overflows if > above 65535 > length++; > SCI_OutChar(character,port); > } > // If the input is a backspace, then the return number is > // changed and a backspace is outputted to the screen > else if((character==BS) && length) > { > number /= 10; > length--; > SCI_OutChar(character,port); > } > character = SCI_InChar(port); > } > return number; > } > > > //-----------------------SCI_OutUDec----------------------- > // Output a 16-bit number in unsigned decimal format > // Input: 16-bit number to be transferred, unsigned int port > // Output: none > // Variable format 1-5 digits with no space before or after > void SCI_OutUDec(unsigned short n,unsigned int port) > { > // This function uses recursion to convert decimal number > // of unspecified length as an ASCII string > if(n >= 10){ > SCI_OutUDec(n/10,port); > n = n%10; > } > SCI_OutChar(n+'0',port); /* n is between 0 and 9 */ > } > > > > //---------------------SCI_InUHex---------------------------------------- > // Accepts ASCII input in unsigned hexadecimal (base 16) format > // Input: unsigned int port > // Output: 16-bit unsigned number > // No '$' or '0x' need be entered, just the 1 to 4 hex digits > // It will convert lower case a-f to uppercase A-F > // and converts to a 16 bit unsigned number > // value range is 0 to FFFF > // If you enter a number above FFFF, it will truncate without an error > // Backspace will remove last digit typed > unsigned short SCI_InUHex(unsigned int port){ > unsigned short number=0, digit, length=0; > char character; > character = SCI_InChar(port); > while(character!=CR){ > digit = 0x10; // assume bad > if((character>='0') && (character<='9')){ > digit = character-'0'; > } > else if((character>='A') && (character<='F')){ > digit = (character-'A')+0xA; > } > else if((character>='a') && (character<='f')){ > digit = (character-'a')+0xA; > } > // If the character is not 0-9 or A-F, it is ignored and not echoed > if(digit<=0xF ){ > number = number*0x10+digit; > length++; > SCI_OutChar(character,port); > } > // Backspace outputted and return value changed if a backspace is inputted > else if(character==BS && length){ > number /=0x10; > length--; > SCI_OutChar(character,port); > } > character = SCI_InChar(port); > } > return number; > } > > //--------------------------SCI_OutUHex---------------------------- > // Output a 16 bit number in unsigned hexadecimal format > // Input: 16-bit number to be transferred, unsigned int port > // Output: none > // Variable format 1 to 4 digits with no space before or after > void SCI_OutUHex(unsigned short number,unsigned int port){ > // This function uses recursion to convert the number of > // unspecified length as an ASCII string > if(number>=0x10) { > SCI_OutUHex(number/0x10,port); > SCI_OutUHex(number%0x10,port); > } > else if(number<0xA){ > SCI_OutChar(number+'0',port); > } > else{ > SCI_OutChar((number-0x0A)+'A',port); > } > } > > //------------------------SCI_InString------------------------ > // This function accepts ASCII characters from the serial port > // and adds them to a string until a carriage return is inputted > // or until max length of the string is reached. > // It echoes each character as it is inputted. > // If a backspace is inputted, the string is modified > // and the backspace is echoed > // InString terminates the string with a null character > // -- Modified by Agustinus Darmawan + Mingjie Qiu -- > void SCI_InString(char *string,unsigned short max,unsigned int port) > { > int length=0; > char character; > character = SCI_InChar(port); > while(character!=CR) > { > if(character==BS) > { > if(length) > { > string--; > length--; > SCI_OutChar(BS,port); > } > } > else if(length<max) > { > *string++=character; > length++; > SCI_OutChar(character,port); > } > character = SCI_InChar(port); > } > *string = 0; > } > > > > > > ------------------------------------ > > Yahoo! Groups Links > > > |
|
|
Re: Dragon Board 12 Serial Communication C code Help > Edward Karpicz writes on 12:51 AM 10/27/2009
>Probably malloc didn't succeed > >char* outData =(char*) malloc (sizeof (char*)* 5); // make room for 5 char > >BTW comment is wrong, should be make room for 5 pointers to char Both points are good. Furthermore, for this series of processors or smaller and generally in embedded systems, avoid malloc and free. These smaller processors are just not that good at supporting dynamic memory. For a Freescale PowerPC with 100's of MB of memory - fine, dynamic memory using malloc and free can be used. But you must always consider that memory can fragment and requests for memory can fail over long runs of the program (malloc returns NULL on error). I'm not looking for a big debate on malloc/free in an embedded system. On a system with less than 32MB of RAM, I just don't do it - ever. Bill >Edward > >----- Original Message ----- >From: <<mailto:zach.r.long%40gmail.com>zach.r.long@...> >To: <<mailto:68hc12%40yahoogroups.com>68hc12@...> >Sent: Monday, October 26, 2009 10:26 PM >Subject: [68HC12] Dragon Board 12 Serial Communication C code Help > > > Hello all, I am hoping someone has some incite as to what I am doing wrong > > here, I figure it is a small problem but I am out of ideas. This is just a > > test to figure out how to pass char * through methods. The code should > > print Hello World to the serial port which it does, then print tes > > repeatedly, which it does not, rather the output is as follows: > > > > Hello World""""""""""""""""""""""""""""""""""""""""""""""""""""""" > > """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" > > > > Here is the code, also below is the sci.c and sci.h that do the actually > > serial communication. > > > > Thank You in advanced ! > > > > Zach Long > > > > MAIN: > > > > #include "sci.h" > > > > int main(void); > > void encode(char *out); > > > > int main(void) > > { > > char* head = "Hello World"; // declare first print statement > > char* outData =(char*) malloc (sizeof (char*)* 5); // make room for 5 char > > > > SCI_Init(9600,0); //Startup serial port 0(under LCD) at 9600 BAUD > > SCI_OutStatus(1); // Is it clear to send (buffer empty) > > SCI_OutString(head,0); // print "Hello World" to serial port (WORKS !!) > > > > while(1) > > { > > if(SCI_OutStatus(0))// Is it clear to send (buffer empty) > > { > > encode(outData);//,out.throt,out.heading); // build output > > SCI_OutString(outData,0); // print out put to serial port > > } > > } > > return 0; > > } > > > > void encode(char *out) // take in pointer and fill with chars > > { > > out[0] = 't'; > > out[1] = 'e'; > > out[2] = 's'; > > out[3] = 0; > > } > > > > SCI include: > > > > // filename ******************* SCI.H ************************** > > // Jonathan W. Valvano 1/29/04 > > > > // This example accompanies the books > > // "Embedded Microcomputer Systems: Real Time Interfacing", > > // Brooks-Cole, copyright (c) 2000, > > // "Introduction to Embedded Microcomputer Systems: > > // Motorola 6811 and 6812 Simulation", Brooks-Cole, copyright (c) 2002 > > > > // Copyright 2004 by Jonathan W. Valvano, > <mailto:valvano%40mail.utexas.edu>valvano@... > > // You may use, edit, run or distribute this file > > // as long as the above copyright notice remains > > // Modified by EE345L students Charlie Gough && Matt Hawk > > // Modified by EE345M students Agustinus Darmawan + Mingjie Qiu > > // Modified by Zachary Long Oct 16, 2009 (setup for Dragon Board 12 9600 > > BAUD, use of both serial ports enabled) > > > > //How To > > /* > > Each method has an unsigned int port parameter, this specifices the > > serial port > > the method will act on. Dragon Board 12: Serial port under LCD (top) = > > 0, Serial port near power plug (bottom) = 1 > > */ > > > > // standard ASCII symbols > > #define CR 0x0D > > #define LF 0x0A > > #define BS 0x08 > > #define ESC 0x1B > > #define SP 0x20 > > #define DEL 0x7F > > > > //-------------------------SCI_Init------------------------ > > //-------------------------SCI_Init------------------------ > > // Initialize Serial port SCI > > // Input: baudRate is tha baud rate in bits/sec > > // Output: none > > // SCIBDL = 24000000/(16 x BR) > > // baudRate = 2400 bits/sec SCIBDL=625 > > // baudRate = 4800 bits/sec SCIBDL=313 > > // baudRate = 9600 bits/sec SCIBDL=156 > > // baudRate = 19200 bits/sec SCIBDL=78 > > // assumes a module clock frequency of 4 MHz > > // sets baudRate to 9600 > > void SCI_Init(unsigned short baudRate,unsigned int port); > > > > //-------------------------SCI_InStatus-------------------------- > > // Checks if new input is ready, TRUE if new input is ready > > // Input: unsigned int port > > // Output: TRUE if a call to InChar will return right away with data > > // FALSE if a call to InChar will wait for input > > char SCI_InStatus(unsigned int port); > > > > //-------------------------SCI_InChar------------------------ > > // Wait for new serial port input, busy-waiting synchronization > > // Input: unsigned int port > > // Output: ASCII code for key typed > > char SCI_InChar(unsigned int port); > > > > void SCI_InString(char* string,unsigned short max,unsigned int port); // > > Reads in a String of max length > > > > //----------------------SCI_InUDec------------------------------- > > // InUDec accepts ASCII input in unsigned decimal format > > // and converts to a 16 bit unsigned number > > // valid range is 0 to 65535 > > // Input: unsigned int port > > // Output: 16-bit unsigned number > > // If you enter a number above 65535, it will truncate without an error > > // Backspace will remove last digit typed > > unsigned short SCI_InUDec(unsigned int port); > > > > //---------------------SCI_InUHex---------------------------------------- > > // Accepts ASCII input in unsigned hexadecimal (base 16) format > > // Input: unsigned int port > > // Output: 16-bit unsigned number > > // No '$' or '0x' need be entered, just the 1 to 4 hex digits > > // It will convert lower case a-f to uppercase A-F > > // and converts to a 16 bit unsigned number > > // value range is 0 to FFFF > > // If you enter a number above FFFF, it will truncate without an error > > // Backspace will remove last digit typed > > unsigned short SCI_InUHex(unsigned int port); > > > > //-----------------------SCI_OutStatus---------------------------- > > // Checks if output data buffer is empty, TRUE if empty > > // Input: unsigned int port > > // Output: TRUE if a call to OutChar will output and return right away > > // FALSE if a call to OutChar will wait for output to be ready > > char SCI_OutStatus(unsigned int port); > > > > //-------------------------SCI_OutChar------------------------ > > // Wait for buffer to be empty, output 8-bit to serial port > > // busy-waiting synchronization > > // Input: 8-bit data to be transferred, unsigned int port > > // Output: none > > void SCI_OutChar(char data,unsigned int port); > > > > //-----------------------SCI_OutUDec----------------------- > > // Output a 16-bit number in unsigned decimal format > > // Input: 16-bit number to be transferred, unsigned int port > > // Output: none > > // Variable format 1-5 digits with no space before or after > > void SCI_OutUDec(unsigned short,unsigned int port); > > > > //-------------------------SCI_OutString------------------------ > > // Output String (NULL termination), busy-waiting synchronization > > // Input: pointer to a NULL-terminated string to be transferred, unsigned > > int port > > // Output: none > > void SCI_OutString(char *pt,unsigned int port); > > > > //--------------------------SCI_OutUHex---------------------------- > > // Output a 16 bit number in unsigned hexadecimal format > > // Input: 16-bit number to be transferred, unsigned int port > > // Output: none > > // Variable format 1 to 4 digits with no space before or after > > void SCI_OutUHex(unsigned short,unsigned int port); > > > > > > > > // filename *************** SCI.C ****************************** > > // Simple I/O routines to 9S12C32 serial port > > // Jonathan W. Valvano 1/29/04 > > > > // This example accompanies the books > > // "Embedded Microcomputer Systems: Real Time Interfacing", > > // Brooks-Cole, copyright (c) 2000, > > // "Introduction to Embedded Microcomputer Systems: > > // Motorola 6811 and 6812 Simulation", Brooks-Cole, copyright (c) 2002 > > > > // Copyright 2004 by Jonathan W. Valvano, > <mailto:valvano%40mail.utexas.edu>valvano@... > > // You may use, edit, run or distribute this file > > // as long as the above copyright notice remains > > // Modified by EE345L students Charlie Gough && Matt Hawk > > // Modified by EE345M students Agustinus Darmawan + Mingjie Qiu > > // Modified by Steven Lamb April 28, 2004 (minor changes for g++) > > // Modified by Zachary Long Oct 16, 2009 (serial init (9600)updated, use > > of both serial ports enabled) > > > > > > //How To > > /* > > > > */ > > > > #include "hcs12.h" // io register map > > #include "SCI.h" > > #define RDRF 0x20 // Receive Data Register Full Bit > > #define TDRE 0x80 // Transmit Data Register Empty Bit > > > > > > //-------------------------SCI_Init------------------------ > > // Initialize Serial port SCI > > // Input: baudRate is tha baud rate in bits/sec > > // Output: none > > // SCIBDL = 24000000/(16 x BR) > > // baudRate = 2400 bits/sec SCIBDL=625 > > // baudRate = 4800 bits/sec SCIBDL=313 > > // baudRate = 9600 bits/sec SCIBDL=156 > > // baudRate = 19200 bits/sec SCIBDL=78 > > // assumes a module clock frequency of 4 MHz > > // sets baudRate to 9600 > > void SCI_Init(unsigned short baudRate, unsigned int port) > > { > > switch(port) > > { > > case 0: > > { > > SCI0BDH = 0; > > switch(baudRate) > > { > > case 2400: SCI0BDL=625; break; > > case 4800: SCI0BDL=313; break; > > case 9600: SCI0BDL=156; break; > > case 19200: SCI0BDL=78; break; > > default: SCI0BDL = 156 ; // 9600 > > } > > break; > > > > SCI0CR1 = 0; > > /* bit value meaning > > 7 0 LOOPS, no looping, normal > > 6 0 WOMS, normal high/low outputs > > 5 0 RSRC, not appliable with LOOPS=0 > > 4 0 M, 1 start, 8 data, 1 stop > > 3 0 WAKE, wake by idle (not applicable) > > 2 0 ILT, short idle time (not applicable) > > 1 0 PE, no parity > > 0 0 PT, parity type (not applicable with PE=0) > > */ > > > > SCI0CR2 = 0x0C; > > /* bit value meaning > > 7 0 TIE, no transmit interrupts on TDRE > > 6 0 TCIE, no transmit interrupts on TC > > 5 0 RIE, no receive interrupts on RDRF > > 4 0 ILIE, no interrupts on idle > > 3 1 TE, enable transmitter > > 2 1 RE, enable receiver > > 1 0 RWU, no receiver wakeup > > 0 0 SBK, no send break > > */ > > break; > > } > > case 1: > > { > > SCI1BDH = 0; > > switch(baudRate) > > { > > case 2400: SCI1BDL=625; break; > > case 4800: SCI1BDL=313; break; > > case 9600: SCI1BDL=156; break; > > case 19200: SCI1BDL=78; break; > > default: SCI1BDL = 156 ; // 9600 > > } > > break; > > > > SCI1CR1 = 0; > > /* bit value meaning > > 7 0 LOOPS, no looping, normal > > 6 0 WOMS, normal high/low outputs > > 5 0 RSRC, not appliable with LOOPS=0 > > 4 0 M, 1 start, 8 data, 1 stop > > 3 0 WAKE, wake by idle (not applicable) > > 2 0 ILT, short idle time (not applicable) > > 1 0 PE, no parity > > 0 0 PT, parity type (not applicable with PE=0) > > */ > > > > SCI1CR2 = 0x0C; > > /* bit value meaning > > 7 0 TIE, no transmit interrupts on TDRE > > 6 0 TCIE, no transmit interrupts on TC > > 5 0 RIE, no receive interrupts on RDRF > > 4 0 ILIE, no interrupts on idle > > 3 1 TE, enable transmitter > > 2 1 RE, enable receiver > > 1 0 RWU, no receiver wakeup > > 0 0 SBK, no send break > > */ > > break; > > } > > } > > } > > > > > > //-------------------------SCI_InChar------------------------ > > // Wait for new serial port input, busy-waiting synchronization > > // Input: int port > > // Output: ASCII code for key typed > > char SCI_InChar(unsigned int port) > > { > > switch(port) > > { > > case 0: > > while((SCI0SR1 & RDRF) == 0){}; > > return(SCI0DRL); > > break; > > case 1: > > while((SCI1SR1 & RDRF) == 0){}; > > return(SCI1DRL); > > break; > > } > > } > > > > //-------------------------SCI_OutChar------------------------ > > // Wait for buffer to be empty, output 8-bit to serial port > > // busy-waiting synchronization > > // Input: 8-bit data to be transferred > > // Output: none > > void SCI_OutChar(char data,unsigned int port) > > { > > switch(port) > > { > > case 0: > > while((SCI0SR1 & TDRE) == 0){}; > > SCI0DRL = data; > > break; > > case 1: > > while((SCI1SR1 & TDRE) == 0){}; > > SCI1DRL = data; > > break; > > } > > } > > > > //-------------------------SCI_InStatus-------------------------- > > // Checks if new input is ready, TRUE if new input is ready > > // Input: unsigned int port > > // Output: TRUE if a call to InChar will return right away with data > > // FALSE if a call to InChar will wait for input > > char SCI_InStatus(unsigned int port) > > { > > switch(port) > > { > > case 0: > > return(SCI0SR1 & RDRF);break; > > case 1: > > return(SCI1SR1 & RDRF);break; > > } > > } > > //-----------------------SCI_OutStatus---------------------------- > > // Checks if output data buffer is empty, TRUE if empty > > // Input: unsigned int port > > // Output: TRUE if a call to OutChar will output and return right away > > // FALSE if a call to OutChar will wait for output to be ready > > char SCI_OutStatus(unsigned int port) > > { > > switch(port) > > { > > case 0: > > return(SCI0SR1 & TDRE); > > break; > > case 1: > > return(SCI1SR1 & TDRE); > > break; > > } > > } > > > > > > //-------------------------SCI_OutString------------------------ > > // Output String (NULL termination), busy-waiting synchronization > > // Input: pointer to a NULL-terminated string to be transferred, unsigned > > int port > > // Output: none > > void SCI_OutString(char *pt,unsigned int port) > > { > > while(*pt){ > > SCI_OutChar(*pt,port); > > pt++; > > } > > } > > > > //----------------------SCI_InUDec------------------------------- > > // InUDec accepts ASCII input in unsigned decimal format > > // and converts to a 16 bit unsigned number > > // valid range is 0 to 65535 > > // Input: unsigned int port > > // Output: 16-bit unsigned number > > // If you enter a number above 65535, it will truncate without an error > > // Backspace will remove last digit typed > > unsigned short SCI_InUDec(unsigned int port) > > { > > unsigned short number=0, length=0; > > char character; > > character = SCI_InChar(port); > > while(character!=CR) // accepts until carriage return input > > { > > // The next line checks that the input is a digit, 0-9. > > // If the character is not 0-9, it is ignored and not echoed > > if((character>='0') && (character<='9')) > > { > > number = 10*number+(character-'0'); // this line overflows if > > above 65535 > > length++; > > SCI_OutChar(character,port); > > } > > // If the input is a backspace, then the return number is > > // changed and a backspace is outputted to the screen > > else if((character==BS) && length) > > { > > number /= 10; > > length--; > > SCI_OutChar(character,port); > > } > > character = SCI_InChar(port); > > } > > return number; > > } > > > > > > //-----------------------SCI_OutUDec----------------------- > > // Output a 16-bit number in unsigned decimal format > > // Input: 16-bit number to be transferred, unsigned int port > > // Output: none > > // Variable format 1-5 digits with no space before or after > > void SCI_OutUDec(unsigned short n,unsigned int port) > > { > > // This function uses recursion to convert decimal number > > // of unspecified length as an ASCII string > > if(n >= 10){ > > SCI_OutUDec(n/10,port); > > n = n%10; > > } > > SCI_OutChar(n+'0',port); /* n is between 0 and 9 */ > > } > > > > > > > > //---------------------SCI_InUHex---------------------------------------- > > // Accepts ASCII input in unsigned hexadecimal (base 16) format > > // Input: unsigned int port > > // Output: 16-bit unsigned number > > // No '$' or '0x' need be entered, just the 1 to 4 hex digits > > // It will convert lower case a-f to uppercase A-F > > // and converts to a 16 bit unsigned number > > // value range is 0 to FFFF > > // If you enter a number above FFFF, it will truncate without an error > > // Backspace will remove last digit typed > > unsigned short SCI_InUHex(unsigned int port){ > > unsigned short number=0, digit, length=0; > > char character; > > character = SCI_InChar(port); > > while(character!=CR){ > > digit = 0x10; // assume bad > > if((character>='0') && (character<='9')){ > > digit = character-'0'; > > } > > else if((character>='A') && (character<='F')){ > > digit = (character-'A')+0xA; > > } > > else if((character>='a') && (character<='f')){ > > digit = (character-'a')+0xA; > > } > > // If the character is not 0-9 or A-F, it is ignored and not echoed > > if(digit<=0xF ){ > > number = number*0x10+digit; > > length++; > > SCI_OutChar(character,port); > > } > > // Backspace outputted and return value changed if a backspace is inputted > > else if(character==BS && length){ > > number /=0x10; > > length--; > > SCI_OutChar(character,port); > > } > > character = SCI_InChar(port); > > } > > return number; > > } > > > > //--------------------------SCI_OutUHex---------------------------- > > // Output a 16 bit number in unsigned hexadecimal format > > // Input: 16-bit number to be transferred, unsigned int port > > // Output: none > > // Variable format 1 to 4 digits with no space before or after > > void SCI_OutUHex(unsigned short number,unsigned int port){ > > // This function uses recursion to convert the number of > > // unspecified length as an ASCII string > > if(number>=0x10) { > > SCI_OutUHex(number/0x10,port); > > SCI_OutUHex(number%0x10,port); > > } > > else if(number<0xA){ > > SCI_OutChar(number+'0',port); > > } > > else{ > > SCI_OutChar((number-0x0A)+'A',port); > > } > > } > > > > //------------------------SCI_InString------------------------ > > // This function accepts ASCII characters from the serial port > > // and adds them to a string until a carriage return is inputted > > // or until max length of the string is reached. > > // It echoes each character as it is inputted. > > // If a backspace is inputted, the string is modified > > // and the backspace is echoed > > // InString terminates the string with a null character > > // -- Modified by Agustinus Darmawan + Mingjie Qiu -- > > void SCI_InString(char *string,unsigned short max,unsigned int port) > > { > > int length=0; > > char character; > > character = SCI_InChar(port); > > while(character!=CR) > > { > > if(character==BS) > > { > > if(length) > > { > > string--; > > length--; > > SCI_OutChar(BS,port); > > } > > } > > else if(length<max) > > { > > *string++=character; > > length++; > > SCI_OutChar(character,port); > > } > > character = SCI_InChar(port); > > } > > *string = 0; > > } > > > > > > > > > > > > ------------------------------------ > > > > Yahoo! Groups Links > > > > > > > > [Non-text portions of this message have been removed] |
|
|
Re: Dragon Board 12 Serial Communication C code HelpI agree that malloc failed and it is passing back 0 to indicate that
it failed, and you are using that as an address of your string. Please have some empathy for the programmer that has to figure out your bugs. Check your return codes, don't use malloc, calloc, realloc, global variables, GOTOs, or "magic numbers". A On 2009-October-26, at 11:01 PM, Bill Auerbach wrote: > > Furthermore, for this series of processors or smaller and generally > in embedded systems, avoid malloc and free. > [Non-text portions of this message have been removed] |
|
|
|
|
|
Re: Dragon Board 12 Serial Communication C code HelpZach,
The code for the serial port looks OK, although for production code it would benefit from a code review. SCI_OutStatus(1); // Is it clear to send (buffer empty) This returns the status, so as is in main does nothing. Since SCI_OutString checks the SCI status for each character, testing the status before the call isn't needed anyway. The following might work (I don't have a running system or I would run it). Bill ------------- int main(void) { char* head = "Hello World"; // declare first print statement char outData[5]; // make room for 5 char SCI_Init(9600,0); //Startup serial port 0(under LCD) at 9600 BAUD SCI_OutStatus(1); // Is it clear to send (buffer empty) SCI_OutString(head,0); // print "Hello World" to serial port (WORKS !!) while(1) { if(SCI_OutStatus(0))// Is it clear to send (buffer empty) { encode(outData);//,out.throt,out.heading); // build output SCI_OutString(outData,0); // print out put to serial port } } return 0; } void encode(char *out) // take in pointer and fill with chars { out[0] = 't'; out[1] = 'e'; out[2] = 's'; out[3] = 0; } --- In 68HC12@..., zach.r.long@... wrote: > > Thanks everyone, your comments on not using malloc make sense for this system, however I am still left with the issue of incorrect output, and the thought of how that pointer works if it is never assigned to memory. Not to get side tracked, if anyone has any working examples of printing variable data to the serial port I would be very interested in seeing it, since this is the goal of this series of post. > > > Thank You, > > Zach > |
|
|
Re: Re: Dragon Board 12 Serial Communication C code HelpOkay, let's take a look at the output and the evidence and make some
wild ass guesses. You can assume that SCI_OutString is okay since 1) the "Hello World" comes out okay and 2) it is what is known as gospel code - written by a god like being and written in a book. Next, in your message you say "then print tes repeatedly". Well, it isn't printing tes (plural of T??) it is printing double quotes. Nowhere in your code do you have a buffer that should be holding a ". So we can assume that either encode() isn't working properly (but by inspection it is pretty simple), or when you call SCI_OutString, you are using a garbage pointer and it is printing random stuff. In the definition of encode - either use pointers or arrays, don't intermix. Use void encode( char out[]) instead. What you have would probably cause all kinds of damage. Now, the character " has the hex value 0x22, so what you are printing looks like 22222222222222222... in hex, with no 0x00 to terminate the string, so it's going to print a whole bunch of it. It is quite hard to determine what you are printing since you are in an infinite loop. The data could be 0x2200, which would print out a single ", but since it is in an infinite loop you would get """"""""""""""""""""""""""". Running your code through lint showed that if malloc failed you would have outData getting set to NULL. This would be a pointer to location 0. Encode would try and alter locations 0, 1, 2 and 3. Then you print the string at location 0. The zero page of an HC12 is internal registers. So you would set PORTA to 0x74, PORTB to 0x65, DDRA to 0x73, DDRB to 0x00, then print them out as a string. If you are running some sort of a bootloader/monitor/debugger it is possible to move the registers and possibly put FLASH down in the zero page, or uninitialized RAM. It's really hard to predict what is going to get printed. Either way, you are printing a location that IS a long string of hex 0x22. We can see that from the output. First, alter your code to have: No infinite loop until you get a bit of control. Fix encode as above. char outData[5]; Then, use SCI_OutChar(outData[0]); and make sure that you are getting a 't'. This would make sure that encode is working properly. Fix the malloc call so that the syntax is expressing what you actually want and check the return code. Use SCI_OutString to print an error message if malloc returns NULL. If you really want to use malloc, use SCI_OutUHex((int)outData) and take a look at where outData is pointing. I'm pretty sure that you will find a whole bunch of 0x22 at that location. From the 10 commandments: Thou shalt run lint frequently and study its pronouncements with care, for verily its perception and judgement oft exceed thine. From the MISRA guidelines: Don't use pointers. Andrei --------------------- Andrei Chichak Systems Developer CBF Systems Inc. 4-038 NINT Innovation Centre 11421 Saskatchewan Drive Edmonton, Alberta Canada T6G 2M9 Phone: 780-628-2072 Skype: andrei.chichak [Non-text portions of this message have been removed] |
|
|
Re: Dragon Board 12 Serial Communication C code HelpAs stated by others it is folly to use malloc/free in simple embedded systems. The best solution is to implement asynchronous static ring buffers for rx/tx with timeout error reporting (see http://www.seattlerobotics.org/encoder/200009/sciint11.c for an asynch example without timeouts). In the case where the output is fixed I wouldn't even bother with a buffer.
#ifndef bit #define bit(x) (1 << (x)) #endif void put_char(char c) { while((SCI0SR1 & bit(7)) == 0); SCI0DRL = c; } void put_s(char* s) { // Assumes char pointer is a zero terminated array (string) while(*s) put_char(*s++); } const char *message = "Hello World"; const char *test_str = "tes0"; void main(void) { sci_init(); // usual sci setup for baudrate, etc. put_s(message); while(1) { put_s(test_str); } } If the output is variable, the addition of the something like the following can be useful. The obvious danger of using this function is the ease of overflowing the buffer. Beware also that compiler implementations of this are typically not re-entrant so don't call it from inside an ISR or thread. #include <stdio.h> void myPrintf(char *format, ...) { char buffer[BUF_SIZE]; va_list stArgList; va_start(stArgList, format); vsprintf(buffer, format, stArgList); va_end(stArgList); put_s(buffer); } -rob > > #include "sci.h" > > int main(void); > void encode(char *out); > > int main(void) > { > char* head = "Hello World"; // declare first print statement > char* outData =(char*) malloc (sizeof (char*)* 5); // make room for 5 char > > SCI_Init(9600,0); //Startup serial port 0(under LCD) at 9600 BAUD > SCI_OutStatus(1); // Is it clear to send (buffer empty) > SCI_OutString(head,0); // print "Hello World" to serial port (WORKS !!) > > while(1) > { > if(SCI_OutStatus(0))// Is it clear to send (buffer empty) > { > encode(outData);//,out.throt,out.heading); // build output > SCI_OutString(outData,0); // print out put to serial port > } > } > return 0; > } > > void encode(char *out) // take in pointer and fill with chars > { > out[0] = 't'; > out[1] = 'e'; > out[2] = 's'; > out[3] = 0; > } |
|
|
Re: Re: Dragon Board 12 Serial Communication C code Help > Andrei Chichak writes on 02:20 AM 10/28/2009
>In the definition of encode - either use pointers or arrays, don't >intermix. Use void encode( char out[]) instead. What you have would >probably cause all kinds of damage. There is no harm to use pointers and arrays and no damage results from doing so. They are equivalent - the only time a problem will occur is when a pointer and array are used in different modules (one public and the other externed). Bill |
|
|
Re: Re: Dragon Board 12 Serial Communication C code HelpOn 2009-October-28, at 11:06 PM, Bill Auerbach wrote: >> > Andrei Chichak writes on 02:20 AM 10/28/2009 >> >In the definition of encode - either use pointers or arrays, don't >> >intermix. Use void encode( char out[]) instead. What you have would >> >probably cause all kinds of damage. >> >> There is no harm to use pointers and arrays and no damage results >> from doing so. They are equivalent - the only time a problem will >> occur is when a pointer and array are used in different modules (one >> public and the other externed). >> >> Bill > > Remember, the program will only be read twice after you write it, > once by the compiler (and it doesn't care what you do), and the poor > sod that has to maintain it. [Non-text portions of this message have been removed] |
|
|
Re: Dragon Board 12 Serial Communication C code Help--- In 68HC12@..., Andrei Chichak <groups@...> wrote: > > > On 2009-October-28, at 11:06 PM, Bill Auerbach wrote: > >> > Andrei Chichak writes on 02:20 AM 10/28/2009 > >> >In the definition of encode - either use pointers or arrays, don't > >> >intermix. Use void encode( char out[]) instead. What you have would > >> >probably cause all kinds of damage. You say "probably cause all kinds of damage". Before anyone here thinks that's a really bad thing and it means they are doing something wrong, perhaps you should back this statement with something concrete. Show us a case that causes "all kinds of damage". If you can't, please don't put your gloom and doom programming rules out on a public forum where beginners may be trying to learn correct programming practices. > >> There is no harm to use pointers and arrays and no damage results > >> from doing so. They are equivalent - the only time a problem will > >> occur is when a pointer and array are used in different modules (one > >> public and the other externed). > >> > >> Bill > > >> Remember, the program will only be read twice after you write it, >> once by the compiler (and it doesn't care what you do), and the poor >> sod that has to maintain it. It's a much larger concern and problem if the maintainer doesn't know the fundamental properties and semantics of the language. |
|
|
Re: Re: Dragon Board 12 Serial Communication C code HelpOn Oct 31, 2009, at 7:54 AM, Bill_CT wrote: > --- In 68HC12@..., Andrei Chichak <groups@...> wrote: >> >> >> On 2009-October-28, at 11:06 PM, Bill Auerbach wrote: >>>>> Andrei Chichak writes on 02:20 AM 10/28/2009 >>>>> In the definition of encode - either use pointers or arrays, don't >>>>> intermix. Use void encode( char out[]) instead. What you have >>>>> would >>>>> probably cause all kinds of damage. > > You say "probably cause all kinds of damage". Before anyone here > thinks that's a really bad thing and it means they are doing > something wrong, perhaps you should back this statement with > something concrete. Show us a case that causes "all kinds of > damage". If you can't, please don't put your gloom and doom > programming rules out on a public forum where beginners may be > trying to learn correct programming practices. This struck me as particularly strange since I've been mixing pointers and arrays since 1980 (when I first used C) and have never caused any kind of damage! In fact you really need to mix the two to get maximum leverage from the language. 1. You have to declare arrays to allocate memory since I think most of us can agree that malloc has no business in embedded programming of small microcontrollers. 2. It is generally more efficient to walk through an array using pointers rather than indexing. 3. Array and pointer parameters are basically identical since the array is passed by reference and the pointer is passed by value. They can be used interchangeably. 4. The comment "the only time a problem will occur is when a pointer and array are used in different modules (one public and the other externed)" isn't an issue if using header files with extern declarations for all global variables is practiced. This will catch the definition being different than the declaration. Tom Almy Tualatin, Oregon USA Internet: tom@... Website: almy.us |
|
|
Re: Re: Dragon Board 12 Serial Communication C code Help > Tom Almy writes on 10:57 AM 10/31/2009
>This struck me as particularly strange since I've been mixing pointers >and arrays since 1980 (when I first used C) and have never caused any >kind of damage! In fact you really need to mix the two to get maximum >leverage from the language. Technically "Hello World" mixes an array used with printf which takes a pointer. >1. You have to declare arrays to allocate memory since I think most of >us can agree that malloc has no >business in embedded programming of small microcontrollers. Agree. >2. It is generally more efficient to walk through an array using >pointers rather than indexing. Yes. I might not be wrong to say it's always more efficient. >3. Array and pointer parameters are basically identical since the >array is passed by reference and the pointer is passed by value. They >can be used interchangeably. Yes. The one place that can burn you because of this is sizeof used on an argument to a function with an array type: void function(char buffer[32]) { int i = sizeof buffer; // This is NOT 32 but sizeof (char *) } However, this isn't going to cause "damage" because this error would fall out quickly in testing. >4. The comment "the only time a problem will occur is when a pointer >and array are used in different modules (one public and the other >externed)" isn't an issue if using header files with extern >declarations for all global variables is practiced. This will catch >the definition being different than the declaration. I agree. It shouldn't be an issue, but since it can be done, it is a problem when it is. I've seen a lot of programmer's code over the years and there's a lot of "quick extern" declarations that are included in the C file and not a header file. It's not a good practice but it's still pretty common. Bill |
| Free embeddable forum powered by Nabble | Forum Help |