用I2C实现两单片机联机,接收程序怎么写?

用I2C实现两单片机联机,接收程序怎么写?,第1张

发送和接收差不多,

这里是个例子,有问题欢迎一起讨论

/*****************************************************

/* 文件名: I2C.h

/* 描述 : I2C.c的头文件

/* 编写环境 : Keil uVision 3 V3.51

/* 作者 : XX

/* 学校 : 广东XX大学

/* Email : lanhaospider@163.com

/* 版本 : V1.0

/* 编写日期 : 2008-3-30

/* 仅供学习参考

/* 芯片 : MCS-51 AT89S52

/* 晶振 : 11.0592MHz

/* 功能描述 : 模拟I2C总线的接口程序库,主机的程序

/* 应用 : 发送n个字节: 起始位->发送控制字节(类型标识符4位->

片选3位->读写位最后1位)->应答位->数据->应答...........应答->终止位

高位先到达,低位后到达

/****************************************************/

#include "reg51.h"/*根据不同主控芯片型号改写该套入*/

#include "intrins.h"

sbit SCL = P1^6 /*定义SCL线所在口,根据实践需要改写该定义*/

sbit SDA = P1^7 /*定义SDA线所在口,根据实践需要改写该定义*/

unsigned char idata error/*错误提示,全局变量*/

extern void Start_I2C(void)

extern void Stop_I2C(void)

extern void Ack_I2C(void)

extern void Send_Ack(void)

extern void Send_Not_Ack(void)

extern void Send_I2C(unsigned char send_byte)

extern unsigned char Receive_I2C(void)

/*****************************************************/

/* 文件名: I2C.c

/* 描述 : I2C通信程序

/* 编写环境 : Keil uVision 3 V3.51

/* 作者 : XX

/* 学校 : 广东XX大学

/* Email : lanhaospider@163.com

/* 版本 : V1.0

/* 编写日期 : 2008-3-30

/* 仅供学习参考

/* 芯片 : MCS-51 AT89S52

/* 晶振 : 11.0592MHz

/* 功能描述 : 模拟I2C总线的接口程序库,为主机的程序

/*****************************************************/

#include "I2C.h"

/**************************************************

调用方式 : void Start_I2C(void)

函数说明: 启动I2C总线

**************************************************/

void Start_I2C(void)

{

EA = 0 /*关总中断*/

SDA = 1 /*发送启动总线的数据信号*/

SCL = 1 /*发送启动总线的时钟信号*/

_nop_() /*保持数据线高,延时*/

_nop_()

_nop_()

_nop_()

_nop_()

SDA = 0 /*发送起始信号*/

_nop_()

_nop_()

_nop_()

_nop_()

_nop_()

SCL = 0 /*时钟线高低跳变一次,I2C通信开始*/

}

/**************************************************

调用方式 : void Stop_I2C(void)

函数说明: 关闭I2C总线

**************************************************/

void Stop_I2C(void)

{

SCL = 0/*发送关闭总线的时钟信号*/

SDA = 0/*发送关闭总线的数据信号*/

_nop_()

_nop_()

_nop_() /*保持数据线低,延时*/

_nop_()

_nop_()

SCL = 1 /*时钟线一次低高跳变,I2C通信停止*/

_nop_()

_nop_()

_nop_()

_nop_()

_nop_()

SDA = 1 /*发送I2C总线停止数据信号*/

_nop_()

_nop_()

_nop_()

_nop_()

_nop_()

EA = 1 /*开总中断*/

}

/**************************************************

调用方式 : void Ask_I2C(void)

函数说明: 主控程序等待从器件接收方式应答

**************************************************/

void Ack_I2C(void)

{

unsigned char errtimes = 0xFF

SDA = 1

SCL = 1

error = 0x10

while(SDA)

{

errtimes--

if(!errtimes)

{

Stop_I2C()

error = 0x11

return

}

}

SCL = 0

}

/**************************************************

调用方式 : void Send_Ask(void)

函数说明: 主控程序为接收方,从器件为发送方时,从

器件等待主器件应答

**************************************************/

void Send_Ack(void)

{

SDA = 0 /*保持数据线低,时钟线发生一次高低跳变 发送一个应答信号*/

_nop_()

_nop_()

_nop_()

_nop_()

_nop_()

SCL = 1 /*时钟线保持低电平*/

_nop_()

_nop_()

_nop_()

_nop_()

_nop_()

SCL = 0

}

/**************************************************

调用方式 : void Send_Not_Ask(void)

函数说明: 主控程序为接收方,从器件为发送方时,非应答信号

**************************************************/

void Send_Not_Ack(void)

{

SDA = 1 /*保持数据线高,时钟线发生一次高低跳变 没有应答*/

_nop_()

_nop_()

_nop_()

_nop_()

_nop_()

SCL = 1 /*时钟线保持高电平*/

_nop_()

_nop_()

_nop_()

_nop_()

_nop_()

SCL = 0

}

/**************************************************

调用方式 : void Send_I2C(unsigned char send_byte)

函数说明: 总线发送一个字节

**************************************************/

void Send_I2C(unsigned char send_byte)

{

unsigned char send_bit

for(send_bit = 8send_bit <= 0send_bit--)

{

SCL = 0

_nop_()

SDA = (send_byte &0x80)

send_byte<<=1

_nop_()

_nop_()

_nop_()

_nop_()

_nop_()

SCL = 1

_nop_()

_nop_()

_nop_()

_nop_()

_nop_()

}

SCL = 0

}

/**************************************************

调用方式 : unsigned char Receive_I2C(void)

函数说明: 从I2C总线上接收一个字节

**************************************************/

unsigned char Receive_I2C(void)

{

unsigned char receive_bit , receive_byte = 0

for(receive_bit = 8receive_bit <= 0receive_bit--)

{

SCL = 0

_nop_()

_nop_()

_nop_()

_nop_()

_nop_()

_nop_()

SCL = 1

_nop_()

_nop_()

_nop_()

_nop_()

_nop_()

receive_byte <<=1

receive_byte |= SDA

}

SCL = 0

return receive_byte

}

#include<at89x51.h>

#define uchar unsigned char

#define uint unsigned int

sbit SCL=P3^1

sbit SDA=P3^2

void delay(uint i)

{

uchar j

while(i--)

for(j=0j<100j++)

}

void write_add(uchar r)//r=1 读否则写

{

uchar i

uchar add_rw

if(r)

add_rw=0x91 //读

else

add_rw=0x90 //写

SCL=1 //START

SDA=1

SDA=0

SCL=0

for(i=0i<8i++) //ADDRESS

{

if(add_rw&0x80)

SDA=1

else SDA=0

SCL=1

SCL=0

add_rw=add_rw<<1

}

SDA=1

SCL=1

while(SDA) //等待应答

SCL=0

}

void write_data(uchar d)

{

uchar i

SCL=0

for(i=0i<8i++) //DATA

{

if(d&0x80)

SDA=1

else SDA=0

SCL=1

SCL=0

d=d<<1

}

SDA=1

SCL=1

while(SDA) //等待应答

SCL=0

}

void stop(void)

{

SCL=1

SDA=1

}

uchar read_data(uchar over)

{

uchar i,d

SCL=0

for(i=0i<8i++) //DATA

{

d=d<<1

SCL=1

if(SDA)

d=d|0x01

SCL=0

}

if(over) SDA=1

else SDA=0

SCL=1 //应答

SCL=0

SDA=0

return d

}

void write_cmd(uchar d)

{

uchar i,w_add=0x90

SCL=1 //START

SDA=1

SDA=0

SCL=0

for(i=0i<8i++) //ADDRESS

{

if(w_add&0x80)

SDA=1

else SDA=0

SCL=1

SCL=0

w_add=w_add<<1

}

SDA=1

SCL=1

while(SDA) //等待应答

SCL=0

SDA=0

for(i=0i<8i++) //DATA

{

if(d&0x80)

SDA=1

else SDA=0

SCL=1

SCL=0

d=d<<1

}

SDA=1

SCL=1

while(SDA) //等待应答

SCL=0

SDA=0

SCL=1

SDA=1

}

uchar read_tmp(void)

{

uchar h,l

write_add(0)

write_data(0xee)//转换

stop()

delay(1000)

write_add(0)

write_data(0xaa)//读温度

stop()

write_add(1)

h=read_data(0)

l=read_data(1)

stop()

return(h)

}

void main(void)

{

while(1)

P0=read_tmp()

}

显示部分我用的串口,你改改就可以了

针对 树莓派 封装的 UWP应用 类,以下代码未经测试,聊以抛砖引玉:

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

}

}


欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/yw/11068749.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-05-13
下一篇2023-05-13

发表评论

登录后才能评论

评论列表(0条)

    保存