Sunday, 10 August 2014

Control a relay module from a PC via a TTL UART with a LPC810

Previously a simple program was created to read the input from a simple comparator based light sensor, now we focus attention on LPC810 GPIO's again to drive a relay module with some simple UART commands sent from a PC.

The module has a green LED for power and a red LED that lights when the relay is active

Using the LPC810's Physical Pin 4 which is pio_2 to drive the relay.

The relay module was wired up as below:-


These modules appear to be slightly different , the one I purchased from ebay operated on 5v and did not have an opto-isolator and so is only suitable for low voltages (In fact i would be vary careful with any of these cheap non-ce devices  from china with  mains level voltages,  just because the relay may-be rated at 240v does not imply the entire module has been designed for 240v,  if your intent is on controlling mains voltages then get a CE certified one) . The relay's active led was lit when IN1 was logic 0 and was off when IN1 was logic 1.For it to work it required that the GPIO output was driven in open drain mode and the required 5v Vcc was obtained from the 5v pin on the USB TTL UART adapter,

To use the GPIO port to drive the relay module he following needs to be done:

  1. Enable the Clock to the GPIO and IOCON with LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 6) | (1 << 18 )
  2. Reset all Fixed pins with LPC_SWM->PINENABLE0 = 0xffffffffUL;
  3. Put the GPIO in open drain mode and disable the internal pull up resistor with LPC_IOCON->PIO0_2 = (1 << 10) ;
  4. Set the PIO_2 direction to output with LPC_GPIO_PORT->DIR0 |= (1 << 2);

The GPIO port can be set or reset by putting a 1 or 0 in

 LPC_GPIO_PORT->B0[2]

when the index , two in this case is the index of the GPIO.


#include "LPC8xx.h"

#define BAUDRATE 57600
#define UART_CFG_DATALEN_8      (0x01 << 2)  /* UART 8 bit length mode */
#define UART_CFG_PARITY_NONE    (0x00 << 4)  /* No parity */
#define UART_CFG_STOPLEN_1      (0x00 << 6)  /* UART One Stop Bit Select */
#define UART_STAT_RXRDY         (0x01 << 0)  /* Receiver ready */
#define UART_STAT_TXRDY         (0x01 << 2)  /* Transmitter ready for data */
#define UART_CFG_ENABLE         (0x01 << 0)

uint32_t SystemCoreClock = 12000000; /* Value @ Reset */
uint32_t SystemMainClock = 12000000; /* Value @ Reset */

int uart0PollChar() {
 if (!(LPC_USART0->STAT & UART_STAT_RXRDY))
  return -1;
 return LPC_USART0->RXDATA;
}
void uart0putc(unsigned char c) {
 /* Wait until we're ready to send */
 while (!(LPC_USART0->STAT & UART_STAT_TXRDY));
 LPC_USART0->TXDATA = c;
}
int main(void) {
 /* Enable AHB clock to the Switch Matrix , UART0 , GPIO , IOCON*/
 LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 7) | (1 << 14) | (1 << 6) | (1 << 18 );

 /* Configure Switch Matrix so that Pin2 = U0_TXD and Pin8 = U0_RXD */
 LPC_SWM->PINASSIGN0 = 0xffff0004UL;

 /* On reset pio_2(swdio), pio_3(swclk) , pio_5(reset) are selected as fixed function.
  * We disable all fixed functions here so they will become GPIO unless a movable function
  * has been assigned in the switch matrix by the line above */
 LPC_SWM->PINENABLE0 = 0xffffffffUL;

 /* Physical Pin 4 (pio_2) is configured as output */
 LPC_GPIO_PORT->DIR0 |= (1 << 2);

 /* pio_2 is set to open drain mode and it's pull up resistor disabled */
 LPC_IOCON->PIO0_2 = (1 << 10)  ;

 /* Set the UART clock divisor to 1  */
 LPC_SYSCON->UARTCLKDIV = 1; // note on reset the value is 0. i.e clock is disabled
 /* Configure UART0 baud rate */
 LPC_USART0->BRG = ((SystemMainClock / LPC_SYSCON->UARTCLKDIV) >> 4)
   / BAUDRATE - 1;
 LPC_SYSCON->UARTFRGMULT =
   ((((SystemMainClock / LPC_SYSCON->UARTCLKDIV) >> 4) * (0x100))
     / (BAUDRATE * (LPC_USART0->BRG + 1))) - (0x100);
 LPC_SYSCON->UARTFRGDIV = 0xFF; //note on reset the value is 0

 /* Set UART0 to 8N1 and finally enable */
 LPC_USART0->CFG = UART_CFG_DATALEN_8 | UART_CFG_PARITY_NONE
   | UART_CFG_STOPLEN_1 | UART_CFG_ENABLE;

 /* Set pio_2 according to which keypress '0' and '1' */
 while (1) {
  switch (uart0PollChar()) {
  case '0':
   LPC_GPIO_PORT->B0[2] = 0;
   uart0putc('0');
   break;
  case '1':
   LPC_GPIO_PORT->B0[2] = 1;
   uart0putc('1');
   break;
  }
 }
 return 0;
}


No comments:

Post a Comment