Simple SCI Polling Receive and Transmit Code

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Simple SCI Polling Receive and Transmit Code

5,132 Views
datamstr
Contributor II
Hi All,
 
I am using the MC908QB8 Demo Board and CW50. I have read through the manual and looked through the posts on this forum for help. I am trying to simply poll the SCI register for an incoming char and then transmit it out the SCI port. My code is listed below, as far as I understand the steps are:
 
1. Check for the SCI Recevier Full Flag. (SCRF)
2. Read the SCI Data Register
3. Check for the SCI Transmitter Empty flag. (SCTE)
4. Write the SCI Data Register
 
 // SCI Loop Test
 for(;:smileywink: /* loop forever */
   {
     __RESET_WATCHDOG(); /* feeds the dog */
   
   if(SCS1_SCRF)  // SCRF Bit - Check for char ready and clear bit
     {
     RChar = SCDR;  // Get SCI Char
     while(!SCS1_SCTE)  //SCTE Bit - wait for transmitter empty
       ;
       SCDR = RChar;   // Send SCI char
     }
   }
My code is not working, any help please?
 
Thanks,
David Evennou
 
Labels (1)
0 Kudos
Reply
23 Replies

1,205 Views
datamstr
Contributor II
OK, got it! I just commented the code from the last test and added the new code below it. At first it did not work even though it should have. Then I remembered that somewhere along the way yesterday I picked up some code from another project and enabled the SCI transmitter by using SCC2 = 0x08. Oh no, this code turns off the receiver! I changed the transmitter enable code to, SCC2_TE = 1, and now the QB8 is echoing chars.:smileyhappy:
I have made a number of code additions and changes over the past few days, so I need to go back to the original code and compare with the changes I made. My goal is to receive a string of 8 characters into a buffer and then do some work with that data. Now at least I know the serial receive part is working!
 
Thanks so much for all of your help!!
David
 
 LED1 = OFF;
 LED2 = OFF;
 SCC2_RE = 1;    // enable Rx
//  SCC2 = 0x08;    // enable Tx
 SCC2_TE = 1;   // enable Tx
 
// SCI Loop Test
 for(;:smileywink: /* loop forever */
   {
     __RESET_WATCHDOG(); /* feeds the dog */
//    if(SCS1_SCRF)  // SCRF Bit - Check for char ready and clear bit
//      LED1 = ON;
     
//    if(SCS1_OR)  // Overrun Bit - Check for missed char read
//      LED2 = ON;
     
     
   if(SCS1_SCRF)  // SCRF Bit - Check for char ready and clear bit
     {
     LED1 = ON;
     RChar = SCDR;  // Get SCI Char
     while(!SCS1_SCTE);  //SCTE Bit - wait for transmitter empty
       LED2 = ON;
       SCDR = RChar;   // Send SCI char
     }
   }
 
0 Kudos
Reply

1,205 Views
datamstr
Contributor II
OK, Good News! I plugged in the code below and that works OK, got characters in HyperTerminal.
So now, how can I get the SCI Rx working?
 
Thanks,
David
 
void MCU_init(void); /* Device initialization function declaration */

void Delay(byte time);

void main(void) {

 MCU_init(); /* call Device Initialization */

 for(;:smileywink: {

 while(!SCS1_TC); SCDR = 0x55;

 Delay(5);

 } /* loop forever */

}

void Delay(byte time)

{

 word i;

 for(i = 0;i < time*255; i++)

 {

 __RESET_WATCHDOG();

 }

}

 

0 Kudos
Reply

1,205 Views
thisobj
Contributor III
Try removing the jumper from the COM EN block (near the RS232 connector).
0 Kudos
Reply

1,205 Views
datamstr
Contributor II
My configuration is:
 
1. SCI receive jumper (Lin/Com) is removed.
2. SCI input data is from an RS-485 Transceiver IC
3. Transmit jumper is on the COM side and the DB9 connector is plugged into the PC using HyperTerminal.
4. The transmit side works OK, I can send a character to the HyperTerminal running at 9600 Baud
5. Receive data is from a single board computer sending serial data to the RS-485 IC.
 
To validate this setup, I connected the output from the RS-485 IC to the COM pin on the Demo Board.
The serial string of characters flows through to HyperTerminal just fine.
So, that is whay I think I must be doing something wrong in the code.
 
Thanks,
David
0 Kudos
Reply

1,205 Views
bigmac
Specialist III
Hello David,
 
From your description, I assume the other single board computer  (that generates the serial data for the demo board to receive) has a RS-485 driver fitted.  Using an oscilloscope, can you actually observe the presence of data at the receiver output pin of the local RS-485 device, i.e. receive mode is enabled.  If so, you may need to swap the differential input connections to achieve correct polarity into the QB8 RxD pin.
 
Also note that the baud rate for the received data will need to be the same rate as for the data forwarded to the PC.
 
You may find it more convenient for initial testing of code, to add a jumper so that the incoming data originates from the PC, rather than the SBC.  Then any character typed at the keyboard should simply be echoed.
 
Regards,
Mac
 
0 Kudos
Reply

1,205 Views
datamstr
Contributor II
OK, I am using only the QB8 Demo Board RS-232 with both jumpers installed for COM SEL (1 & 3, 2 & 4).
Using the same code I originally posted, still nothing back from the SCI. I can't really tell if the SCI Data Register has anything in it. I think the next step is to try to send a character from the SCI Tx to RS-232 port first. (reverse the order)
 
Thanks,
David
0 Kudos
Reply

1,205 Views
thisobj
Contributor III
David,
Hey, your 1/2 way there!
This is just a suggestion, but when bringing up any new board or feature, I disable the watchdog timer to eliminate a variable from the debugging equation. Especially when there are wait loops anywhere in the code.

Also, don't forget to set the RE bit in SCC2 to enable the receiver.

Frank
0 Kudos
Reply

1,205 Views
datamstr
Contributor II
Frank,
 
Here is my MCUInit code ......no interrupts, Transmitter and Receiver Enabled, SCI Enabled.
 
 /* ### Init_SCI init code */
 /* SCIACTL: AM1=0,ALOST=0,AM0=0,ACLK=0,AFIN=0,ARUN=0,AROVFL=0,ARD8=0 */
 SCIACTL = 0x00;                                     
 /* SCPSC: PDS2=0,PDS1=0,PDS0=1,PSSB4=1,PSSB3=0,PSSB2=0,PSSB1=1,PSSB0=1 */
 SCPSC = 0x33;                                     
 /* SCC3: R8=0,T8=0,ORIE=0,NEIE=0,FEIE=0,PEIE=0 */
 SCC3 = 0x00;                                     
 /* SCBR: LINT=0,LINR=0,SCP1=1,SCP0=0,SCR2=0,SCR1=0,SCR0=1 */
 SCBR = 0x21;                                     
 /* SCC1: LOOPS=0,ENSCI=1,TXINV=0,M=0,WAKE=0,ILTY=0,PEN=0,PTY=0 */
 SCC1 = 0x40;                                     
 /* SCC2: SCTIE=0,TCIE=0,SCRIE=0,ILIE=0,TE=1,RE=1,RWU=0,SBK=0 */
 SCC2 = 0x0C;                                     
Config Registers - (COP is Disabled)
 
 /* Common initialization of the write once registers */
 /* CONFIG1: COPRS=0,LVISTOP=0,LVIRSTD=0,LVIPWRD=0,LVITRIP=0,SSREC=0,STOP=0,COPD=1 */
 CONFIG1 = 0x01;                                     
 /* CONFIG2: IRQPUD=0,IRQEN=0,ESCIBDsrc=0,OSCENINSTOP=0,RSTEN=0 */
 CONFIG2 = 0x00;                              
       
 
Thanks,
David
0 Kudos
Reply

1,205 Views
thisobj
Contributor III
David,

What is your clock source? Assuming you want to use the internal clock and you want a baud rate of 9600, you should initialized the OSCSC register for 12.8MHz ( ICFS1:ICFS0 = 10) for the register values you've chosen to work out to 9600. Otherwise, the reset value will give you a 4.0MHz clock.

Frank
0 Kudos
Reply

1,205 Views
datamstr
Contributor II
Hi Frank,
 
The following information from Freescale Support is what I am using:
 
When using internal oscillator it is not possible to set internal bus
frequency to 4.9152 Mhz.
You can for example set the bus frequency to 3.2MHz and set the ECSI
prescallers following way

For 9600Bd
ESCI baud rate clock source = CGMXCLK,
Prescaler divisor = 2,
Prescaler divisor fine adjust = $13
Baud rate prescaler = 4
Baud rate divisor = 2
 
Thanks,
David
0 Kudos
Reply

1,205 Views
thisobj
Contributor III
David,

That info is correct. But I don't think you'll get a 3.2MHz bus frequency unless you select the internal 12.8MHz clock, since Bus Clock = CGMXCLK/4. Since you're selecting CGMXCLK as the ESCI clock source, it needs to be init'd to 12.8MHz by setting the bits in OSCSC. This is called out in the document, MC68HC08QB8.pdf on page 100.

Frank
0 Kudos
Reply

1,205 Views
datamstr
Contributor II
Hi Frank,
 
Thanks for pointing that out to me. I remember now that the email from Freescale Support had that error, so I changed to internal clock. I just reviewed my settings in the CW Inspector and the Clock Source is set to Internal and the Internal Oscillator Frequency is 12.8 MHZ. The internal Bus Clock is set to 3.2 MHZ.
 
Sorry about that.
 
Thanks,
David
0 Kudos
Reply

1,205 Views
peg
Senior Contributor IV
Hi David,
 
You said earlier that you could send from the MCU to a terminal on a PC so as the Tx and Rx baudrate is the same I believe that the clock/baudrate divisor must already be OK!
I don't know your hardware and as everything else seems OK that is why I was suspecting that the data is not actually getting into the MCU.
Have you confirmed this?
 
Regards
Peg
 
0 Kudos
Reply

1,205 Views
datamstr
Contributor II
Hi Peg,
 
I just got back to the testing and I do have data at the MCU Rx pin. The DVM voltage drops when I hold down a key in HyperTermminal. Also, the hardware is just the Demo Board.
 
Anything I can try in code?
 
Thanks,
David
0 Kudos
Reply

1,205 Views
peg
Senior Contributor IV
Hi David,
 
A few things to try:
 
Poll the SCS1 register for OR, NF and FE as well and turn on an LED if they get set.
Turn on another LED if RDRF gets set.
Do a plain ascii transfer at the MCU and see if any LED's come on
 
Run this in the simulator and see if it looks like it works.
 
If this still gets you nowhere, try to set the Rx pin up as a GP input and see if it works to detect high and low. Maybe you have broken this input. This won't test if it works as RxD but if it fails to work as a GP input then its a fair bet it isn't working as RxD either.
 
Regards
Peg
 
0 Kudos
Reply

1,205 Views
datamstr
Contributor II
Hi Peg,
 
This code works OK. When I send one character, LED1 comes ON. Then LED2 comes ON when I send the next character over RS-232. It makes sense, the Overrun bit is set becuse the data register has not been read when the 2nd char is received.
 
Thanks,
David
 
 LED1 = OFF;
 LED2 = OFF;
 SCC2_RE = 1;    // enable Rx
 // SCI Loop Test
 for(;:smileywink: /* loop forever */
   {
     __RESET_WATCHDOG(); /* feeds the dog */
   if(SCS1_SCRF)  // SCRF Bit - Check for char ready and clear bit
     LED1 = ON;
     
   if(SCS1_OR)  // Overrun Bit - Check for missed char read
     LED2 = ON;
   }
0 Kudos
Reply

1,205 Views
datamstr
Contributor II
I should be able to set a breakpoint in CW and when I hit a key in HyperTerminal the code should hit the breakpoint and stop running. I have not been able to figure out how to get this working.
 
Any tips?

Thanks,
David
0 Kudos
Reply

1,205 Views
peg
Senior Contributor IV
Hi David,
 
I am right at this moment writing a protocol translator using both SCI ports of a 9S08GT16.
This is to allow two incompatible pieces of equipment to talk to one another.
One side is two wire 485 9600 baud and the other is 4 wire 19200 and the protocol is completely different.
So all this stuff is right in my head now.
At this point I can see nothing wrong with what you are doing and so would suggest that you have a hardware issue.
 
What I did is this:
Replace one side with a PC running a terminal emulator.
Write some code to send a string to the PC when the device is reset using the same mechanisms in the code that will be used by the application. This tests many things before you get started. Most SCI setup including baudrate and your PC terminal setup etc.
 
You should only need:
Enable SCI
enable tx and rx
set baudrate
which you seem to have.
 
Can you test for the presence of data right at the MCU pin input?
Even if the baudrate is a bit off or parity wrong or whatever you generally will get some rubbish occasionally if you throw enough data at it. Maybe get your terminal emulator to sent a small file at your MCU to see if you can recieve anything at all.
 
Even if you only have a multimeter you can put it on the RDI pin (it should idle high) then type at the terminal as fast as you can, you should see a small drop in voltage as the data passes. I just tested this, I saw 3.28 idle and  3.24 with data. Sendig a file drops it to below 2 volts.
 
Hope this helps
 
Regards
David (Peg)
 
 
 
0 Kudos
Reply

1,205 Views
datamstr
Contributor II
Hi Mac,
 
That is correct, the SBC has a RS-485 Driver. I swapped the differential inputs just to try it, but still not getting data to the SCI. The baud rate should be correct for both xmit and receive. I used the settings I received from a Freescale Support Request a couple of months ago. The Device Initialization Inspector in CW50 shows the baud rate as 9638.5542. My next step is to try loopback using the RS-232 and HyperTerminal. Do you know if there is a program already written to run this test?
 
Also, I not yet figured out how to use breakpoints in CW50 with the QB8 Demo Board.
 
Thanks,
David
0 Kudos
Reply

1,205 Views
thisobj
Contributor III

datamstr wrote:
[snip.....] To validate this setup, I connected the output from the RS-485 IC to the COM pin on the Demo Board.
The serial string of characters flows through to HyperTerminal just fine.
So, that is whay I think I must be doing something wrong in the code.
Thanks,
David




Sorry, I first read this as a 9S08QG8 demo board. So, the following comments/questions:

1. Are the LIN/COM jumpers installed between pins 1&3 (xmit) and 2&4 (rcv)?
2. By "COM pin", do you mean pin #3 of the RS232 connector? If so, can you scope J1-7 to see if you have the Rx signal there?
3. Check the pins on the ICL3232 (com) chip to make sure they are on the solder pads and are making good connections.
0 Kudos
Reply