Classe ShiftRegister

using System;
using Microsoft.SPOT.Hardware;

namespace SlotDaemon.Util
{
    /// <summary>
    /// This class abstracts the bit shifting process
    /// needed to send data to a 74HC595 shift register
    /// </summary>
    public class ShiftRegister : IDisposable
    {
        public enum BitOrder
        {
            MSBFirst,
            LSBFirst
        }

        #region Private attributes
        private readonly int _numRegisters;
        private readonly BitOrder _bitOrder;
        private readonly OutputPort _dataPort;
        private readonly OutputPort _clockPort;
        private readonly OutputPort _latchPort;
        #endregion

        #region Public properties
        public int OutputCount
        {
            get { return _numRegisters * 8; }
        }
        #endregion

        #region Constructors
        /// <summary>
        /// Code for using a 74HC595 Shift Register
        /// </summary>
        /// <param name="numRegisters">Number of shift register connected in series</param>
        /// <param name="latchPin">Pin connected to ST_CP of 74HC595</param>
        /// <param name="clockPin">Pin connected to SH_CP of 74HC595</param>
        /// <param name="dataPin">Pin connected to DS of 74HC595</param>
        /// <param name="bitOrder"></param>
        public ShiftRegister(int numRegisters, Cpu.Pin latchPin, Cpu.Pin clockPin, Cpu.Pin dataPin, BitOrder bitOrder)
        {
            if (numRegisters <= 0)
            {
                throw new ArgumentOutOfRangeException("numRegisters", "You must specify and positive value for numRegisters.");
            }

            _numRegisters = numRegisters;
            _bitOrder = bitOrder;

            _latchPort = new OutputPort(latchPin, false);
            _clockPort = new OutputPort(clockPin, false);
            _dataPort = new OutputPort(dataPin, false);
        }

        public ShiftRegister(int numRegisters, Cpu.Pin latchPin, Cpu.Pin clockPin, Cpu.Pin dataPin)
            : this(numRegisters, latchPin, clockPin, dataPin, BitOrder.MSBFirst)
        { }
        #endregion

        /// <summary>
        /// Sends the buffer to the shift register
        /// </summary>
        /// <param name="buffer">Bytes to be sent</param>
        public void Write(params byte[] buffer)
        {
            if (buffer == null) throw new ArgumentNullException("buffer");

            // Ground latchPin and hold low for as long as you are transmitting
            _latchPort.Write(false);

            //Shift out the byte buffer
            for (int i = 0; i < buffer.Length; i++)
            {
                ShiftOut(buffer[i]);
            }

            // Pulse the latch pin high to signal chip that it 
            // no longer needs to listen for information
            _latchPort.Write(true);
            _latchPort.Write(false);
        }

        /// <summary>
        /// Sends the low then the high byte of an int
        /// </summary>
        /// <param name="value">Value to be sent</param>
        public void Write(int value)
        {
            byte low = (byte)(value & 0xFF);
            byte high = (byte)(value >> 8);

            Write(low, high);
        }

        /// <summary>
        /// This method is the actual responsible for sengind the bits to the shift register
        /// </summary>
        /// <param name="value"></param>
        private void ShiftOut(byte value)
        {
            // Lower Clock
            _clockPort.Write(false);

            byte mask;
            for (int i = 0; i < 8; i++)
            {
                if (_bitOrder == BitOrder.LSBFirst)
                    mask = (byte)(1 << i);
                else
                    mask = (byte)(1 << (7 - i));

                _dataPort.Write((value & mask) != 0);

                // Raise Clock
                _clockPort.Write(true);

                // Raise Data to prevent IO conflict 
                _dataPort.Write(true);

                // Lower Clock
                _clockPort.Write(false);
            }
        }

        #region IDisposable implementation
        /// <summary>
        ///  Free used resources
        /// </summary>
        public void Dispose()
        {
            _dataPort.Dispose();
            _clockPort.Dispose();
            _latchPort.Dispose();
        }
        #endregion
    }
}

Last edited Nov 2, 2012 at 6:14 PM by firegunkiller, version 2

Comments

No comments yet.