產品簡介
直流馬達控制板
直流馬達控制板: MPV
半固定轉速調整
輸入可直接連接PLC用光遮斷感測器,不會有跳動的問題.
適用工業常用 24V DC 電源
馬達運作電流 最高 可達 8A
內建4A保險絲(規格可以搭配調整)
內建運轉/停止控制點
電源擴充輸出接點 [可連接到感測器所需電源 或 指示燈]
電路板尺寸相容於導軌電路板底座
單價 NTD $500
配件 保險絲: MPV-F
規格: 4A / 125V
單價 NTD $10
五線式步進馬達控制板
五線式步進馬達控制板: SPV
高性價比
預設使用步進馬達型號: 28BYJ-48
輸出入板
輸出入板:
具備 3 組 輸出/入 端子接點 , 6 點 供使用者設定.
輸出入 都使用光耦和隔離 及 使用 隔離電源, 輸入使用 24V 直流電源.
提供基本韌體程式 , 及原理圖 資料 可供二次開發 , MCU 使用 TI msp430g2452
輸入可連接 光感應器, 皆有經過測試驗證.
可即刻出貨,請先參照最下方連絡方式報價.
RS485/CAN 藍芽橋接板
RS485/CAN 藍芽橋接板:
橋接 RS485 或 CAN bus 通訊 到 BT5.0 安卓手機或平板
輸入電源可以選擇 48V 或 5V
使用 TI 藍芽晶片,省電/高效能
APP 介面可以客製
可即刻出貨,請先參照最下方連絡方式報價.
請跟我們聯絡,立刻將程式代碼發送給你.
請跟我們聯絡,立刻將程式代碼發送給你.
請跟我們聯絡,立刻將程式代碼發送給你.
高速光耦合板
高速光耦合板:
共用設計板,可兼容使用晶片 PC817 / 6N137
使用 6N137 可達到延遲時間小於 1us 的應用
單通道設計,可以快速連上系統做微調測試
電路板尺寸相容於導軌電路板底座
可即刻出貨,請先參照最下方連絡方式報價.
I2C 從端 轉 UART 橋接板
I2C 從端 轉 UART 橋接板:
輔助 MCU 缺少 I2C slave 功能
不需外掛震盪晶體
電壓位準可以選擇
I2C 從端 ID 可以設定
使用 TI 晶片
電路板尺寸相容於導軌電路板底座
//******************************************************************************
// Function: TX/RX data to slave via I2C
//
// Protocol:
// TX: [register address 3] length of TX data
// [register address 5] data head of TX
// RX: [register address 0] length of RX data
// [register address 2] data head of RX
// MSP430FR2512 eUSCI_B0, I2C Master multiple byte TX/RX
//
// Description: I2C master communicates to I2C slave sending and receiving
// 3 different messages of different length. I2C master will enter LPM0 mode
// while waiting for the messages to be sent/receiving using I2C interrupt.
// ACLK = NA, MCLK = SMCLK = DCO 16MHz.
//
// /|\ /|\
// MSP430FR2512 4.7k |
// ----------------- | 4.7k
// /|\ | P1.3|--------+-------|-- I2C Clock (UCB0SCL)
// | | | |
// ---|RST P1.2|-----------------+-- I2C Data (UCB0SDA)
// | |
// | |
//
// David Chen dvc2@ms31.hinet.net
// WAREGEN LTD.
//******************************************************************************
#include <msp430.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
//******************************************************************************
// Pin Config ******************************************************************
//******************************************************************************
#define LED_OUT P1OUT
#define LED_DIR P1DIR
#define LED0_PIN BIT0
#define LED1_PIN BIT1
//******************************************************************************
// Example Commands ************************************************************
//******************************************************************************
//#define SLAVE_ADDR 0x48
//#define SLAVE_ADDR 0x49
#define SLAVE_ADDR 0x4A
//#define SLAVE_ADDR 0x4B
/* CMD_TYPE_X_SLAVE are example commands the master sends to the slave.
* The slave will send example SlaveTypeX buffers in response.
*
* CMD_TYPE_X_MASTER are example commands the master sends to the slave.
* The slave will initialize itself to receive MasterTypeX example buffers.
* */
#define CMD_TYPE_0_SLAVE 0
#define CMD_TYPE_1_SLAVE 1
#define CMD_TYPE_2_SLAVE 2
#define CMD_TYPE_0_MASTER 3
#define CMD_TYPE_1_MASTER 4
#define CMD_TYPE_2_MASTER 5
#define TYPE_0_LENGTH 1
uint8_t _TYPE_0_LENGTH=1;
#define TYPE_1_LENGTH 2
uint8_t _TYPE_1_LENGTH=2;
#define TYPE_2_LENGTH 6
uint8_t _TYPE_2_LENGTH=6;
#define MAX_BUFFER_SIZE 20
/* MasterTypeX are example buffers initialized in the master, they will be
* sent by the master to the slave.
* SlaveTypeX are example buffers initialized in the slave, they will be
* sent by the slave to the master.
* */
//uint8_t MasterType2 [TYPE_2_LENGTH] = {'F', '4', '1', '9', '2', 'B'};
uint8_t MasterType1 [TYPE_1_LENGTH] = { 8, 9};
uint8_t MasterType0 [TYPE_0_LENGTH] = { 11};
uint8_t SlaveType2 [TYPE_2_LENGTH] = {0};
uint8_t SlaveType1 [TYPE_1_LENGTH] = {0};
uint8_t SlaveType0 [TYPE_0_LENGTH] = {0};
//******************************************************************************
// General I2C State Machine ***************************************************
//******************************************************************************
typedef enum I2C_ModeEnum{
IDLE_MODE,
NACK_MODE,
TX_REG_ADDRESS_MODE,
RX_REG_ADDRESS_MODE,
TX_DATA_MODE,
RX_DATA_MODE,
SWITCH_TO_RX_MODE,
SWITHC_TO_TX_MODE,
TIMEOUT_MODE
} I2C_Mode;
/* Used to track the state of the software state machine*/
I2C_Mode MasterMode = IDLE_MODE;
/* The Register Address/Command to use*/
uint8_t TransmitRegAddr = 0;
/* ReceiveBuffer: Buffer used to receive data in the ISR
* RXByteCtr: Number of bytes left to receive
* ReceiveIndex: The index of the next byte to be received in ReceiveBuffer
* TransmitBuffer: Buffer used to transmit data in the ISR
* TXByteCtr: Number of bytes left to transfer
* TransmitIndex: The index of the next byte to be transmitted in TransmitBuffer
* */
uint8_t ReceiveBuffer[MAX_BUFFER_SIZE] = {0};
uint8_t RXByteCtr = 0;
uint8_t ReceiveIndex = 0;
uint8_t TransmitBuffer[MAX_BUFFER_SIZE] = {0};
uint8_t TXByteCtr = 0;
uint8_t TransmitIndex = 0;
/* I2C Write and Read Functions */
/* For slave device with dev_addr, writes the data specified in *reg_data
*
* dev_addr: The slave device address.
* Example: SLAVE_ADDR
* reg_addr: The register or command to send to the slave.
* Example: CMD_TYPE_0_MASTER
* *reg_data: The buffer to write
* Example: MasterType0
* count: The length of *reg_data
* Example: TYPE_0_LENGTH
* */
I2C_Mode I2C_Master_WriteReg(uint8_t dev_addr, uint8_t reg_addr, uint8_t *reg_data, uint8_t count);
/* For slave device with dev_addr, read the data specified in slaves reg_addr.
* The received data is available in ReceiveBuffer
*
* dev_addr: The slave device address.
* Example: SLAVE_ADDR
* reg_addr: The register or command to send to the slave.
* Example: CMD_TYPE_0_SLAVE
* count: The length of data to read
* Example: TYPE_0_LENGTH
* */
I2C_Mode I2C_Master_ReadReg(uint8_t dev_addr, uint8_t reg_addr, uint8_t count);
void CopyArray(uint8_t *source, uint8_t *dest, uint8_t count);
I2C_Mode I2C_Master_ReadReg(uint8_t dev_addr, uint8_t reg_addr, uint8_t count)
{
/* Initialize state machine */
MasterMode = TX_REG_ADDRESS_MODE;
TransmitRegAddr = reg_addr;
RXByteCtr = count;
TXByteCtr = 0;
ReceiveIndex = 0;
TransmitIndex = 0;
/* Initialize slave address and interrupts */
UCB0I2CSA = dev_addr;
UCB0IFG &= ~(UCTXIFG + UCRXIFG); // Clear any pending interrupts
UCB0IE &= ~UCRXIE; // Disable RX interrupt
UCB0IE |= UCTXIE; // Enable TX interrupt
UCB0CTLW0 |= UCTR + UCTXSTT; // I2C TX, start condition
__bis_SR_register(LPM0_bits + GIE); // Enter LPM0 w/ interrupts
return MasterMode;
}
I2C_Mode I2C_Master_WriteReg(uint8_t dev_addr, uint8_t reg_addr, uint8_t *reg_data, uint8_t count)
{
/* Initialize state machine */
MasterMode = TX_REG_ADDRESS_MODE;
TransmitRegAddr = reg_addr;
//Copy register data to TransmitBuffer
CopyArray(reg_data, TransmitBuffer, count);
TXByteCtr = count;
RXByteCtr = 0;
ReceiveIndex = 0;
TransmitIndex = 0;
/* Initialize slave address and interrupts */
UCB0I2CSA = dev_addr;
UCB0IFG &= ~(UCTXIFG + UCRXIFG); // Clear any pending interrupts
UCB0IE &= ~UCRXIE; // Disable RX interrupt
UCB0IE |= UCTXIE; // Enable TX interrupt
UCB0CTLW0 |= UCTR + UCTXSTT; // I2C TX, start condition
__bis_SR_register(LPM0_bits + GIE); // Enter LPM0 w/ interrupts
return MasterMode;
}
void CopyArray(uint8_t *source, uint8_t *dest, uint8_t count)
{
uint8_t copyIndex = 0;
for (copyIndex = 0; copyIndex < count; copyIndex++)
{
dest[copyIndex] = source[copyIndex];
}
}
//******************************************************************************
// Device Initialization *******************************************************
//******************************************************************************
void initGPIO()
{
// Configure GPIO
LED_OUT &= ~(LED0_PIN | LED1_PIN); // P1 setup for LED & reset output
LED_DIR |= (LED0_PIN | LED1_PIN);
// I2C pins
P1SEL0 |= BIT2 | BIT3;
P1SEL1 &= ~(BIT2 | BIT3);
// Disable the GPIO power-on default high-impedance mode to activate
// previously configured port settings
PM5CTL0 &= ~LOCKLPM5;
}
void initClockTo16MHz()
{
// Configure one FRAM waitstate as required by the device datasheet for MCLK
// operation beyond 8MHz _before_ configuring the clock system.
FRCTL0 = FRCTLPW | NWAITS_1;
// Clock System Setup
__bis_SR_register(SCG0); // disable FLL
CSCTL3 |= SELREF__REFOCLK; // Set REFO as FLL reference source
CSCTL0 = 0; // clear DCO and MOD registers
CSCTL1 &= ~(DCORSEL_7); // Clear DCO frequency select bits first
CSCTL1 |= DCORSEL_5; // Set DCO = 16MHz
CSCTL2 = FLLD_0 + 487; // DCOCLKDIV = 16MHz
__delay_cycles(3);
__bic_SR_register(SCG0); // enable FLL
while(CSCTL7 & (FLLUNLOCK0 | FLLUNLOCK1)); // FLL locked
}
void initI2C()
{
UCB0CTLW0 = UCSWRST; // Enable SW reset
UCB0CTLW0 |= UCMODE_3 | UCMST | UCSSEL__SMCLK | UCSYNC; // I2C master mode, SMCLK
UCB0BRW = 160; // fSCL = SMCLK/160 = ~100kHz
UCB0I2CSA = SLAVE_ADDR; // Slave Address
UCB0CTLW0 &= ~UCSWRST; // Clear SW reset, resume operation
UCB0IE |= UCNACKIE;
}
void _delay(int ms)
{
while(ms--)
{
__delay_cycles(9595);
}
}
//******************************************************************************
// Main ************************************************************************
// Send and receive three messages containing the example commands *************
//******************************************************************************
int main(void) {
WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer
initClockTo16MHz();
initGPIO();
initI2C();
//TX
//I2C_Master_WriteReg(SLAVE_ADDR, CMD_TYPE_0_MASTER, MasterType0, TYPE_0_LENGTH);
//I2C_Master_WriteReg(SLAVE_ADDR, CMD_TYPE_1_MASTER, MasterType1, TYPE_1_LENGTH);
//I2C_Master_WriteReg(SLAVE_ADDR, CMD_TYPE_2_MASTER, MasterType2, TYPE_2_LENGTH);
//
///*
//*/
//
//RX
//I2C_Master_ReadReg(SLAVE_ADDR, CMD_TYPE_0_SLAVE, TYPE_0_LENGTH);
//CopyArray(ReceiveBuffer, SlaveType0, TYPE_0_LENGTH);
//I2C_Master_ReadReg(SLAVE_ADDR, CMD_TYPE_1_SLAVE, TYPE_1_LENGTH);
//CopyArray(ReceiveBuffer, SlaveType1, TYPE_1_LENGTH);
//I2C_Master_ReadReg(SLAVE_ADDR, CMD_TYPE_2_SLAVE, TYPE_2_LENGTH);
//CopyArray(ReceiveBuffer, SlaveType2, TYPE_2_LENGTH);
//
_delay(95);
while(1)
{
//RX
uint8_t RxDataLength[1];
uint8_t RxData[0x80];
I2C_Master_ReadReg(SLAVE_ADDR, 0, 1);//address 0 , read data length of data
RxDataLength[0]=ReceiveBuffer[0];
if(!RxDataLength[0]==0)
{
I2C_Master_ReadReg(SLAVE_ADDR,2,RxDataLength[0]);//address 2 , read data
CopyArray(ReceiveBuffer, RxData, RxDataLength[0]);
//TX
//uint8_t TxDataLength[1]={0};
I2C_Master_WriteReg(SLAVE_ADDR, 0x03, RxDataLength, 1);//address 3 , write 0x0B : write data length is 0x0B
//uint8_t TxData[0x80]={0};
I2C_Master_WriteReg(SLAVE_ADDR, 0x05 , RxData, RxDataLength[0]);//address 5, write data
}
_delay(9);
}
//
//__bis_SR_register(LPM0_bits + GIE);
//return 0;
}
//******************************************************************************
// I2C Interrupt ***************************************************************
//******************************************************************************
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector = USCI_B0_VECTOR
__interrupt void USCI_B0_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(USCI_B0_VECTOR))) USCI_B0_ISR (void)
#else
#error Compiler not supported!
#endif
{
//Must read from UCB0RXBUF
uint8_t rx_val = 0;
switch(__even_in_range(UCB0IV, USCI_I2C_UCBIT9IFG))
{
case USCI_NONE: break; // Vector 0: No interrupts
case USCI_I2C_UCALIFG: break; // Vector 2: ALIFG
case USCI_I2C_UCNACKIFG: // Vector 4: NACKIFG
break;
case USCI_I2C_UCSTTIFG: break; // Vector 6: STTIFG
case USCI_I2C_UCSTPIFG: break; // Vector 8: STPIFG
case USCI_I2C_UCRXIFG3: break; // Vector 10: RXIFG3
case USCI_I2C_UCTXIFG3: break; // Vector 12: TXIFG3
case USCI_I2C_UCRXIFG2: break; // Vector 14: RXIFG2
case USCI_I2C_UCTXIFG2: break; // Vector 16: TXIFG2
case USCI_I2C_UCRXIFG1: break; // Vector 18: RXIFG1
case USCI_I2C_UCTXIFG1: break; // Vector 20: TXIFG1
case USCI_I2C_UCRXIFG0: // Vector 22: RXIFG0
rx_val = UCB0RXBUF;
if (RXByteCtr)
{
ReceiveBuffer[ReceiveIndex++] = rx_val;
RXByteCtr--;
}
if (RXByteCtr == 1)
{
UCB0CTLW0 |= UCTXSTP;
}
else if (RXByteCtr == 0)
{
UCB0IE &= ~UCRXIE;
MasterMode = IDLE_MODE;
__bic_SR_register_on_exit(CPUOFF); // Exit LPM0
}
break;
case USCI_I2C_UCTXIFG0: // Vector 24: TXIFG0
switch (MasterMode)
{
case TX_REG_ADDRESS_MODE:
UCB0TXBUF = TransmitRegAddr;
if (RXByteCtr)
MasterMode = SWITCH_TO_RX_MODE; // Need to start receiving now
else
MasterMode = TX_DATA_MODE; // Continue to transmision with the data in Transmit Buffer
break;
case SWITCH_TO_RX_MODE:
UCB0IE |= UCRXIE; // Enable RX interrupt
UCB0IE &= ~UCTXIE; // Disable TX interrupt
UCB0CTLW0 &= ~UCTR; // Switch to receiver
MasterMode = RX_DATA_MODE; // State state is to receive data
UCB0CTLW0 |= UCTXSTT; // Send repeated start
if (RXByteCtr == 1)
{
//Must send stop since this is the N-1 byte
while((UCB0CTLW0 & UCTXSTT));
UCB0CTLW0 |= UCTXSTP; // Send stop condition
}
break;
case TX_DATA_MODE:
if (TXByteCtr)
{
UCB0TXBUF = TransmitBuffer[TransmitIndex++];
TXByteCtr--;
}
else
{
//Done with transmission
UCB0CTLW0 |= UCTXSTP; // Send stop condition
MasterMode = IDLE_MODE;
UCB0IE &= ~UCTXIE; // disable TX interrupt
__bic_SR_register_on_exit(CPUOFF); // Exit LPM0
}
break;
default:
__no_operation();
break;
}
break;
default: break;
}
}
//******************************************************************************
// Function: Slave of I2C bridge to UART
//
// Protocol:
// I2C RX:
// I2C register address 3 for RX data length
// I2C register address 5 for data , then send to UART TX
//
// I2C TX:
// I2C register address 0 for TX data length
// I2C register address 2 for TX data , here buffered UART RX data
//
// MSP430FR2512 eUSCI_B0, I2C Slave multiple byte TX/RX
//
// Description: I2C master communicates to I2C slave sending and receiving
// 3 different messages of different length. (This is the slave code). The
// slave will be in LPM0 mode, waiting for the master to initiate the
// communication. The slave will send/receive bytes based on the master's
// request. The slave will handle I2C bytes sent/received using the
// I2C interrupt.
// ACLK = NA, MCLK = SMCLK = DCO 16MHz.
//
// /|\ /|\
// MSP430FR2512 4.7k |
// ----------------- | 4.7k
// /|\ | P1.3|--+--------------|-- I2C Clock (UCB0SCL)
// | | | |
// ---|RST P1.2|-----------------+-- I2C Data (UCB0SDA)
// | |
// UART RX -->| P1.5 P1.0|-LED
// UART TX <--| P1.4 |
// | P1.1|-->INT
// | P2.0|<--ID.0
// | P2.1|<--ID.1
//
// David Chen dvc2@ms31.hinet.net
// WAREGEN LTD.
//
//******************************************************************************
#include <msp430.h>
#include <stdint.h>
#include <string.h>
//******************************************************************************
// Example Commands ************************************************************
//******************************************************************************
#define LED_OUT P1OUT
#define LED_DIR P1DIR
#define LED0_PIN BIT0
#define INT_PIN BIT1
#define RxInt(s) (s)? (P1OUT|INT_PIN):(P1OUT&(~INT_PIN))
#define TX_DATA_LENGTH 0
#define TX_DATA 2
#define RX_DATA_LENGTH 3
#define RX_DATA 5
#define MAX_BUFFER_SIZE 200
#define putChar(_c) while(!(UCA0IFG & UCTXIFG));\
UCA0TXBUF = _c
uint8_t RxLength=0;
uint8_t TxLength=0;
uint8_t UartBuffer[MAX_BUFFER_SIZE]={0};
uint8_t UartIndex=0;
uint8_t TxData[MAX_BUFFER_SIZE]={0};
//******************************************************************************
// General I2C State Machine ***************************************************
//******************************************************************************
typedef enum I2C_ModeEnum{
IDLE_MODE,
NACK_MODE,
TX_REG_ADDRESS_MODE,
RX_REG_ADDRESS_MODE,
TX_DATA_MODE,
RX_DATA_MODE,
SWITCH_TO_RX_MODE,
SWITHC_TO_TX_MODE,
TIMEOUT_MODE
} I2C_Mode;
/* Used to track the state of the software state machine*/
I2C_Mode SlaveMode = RX_REG_ADDRESS_MODE;
/* The Register Address/Command to use*/
uint8_t ReceiveRegAddr = 0;
/* ReceiveBuffer: Buffer used to receive data in the ISR
* RXByteCtr: Number of bytes left to receive
* ReceiveIndex: The index of the next byte to be received in ReceiveBuffer
* TransmitBuffer: Buffer used to transmit data in the ISR
* TXByteCtr: Number of bytes left to transfer
* TransmitIndex: The index of the next byte to be transmitted in TransmitBuffer
* */
uint8_t ReceiveBuffer[MAX_BUFFER_SIZE] = {0};
uint8_t RXByteCtr = 0;
uint8_t ReceiveIndex = 0;
uint8_t TransmitBuffer[MAX_BUFFER_SIZE] = {0};
uint8_t TXByteCtr = 0;
uint8_t TransmitIndex = 0;
/* Initialized the software state machine according to the received cmd
*
* cmd: The command/register address received
* */
//void I2C_Slave_ProcessCMD(uint8_t cmd);
/* The transaction between the slave and master is completed. Uses cmd
* to do post transaction operations. (Place data from ReceiveBuffer
* to the corresponding buffer based in the last received cmd)
*
* cmd: The command/register address corresponding to the completed
* transaction
*/
//void I2C_Slave_TransactionDone(uint8_t cmd);
void I2C_Slave_ProcessCMD(uint8_t cmd)
{
ReceiveIndex = 0;
TransmitIndex = 0;
RXByteCtr = 0;
TXByteCtr = 0;
switch (cmd)
{
case (TX_DATA_LENGTH)://adr 0 , TX data length //Send slave device id (This device's id)
SlaveMode = TX_DATA_MODE;
TXByteCtr = 0x01;
//Fill out the TransmitBuffer
TransmitBuffer[0]=TxLength;//TxLength get from UART data length
UCB0IE &= ~UCRXIE; // Disable RX interrupt
UCB0IE |= UCTXIE; // Enable TX interrupt
break;
case (TX_DATA): //adr 2, TX data //Send slave device location (This device's location)
SlaveMode = TX_DATA_MODE;
TXByteCtr =TxLength;
//Fill out the TransmitBuffer
memcpy(TransmitBuffer,TxData,TxLength); //TxData get from UART data
UCB0IE &= ~UCRXIE; // Disable RX interrupt
UCB0IE |= UCTXIE; // Enable TX interrupt
break;
case (RX_DATA_LENGTH)://adr 3, RX data length
SlaveMode = RX_DATA_MODE;
RXByteCtr = 0x01;
UCB0IE &= ~UCTXIE; // Disable RX interrupt
UCB0IE |= UCRXIE; // Enable TX interrupt
break;
case (RX_DATA)://adr 5, RX data
SlaveMode = RX_DATA_MODE;
RXByteCtr =RxLength;//
UCB0IE &= ~UCTXIE; // Disable RX interrupt
UCB0IE |= UCRXIE; // Enable TX interrupt
break;
default:
__no_operation();
break;
}
}
void I2C_Slave_TransactionDone(uint8_t cmd)
{
switch (cmd)
{
case (TX_DATA_LENGTH)://adr 0, TX data length
break;
case (TX_DATA)://adrt 2, TX data
TxLength=0;
RxInt(1);//INT pin high, no data in buffer
break;
case (RX_DATA_LENGTH)://adr 3, RX data length
RxLength=ReceiveBuffer[0];
break;
case (RX_DATA)://adr 5 , RX data
for(int ii=0;ii<RxLength;ii++)
{
putChar(ReceiveBuffer[ii]);
}
break;
default:
_NOP();
break;
}
}
//******************************************************************************
// Device Initialization *******************************************************
//******************************************************************************
void initGPIO()
{
// Configure LED GPIO
LED_OUT &= ~(LED0_PIN); // P1 setup for LED & reset output
LED_OUT |= (INT_PIN); //INT output pin
LED_DIR |= (LED0_PIN | INT_PIN);
//
P2DIR &=~(BIT1|BIT0);//ID Input
P2REN |=(BIT1|BIT0);//R enable
// I2C pins
P1SEL0 |= BIT2 | BIT3;
P1SEL1 &= ~(BIT2 | BIT3);
// Configure UART GPIO
P1SEL1 &= ~(BIT4 | BIT5); // USCI_A0 UART operation
P1SEL0 |= BIT4 | BIT5;
// Disable the GPIO power-on default high-impedance mode to activate
// previously configured port settings
PM5CTL0 &= ~LOCKLPM5;
}
#define SLAVE_ADDR 0x48
//#define SLAVE_ADDR(in) (0x48|in)
void initI2C()
{
UCB0CTLW0 = UCSWRST; // Software reset enabled
UCB0CTLW0 |= UCMODE_3 | UCSYNC; // I2C mode, sync mode
UCB0I2COA0 = (SLAVE_ADDR|(P2IN&0x03)) | UCOAEN; // Own Address and enable
//UCB0I2COA0 = SLAVE_ADDR(P2IN&0x03) | UCOAEN; // Own Address and enable
UCB0CTLW0 &= ~UCSWRST; // clear reset register
UCB0IE |= UCRXIE + UCSTPIE;
}
//******************************************************************************
// UART Initialization *********************************************************
//******************************************************************************
#define SMCLK_115200 0
#define SMCLK_9600 1
//there are 2 baud rate 115200 and 9600 , below is 115200
#define UART_MODE SMCLK_115200//SMCLK_9600//
void initUART()
{
// Configure USCI_A0 for UART mode
UCA0CTLW0 |= UCSWRST; // Put eUSCI in reset
#if UART_MODE == SMCLK_115200
UCA0CTLW0 |= UCSSEL__SMCLK; // CLK = SMCLK
// Baud Rate Setting
// Use Table 21-5
UCA0BRW = 8;
UCA0MCTLW |= UCOS16 | UCBRF_10 | 0xF700; //0xF700 is UCBRSx = 0xF7
#elif UART_MODE == SMCLK_9600
UCA0CTLW0 |= UCSSEL__SMCLK; // CLK = SMCLK
// Baud Rate Setting
// Use Table 21-5
UCA0BRW = 104;
UCA0MCTLW |= UCOS16 | UCBRF_2 | 0xD600; //0xD600 is UCBRSx = 0xD6
#else
# error "Please specify baud rate to 115200 or 9600"
#endif
UCA0CTLW0 &= ~UCSWRST; // Initialize eUSCI
UCA0IE |= UCRXIE; // Enable USCI_A0 RX interrupt
}
void initClockTo16MHz()
{
// Configure one FRAM waitstate as required by the device datasheet for MCLK
// operation beyond 8MHz _before_ configuring the clock system.
FRCTL0 = FRCTLPW | NWAITS_1;
__bis_SR_register(SCG0); // disable FLL
CSCTL3 |= SELREF__REFOCLK; // Set REFO as FLL reference source
CSCTL0 = 0; // clear DCO and MOD registers
CSCTL1 &= ~(DCORSEL_7); // Clear DCO frequency select bits first
CSCTL1 |= DCORSEL_5; // Set DCO = 16MHz
CSCTL2 = FLLD_0 + 487; // set to fDCOCLKDIV = (FLLN + 1)*(fFLLREFCLK/n)
// = (487 + 1)*(32.768 kHz/1)
// = 16 MHz
__delay_cycles(3);
__bic_SR_register(SCG0); // enable FLL
while(CSCTL7 & (FLLUNLOCK0 | FLLUNLOCK1)); // FLL locked
CSCTL4 = SELMS__DCOCLKDIV | SELA__REFOCLK;
}
//******************************************************************************
// Main ************************************************************************
// Enters LPM0 and waits for I2C interrupts. The data sent from the master is *
// then interpreted and the device will respond accordingly *
//******************************************************************************
int main(void) {
WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer
initClockTo16MHz();
initGPIO();
initI2C();
initUART();
__bis_SR_register(LPM0_bits + GIE);
return 0;
}
//******************************************************************************
// I2C Interrupt ***************************************************************
//******************************************************************************
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector = USCI_B0_VECTOR
__interrupt void USCI_B0_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(USCI_B0_VECTOR))) USCI_B0_ISR (void)
#else
#error Compiler not supported!
#endif
{
//Must read from UCB0RXBUF
uint8_t rx_val = 0;
switch(__even_in_range(UCB0IV, USCI_I2C_UCBIT9IFG))
{
case USCI_NONE: break; // Vector 0: No interrupts
case USCI_I2C_UCALIFG: break; // Vector 2: ALIFG
case USCI_I2C_UCNACKIFG: // Vector 4: NACKIFG
break;
case USCI_I2C_UCSTTIFG: break; // Vector 6: STTIFG
case USCI_I2C_UCSTPIFG:
UCB0IFG &= ~(UCTXIFG0);
break; // Vector 8: STPIFG
case USCI_I2C_UCRXIFG3: break; // Vector 10: RXIFG3
case USCI_I2C_UCTXIFG3: break; // Vector 12: TXIFG3
case USCI_I2C_UCRXIFG2: break; // Vector 14: RXIFG2
case USCI_I2C_UCTXIFG2: break; // Vector 16: TXIFG2
case USCI_I2C_UCRXIFG1: break; // Vector 18: RXIFG1
case USCI_I2C_UCTXIFG1: break; // Vector 20: TXIFG1
case USCI_I2C_UCRXIFG0: // Vector 22: RXIFG0
rx_val = UCB0RXBUF;
switch (SlaveMode)
{
case (RX_REG_ADDRESS_MODE):
ReceiveRegAddr = rx_val;
I2C_Slave_ProcessCMD(ReceiveRegAddr);
break;
case (RX_DATA_MODE):
ReceiveBuffer[ReceiveIndex++] = rx_val;
RXByteCtr--;
if (RXByteCtr == 0)
{
//Done Receiving MSG
SlaveMode = RX_REG_ADDRESS_MODE;
UCB0IE &= ~(UCTXIE);
UCB0IE |= UCRXIE; // Enable RX interrupt
I2C_Slave_TransactionDone(ReceiveRegAddr);
}
break;
default:
__no_operation();
break;
}
break;
case USCI_I2C_UCTXIFG0: // Vector 24: TXIFG0
switch (SlaveMode)
{
case (TX_DATA_MODE):
UCB0TXBUF = TransmitBuffer[TransmitIndex++];
TXByteCtr--;
if (TXByteCtr == 0)
{
//Done Transmitting MSG
SlaveMode = RX_REG_ADDRESS_MODE;
UCB0IE &= ~(UCTXIE);
UCB0IE |= UCRXIE; // Enable RX interrupt
I2C_Slave_TransactionDone(ReceiveRegAddr);
}
break;
default:
_NOP();
break;
}
break; // Interrupt Vector: I2C Mode: UCTXIFG
default: break;
}
}
//******************************************************************************
// UART Interrupt ***********************************************************
//******************************************************************************
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=USCI_A0_VECTOR
__interrupt void USCI_A0_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(USCI_A0_VECTOR))) USCI_A0_ISR (void)
#else
#error Compiler not supported!
#endif
{
switch(__even_in_range(UCA0IV, USCI_UART_UCTXCPTIFG))
{
case USCI_NONE: break;
case USCI_UART_UCRXIFG:
//while(!(UCA0IFG&UCTXIFG));
//UCA0TXBUF = UCA0RXBUF;
if(UartIndex>0 && UCA0RXBUF==0x0A && UartBuffer[UartIndex-1]==0x0D)
{
TxLength=UartIndex-1;
memcpy(TxData,UartBuffer,TxLength);
UartIndex=0;
memset(UartBuffer,0,TxLength+1);//TxLength+1 => there is 0x0D in UartBuffer need to be clear up
RxInt(0);//INT pin low ,there are data in buffer,and get endded code
}
else
{
UartBuffer[UartIndex++]=UCA0RXBUF;
}
break;
case USCI_UART_UCTXIFG: break;
case USCI_UART_UCSTTIFG: break;
case USCI_UART_UCTXCPTIFG: break;
}
}
16 位元 類比數位轉換器 ADS8681 / ADS8685 / ADS8689 應用
//ADS8681 initial
void AmpAdInit(void)
{
__delay_cycles(160000); //dvc don't move ,Delay for 160,000*(1/MCLK)=0.02 seconds,wait for ADS8689 REF turn-on
AmpADS8689(0xD4040000); //register 0x04 -> 0 (default value) (MS high byte ignore)
AmpADS8689(0xD4080000); //register 0x08 -> 0 (default value) (MS high byte ignore)
AmpADS8689(0xD20C0100); //set SDO-1 as alarm(LS low byte ignore)
AmpADS8689(0xD2100000); //register 0x10 ->0 (default) (LS low byte ignore)
AmpADS8689(0xD4100000); //register 0x10 ->0 (defualt) (MS high byte ignore)
AmpADS8689(0xD4140004); //set 0x14 for input range= +/-0.625*Vref = 2.56V(MS high byte ignore)
AmpADS8689(0);
}
//ADS8681 driver
unsigned short AmpADS8689(long adicmd) //Amp ADS8681
{
unsigned char indi;
long adii=0;
while(!(P7IN & BIT1)) __delay_cycles(9); //prevent IAD_RVS low
P6OUT |= BIT0; //IAD_CS
P6OUT &=~ (BIT1+BIT2); //IAD_CLK IAD_SDI
P6OUT &= ~BIT0; //IAD_CS low
while( P7IN & BIT1) __delay_cycles(9); //wait for IAD_RVS high
for(indi=0;indi<32;indi++)
{
(adicmd &0x80000000)? (P6OUT |= BIT2):(P6OUT &= ~BIT2); //write to SDI P6.2
adicmd<<=1;
__delay_cycles(AdTd); //dvc fixed
P6OUT |= BIT1; //IAD_CLK high
adii *= 2;
__delay_cycles(AdTd); //dvc fixed
if(P6IN & BIT3) adii++; //IAD_DO_0 , P6.3
P6OUT &= ~BIT1; //IAD_CLK low
}
P6OUT |= BIT0; //IAD_CS high
while(!(P7IN & BIT1)); //wait for IAD_RVS low
return (unsigned short)(adii/0x10000);
}
FSK CMT2119A 驅動 設定
// WAREGEN LTD.
//function:test CMT2119A (RFM1119 module board)
// Description; Toggle P1.0 by xor'ing P1.0 inside of a software loop.
// ACLK = n/a, MCLK = SMCLK = default DCO
//
// MSP430G2452
// -----------------
// /|\| 19 XIN|-
// | | | 32.768K Hz
// --|RST 18 XOUT|-
// | |
// | P1.0|-->LED
// | P1.6|-->LED
// | |
// | P1.4|-->CLK
// | P1.5|<->DATA
//
// David Chen dvc2@ms31.hinet.net 25th AUG 2022
// Built with IAR Embedded Workbench Version 7.12.1
//******************************************************************************
#include <msp430.h>
#include "stdbool.h"
//定義 SCL 腳
#define SCL BIT4
//定義 SDA 腳
#define SDA BIT5
//若 C = HIGH , SCL = HIGH ; C=LOW ,SCL=LOW
#define TWI_SCL(C) (C)? (P1OUT |= SCL) : (P1OUT &= ~SCL)
//若 D = HIGH , SDA = HIGH ; D=LOW ,SDA=LOW
#define TWI_SDA(D) (D)? (P1OUT |= SDA) : (P1OUT &= ~SDA)
#define HIGH true
#define LOW false
//設定 SCL 為 輸入 , 預留而已沒有用到
#define TWI_SCL_as_INPUT P1DIR &= ~SCL
//設定 SCL 為 輸出
#define TWI_SCL_as_OUTPUT P1DIR |= SCL
//設定 SDA 為 輸入
#define TWI_SDA_as_INPUT P1DIR &= ~SDA
//設定 SDA 為 輸出
#define TWI_SDA_as_OUTPUT P1DIR |= SDA
//讀取 SDA 腳的 HIGH / LOW
#define TWI_SDA_read (P1IN & SDA)
//這是用示波器量測的實際值,每個系統不同,僅作紀錄使用
//__delay_cycles(1); offset time =7.3us
//__delay_cycles(2); delay time =8.3us
//__delay_cycles(3); delay time =9.3us
//__delay_cycles(4); delay time =10.3us
//延時 10 us
#define delay_10us __delay_cycles(4)
//延時
//ms=1 , 1ms
//ms=2 , 2ms ...
void delay_ms(unsigned short ms)
{
while(ms--)
{
__delay_cycles(993);//
}
}
//*************************************************************
//Mode = Basic
//Part Number = CMT2119A
//Frequency = 750 MHz
//Modulation = OOK
//Symbol Rate = 0.5 - 30.0 ksps
//Tx Power = +10 dBm
//PA Ramping Time = 0 us
//Deviation = NA
//Xtal Cload = 15.00 pF
//Tx Start by = DATA Pin Rising Edge
//Tx Stop by = DATA Pin Holding Low for 20 ms
//Increase XO Current = No
//FILE CRC = A470
unsigned short CfgTbl[21] = {
0x007F,
0x5000,
0x0000,
0x0000,
0x0000,
0xF000,
0x0000,
0xB13B,
0x3900,
0x0000,
0x2401,
0x01B0,
0x8000,
0x000A,
0xFFFF,
0x0020,
0x5F12,
0x22D6,
0x0E13,
0x0019,
0x2000
};
//對 SCL / SDA 初始化
void vTWIInit()
{
TWI_SCL_as_OUTPUT; //設 SCL 為輸出
TWI_SCL(HIGH); //SCL=HIGH
TWI_SDA_as_OUTPUT; //設SDA為輸出
TWI_SDA(HIGH); //SDA=HIGH
}
//寫入 BYTE
void vTWIWriteByte(unsigned char dat)
{
TWI_SCL_as_OUTPUT; //設 SCL 為輸出
TWI_SCL(HIGH); //SCL=HIGH
TWI_SDA_as_OUTPUT; //設 SDA 為輸出
TWI_SDA(LOW); //SDA=LOW
unsigned char bitcnt;
for (bitcnt = 8; bitcnt != 0; bitcnt--)//迴圈 bitcnt 從 8 開始,每次減1
{
TWI_SCL(HIGH); //SCL=HIGH
if (dat & 0x80) // 若 dat & 0x80 不是 0
{
TWI_SDA(HIGH); //SDA=HIGH
}
else
{
TWI_SDA(LOW); //SDA=LOW
}
delay_10us; //延時 10us
TWI_SCL(LOW); //SCL=LOW
delay_10us; //延時 10us
dat <<= 1; //dat 左旋 1 bit
} //迴圈結束
TWI_SCL(HIGH); //SCL=HIGH
//TWI_SDA(LOW); //this pin low , RF will going down
TWI_SDA(HIGH); //dvc 20220828 keep RF power on SDA=HIGH
}
void vTWIWrite(unsigned char adr, unsigned char dat)//寫入
{
adr |= 0x80; //因為 CMT2119A 格式 bit7=1
adr &= 0xBF; //CMT2119A 若 寫入 bit6=0
vTWIWriteByte(adr); //呼叫 vTWIWriteByte 寫入 位址
vTWIWriteByte(dat); //呼叫 vTWIWriteByte 寫入 資料
}
void vTWIReset() //重置 , 作用為喚醒 CMT2119A
{
TWI_SCL_as_OUTPUT; //設SCL為輸出
TWI_SCL(HIGH); //SCL=HIGH
TWI_SDA_as_OUTPUT; //設SDA為輸出
TWI_SDA(LOW); //SDA=LOW
unsigned char bitcnt;
for (bitcnt = 32; bitcnt !=0; bitcnt--) //32次迴圈,CMT2119A 要有32個 SCL
{
TWI_SCL(HIGH); //SCL=HIGH
delay_10us; //延時 10u
TWI_SCL(LOW); //SCL=LOW
delay_10us; //延時 10u
} //迴圈結束
TWI_SCL(HIGH); //SCL=HIGH
TWI_SDA(LOW); //SDA=LOW
vTWIWrite(0x0D, 0x00); //0x8D00 寫入 0x8D00
}
//
void vSoftReset() //軟體重置,清除CMT2119A 部分軟體功能
{
vTWIWrite(0x3D, 0x01); // write 0xBD01 寫入 0xBD01
}
void vOpenLdoAndOsc() //開啟 CMT2119A LDO 及 OSC
{
vTWIWrite(0x02, 0x78); //寫入 0x8278
}
void vActiveRegister() //啟動CMT2119A暫存器
{
unsigned char adr[5] = {0x2F,0x35,0x36,0x37,0x38};
unsigned char data[5] = {0x80,0xCA,0xEB,0x37,0x82};
unsigned char i;
for (i = 0; i < 5; i++) //將上面資料寫入 CMT2119A
{
vTWIWrite(adr[i], data[i]);
}
}
void vEnableRegMode() //進入 CMT2119A 暫存器模式
{
unsigned char adr[4] = { 0x12,0x12,0x24,0x1D};
unsigned char data[4] = { 0x10,0x00,0x07,0x20 };
unsigned char i;
for (i = 0; i < 4; i++) //將上面資料寫入 CMT2119A
{
vTWIWrite(adr[i], data[i]);
}
}
void vTWIOff() //關閉CMTA2119A暫存器存取
{
vTWIWrite(0x0D, 0x02); //0x8D02 寫入 0x8D02
}
void vWriteReg(unsigned char adr, unsigned short wrPara) //寫入 CMT2119A 設定
{
vTWIWrite(0x18, adr); //0x18 要放設定的 位址
vTWIWrite(0x19, wrPara % 0x100); //0x19 要放設定資料的 low byte
vTWIWrite(0x1A, wrPara / 0x100); //0x20 要放設定資料的 High byte
vTWIWrite(0x25, 0x01); //0xA501 完成一筆設定
}
void vCMT2119AInit(unsigned short para[], unsigned char length) //
{
vTWIInit(); //SCL SDA 初始化
vTWIReset(); //step 1 喚醒 CMT2119A
vSoftReset(); //step 2 軟體重置
delay_ms(2); //延時 2ms
#if 1 //if no register configuration, disable it
vOpenLdoAndOsc(); //開啟 CMT2119A LDO 及 OSC
vActiveRegister(); //啟動 CMT2119A 暫存器
vEnableRegMode(); //進入 CMT2119A 暫存器模式
unsigned char i;
for (i = 0; i < length; i++) //將 USB Programmer [RFPDK] 的表格寫入 CMT2119A
{
vWriteReg(i, para[i]);
}
vTWIOff(); //退出 CMT2119A 暫存器模式
#endif
TWI_SDA_as_OUTPUT; //設定 SDA 為輸出
//TWI_SDA(LOW); //this pin low , RF will going down
TWI_SDA(HIGH);//dvc 20220828 keep RF power on SDA=HIGH
}
//*********************************************************************************************
int main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer , TI MCU 的初始設定
P1DIR |= (BIT6+SDA+SCL+BIT0); // Set P1.0 P1.6 作 LED , P1.4=CMT2119A SCL , P1.5=CMT2119A SDA to output direction
//
delay_ms(3); //延時 3ms
while(1)
{
CfgTbl[0x10]=0x4786; //更改 資料表的輸出功率為 -10dbm
vCMT2119AInit(CfgTbl,21); //把資料表寫入 CMT2119A
delay_ms(2000); //延時 2s
CfgTbl[0x10]=0x474B; //更改 資料表的輸出功率為 -5dbm
vCMT2119AInit(CfgTbl,21); //把資料表寫入 CMT2119A
delay_ms(2000); //延時 2s
CfgTbl[0x10]=0x4F0A; //更改 資料表的輸出功率為 0dbm
vCMT2119AInit(CfgTbl,21); //把資料表寫入 CMT2119A
delay_ms(2000); //延時 2s
CfgTbl[0x10]=0x5FC9; //更改 資料表的輸出功率為 +5dbm
vCMT2119AInit(CfgTbl,21); //把資料表寫入 CMT2119A
delay_ms(2000); //延時 2s
CfgTbl[0x10]=0x5F12; //更改 資料表的輸出功率為 +10dbm
vCMT2119AInit(CfgTbl,21); //把資料表寫入 CMT2119A
delay_ms(2000); //延時 2s
}
}