I modified the source code of MCP2515.ccp
(http://code.google.com/p/netduino-mcp2515/downloads/list)
to meet my project's requirement.
It support two CAN bus protocol chips and control by one SPI interface.
//-------------------------------------------------------------------------------------------
using System;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
namespace System
{
/// <summary>
/// Represents a class that handles the CAN transceiver MCP2515.
/// </summary>
public class MCP2515
{
//-------------------------------------
#region REGISTERS
//-------------------------------------
private const byte RXF0SIDH = 0x00;
private const byte RXF0SIDL = 0x01;
private const byte RXF0EID8 = 0x02;
private const byte RXF0EID0 = 0x03;
private const byte RXF1SIDH = 0x04;
private const byte RXF1SIDL = 0x05;
private const byte RXF1EID8 = 0x06;
private const byte RXF1EID0 = 0x07;
private const byte RXF2SIDH = 0x08;
private const byte RXF2SIDL = 0x09;
private const byte RXF2EID8 = 0x0A;
private const byte RXF2EID0 = 0x0B;
private const byte BFPCTRL = 0x0C;
private const byte TXRTSCTRL = 0x0D;
private const byte CANSTAT = 0x0E;
private const byte CANCTRL = 0x0F;
private const byte RXF3SIDH = 0x10;
private const byte RXF3SIDL = 0x11;
private const byte RXF3EID8 = 0x12;
private const byte RXF3EID0 = 0x13;
private const byte RXF4SIDH = 0x14;
private const byte RXF4SIDL = 0x15;
private const byte RXF4EID8 = 0x16;
private const byte RXF4EID0 = 0x17;
private const byte RXF5SIDH = 0x18;
private const byte RXF5SIDL = 0x19;
private const byte RXF5EID8 = 0x1A;
private const byte RXF5EID0 = 0x1B;
private const byte TEC = 0x1C;
private const byte REC = 0x1D;
private const byte RXM0SIDH = 0x20;
private const byte RXM0SIDL = 0x21;
private const byte RXM0EID8 = 0x22;
private const byte RXM0EID0 = 0x23;
private const byte RXM1SIDH = 0x24;
private const byte RXM1SIDL = 0x25;
private const byte RXM1EID8 = 0x26;
private const byte RXM1EID0 = 0x27;
private const byte CNF3 = 0x28;
private const byte CNF2 = 0x29;
private const byte CNF1 = 0x2A;
private const byte CANINTE = 0x2B;
private const byte MERRE = 7;
private const byte WAKIE = 6;
private const byte ERRIE = 5;
private const byte TX2IE = 4;
private const byte TX1IE = 3;
private const byte TX0IE = 2;
private const byte RX1IE = 1;
private const byte RX0IE = 0;
private const byte CANINTF = 0x2C;
private const byte MERRF = 7;
private const byte WAKIF = 6;
private const byte ERRIF = 5;
private const byte TX2IF = 4;
private const byte TX1IF = 3;
private const byte TX0IF = 2;
private const byte TX0IF_MASK = 0x04;
private const byte RX1IF = 1;
private const byte RX0IF = 0;
private const byte RX1IF_MASK = 0x02;
private const byte RX0IF_MASK = 0x01;
private const byte EFLG = 0x2D;
private const byte TXB0CTRL = 0x30;
private const byte TXREQ = 3;
private const byte TXB0SIDH = 0x31;
private const byte TXB0SIDL = 0x32;
private const byte EXIDE = 3;
private const byte EXIDE_MASK = 0x08;
private const byte TXB0EID8 = 0x33;
private const byte TXB0EID0 = 0x34;
private const byte TXB0DLC = 0x35;
private const byte TXRTR = 7;
private const byte TXB0D0 = 0x36;
private const byte RXB0CTRL = 0x60;
private const byte RXM1 = 6;
private const byte RXM0 = 5;
private const byte RXRTR = 3;
// Bits 2:0 FILHIT2:0
private const byte RXB0SIDH = 0x61;
private const byte RXB0SIDL = 0x62;
private const byte RXB0EID8 = 0x63;
private const byte RXB0EID0 = 0x64;
private const byte RXB0DLC = 0x65;
private const byte RXB0D0 = 0x66;
//-------------------------------------
#endregion REGISTERS
//-------------------------------------
//MCP2515 Command Bytes
private readonly byte RESET = 0xC0;
private readonly byte READ = 0x03;
// private readonly byte READ_RX_BUFFER = 0x90;
private readonly byte WRITE = 0x02;
// private readonly byte LOAD_TX_BUFFER = 0x40;
// private readonly byte RTS = 0x80;
// private readonly byte READ_STATUS = 0xA0;
// private readonly byte RX_STATUS = 0xB0;
private readonly byte BIT_MODIFY = 0x05;
/// <summary>Represent a LOW (false) state.</summary>
private const bool LOW = false;
/// <summary>Represent a HIGH (true) state.</summary>
private const bool HIGH = true;
/// <summary></summary>
private const byte DataIndexOffset = 2;
/// <summary>The max CAN ID that can be represented on an 11 bit ID.</summary>
private const int CANID_11BITS = 0x7FF;
//-------------------------------------------------------------
//// This must be modified for your CAN ID
private const uint VMS_CAN0_ID = 0x7E8, VMS_CAN1_ID = 0x329;
//-------------------------------------------------------------
// This must be modified depend on hardware
/// <summary>SPI PIN for VMS control.</summary>
public const Cpu.Pin SPI_CAN1_SEL = (Cpu.Pin)45; // PC13
public const Cpu.Pin SPI_CAN0_SEL = (Cpu.Pin)1; // PA1
/// <summary>the SPI object that communicate with the transceiver.</summary>
private SPI spi;
// Configure SPI CAN channel0 and channel1
private SPI.Configuration [] configSPI = new SPI.Configuration[2];
/// <summary>
/// Represents the available baud rates.
/// </summary>
public enum enBaudRate
{
CAN_BAUD_10K = 1, CAN_BAUD_50K = 2, CAN_BAUD_100K = 3,
CAN_BAUD_125K = 4, CAN_BAUD_250K = 5, CAN_BAUD_500K = 6
}
/// <summary>Represents a CAN message.</summary>
public class CANMSG
{
public uint CANID { get; set; }
public bool IsExtended { get { return CANID > CANID_11BITS; } }
public bool IsRemote { get; set; }
public int DataLength { get { return data.Length; } }
public byte[] data = new byte[8];
}
/// <summary>Initialize the CAN transceiver.</summary>
/// <param name="baudrate">The selected baud rate.</param>
/// <returns>True if configuration was successful.</returns>
/// <remarks>Transceiver needs to be set to normal mode before starting TX/RX operations.</remarks>
public bool InitCAN(enBaudRate baudrate)
{
configSPI[0] = new SPI.Configuration(SPI_CAN0_SEL, LOW, 0, 0, HIGH, HIGH, 10000, SPI.SPI_module.SPI1);
configSPI[1] = new SPI.Configuration(SPI_CAN1_SEL, LOW, 0, 0, HIGH, HIGH, 10000, SPI.SPI_module.SPI1);
spi = new SPI(configSPI[0]);
// Write reset to the CAN0/CAN1 transceiver.
spi.Write(new byte[] {RESET});
spi.Config = configSPI[1];
spi.Write(new byte[] {RESET});
//Read mode and make sure it is config
Thread.Sleep(100);
byte mode0 = (byte)(ReadRegister(0,CANSTAT) >> 5);
byte mode1 = (byte)(ReadRegister(1,CANSTAT) >> 5);
if ((mode0 != 0x04) || (mode1 != 0x04))
{
return false;
}
else // ------ Config mode -------------------
{
VMS_FilterInit();
SetCANBaud(baudrate); // will set to normal
SetCANNormalMode();
VMS_CAN0IdFilter();
//--------------- normal mode -----------------
return true;
}
}
/// <summary>Set the CAN baud rate.</summary>
/// <param name="baudrate">The configured baud rate.</param>
/// <returns>True if configured.</returns>
private bool SetCANBaud(enBaudRate baudrate)
{
byte brp;
//BRP<5:0> = 00h, so divisor (0+1)*2 for 125ns per quantum at 16MHz for 500K
//SJW<1:0> = 00h, Sync jump width = 1
switch (baudrate)
{
case enBaudRate.CAN_BAUD_10K:
brp = 5;
break;
case enBaudRate.CAN_BAUD_50K:
brp = 4;
break;
case enBaudRate.CAN_BAUD_100K:
brp = 3;
break;
case enBaudRate.CAN_BAUD_125K:
brp = 2;
break;
case enBaudRate.CAN_BAUD_250K:
brp = 1;
break;
case enBaudRate.CAN_BAUD_500K:
brp = 0;
break;
default:
return false;
}
byte[] cmdBuffer = new byte[] { WRITE, CNF1, (byte)(brp & 0x3F) };
spi.Config = configSPI[0];
spi.Write(cmdBuffer);
//-------------------------------------------------
//PRSEG<2:0> = 0x01, 2 time quantum for prop
//PHSEG<2:0> = 0x06, 7 time constants to PS1 sample
//SAM = 0, just 1 sampling
//BTLMODE = 1, PS2 determined by CNF3
spi.Write(new byte[] { WRITE, CNF2, 0xB1 });
//-----------------------------------------------
//PHSEG2<2:0> = 5 for 6 time constants after sample
//SOF enable <bit7>
spi.Write(new byte[] { WRITE, CNF3, 0x85 });
spi.Config = configSPI[1];
spi.Write(cmdBuffer);
spi.Write(new byte[] { WRITE, CNF2, 0xB1 });
spi.Write(new byte[] { WRITE, CNF3, 0x85 });
//SyncSeg + PropSeg + PS1 + PS2 = 1 + 2 + 7 + 6 = 16
return true;
}
/// <summary>Writes a value to the selected register.</summary>
/// <param name="registerAddress">The address of the register.</param>
/// <param name="value">The value to be write to the register.</param>
private void WriteRegister(uint channel ,byte registerAddress, byte value)
{
spi.Config = configSPI[channel];
spi.Write(new byte[] { WRITE, registerAddress, value});
}
/// <summary>Reads the value of the selected register.</summary>
/// <param name="registerAddress">The address of the register.</param>
/// <returns>A byte with the value read from the register.</returns>
private byte ReadRegister(uint channel,byte registerAddress)
{
byte[] CmdBuffer = new byte[] { READ, registerAddress };
byte[] outData = new byte[1];
spi.Config = configSPI[channel];
spi.WriteRead(CmdBuffer, outData, 2);
return outData[0];
}
/// <summary>Writes a bit to a register.</summary>
/// <param name="registerAddress">The address of the register that supports bit writing.</param>
/// <param name="bitNumber">The zero index based of the bit to write.</param>
/// <param name="value">the value of the bit to write.</param>
private void WriteRegisterBit(uint channel,byte registerAddress, byte bitNumber, byte value)
{
spi.Config = configSPI[channel];
//spi.Write(new byte[] { BIT_MODIFY, regno, (byte)(1 << bitno) });
if (value != 0)
{
spi.Write(new byte[] { BIT_MODIFY, registerAddress, (byte)(1 << bitNumber), 0xFF });
}
else
{
spi.Write(new byte[] { BIT_MODIFY, registerAddress, (byte)(1 << bitNumber), 0x00 });
}
}
/// <summary>Transmit a CAN message to the bus.</summary>
/// <param name="message">The CAN Message to be transmitted.</param>
/// <param name="timeout"></param>
/// <returns></returns>
public bool Transmit(uint channel ,CANMSG message, int timeout)
{
// Holds if message was sent or not.
bool sentMessage = false;
// Calculate the end time based on current device time.
TimeSpan startTime = Utility.GetMachineTime();
TimeSpan endTime = startTime.Add(new TimeSpan(0,0,0,0,timeout));
//--------------------------------------
// Set the CAN ID.
byte val = 0x00;
uint bit11Address = 0x00;
uint bit18Address = 0x00;
// Build Extended CAN ID
if (message.IsExtended)
{
// Split the 11 bit and 18 bit sections of the ID.
bit11Address = (uint)((message.CANID >> 16) & 0xFFFF);
bit18Address = (uint)(message.CANID & 0xFFFFF);
// Set the first part of the ID
val = (byte)(bit11Address >> 5);
WriteRegister(channel,TXB0SIDH, val);
// Set the second part of the ID.
val = (byte)(bit11Address << 3);
val |= (byte)(bit11Address & 0x07);
// Mark the message as extended.
val |= 1 << EXIDE;
WriteRegister(channel, TXB0SIDL, val);
// Write the 18 bit part of the ID
val = (byte)(bit18Address >> 8);
WriteRegister(channel, TXB0EID8, val);
val = (byte)(bit18Address);
WriteRegister(channel, TXB0EID0, val);
}
else
{
// Transmit a 11 bit ID.
bit11Address = (uint)(message.CANID);
val = (byte)(bit11Address >> 3);
WriteRegister(channel, TXB0SIDH, val);
val = (byte)(bit11Address << 5);
WriteRegister(channel, TXB0SIDL, val);
}
//--------------------------------------
val = (byte)(message.DataLength & 0x0f);
// Check if is a remote frame
if (message.IsRemote)
{
// Mark the frame as remote
val |= (byte)(1UL << (TXRTR));
WriteRegisterBit(channel, val, TXRTR, 1);
}
WriteRegister(channel, TXB0DLC, val);
//--------------------------------------
//Write Message Data
byte[] txDATA = new byte[10];
txDATA[0] = WRITE;
txDATA[1] = TXB0D0;
for (int i = DataIndexOffset; i < message.DataLength + DataIndexOffset; i++)
{
txDATA[i] = message.data[i - DataIndexOffset];
}
spi.Config = configSPI[channel];
spi.Write(txDATA);
//----------------------
// Command to transmit the CAN message
WriteRegisterBit(channel,TXB0CTRL, TXREQ, 1);
//----------------------
// Wait until time out to get confirmation of message was sent.
while (Utility.GetMachineTime() < endTime)
{
val = ReadRegister(channel, CANINTF);
if((val & TX0IF_MASK ) == TX0IF_MASK )
{
sentMessage = true;
break;
}
}
////Abort the send if failed
WriteRegisterBit(channel, TXB0CTRL, TXREQ, 0);
////And clear write interrupt
WriteRegisterBit(channel, CANINTF, TX0IF, 0);
return sentMessage;
}
/// <summary>
/// Check if a new message was received by the transceiver.
/// </summary>
/// <param name="msg">The CAN message that will contain the retrived message.</param>
/// <param name="timeout">The time to wait if a message become available.</param>
/// <returns>True if a message was received.</returns>
public bool Receive(uint channel,out CANMSG msg, int timeout)
{
bool gotMessage = false;
uint val;
msg = new CANMSG();
TimeSpan startTime = Utility.GetMachineTime();
TimeSpan endTime = startTime.Add(new TimeSpan(0, 0, 0, 0, timeout));
gotMessage = false;
while (Utility.GetMachineTime() < endTime)
{
val = ReadRegister(channel, CANINTF);
//If we have a message available, read it
if ((val & RX0IF_MASK) == RX0IF_MASK)
{
gotMessage = true;
break;
}
}
if (gotMessage)
{
val = ReadRegister(channel, RXB0CTRL);
msg.IsRemote = ((val & 0x04) == 0x04) ? true : false;
//Address received from
uint adddresVal = 0;
val = ReadRegister(channel, RXB0SIDH);
adddresVal |= (val << 3);
val = ReadRegister(channel, RXB0SIDL);
adddresVal |= (val >> 5);
bool isExtended = ((val & EXIDE_MASK) == EXIDE_MASK) ? true : false;
uint adddresExtVal = 0;
if (isExtended)
{
adddresExtVal = (uint)((val & 0x03) << 16);
val = ReadRegister(channel, RXB0EID8);
adddresExtVal |= (uint)(val << 8);
val = ReadRegister(channel, RXB0EID0);
adddresExtVal |= val;
adddresVal = ((adddresVal << 18) | adddresExtVal);
}
msg.CANID = (uint)adddresVal;
//Read data bytes
val = ReadRegister(channel,RXB0DLC);
uint dataLen = (val & 0xf);
byte[] CmdBuffer = new byte[] { READ, RXB0D0 };
msg.data = new byte[dataLen];
spi.Config = configSPI[channel];
spi.WriteRead(CmdBuffer, msg.data, 2);
//And clear read interrupt
WriteRegisterBit(channel,CANINTF, RX0IF, 0);
}
else
{
}
return gotMessage;
}
/// <summary>Set transceiver to normal state.</summary>
/// <remarks>This state needs to be selected before starting TX/RX.</remarks>
public void SetCANNormalMode()
{
//REQOP2<2:0> = 000 for normal mode
//ABAT = 0, do not abort pending transmission
//OSM = 0, not one shot
//CLKEN = 1, disable output clock
//CLKPRE = 0b11, clk/8
WriteRegister(0,CANCTRL,0x07);
WriteRegister(1,CANCTRL,0x07);
//Read mode and make sure it is normal
byte mode = ReadRegister(0,CANSTAT);
ReadRegister(1, CANSTAT);
mode = (byte)(mode >> 5);
if (mode != 0)
{ }
// Set RX buffer control to turn filters OFF and receive any message.
WriteRegister(0,RXB0CTRL, 0x60);
WriteRegister(1,RXB0CTRL, 0x60);
}
//--------------------------------------------------------------
// VMS_FilterInit()
//purpose : write the filter to CAN0'Receiver buf0 and buf1
// to receive the VMS_CAN0_ID and VMS_CAN1_ID
//-------------------------------------------------------------
private void VMS_FilterInit()
{
WriteRegister(0, RXF0SIDH, (byte)(VMS_CAN0_ID >> 3));
WriteRegister(0, RXF0SIDL , (byte)((VMS_CAN0_ID << 5)&0xe0));
WriteRegister(0, RXF1SIDH, (byte)(VMS_CAN1_ID >> 3));
WriteRegister(0, RXF1SIDL, (byte)((VMS_CAN1_ID << 5) & 0xe0));
WriteRegister(0, RXM0SIDH, 0xff); // config the MASK
WriteRegister(0, RXM0SIDL, 0xff);
}
//---------------------------------------------
public void VMS_CAN0IdFilter()
{
WriteRegister(0, RXB0CTRL, 0x0); // receive the standard/ext ID with RXF0 filter
}
//---------------------------------------------
public void VMS_CAN1IdFilter()
{
WriteRegister(0, RXB0CTRL, 0x1); // receive the standard/ext ID with RXF1 filter
}
//---------------------------------------------
public void SetConfigMode(uint channel)
{
WriteRegister(channel, CANCTRL, 0x87);
}
}
}
NETMF
2014年4月1日 星期二
2013年9月6日 星期五
NETMF Character LCD (C# Code)
I found a usable C# sorec code for HD44780-compatible Character LCD.
The BitBucket open source netmf LCD page . has NETMF source code for your projcet.
The online LCD simulator is very useful for you to verify code that you send to LCD.
The BitBucket open source netmf LCD page . has NETMF source code for your projcet.
The online LCD simulator is very useful for you to verify code that you send to LCD.
2013年9月4日 星期三
NETMF C# hardware Watchdog for FEZ Cerb40
Hardware watchdog is very important in industrial control. The FEZ Cerberus main board /FEZ Cerb40 module are good choose for low cost design. Unfortunately, it is not support watchdog in firmware! (also, The GHI guy said : Open Source "OSHW" is not support!)
I read the STM32F405 reference manual to find out the solution ... And I try to write the low leve CPU register setting to enable watchdog ... It is working !
The C# source code as follows :
using System;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using GHI.OSHW.Hardware.LowLevel;
class iWatchDog
{
public uint TimeOut = 4000; // default 4000 units
private uint AccKey = 0x5555;
private uint RstKey = 0xAAAA;
private uint EnableKey = 0xCCCC;
//----------------------------------------------------------------
Register IWDG_KR = new Register(0x40003000);
Register IWDG_PR = new Register(0x40003004);
Register IWDG_RLR = new Register(0x40003008);
Register IWDG_SR = new Register(0x4000300C);
//-----------------------------------------------------------------
public void Init()
{
IWDG_KR.Write(AccKey); // open the access key
IWDG_PR.Write(4); // write the Prescaler for 2ms (One unit)
IWDG_KR.Write(AccKey); // open again
IWDG_RLR.Write(TimeOut); // write the down counter
}
//--------------------------------------------------------------
public void Enable()
{
IWDG_KR.Write(AccKey); // open access key
IWDG_KR.Write(EnableKey); // enable counter
}
//---------------------------------------------------------------
public void Reset()
{
IWDG_KR.Write(AccKey); // open access key
IWDG_KR.Write(RstKey); // reload counter
}
}
//--------------------------------------------
// your main program as follows:
//--------------------------------------------.
.
iWatchDog Wdog = new iWatchDog();
Wdog.TimeOut = 2500; // for 5 second time out
Wdog.Init();
Wdog.Enable(); // enable watch dog
.
.
//-------- the easy way to reset the watchdos counter -----------------
void timer500_Tick(GT.Timer timer)// 500mS timer tick
{
Wdog.Reset(); // reload the watchdog timeout counter
}
I read the STM32F405 reference manual to find out the solution ... And I try to write the low leve CPU register setting to enable watchdog ... It is working !
The C# source code as follows :
using System;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using GHI.OSHW.Hardware.LowLevel;
class iWatchDog
{
public uint TimeOut = 4000; // default 4000 units
private uint AccKey = 0x5555;
private uint RstKey = 0xAAAA;
private uint EnableKey = 0xCCCC;
//----------------------------------------------------------------
Register IWDG_KR = new Register(0x40003000);
Register IWDG_PR = new Register(0x40003004);
Register IWDG_RLR = new Register(0x40003008);
Register IWDG_SR = new Register(0x4000300C);
//-----------------------------------------------------------------
public void Init()
{
IWDG_KR.Write(AccKey); // open the access key
IWDG_PR.Write(4); // write the Prescaler for 2ms (One unit)
IWDG_KR.Write(AccKey); // open again
IWDG_RLR.Write(TimeOut); // write the down counter
}
//--------------------------------------------------------------
public void Enable()
{
IWDG_KR.Write(AccKey); // open access key
IWDG_KR.Write(EnableKey); // enable counter
}
//---------------------------------------------------------------
public void Reset()
{
IWDG_KR.Write(AccKey); // open access key
IWDG_KR.Write(RstKey); // reload counter
}
}
//--------------------------------------------
// your main program as follows:
//--------------------------------------------.
.
iWatchDog Wdog = new iWatchDog();
Wdog.TimeOut = 2500; // for 5 second time out
Wdog.Init();
Wdog.Enable(); // enable watch dog
.
.
//-------- the easy way to reset the watchdos counter -----------------
void timer500_Tick(GT.Timer timer)// 500mS timer tick
{
Wdog.Reset(); // reload the watchdog timeout counter
}
2013年9月3日 星期二
I2C for EEPROM
The Cerb Family has one I2C interface that connected to socket1 and socket2. I found a very usable code from GHI Electronics . I test the sorce code for 24LC16 eeprom and it is working.
The source code as follows:
//-------------- setup the I2C device ----------------------
I2CDevice EepI2C = new I2CDevice(new I2CDevice.Configuration(0x50, 400)); // 24LC16 Chip @400KHZ clock
//--------------- Write to EEPROM -----------------------
public void EepWrite(int Address, byte data)
{
var xActions = new I2CDevice.I2CTransaction[1];
xActions[0] = I2CDevice.CreateWriteTransaction(new byte[] { (byte)(Address >> 8), (byte)(Address & 0xFF),data });
EepI2C.Execute(xActions, 1000);
Thread.Sleep(5); // Mandatory after each Write transaction !!!
}
//----------- Read from EEPROM ----------------------
public byte EepRead(int Address)
{
var Data = new byte[1];
var xActions = new I2CDevice.I2CTransaction[1];
xActions[0] = I2CDevice.CreateWriteTransaction(new byte[] { (byte)(Address >> 8), (byte)(Address & 0xFF) });
EepI2C.Execute(xActions, 1000);
Thread.Sleep(5); // Mandatory after each Write transaction !!!
xActions[0] = I2CDevice.CreateReadTransaction(Data);
EepI2C.Execute(xActions, 1000);
return Data[0];
}
The source code as follows:
//-------------- setup the I2C device ----------------------
I2CDevice EepI2C = new I2CDevice(new I2CDevice.Configuration(0x50, 400)); // 24LC16 Chip @400KHZ clock
//--------------- Write to EEPROM -----------------------
public void EepWrite(int Address, byte data)
{
var xActions = new I2CDevice.I2CTransaction[1];
xActions[0] = I2CDevice.CreateWriteTransaction(new byte[] { (byte)(Address >> 8), (byte)(Address & 0xFF),data });
EepI2C.Execute(xActions, 1000);
Thread.Sleep(5); // Mandatory after each Write transaction !!!
}
//----------- Read from EEPROM ----------------------
public byte EepRead(int Address)
{
var Data = new byte[1];
var xActions = new I2CDevice.I2CTransaction[1];
xActions[0] = I2CDevice.CreateWriteTransaction(new byte[] { (byte)(Address >> 8), (byte)(Address & 0xFF) });
EepI2C.Execute(xActions, 1000);
Thread.Sleep(5); // Mandatory after each Write transaction !!!
xActions[0] = I2CDevice.CreateReadTransaction(Data);
EepI2C.Execute(xActions, 1000);
return Data[0];
}
2013年9月2日 星期一
NETMF Cpu.Pin / PWM Channel /Analog Channel
A usable reference :
C# Example:
LED = new OutputPort((Cpu.Pin)5, true); //PA5
// Assign the I/O port PA5 as a output port for LED display.
C# Example :
AnalogInput Sensor1 = new AnalogInput(Cpu.AnalogChannel.ANALOG_3);
// Assign the Analog input channel 3 as a Sensor1
PWM Moto1Pwm = new PWM(Cpu.PWMChannel.PWM_0, 10000, 0.5, false);
// Assign PWM channel 0 as Moto1Pwm output and working at 10KHz, 50% duty cycle
NETMF pin map
| |||||
Cpu.Pin
|
Port
|
Cpu.Pin
|
Port
|
Cpu.Pin
|
Port
|
0
|
PA0
|
32
|
PC0
|
64
|
PE0
|
1
|
PA1
|
33
|
PC1
|
65
|
PE1
|
2
|
PA2
|
34
|
PC2
|
66
|
PE2
|
3
|
PA3
|
35
|
PC3
|
67
|
PE3
|
4
|
PA4
|
36
|
PC4
|
68
|
PE4
|
5
|
PA5
|
37
|
PC5
|
69
|
PE5
|
6
|
PA6
|
38
|
PC6
|
70
|
PE6
|
7
|
PA7
|
39
|
PC7
|
71
|
PE7
|
8
|
PA8
|
40
|
PC8
|
72
|
PE8
|
9
|
PA9
|
41
|
PC9
| ||
10
|
PA10
|
42
|
PC10
| ||
11
|
PA11
|
43
|
PC11
| ||
12
|
PA12
|
44
|
PC12
| ||
13
|
PA13
|
45
|
PC13
| ||
14
|
PA14
|
46
|
PC14
| ||
15
|
PA15
|
47
|
PC15
| ||
16
|
PB0
|
48
|
PD0
| ||
17
|
PB1
|
49
|
PD1
| ||
18
|
PB2
|
50
|
PD2
| ||
19
|
PB3
|
51
|
PD3
| ||
20
|
PB4
|
52
|
PD4
| ||
21
|
PB5
|
53
|
PD5
| ||
22
|
PB6
|
54
|
PD6
| ||
23
|
PB7
|
55
|
PD7
| ||
24
|
PB8
|
56
|
PD8
| ||
25
|
PB9
|
57
|
PD9
| ||
26
|
PB10
|
58
|
PD10
| ||
27
|
PB11
|
59
|
PD11
| ||
28
|
PB12
|
60
|
PD12
| ||
29
|
PB13
|
61
|
PD13
| ||
30
|
PB14
|
62
|
PD14
| ||
31
|
PB15
|
63
|
PD15
|
C# Example:
LED = new OutputPort((Cpu.Pin)5, true); //PA5
// Assign the I/O port PA5 as a output port for LED display.
PWM
CHANNEL
|
Physical Pin
|
ANALOG CHANNEL
|
Physical Pin
| |
0
|
PC6
|
0
|
PA6
| |
1
|
PA7
|
1
|
PA2
| |
2
|
PC7
|
2
|
PA3
| |
3
|
PA8
|
3
|
PC0
| |
4
|
PB0
|
4
|
PC1
| |
5
|
PB1
|
5
|
PA4
| |
6
|
PB5
|
6
|
PC2
| |
7
|
PB4
|
7
|
PC3
| |
8
|
PB3
|
8
|
PA5
| |
9
|
PB11
|
9
|
PB0
| |
10
|
PB10
|
10
|
PB1
| |
11
|
PA10
| |||
12
|
PA9
| |||
13
|
PA15
| |||
14
|
PB8
| |||
15
|
PB9
|
C# Example :
AnalogInput Sensor1 = new AnalogInput(Cpu.AnalogChannel.ANALOG_3);
// Assign the Analog input channel 3 as a Sensor1
PWM Moto1Pwm = new PWM(Cpu.PWMChannel.PWM_0, 10000, 0.5, false);
// Assign PWM channel 0 as Moto1Pwm output and working at 10KHz, 50% duty cycle
訂閱:
文章 (Atom)