2017
Percobaan 2
Serial RS-232 (Lanjut) dan Serial RS-485
I. Tujuan
Mahasiswa dapat melakukan transfer data dengan menggunakan serial RS-232.
Mahasiswa dapat menghubungkan PC dengan mikrokontroller untuk dapat
berkomunikasi melalui port serial.
V. Hasil Percobaan
Program Serial RS-232 Lanjut
/* Includes ------------------------------------------------------------------*/
#include "stm32f4xx_hal.h"
#include "lcd_character.h"
#include "stdio.h"
#include "stdlib.h"
#define RX_BUFFER_SIZE 16
uint8_t rx_data,rx_buffer[RX_BUFFER_SIZE+1];
unsigned int rx_index,n;
char buffer[RX_BUFFER_SIZE+1];
UART_HandleTypeDef huart1;
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) //mengambil data ketika
interupt
{
HAL_UART_Receive_IT(&huart1,&rx_data,1);
if(rx_data == '*'||rx_index>=RX_BUFFER_SIZE) rx_index=0;
rx_buffer[rx_index]=rx_data;
rx_index++;
}
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_USART1_UART_Init(void);
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_USART1_UART_Init();
lcd_init();
HAL_UART_Receive_IT(&huart1,&rx_data,1);
lcd_gotoxy(0,0);
lcd_puts("Redif's House");
HAL_Delay(1000);
while (1)
{
int ch, add_dev,add_data,data_analog;
char buffer[5];
add_dev = 7;
lcd_gotoxy(0,1);
lcd_data(rx_buffer[0]);lcd_data(rx_buffer[1]);
lcd_data(rx_buffer[2]);lcd_data(rx_buffer[3]);
lcd_data(rx_buffer[4]);lcd_data(rx_buffer[5]);
lcd_data(rx_buffer[6]);lcd_data(rx_buffer[7]);
lcd_data(rx_buffer[8]);lcd_data(rx_buffer[9]);
lcd_data(rx_buffer[10]);lcd_data(rx_buffer[11]);
lcd_data(rx_buffer[12]);lcd_data(rx_buffer[13]);
lcd_data(rx_buffer[14]);lcd_data(rx_buffer[15]);
if (rx_buffer[0]=='*'&& rx_buffer[8]=='#')
if(rx_buffer[1]=='W'||rx_buffer[1]=='w')
{
sprintf(buffer,"%c%c%c",rx_buffer[2],rx_buffer[3],rx_buffer[4]);
add_data = atoi(buffer);
if(add_dev == add_data)
{
sprintf(buffer,"%c%c",rx_buffer[5],rx_buffer[6]);
ch=atoi(buffer);
data_analog=rx_buffer[7];
if(ch==0)
{if (data_analog=='1')HAL_GPIO_WritePin(GPIOE, GPIO_PIN_0,GPIO_PIN_SET);
if (data_analog=='0')HAL_GPIO_WritePin(GPIOE, GPIO_PIN_0,GPIO_PIN_RESET);
}
else if(ch == 1)
{if (data_analog=='1')HAL_GPIO_WritePin(GPIOE, GPIO_PIN_1,GPIO_PIN_SET);
if (data_analog=='0')HAL_GPIO_WritePin(GPIOE, GPIO_PIN_1,GPIO_PIN_RESET);
}
else if(ch == 2)
{if (data_analog=='1')HAL_GPIO_WritePin(GPIOE, GPIO_PIN_2,GPIO_PIN_SET);
if (data_analog=='0')HAL_GPIO_WritePin(GPIOE, GPIO_PIN_2,GPIO_PIN_RESET);
}
else if(ch == 3)
{if (data_analog=='1')HAL_GPIO_WritePin(GPIOE, GPIO_PIN_3,GPIO_PIN_SET);
if (data_analog=='0')HAL_GPIO_WritePin(GPIOE, GPIO_PIN_3,GPIO_PIN_RESET);
}}}
rx_buffer[8]=0; //Untuk mencegah eksekusi sebelum komplit
}
}
/** System Clock Configuration
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct;
RCC_ClkInitTypeDef RCC_ClkInitStruct;
__PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLM = 8;
RCC_OscInitStruct.PLL.PLLN = 336;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = 4;
HAL_RCC_OscConfig(&RCC_OscInitStruct);
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_PCLK1
|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV4;
HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5);
HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
/* SysTick_IRQn interrupt configuration */
HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
}
/* USART1 init function */
void MX_USART1_UART_Init(void)
{
huart1.Instance = USART1;
huart1.Init.BaudRate = 9600;
huart1.Init.WordLength = UART_WORDLENGTH_8B;
huart1.Init.StopBits = UART_STOPBITS_1;
huart1.Init.Parity = UART_PARITY_NONE;
huart1.Init.Mode = UART_MODE_TX_RX;
huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart1.Init.OverSampling = UART_OVERSAMPLING_16;
HAL_UART_Init(&huart1);
}
/** Configure pins as
* Analog
* Input
* Output
* EVENT_OUT
* EXTI
*/
void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
/* GPIO Ports Clock Enable */
__GPIOE_CLK_ENABLE();
__GPIOH_CLK_ENABLE();
__GPIOD_CLK_ENABLE();
__GPIOB_CLK_ENABLE();
if (rx_buffer[0]=='*'&& rx_buffer[8]=='#')
if(rx_buffer[1]=='W'||rx_buffer[1]=='w')
{
sprintf(buffer,"%c%c%c",rx_buffer[2],rx_buffer[3],rx_buffer[4]);
add_data = atoi(buffer);
if(add_dev == add_data)
{
sprintf(buffer,"%c%c",rx_buffer[5],rx_buffer[6]);
ch=atoi(buffer);
data_analog=rx_buffer[7];
(ch==0)
{if (data_analog=='1')HAL_GPIO_WritePin(GPIOE, GPIO_PIN_0,GPIO_PIN_SET);
if (data_analog=='0')HAL_GPIO_WritePin(GPIOE, GPIO_PIN_0,GPIO_PIN_RESET);
}
else if(ch == 1)
{if (data_analog=='1')HAL_GPIO_WritePin(GPIOE, GPIO_PIN_1,GPIO_PIN_SET);
if (data_analog=='0')HAL_GPIO_WritePin(GPIOE, GPIO_PIN_1,GPIO_PIN_RESET);
}
else if(ch == 2)
{if (data_analog=='1')HAL_GPIO_WritePin(GPIOE, GPIO_PIN_2,GPIO_PIN_SET);
if (data_analog=='0')HAL_GPIO_WritePin(GPIOE, GPIO_PIN_2,GPIO_PIN_RESET);
}
else if(ch == 3)
{if (data_analog=='1')HAL_GPIO_WritePin(GPIOE, GPIO_PIN_3,GPIO_PIN_SET);
if (data_analog=='0')HAL_GPIO_WritePin(GPIOE, GPIO_PIN_3,GPIO_PIN_RESET);
}
}
}
rx_buffer[8]=0; //Untuk mencegah eksekusi sebelum komplit
}
}
/** System Clock Configuration
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct;
RCC_ClkInitTypeDef RCC_ClkInitStruct;
__PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLM = 8;
RCC_OscInitStruct.PLL.PLLN = 336;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = 4;
HAL_RCC_OscConfig(&RCC_OscInitStruct);
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_PCLK1
|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV4;
HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5);
HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
/* SysTick_IRQn interrupt configuration */
HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
}
/* USART2 init function */
void MX_USART2_UART_Init(void)
{
huart2.Instance = USART2;
huart2.Init.BaudRate = 9600;
huart2.Init.WordLength = UART_WORDLENGTH_8B;
huart2.Init.StopBits = UART_STOPBITS_1;
huart2.Init.Parity = UART_PARITY_NONE;
huart2.Init.Mode = UART_MODE_TX_RX;
huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart2.Init.OverSampling = UART_OVERSAMPLING_16;
HAL_UART_Init(&huart2);
}
/** Configure pins as
* Analog
* Input
* Output
* EVENT_OUT
* EXTI
*/
void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
/* GPIO Ports Clock Enable */
__GPIOE_CLK_ENABLE();
__GPIOH_CLK_ENABLE();
__GPIOA_CLK_ENABLE();
__GPIOD_CLK_ENABLE();
__GPIOB_CLK_ENABLE();
if (rx_buffer[0]=='*'&& rx_buffer[8]=='#') 1
if(rx_buffer[1]=='W'||rx_buffer[1]=='w') 2
sprintf(buffer,"%c%c%c",rx_buffer[2],rx_buffer[3],rx_buffer[4]);
add_data = atoi(buffer); 3
if(add_dev == add_data)
Pada program no. 1, digunakan untuk memeriksa apakah format data yang dikirim
telah sesuai dengan format data yang telah ditentukan sebelumnya. Apabila sesuai
maka akan dilanjutkan dengan memeriksa karakter kedua menggunakan program no. 2,
yaitu huruf W yang menunjukkan write command, huruf W disini dapar ditulis dalam
bentuk kapital maupun huruf kecil karena menggunakan tanda OR. Setelah itu, akan
diperiksa address data nya pada program no. 3, yaitu 3 karakter setelah huruf W.
Karena masih dalam bentuk char maka harus diubah ke integer supaya dapat
dibandingkan dengan nilai address data yang telah diinisialisasikan sebelumnya.
sprintf(buffer,"%c%c",rx_buffer[5],rx_buffer[6]);
ch=atoi(buffer); 4
data_analog=rx_buffer[7];
Pada program no. 4, digunakan untuk memeriksa channel yang digunakan. Karena
input data nya masih dalam bentuk char, maka harus diubah ke integer terlebih dahulu.
Selanjutnya akan diperiksa data value yang akan dieksekusikan ke channel relay.
Sebagai contoh *W007011#, maka pada format data tersebut address data yang
digunakan adalah 007, sedangkan channel relay sebagai outputnya yaitu relay channel
1 dengan kondisi ON (data value =1).
rx_buffer[8]=0; 5
Untuk mencegah eksekusi program sebelum data yang dituliskan lengkap (terutama
untuk penulisan format data yang kedua dan seterusnya), maka harus ditambahkan
program no. 5 diatas.
Pada percobaan serial dengan RS-485, format data yang digunakan sama dengan serial
menggunakan RS-232, yang membedakan adalah konfigurasi pada STM32CubeMX
nya, yaitu serial RS-485 menggunakan USART2. Selain itu juga Port serial yang
digunakan pada serial RS-485 harus menggunakan konverter RS-232 to RS-485
sebelum dihubungkan ke komputer.
VII. Kesimpulan
Komunikasi serial RS-485 harus menggunakan konverter RS-232 to RS-485
sebelum dihubungkan ke komputer.
Komunikasi serial RS-485 menggunakan USART2 dikarenakan USART1
sudah digunakan untuk komunikasi serial RS-232 sehingga tidak dapat
digunakan lagi.
Komunikasi serial RS-485 dapat digunakan untuk mengirim atau menerima
data tertentu dari lebih dari satu Mikrokontroller.