using System
using System.Collections.Generic
using System.Linq
using System.Text
using System.Threading.Tasks
using Windows.Devices.Gpio
using Windows.Storage.Streams
using Windows.Devices.Enumeration
using Windows.Devices.SerialCommunication
using Windows.Devices.I2c
using Windows.Devices.Spi
namespace SlotAgentApp.Services
{
public class DevicesHelper
{
public static void GPIO(int eLevel=0, int ioPortNumber = 5)
{
// 获得系统板载缺省GPIO controller
GpioController gpio = GpioController.GetDefault()
if (gpio == null)
return// 如果系瞎逗手统板载磨嫌无可用GPIO,则返回
// 打开指定的GPIO
using (GpioPin pin = gpio.OpenPin(ioPortNumber))
{
// Latch HIGH value first. This ensures a default value when the pin is set as output
pin.Write(eLevel==0? GpioPinValue.Low: GpioPinValue.High)
// 设置IO为输出方向
pin.SetDriveMode(GpioPinDriveMode.Output)
} //关闭 pin - will revert to its power-on state
}
#region 示例代码
/*
(一)GPIO接口使用
*/
public void GPIO()
{
// Get the default GPIO controller on the system
GpioController gpio = GpioController.GetDefault()
if (gpio == null)
return// GPIO not available on this system
// Open GPIO 5
using (GpioPin pin = gpio.OpenPin(5))
{
// Latch HIGH value first. This ensures a default value when the pin is set as output
pin.Write(GpioPinValue.High)
// Set the IO direction as output
pin.SetDriveMode(GpioPinDriveMode.Output)
} // Close pin - will revert to its power-on state
}
/*
(二)指带 UART接口
Pin 8 - UART0 TX
Pin 10- UART0 RX
下面的例子先是初始化UART0,然后做了一次读 *** 作和一次写 *** 作
*/
public async void Serial()
{
string aqs = SerialDevice.GetDeviceSelector("UART0") /* Find the selector string for the serial device */
var dis = await DeviceInformation.FindAllAsync(aqs) /* Find the serial device with our selector string */
SerialDevice SerialPort = await SerialDevice.FromIdAsync(dis[0].Id) /* Create an serial device with our selected device */
/* Configure serial settings */
SerialPort.WriteTimeout = TimeSpan.FromMilliseconds(1000)
SerialPort.ReadTimeout = TimeSpan.FromMilliseconds(1000)
SerialPort.BaudRate = 9600
SerialPort.Parity = SerialParity.None
SerialPort.StopBits = SerialStopBitCount.One
SerialPort.DataBits = 8
/* Write a string out over serial */
string txBuffer = "Hello Serial"
DataWriter dataWriter = new DataWriter()
dataWriter.WriteString(txBuffer)
uint bytesWritten = await SerialPort.OutputStream.WriteAsync(dataWriter.DetachBuffer())
/* Read data in from the serial port */
const uint maxReadLength = 1024
DataReader dataReader = new DataReader(SerialPort.InputStream)
uint bytesToRead = await dataReader.LoadAsync(maxReadLength)
string rxBuffer = dataReader.ReadString(bytesToRead)
}
/*
使用上面的例子时,需要在Package.appxmanifest 中修改下权限修改如下
<Capabilities>
<DeviceCapability Name="serialcommunication">
<Device Id="any">
<Function Type="name:serialPort" />
</Device>
</DeviceCapability>
</Capabilities>
*/
/*
(三)I2C 总线
Pin 3 - I2C1 SDA
Pin 5 - I2C1 SCL
下面的例子首先初始化I2C1 然后向地址为0x40的I2C设备写数据
*/
public async void I2C()
{
// Get a selector string for bus "I2C1"
string aqs = I2cDevice.GetDeviceSelector("I2C1")
// Find the I2C bus controller with our selector string
var dis = await DeviceInformation.FindAllAsync(aqs)
if (dis.Count == 0)
return// bus not found
// 0x40 is the I2C device address
var settings = new I2cConnectionSettings(0x40)
// Create an I2cDevice with our selected bus controller and I2C settings
using (I2cDevice device = await I2cDevice.FromIdAsync(dis[0].Id, settings))
{
byte[] writeBuf = { 0x01, 0x02, 0x03, 0x04 }
device.Write(writeBuf)
}
}
/*
(四) SPI 总线
Pin 19 - SPI0 MOSI
Pin 21 - SPI0 MISO
Pin 23 - SPI0 SCLK
Pin 24 - SPI0 CS0
Pin 26 - SPI0 CS1
下面的例子向SPI0 做了一次写 *** 作
*/
public async void SPI()
{
// Get a selector string for bus "SPI0"
string aqs = SpiDevice.GetDeviceSelector("SPI0")
// Find the SPI bus controller device with our selector string
var dis = await DeviceInformation.FindAllAsync(aqs)
if (dis.Count == 0)
return// "SPI0" not found on this system
// Use chip select line CS0
var settings = new SpiConnectionSettings(0)
// Create an SpiDevice with our bus controller and SPI settings
using (SpiDevice device = await SpiDevice.FromIdAsync(dis[0].Id, settings))
{
byte[] writeBuf = { 0x01, 0x02, 0x03, 0x04 }
device.Write(writeBuf)
}
}
#endregion
}
}
现像:开了接收中断,然后不断进入中断,而且P_UART_Command2寄存器读取值为0x00f1,而 P_UART_Data 值为0x0000。分析:如果出现这样的情况,首先确定问题的所在,另外一端的UART发送是否存在问题,UART传输通道是否正常?等…… 如除SPCE061A外的器件、外围都正常,则检查一下MCU的IO口设置状态,一般会由于IOB7与IOB10设置有误才导至问题的出现的;
解决:所以剩下的工作就是好好检查一下程序里面除了初始化程序外,是不是还有地方修改了IO的属性了?
现像:开或者没有开串行口发送使能时,对IOB口(特别是IOB10)进行输出 *** 作时,在PC端的接收程序中(串口测试程序)都可以收到一些串口数据,且多为0x00。
分析:这些问题与MCU无关,因为232的电平转换芯片没有使能端,所以,对IOB10口进行输出 *** 作时,特别是有高低电平的交叉输出时,也会把信号送到232的电平转换芯片中去,这样就送到了PC端的串行口,所以有时就会在PC端那边的串行口会接收到数据;
解决:所以当在用户的系统中会存在使用了UART也使用到IOB10口用作他用时,可以建议用户选用带使能的232电平转换芯片,或者通讯时采用数据包格式,同时作数据包的软校验处理。
现像:打开UART IRQ中断后,程序会不断进入UART IRQ中断。
分析:……
解决:
关于UART的IRQ使用方式,有以下几点需要注意:
1,一般我会建议在用UART IRQ中断时,初始化P_UART_Command1时只打开接收中断,而不打开发送中断;从教程或者DataSheet中可以得知,发送中断是由TxRDY信号触发的,而TxRDY信号的意义为:该标志位被置为“1”,表示发送器的数据缓存器为空,已准备好可以发送写入P_UART_Data单元的数据。问题就在这个解释里了,很多人没有注意到这个问题;串行口只要在闲置时,P_UART_Data寄存器里面是空的,肯定是随时准备好可以发送数据了,这时候TxRDY标志位应该为1的,也就会随时触发Tx IRQ中断(Tx中断打开时);所以就会出现打开串行发送、接收中断后,程序会不断地进UART IRQ中断里面去的现像了。所以建议在初始化串行口时,只打开Rx中断,而不卖凯打开Tx中断,当发送数据(需要用到Tx中断的话)后,再打开Tx中断,等全部数据发送完后,再关掉Tx中断,就不会出现这样的问题了。另外,这样的情况其实并不算是问题,本身MCU要发送数据就是可控的嘛!只要程序设计时考虑多一点就可以避免这样的麻烦了。
2,另外一点也是很重要的,关于Rx中断,其实很多人在做实验的时候关没有注意到,在避免第一种情况后,还是会出现不断进入UART IRQ中断的现像;这跟UART的寄存器设置没有太多关系,试一下,当有这样的现像时,把UART的Tx、Rx的管脚连上(当然前提是保证IO的设置是没有问题的),应该不会再有不断进入UART IRQ中断的现像。这个例子说明,在用UART IRQ中断时,要保证UART的通道有正确的连接,即IOB7、IOB10脚连到了UART的通讯通道上了(双机通讯连接也行、MCU和PC通讯连接也行,只要保证UART通讯管脚有效地连接上了且连对了),就可枝码以避免这样的问题。
3,一般对UART IRQ应用的设置,我会如此建议:先设置好IOB的相应的端口,IOB7输出、IOB10输入——》设置正确的串行波特率——》打开Rx中断,而不打开Tx中断(原因前面已有述)——》使能发送、接收管脚——》读一次P_UART_Data,以清除之前的UART状态及错误——》再下面是用户自中搭唤的程序了……。当然在用户的UART联IRQ中断里面要记得进中断后清中断标志了(读写P_UART_Data寄存器即可清除)。
PS:
unsigned int b
*P_IOB_Attrib |= 0x0480
*P_IOB_Dir |= 0x0400
*P_IOB_Data = 0x0000
*P_UART_BaudScalarLow = 0x0000
*P_UART_BaudScalarHigh = 0x0005
关于读写BUFFER,可中档以参差培答考代码。第一,APB总线不可能同时对,一个寄存器进行读写。读写肯定有先后顺序。第二,度写寄虚慧存器在代码里面是分开的,写是写buffer,读是读buffer他们只是公用地址。欢迎分享,转载请注明来源:内存溢出
评论列表(0条)