This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

RM42L432: decimal print with sci

Part Number: RM42L432

hello everyone,

I'm working on a simple aplicattion. Where I want to make a PWM vary the dutycicle and print the current dutycicle in the terminal. I based my code on the hetPwm and adcDisplay examples. The code is working fine but I'd like the dutyCicle value to be print as decimal. 

here is my code:

/* Include Files */

#include "sys_common.h"

/* USER CODE BEGIN (1) */
#include "het.h"
#include "sci.h"

#define TSIZE1 8
uint8 TEXT1[TSIZE1]= {'\r','\n','|','\t','M','A','I','N'};
#define TSIZE2 14
uint8 TEXT2[TSIZE2]= {'\r','\n','|','\t','L','O','O','P','.','W','H','I','L','E'};
#define TSIZE3 20
uint8 TEXT3[TSIZE3]= {'\r','\n','|','\t','L','O','O','P','.','D','U','T','Y','_','C','I','C','L','E','\t'};
#define TSIZE4 8
uint8 TEXT4[TSIZE4]= {'\r','\n','|','\t','W','A','I','T'};

void setPwm (uint32 dutyCicle, float64 period_us);

void sciDisplayText(sciBASE_t *sci, uint8 *text, uint32 length);

void sciDisplayData(sciBASE_t *sci, uint8 *text,uint32 length);

void wait (uint32 time);

/* USER CODE END */

/** @fn void main(void)
* @brief Application main function
* @note This function is empty by default.
*
* This function is called after startup.
* The user can use this function to implement the application.
*/

/* USER CODE BEGIN (2) */
uint32 time;
uint32 dutyCicle;
float64 period_us;
uint32 value;

/* USER CODE END */

int main(void)
{
/* USER CODE BEGIN (3) */
sciInit();
sciDisplayText(scilinREG,&TEXT1[0],TSIZE1);

hetInit();

dutyCicle = 50;
period_us = 100.0;
time = 1000.0;

setPwm(dutyCicle, period_us);

while(1)
{
sciDisplayText(scilinREG,&TEXT2[0],TSIZE2);

dutyCicle=0;
value = dutyCicle;

while(dutyCicle<=100)
{
sciDisplayText(scilinREG,&TEXT3[0],TSIZE3);
sciDisplayData(scilinREG,(uint8*)&value,4);
value = dutyCicle;

setPwm(dutyCicle, period_us);
// __delay_cycles(50000000);
dutyCicle+=5;

wait(0xFFFFFF);
}
pwmStop(hetRAM1,pwm0);
sciDisplayText(scilinREG,&TEXT4[0],TSIZE4);
wait(0xFFFFFF);
}

/* USER CODE END */
}


/* USER CODE BEGIN (4) */
void setPwm (uint32 dutyCicle, float64 period_us)
{
hetInit();

hetSIGNAL_t pwmSignal;

pwmSignal.duty = dutyCicle;
pwmSignal.period = period_us;

pwmSetSignal(hetRAM1,pwm0,pwmSignal);
pwmSetDuty(hetRAM1,pwm0,pwmSignal.duty);
pwmStart(hetRAM1,pwm0);
}

void sciDisplayText(sciBASE_t *sci, uint8 *text,uint32 length)
{
while(length--)
{
while ((scilinREG->FLR & 0x4) == 4); /* wait until busy */
sciSendByte(scilinREG,*text++); /* send out text */
};
}

void sciDisplayData(sciBASE_t *sci, uint8 *text,uint32 length)
{
uint8 txt = 0;
uint8 txt1 = 0;

#if ((__little_endian__ == 1) || (__LITTLE_ENDIAN__ == 1))
text = text + (length -1);
#endif

while(length--)
{
#if ((__little_endian__ == 1) || (__LITTLE_ENDIAN__ == 1))
txt = *text--;
#else
txt = *text++;
#endif
txt1 = txt;

txt &= ~(0xF0);
txt1 &= ~(0x0F);
txt1 =txt1>>4;

if(txt<=0x9)
{
txt +=0x30;
}
else if(txt > 0x9 && txt < 0xF)
{
txt +=0x37;
}
else
{
txt = 0x30;
}

if(txt1 <= 0x9)
{
txt1 +=0x30;
}
else if((txt1 > 0x9) && (txt1 <= 0xF))
{
txt1 +=0x37;
}
else
{
txt1 = 0x30;
}

while ((scilinREG->FLR & 0x4) == 4); /* wait until busy */
sciSendByte(scilinREG,txt1); /* send out text */
while ((scilinREG->FLR & 0x4) == 4); /* wait until busy */
sciSendByte(scilinREG,txt); /* send out text */
};
}

void wait(uint32 time)
{
while(time)time--;
}

My teacher suggested that it could be a terminal configuration. But I tried on three different terminal software, no success.

Any suggestion is welcome.

  • Hello Marco,

    Can you post a snapshot of that the output is and describe what you would expect to see on the output? Are you able to see the ASCII string output and it is only an issue when trying to display the decimal output? Or is all output corrupted? Some detailed description of the symptoms of the problem could be helpful in resolving the issue.
  • Hello Chuck.

    Here is my output.

    Yes, is just an issue for dispay those hexadecmal (just after the 'LOOP.DUTY_CICLE') as decimal 0, 5, 10, 15, .., 100, 0, 5, 10, .., 100, 0, 5, ..
    My issue is how to organize or edit the function sciDisplayData to have an decimal output. I'm not sure if the problem is in the function.

    If necessary I can attach a zip with the files.

  • This is the right screenshot of my output. Sorry, the other one had an interruption.

  • Why not try www.cplusplus.com/.../ to create a formatted string and then send the string you create to the sciDisplayText function.
  • Anthony

    Thanks for your suggestion. It seem to work, but not as I wish. The sprintf function prints on the console and sciDisplayData prints on the terminal, look the screenshot below. Why does it happen and whats the difference?

    The modified slice of  the code

    while(dutyCicle<=100)
    		{
    			//sciDisplayText(scilinREG,&TEXT3[0],TSIZE3);
    			//sciDisplayData(scilinREG,(uint8*)&value,4);
    
    			value = sprintf(buffer, "LOOP.DUTY_CICLE \t %d", dutyCicle);
    
    			setPwm(dutyCicle, period_us);
    			// __delay_cycles(50000000);
    			dutyCicle+=5;
    
    			printf (buffer, value);
    
    
    	                wait(0xFFFFFF);
    		}


    I thougth about this solution, but I didn't applie it before becouse I'd want to understand what's happening and like to use the sci lib.  And I'v got the aim to implement a sensor reading in this function and compare the percentage of pwm dutyCicle with the value read from the sensor.

  • You need to convert the variable "value" to BCD before sending to the send data routine. The send data routine is setup to send out hex values.

    Some simple code to convert a hex value to up to a 3-digit BCD value is:

    uint8 val;          // The value you want to convert
    uint16 bcdval;   // The converted value
    uint8 d0, d1, d2; // the 3 decimal figures used to write a 0 ~ 255
    
    d2 = val / 100;
    val -= 100 * d2;
    d1 = val  / 10;
    d0 = val % 10;
    
    bcdval = d2 << 8 + d1 << 4 + d0;

    This will handle up to a value of 999.  If you need more digits you would need to add a step to divide by 1000.

    Also note that the send routine only is designed for 2 characters (i.e. 00 to 99) so it would need to be modified to handle the larger 16 bit value that will need to be passed into it or the printed value would need to be partitioned such that you pass 2 8-bit BCD values into it separately.

  • Chuck, I spended some time on trying your code, but I'm not sure if it's working fine or if I understood where the conversion should be.
    I adjusted the code you shown to convert just 2 characters, because with 3 characters only zeros were displayed. Look what I'v got from output.




    This correnspond to the following adjusts on the code:

    while(1)
    	{
    		sciDisplayText(scilinREG,&TEXT2[0],TSIZE2);
    
    		dutyCicle=0;
    		value = dutyCicle;
    
    		while(dutyCicle<=100)
    		{
    			sciDisplayText(scilinREG,&TEXT3[0],TSIZE3);
    			value = bcdConvert(dutyCicle);
    			sciDisplayData(scilinREG,(uint8*)&value,4);
    
    			setPwm(dutyCicle, period_us);
    			// __delay_cycles(5000000);
    			dutyCicle+=5;
    
    	        wait(0xFFFFFF);
    		}
    		pwmStop(hetRAM1,pwm0);
    		sciDisplayText(scilinREG,&TEXT4[0],TSIZE4);
    		wait(0xFFFFFF);
    	}
    
    
    uint32 bcdConvert (uint32 value)
    {
    uint16 d0, d1, d2, d3;
    uint32 bcdValue;
    
    //d3 = value/1000;
    //value -= d3*1000;
    //d2 = value/100;
    //value -= d2*100;
    d1 = value/10;
    d0 = value%10;
    bcdValue = d1 << 4+d0;
    
    return bcdValue;
    }

    After that, I noted that I'm sending a decimal to the send routine. I thought a converter hex to bcd could not work this way, right? Shouldn't I send an hex to the routine and convert this valoue before de sciSendByte?

  • Marco,

    The problem with sending a true hex value to sciSendByte is that when you convert the bite to decimal it can be anywhere from 0 to 255 in value. So to send this you would have to break it down into three byte transmissions. '2' '5' '5'. Your sciSendByte routine should never receive anything as input that isn't a string unless the device on the receiving end can understand the hex values being sent.

    So the procedure should be:
    1.) range check your value to insure it doesn't over flow the SW capability (how many digits can be handled)
    2.) Convert the value to BCD (lets call it BCD_value)
    3.) Convert most significant digit in BCD_value to ASCII
    4.) Send ASCII byte
    5.) Convert next digit in BCD_value to ASCII
    6.) Goto 4 and repeat untl all digits are sent.

  • Chuck, I got it. I found a significancy operation mistake. At review I saw a screenshot from when I used the convertion the data to BCD before sending to the send routine, and noted the output was half correct (the output was alternating on correct values and wrong values). So I just put a parenthesis and everything seems to work fine.

    uint32 bcdConvert (uint32 value)
    {
    uint8 d0, d1, d2, d3;
    uint32 bcdValue;
    
    //d3 = value/1000;
    //value -= d3*1000;
    d2 = value/0x64;
    value -= d2*100;
    d1 = value/0x0A;
    d0 = value%0x0A;
    bcdValue = (d2 << 8) + (d1 << 4) + d0;
    
    return bcdValue;
    }

    Thanks for the support and explanations.


  • Great to hear!!

    I'm glad you were able to resolve the issue and thanks for using the Hercules E2E!!