Skip to content

Instantly share code, notes, and snippets.

@Ishibasystems
Last active January 5, 2019 00:51
Show Gist options
  • Save Ishibasystems/9a2d14cd1558f8e8f684 to your computer and use it in GitHub Desktop.
Save Ishibasystems/9a2d14cd1558f8e8f684 to your computer and use it in GitHub Desktop.
UART出力インターフェイスユニット

UART出力インターフェイスユニット

LPC810のピン説明:

  • 2ピン(U0_TXD) 正論理 UART RX (5Vトレラント)
  • 8ピン(U0_RXD) 正論理 UART TX (ほぼ電源電圧)
  • 5ピン(PIO0_1) 負論理 リレーNo1 赤
  • 3ピン(PIO0_3) 負論理 リレーNo2 黄
  • 1ピン(PIO0_5) 負論理 リレーNo3 緑
  • 4ピン(PIO0_2) 負論理 リレーNo4 紫(ブザー1)
  • 6ピン(VDD) 電源
  • 7ピン(VSS) 電源

起動時に5ピン(PIO0_1)をGNDに接続するとISPモードがUARTそのままで利用できます。

通信プロトコル

  • PHE-3FB表示灯に準拠
  • 9600bps
  • ノンパリティ
  • データ長8ビット
  • ストップビット1
  • リレーNo[動作番号]
#include "LPC8xx.h"
#include "lpc8xx_gpio.h"
#include "lpc8xx_mrt.h"
#include "lpc8xx_uart.h"
extern volatile uint32_t mrt_counter;
extern volatile uint32_t UARTRxCount;
extern volatile uint32_t RxErrorCount;
extern volatile uint8_t UARTRxBuffer[BUFSIZE];
#include <NXP/crp.h>
__CRP const unsigned int CRP_WORD = CRP_NO_CRP ;
#define sysclock 12000
#define IAP_LOCATION 0x1fff1ff1
typedef void ( *IAP )( unsigned int [], unsigned int[] );
IAP iap_entry;
int main ( void )
{ /* Main Program */
unsigned int command_param[5], status_result[4];
uint8_t status = 0xff, setnow, fflag = 0, *mem, id[64] = { 0 }, rtn[2] = { 5, 16 };
uint32_t RxCount = 0;
mem = ( uint8_t * ) 0x00000C00UL;
id[0] = mem[0];
id[1] = mem[1];
SystemCoreClockUpdate ();
/* SwitchMatrix_Init */
/* Enable SWM clock */
LPC_SYSCON->SYSAHBCLKCTRL |= 1 << 7;
/* Pin Assign 8 bit Configuration */
/* U0_TXD & U0_RXD */
LPC_SWM->PINASSIGN0 = 0xffff0004UL;
/* Pin Assign 1 bit Configuration */
LPC_SWM->PINENABLE0 = 0xffffffffUL;
/* Flash IAP Func */
iap_entry = ( IAP ) IAP_LOCATION;
iap_entry ( command_param, status_result );
GPIOSetDir ( 0, 1, 1 );
GPIOSetDir ( 0, 2, 1 );
GPIOSetDir ( 0, 3, 1 );
GPIOSetDir ( 0, 5, 1 );
GPIOSetBitValue ( 0, 1, 1 );
GPIOSetBitValue ( 0, 2, 1 );
GPIOSetBitValue ( 0, 3, 1 );
GPIOSetBitValue ( 0, 5, 0 );
/* MRT起動(緑を1秒間点灯) */
init_mrt ( SystemCoreClock / 10 );
while ( mrt_counter < 10 );
GPIOSetBitValue ( 0, 5, 1 );
/* UART起動 */
UARTInit ( LPC_USART0, 9600 );
while ( 1 )
{
if ( UARTRxCount && !RxErrorCount )
{ /* UART処理 - PHC-100Aの仕様に合わせた信号のバイナリデータ */
NVIC_DisableIRQ ( MRT_IRQn ); /* MRT無効化 */
LPC_USART0->INTENCLR = RXRDY; /* RXRDY無効化 */
RxCount = UARTRxCount;
if ( UARTRxCount == 7 /* 通信プロトコル準拠であることを確認 */
&& UARTRxBuffer[0] == '@' && UARTRxBuffer[4] >> 4 == 3
&& UARTRxBuffer[6] == '!' && UARTRxBuffer[5] >> 4 == 3 )
{ /* 本製品の識別番号(操作対象)であることを確認 */
if ( ( UARTRxBuffer[1] == id[0] && UARTRxBuffer[2] == id[1] )
|| ( UARTRxBuffer[1] == '?' && UARTRxBuffer[2] == '?' ) )
{ /* リレーを操作 */
setnow = ( UARTRxBuffer[4] & 0x0f ) << 4
| ( UARTRxBuffer[5] & 0x0f );
if ( UARTRxBuffer[3] == '0' ) status |= setnow; /* OFF */
if ( UARTRxBuffer[3] == '1' ) status &= ~setnow; /* ON */
if ( UARTRxBuffer[3] == '?' )
{ /* 本製品の識別番号を設定 */
id[0] = UARTRxBuffer[4];
id[1] = UARTRxBuffer[5];
__disable_irq();
command_param[0] = 50;
command_param[1] = 3;
command_param[2] = 3;
iap_entry(command_param, status_result);
command_param[0] = 52;
command_param[1] = 3;
command_param[2] = 3;
command_param[3] = sysclock;
iap_entry(command_param, status_result);
command_param[0] = 50;
command_param[1] = 3;
command_param[2] = 3;
iap_entry(command_param, status_result);
command_param[0] = 51;
command_param[1] = 0x00000C00UL; /* 書き込み先の先頭アドレス */
command_param[2] = ( unsigned int ) id; /* 書き込み元の先頭アドレス */
command_param[3] = 64; /* 64byte書き込む */
command_param[4] = sysclock;
iap_entry(command_param, status_result);
__enable_irq();
}
fflag ^= 1; /* 点滅・点灯処理で状態更新 */
}
UARTSend ( LPC_USART0, (uint8_t *) &rtn[0], 1); /* ACK */
}
else UARTSend ( LPC_USART0, (uint8_t *) &rtn[1], 1); /* NACK */
LPC_USART0->INTENSET = RXRDY; /* RXRDY有効化 */
NVIC_EnableIRQ ( MRT_IRQn ); /* MRT有効化 */
}
if ( RxErrorCount )
{ /* UARTエラー処理 - RS-232Cの不正フォーマット・信号断パルスなど */
UARTRxCount = 0;
RxErrorCount = 0;
}
if ( fflag == 0 && mrt_counter > 0 && mrt_counter <= 4 )
{ /* 点滅・点灯処理 - どちらかなら点灯 */
fflag = 1;
GPIOSetBitValue ( 0, 1, ( ( status >> 0 & 1 ) && ( status >> 5 & 1 ) ) );
GPIOSetBitValue ( 0, 3, ( ( status >> 1 & 1 ) && ( status >> 6 & 1 ) ) );
GPIOSetBitValue ( 0, 5, ( ( status >> 2 & 1 ) && ( status >> 7 & 1 ) ) );
GPIOSetBitValue ( 0, 2, ( ( status >> 3 & 1 ) && ( status >> 4 & 1 ) ) );
if ( RxCount == UARTRxCount ) UARTRxCount = 0;
}
else if ( fflag == 1 && mrt_counter > 4 && mrt_counter <= 8 )
{ /* 点滅・点灯処理 - 点滅ならこの区間は消灯 */
fflag = 0;
GPIOSetBitValue ( 0, 1, ( ( status >> 0 & 1 ) ||!( status >> 5 & 1 ) ) );
GPIOSetBitValue ( 0, 3, ( ( status >> 1 & 1 ) ||!( status >> 6 & 1 ) ) );
GPIOSetBitValue ( 0, 5, ( ( status >> 2 & 1 ) ||!( status >> 7 & 1 ) ) );
GPIOSetBitValue ( 0, 2, ( ( status >> 3 & 1 ) ||!( status >> 4 & 1 ) ) );
if ( RxCount == UARTRxCount ) UARTRxCount = 0;
}
else if ( mrt_counter > 8 ) mrt_counter = 0;
}
}
@Ishibasystems
Copy link
Author

  • シリアル通信の半端な受信バッファクリアのタイミングを受信バッファ処理後から最長半点灯サイクル時間後に変更
  • 識別番号(IDデータ)を不揮発領域にセーブ・起動時ロードするように実装
  • 返送コード(ACK, NACK)を実装

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment