AENG 505 – INTRO TO EMBEDDED SYSTEMS
Dr. Jaerock Kwon
Experiment-3
Serial Communication, C Programming
Nipun Kumar – 31440148
Objectives:
● To gain experience in C-Programming of an ARM microcontroller
● To gain experience the CCS ARM development environment and debugging
features.
● To gain experience writing UART serial communication protocol.
Experiment Result:
Q1) Show your solution, (i) your implementation of convertToFahrenheit(), (ii) your
implementation of PrintTemps(), and (iii) a screenshot of the terminal output.
Ans:
//This function converts the 32bit unsigned value representation of Celsius
//Temperature from the ADC and converts it to Farenheit
uint32_t convertToFahrenheit ( uint32_t TempC)
{
//Conversion from Celsius to Fahrenheit
uint32_t TempF=(TempC*(9.0/5.0))+32;
return TempF;
}
The ‘convertToFahrenheit’ function takes input as temperature in Celsius and converts it into
temperature value in Fahrenheit by using the formula TempF=(TempC*(9.0/5.0))+32’. Then
it returns the calculated value from function.
//This function prints the temperatures in both Celsius and Fahrenheit to the
console in an easy human readable format.
void PrintTemps (uint32_t TempC)
{
UARTprintf("Temperature in Celsius = %3d*Cn", TempC);
UARTprintf("Temperature in Fahrenheit = %3d*Fn", convertToFahrenheit(TempC));
}
The ‘PrintTemps’ function takes input as temperature in Celsius and prints the value in first
line. In second line it prints the value returned after calling the function
‘convertToFahrenheit(TempC)’ i.e., temperature in Celsius. The output in Terminal window
after calling ‘PrintTemps’ function is shown as below.
Q2) Show and discuss your software function that decodes the received character and
reacts accordingly. Also, record a video demonstration for this part.
Ans: When a character is inputted in terminal window, it is saved in UART0_BASE address.
So, if there is any input, it enters the first if loop and saves the character into InputChar variable.
When ‘C’ or ‘F’ is entered , temperature is calculated by averaging four values and converts
into digital and calls PrintTemps function. Based on the letter ‘C’ or ‘F’ input, it prints the
temperature value in Celsius or Fahrenheit respectively by taking two inputs of TempC and
Input character.
If character ‘G’ is received, it enters the third If loop which calls toggleGreenLED() function
to turn on or off the green led. Prototypes for newly added functions ‘toggleGreenLED()’ and
‘InitPortF()’ in main.c file must be entered.
OUTPUT
• Recorded video for the same is present in below link
https://youtube.com/shorts/eEJTT30kyF4?feature=share
• Code inside the while infinite loop with above discussed logic is shown below:
while(1)
{
// Check whether UART0_BASE is nonzero which happens when any character is
input in terminal window.
if(UARTCharsAvail(UART0_BASE)){
// Store the character as InputChar variable
InputChar = UARTCharGetNonBlocking (UART0_BASE);
// Check for reading from temperature sensor only when C or F is entered
if (InputChar == 'C' || InputChar == 'F'){
// Trigger the ADC conversion.
ADCProcessorTrigger(ADC0_BASE, 1);
// Wait for conversion to be completed.
while(!ADCIntStatus(ADC0_BASE, 1, false))
{
}
// Clear the ADC interrupt flag.
ADCIntClear(ADC0_BASE, 1);
// Read ADC Values.
ADCSequenceDataGet(ADC0_BASE, 1, ui32ADC0Value);
//Average the 4 Samples
ui32TempAvg = (ui32ADC0Value[0] + ui32ADC0Value[1] +
ui32ADC0Value[2] + ui32ADC0Value[3] + 2)/4;
//Convert Raw Data to Temp Celsius
ui32TempValueC = (1475 - ((2475 * ui32TempAvg)) / 4096)/10;
// Display the temperature value on the console.
PrintTemps(ui32TempValueC,InputChar);
}
// Enter into the if loop only when G is received and toggle the Green LED
if (InputChar == 'G'){
toggleGreenLED();
}
}
// This function provides a means of generating a constant length
// delay. The function delay (in cycles) = 3 * parameter. Delay
// 250ms arbitrarily.
//
SysCtlDelay(SysCtlClockGet() / clkscalevalue);
Below shown is the code for PrintTemps function:
//This function prints the temperatures in Celsius or Fahrenheit based on Char
variable value, to the console in an easy human readable format.
void PrintTemps (uint32_t TempC, uint8_t Char)
{
if(Char=='C'){
UARTprintf("Temperature = %3d*Cn", TempC);
}
if(Char=='F') {
UARTprintf("Temperature = %3d*Fn", convertToFahrenheit(TempC));
}
}
Q3) Show the GPIO initialization routine. Comment on how this compared to the
assembly GPIO initialization functions used in experiments 1 and 2.
Ans:
1. The first step is to set the clock bit related to Port F (5th
bit in SYSCTL_RCGC2_R)
• . Using Tivaware it can be done with the help of inbuilt function
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
• The same functionality was done with the help of registers and ORR operation
manually in assembly code.
2. Wait until the clock gets activated with the help of while loop in C language code.
while(!SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOF))
{}
3. Set the LEDs as output(One-Positive Logic) and switches as input(Zero bit-Negative
Logic)which needs the GPIO_PORTF_DIR_R bits to be set accordingly. Below two
functions are used in Tivaware to set the direction of switches and LED.
//Sets pins 1,2,3 as outputs
GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE,GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3);
//Sets pins 4,0 as inputs
GPIODirModeSet(GPIO_PORTF_BASE, GPIO_PIN_4|GPIO_PIN_0, GPIO_DIR_MODE_IN);
• In assembly language, GPIO_PORTF_DIR_R address value is set to 0x0E to set
the direction for switches and LEDs
4. Set the drive strength and enable weak pull up resistors for switches using the below
function in TivaWare.
GPIOPadConfigSet(GPIO_PORTF_BASE, GPIO_PIN_4|GPIO_PIN_0, GPIO_STRENGTH_4MA,
GPIO_PIN_TYPE_STD_WPU);
• In assembly language, GPIO_PORTF_PUR_R address value is set to 0x11 to
enable the pull up resistors for switches.
Q4) Discuss how the compiled assembly code compares to the code written in C? How
many assembly instructions does the conversion from Celsius to Fahrenheit require?
Ans:
Below is the assembly code written by the compiler for the function convertToFahrenheit():
• Since assembly code uses registers to perform any kind of arithmetic operation,
compiler dedicates certain registers in this case, r0,r1,r2,r3,LR by saving their
previous values into stack pointer.
• TempC value is saved initially loaded into r0 register from [r13] address.
• After calculating the value of TempF, its value is saved into address [r13+4] for
usage.
• At the end r1,r2,r3 register values were restored from stack pointer for usage. LR
location is saved into PC for continuation of program.
Total 14 lines of assembly code (excluding the code inside labels) is written by the compiler
for the function convertToFahrenheit().
Conclusion:
• Communicating the data from and to Micro controller with the help of terminal
window and UART ports is understood.
• Simplification of port initialization is done with the help of library functions inside
TivaWare.
• Understood the difference in programming codes between assembly language and
any high-level language to perform the same functionality with micro controller.

C programming of an ARM microcontroller and writing UART serial communication protocol.

  • 1.
    AENG 505 –INTRO TO EMBEDDED SYSTEMS Dr. Jaerock Kwon Experiment-3 Serial Communication, C Programming Nipun Kumar – 31440148
  • 2.
    Objectives: ● To gainexperience in C-Programming of an ARM microcontroller ● To gain experience the CCS ARM development environment and debugging features. ● To gain experience writing UART serial communication protocol. Experiment Result: Q1) Show your solution, (i) your implementation of convertToFahrenheit(), (ii) your implementation of PrintTemps(), and (iii) a screenshot of the terminal output. Ans: //This function converts the 32bit unsigned value representation of Celsius //Temperature from the ADC and converts it to Farenheit uint32_t convertToFahrenheit ( uint32_t TempC) { //Conversion from Celsius to Fahrenheit uint32_t TempF=(TempC*(9.0/5.0))+32; return TempF; } The ‘convertToFahrenheit’ function takes input as temperature in Celsius and converts it into temperature value in Fahrenheit by using the formula TempF=(TempC*(9.0/5.0))+32’. Then it returns the calculated value from function. //This function prints the temperatures in both Celsius and Fahrenheit to the console in an easy human readable format. void PrintTemps (uint32_t TempC) { UARTprintf("Temperature in Celsius = %3d*Cn", TempC); UARTprintf("Temperature in Fahrenheit = %3d*Fn", convertToFahrenheit(TempC)); } The ‘PrintTemps’ function takes input as temperature in Celsius and prints the value in first line. In second line it prints the value returned after calling the function ‘convertToFahrenheit(TempC)’ i.e., temperature in Celsius. The output in Terminal window after calling ‘PrintTemps’ function is shown as below.
  • 3.
    Q2) Show anddiscuss your software function that decodes the received character and reacts accordingly. Also, record a video demonstration for this part. Ans: When a character is inputted in terminal window, it is saved in UART0_BASE address. So, if there is any input, it enters the first if loop and saves the character into InputChar variable. When ‘C’ or ‘F’ is entered , temperature is calculated by averaging four values and converts into digital and calls PrintTemps function. Based on the letter ‘C’ or ‘F’ input, it prints the temperature value in Celsius or Fahrenheit respectively by taking two inputs of TempC and Input character. If character ‘G’ is received, it enters the third If loop which calls toggleGreenLED() function to turn on or off the green led. Prototypes for newly added functions ‘toggleGreenLED()’ and ‘InitPortF()’ in main.c file must be entered. OUTPUT
  • 4.
    • Recorded videofor the same is present in below link https://youtube.com/shorts/eEJTT30kyF4?feature=share • Code inside the while infinite loop with above discussed logic is shown below: while(1) { // Check whether UART0_BASE is nonzero which happens when any character is input in terminal window. if(UARTCharsAvail(UART0_BASE)){ // Store the character as InputChar variable InputChar = UARTCharGetNonBlocking (UART0_BASE); // Check for reading from temperature sensor only when C or F is entered if (InputChar == 'C' || InputChar == 'F'){ // Trigger the ADC conversion. ADCProcessorTrigger(ADC0_BASE, 1); // Wait for conversion to be completed. while(!ADCIntStatus(ADC0_BASE, 1, false)) { } // Clear the ADC interrupt flag. ADCIntClear(ADC0_BASE, 1); // Read ADC Values. ADCSequenceDataGet(ADC0_BASE, 1, ui32ADC0Value); //Average the 4 Samples ui32TempAvg = (ui32ADC0Value[0] + ui32ADC0Value[1] + ui32ADC0Value[2] + ui32ADC0Value[3] + 2)/4; //Convert Raw Data to Temp Celsius ui32TempValueC = (1475 - ((2475 * ui32TempAvg)) / 4096)/10; // Display the temperature value on the console. PrintTemps(ui32TempValueC,InputChar); } // Enter into the if loop only when G is received and toggle the Green LED if (InputChar == 'G'){ toggleGreenLED(); } } // This function provides a means of generating a constant length // delay. The function delay (in cycles) = 3 * parameter. Delay // 250ms arbitrarily. // SysCtlDelay(SysCtlClockGet() / clkscalevalue); Below shown is the code for PrintTemps function: //This function prints the temperatures in Celsius or Fahrenheit based on Char variable value, to the console in an easy human readable format. void PrintTemps (uint32_t TempC, uint8_t Char) {
  • 5.
    if(Char=='C'){ UARTprintf("Temperature = %3d*Cn",TempC); } if(Char=='F') { UARTprintf("Temperature = %3d*Fn", convertToFahrenheit(TempC)); } } Q3) Show the GPIO initialization routine. Comment on how this compared to the assembly GPIO initialization functions used in experiments 1 and 2. Ans: 1. The first step is to set the clock bit related to Port F (5th bit in SYSCTL_RCGC2_R) • . Using Tivaware it can be done with the help of inbuilt function SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF); • The same functionality was done with the help of registers and ORR operation manually in assembly code. 2. Wait until the clock gets activated with the help of while loop in C language code. while(!SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOF)) {} 3. Set the LEDs as output(One-Positive Logic) and switches as input(Zero bit-Negative Logic)which needs the GPIO_PORTF_DIR_R bits to be set accordingly. Below two functions are used in Tivaware to set the direction of switches and LED. //Sets pins 1,2,3 as outputs GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE,GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3); //Sets pins 4,0 as inputs GPIODirModeSet(GPIO_PORTF_BASE, GPIO_PIN_4|GPIO_PIN_0, GPIO_DIR_MODE_IN); • In assembly language, GPIO_PORTF_DIR_R address value is set to 0x0E to set the direction for switches and LEDs 4. Set the drive strength and enable weak pull up resistors for switches using the below function in TivaWare. GPIOPadConfigSet(GPIO_PORTF_BASE, GPIO_PIN_4|GPIO_PIN_0, GPIO_STRENGTH_4MA, GPIO_PIN_TYPE_STD_WPU); • In assembly language, GPIO_PORTF_PUR_R address value is set to 0x11 to enable the pull up resistors for switches.
  • 6.
    Q4) Discuss howthe compiled assembly code compares to the code written in C? How many assembly instructions does the conversion from Celsius to Fahrenheit require? Ans: Below is the assembly code written by the compiler for the function convertToFahrenheit(): • Since assembly code uses registers to perform any kind of arithmetic operation, compiler dedicates certain registers in this case, r0,r1,r2,r3,LR by saving their previous values into stack pointer. • TempC value is saved initially loaded into r0 register from [r13] address. • After calculating the value of TempF, its value is saved into address [r13+4] for usage. • At the end r1,r2,r3 register values were restored from stack pointer for usage. LR location is saved into PC for continuation of program. Total 14 lines of assembly code (excluding the code inside labels) is written by the compiler for the function convertToFahrenheit(). Conclusion: • Communicating the data from and to Micro controller with the help of terminal window and UART ports is understood. • Simplification of port initialization is done with the help of library functions inside TivaWare. • Understood the difference in programming codes between assembly language and any high-level language to perform the same functionality with micro controller.