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.
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 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.
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?
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!!