精华内容
下载资源
问答
  • 基于STM32等ARM芯片,使用通用GPIO模拟SPI通讯,SPI通讯协议详解
  • GPIO模拟UART Demo

    2020-07-12 17:53:50
    GPIO模拟UART Demo
  • GPIO模拟SPI通信从机代码 主函数为: #include "sys.h" #include "delay.h" #include "usart.h" #include "led.h" #include "key.h" #include "spi.h" #include "lcd.h" #include "sdram.h" unsigned char data[9]=...
  • 基于vxworks系统的gpio模拟mdc/mdio(smi)驱动参考代码。基于vxworks系统的gpio模拟mdc/mdio(smi)驱动参考代码。
  • 实现一个由GPIO模拟的I2C从机工程设计,以前只使用GPIO模拟I2C设计过主机,对于从机的设计,比较少有。本次讲解从机设计思想并做详细记录。 程序模块化设计,核心代码分析讲解和说明,及通信流程图
  • SPI,是英语Serial Peripheral interface的缩写,顾名思义就是 串行外围设备接口。是Motorola首先在其MC68HCXX系列处理 器上定义的。SPI接口主要应用在EEPROM,FLASH,实时时钟, AD转换器,还有数字信号处理器和...
  • 海思GPIO模拟I2C底层驱动,修改makefile中的内核位置和寄存器地址即可适应海思所有型号。
  • 海思GPIO模拟I2C实现源码,海思GPIO模拟I2C实现源码,大家可以下载学习一下,
  • I2C GPIO模拟从设备设备通信源码,时钟引脚PB4,数据引脚PB5,设备地址0xA0
  • GPIO模拟MIPI RFFE

    2018-12-13 12:52:13
    STM32 GPIO模拟MIPI RFFE的代码实现, MIPI 规范简介, MIPIMASTER 读写时序波形
  • 在2440开发板上使用GPIO模拟SPI来控制FLASH芯片对其进行读写
  • spi gpio模拟驱动,支持3线spi,支持4线spi,支持9位,8位数 Spi gpio simulation driver, support 3 line spi, support 4 line spi, support 9 bit,8 bit data据
  • 基于STM32等ARM芯片,使用通用GPIO模拟SPI通讯,SPI通讯协议详解
  • 在ARM Linux下使用GPIO模拟SPI时序详解.pdf
  • 若能提供一种通用可配置可移植的GPIO模拟SPI总线的驱动则能很方便快捷的访问SPI设备,从而提高整个嵌入式系统的开发效率。本文针对GPIO口位寻址与否给出方面,给出了一种可配置GPIO模拟SPI总线的方法并详细介绍了其...
  • 用STM32做的一个USB 模拟发送按键到PC上 当GPIO按下的时候 模拟指定的字符发上来,模拟游戏按下的动作
  • gpio 模拟i2c总线

    2017-05-26 15:30:56
    gpio 模拟i2c总线
  • stm32 gpio模拟i2c_slave

    2018-03-27 09:53:14
    暂时未测试通过。放到csdn存档,如果侵权请联系我删除,谢谢。
  • GPIO模拟SPI通信主机代码 主函数如下: #include "sys.h" #include "delay.h" #include "usart.h" #include "led.h" #include "key.h" #include "spi.h" #include "lcd.h" #include "sdram.h" unsigned char data...
  • linux gpio 模拟I2C驱动

    2015-06-11 21:36:45
    linux gpio 模拟I2C驱动
  • nrf51822硬件串口及模拟的3路串口(利用定时器产生波特率,IO口模拟RX,TX),其数据发送利用的是查询发送,数据接收利用io中断。有需要 模拟串口的可以参考
  • STM32 GPIO 模拟IIC (I2C) c语言 源代码(测试绝对可用) 用STM32 GPIO模拟IIC 的c语言源代码,自己的项目中的,绝对可用。
  • STM32F103VE_NRF24L01_GPIO模拟SPI通讯程序,含接收与发送,根据网上例程修改而成。测试正常。
  • stm8 gpio模拟串口 定时器+中断,项目中已采用 stm8 gpio模拟串口 定时器+中断,项目中已采用
  • STM32 GPIO模拟红外接收

    2013-12-02 15:36:03
    使用STM32 GPIO模拟红外遥控器接收,用来实现对HOST机进行关机下红外开机 功能
  • gpio模拟I2C

    2014-10-15 14:23:14
    gpio模拟I2C 通讯 gpio
  • 海思平台gpio模拟i2c驱动源码
  • Linux驱动实现GPIO模拟I2C读写操作

    千次阅读 2019-11-08 15:28:45
    二、GPIO模拟I2C协议的C代码实现 下面将用C语言实现上面所描述的I2C总线协议的各个动作,并将这些分散的动作整合起来实现字节的读写操作。 1、首先需要定义2个IO口以连接两根总线SDA和SC,例如我这里使用250和251,...

    一、关于i2c协议概述

    I2C总线协议只需要2根信号线即可完成数据的传输,这两根线分别是时钟线SCL和信号线SDA。I2C线上有且只有1个主设备Master和若干个从设备Slave,区别Master和Slave的标准是SCL,即谁是SCL的提供者,谁就是Master,而与SDA无关。这点尤其需要注意,发送SDA不能作为区别Master和Slave的标准。

    关于I2C总线再作以下说明:
    1-两条总线SDA和SCL都必须接上拉电阻,这是为了确保两条总线在空闲时都是高电平,上拉电阻的经典取值是10kΩ;
    2-I2C总线上可以挂载多个主机和多个从机,但是同一时间只允许1个主机和1个从机进行通信;
    3-总线上每一个设备都有一个独立的地址,通过该地址实现通信;
    4-总线上的设备是“线与”的关系,即任一设备的管脚输出低电平都可以将该管脚所在总线的电平拉低,线与关系是时钟同步和总线仲裁的硬件基础;
    5-I2C传输速度有标准速度模式(SS Mode)、快速模式(FS Mode)和高速模式(HS Mode)三种,数据传输速率分别为100kbps、400kbps和3.4Mbps。

    协议层:协议层规定了通讯的起始停止信号、数据有效性、响应、总线仲裁、时钟同步、地址广播等内容。

    1、总线空闲与信号起始终止
       I2C协议规定SDA和SCL都为高电平时总线空闲(not busy)。

    I2C协议规定SCL保持高电平、SDA由高变低为起始信号(start),所有命令和数据的传输必须以起始信号为首。

    I2C协议规定SCL保持高电平、SDA由低变高为终止信号(stop)。所有命令和数据的传输必须以终止信号为尾。

    2、数据有效
    I2C协议规定在总线上出现起始信号start后,若SCL在高电平期间SDA保持电平不变,则SDA的状态表示有效数据(data valid)。在传输数据时SDA的改变必须只能发生在SCL为
    低电平期间,每一bit数据有1个时钟脉冲时长。

    3、应答和非应答
       I2C协议规定每个被寻址设备在接收1字节数据后都必须向发送字节的设备发送应答(ACK)信号,确认的器件必须在应答时钟脉冲期间下拉SDA线,使得SDA线在应答相关时钟脉冲
    SCL为高电平期间稳定为低电平。

    I2C协议规定与ACK信号相反的信号为非应答(not ACK)信号。在主器件从从器件中读取数据时,主器件必须在读取的最后1字节数据后在SDA总线上产生not ACK信号以示意从器
    件停止发送数据。not ACK信号是在SCL为高电平期间保持SDA也为高电平。

    4、地址广播
    地址广播是I2C协议规定的寻址方式。它是指主设备在产生start信号后,各个从设备开始关注总线SDA信号,此时主设备在总线上生成需接受/发送数据的从设备的
    地址(Address),相当于向总线上所有从设备广播了这一地址。每个从设备将总线上的地址与自己的地址相对比,不一致的退出接收,一致的继续接收,直到8bit地址数据
    广播完毕,仍然留下的那一个从设备就是主设备的寻址目标。

    5、总线仲裁解决的是多个主设备竞争使用同一总线的问题。

    假设主控器1要发送的数据DATA1为“101 ……”;主控器2要发送的数据DATA2为“1001 ……”总线被启动后两个主控器在每发送一个数据位时都要对自己的输出电平进行检测,
    只要检测的电平与自己发出的电平一致,他们就会继续占用总线。在这种情况下总线还是得不到仲裁。当主控器1发送第3位数据“1”时(主控器2发送“0” ),由于“线与”的
    结果SDA上的电平为“0”,这样当主控器1检测自己的输出电平时,就会测到一个与自身不相符的“0”电平。这时主控器1只好放弃对总线的控制权;因此主控器2就成为总线的
    唯一主宰者。(实例来自博客)

    从中可以得出:参与仲裁的所有主控器都不会丢失数据;参与仲裁的所有主控器没有固定的优先级别,而是遵循低电平优先的原则。

    6、时钟同步

    时钟同步是用来解决中控器和被控器的数据传输速率不相同的问题。

    被控器可以通过将SCL主动拉低并延长其低电平时间的方法来通知主控器,当主控器在准备下一次传送时发现SCL为低电平,就会等待,直至被控器完成操作并释放SCL线的
    控制控制权。这样,主控器实际上受到被控器的时钟同步控制。由此可见,SCL线上的低电平是由时钟低电平最长的器件决定,高电平的时间由高电平时间最短的器件决定。

    需要说明的是,不管是总线仲裁还是时钟同步,它们得以实现的基础是SDA总线的“线与”性质,而这是由I2C总线独特的IO结构决定的。另外,总线仲裁和时钟同步之间并
    不存在特定的先后关系,它们往往同时发生。

    二、GPIO模拟I2C协议的C代码实现

    下面将用C语言实现上面所描述的I2C总线协议的各个动作,并将这些分散的动作整合起来实现字节的读写操作。

    1、首先需要定义2个IO口以连接两根总线SDA和SC,例如我这里使用250和251,然后定义i2c速率,即delay的值,这里设置为10k,即udelay(100);

    我们可以通过以下两个命令来查看确认自己需要使用的gpio的数字是多少(其他平台可能节点不同,不过名称基本上是pinmux-pins),注意结合硬件原理图或者跟硬件工程师确认:
    cat /d/pinctrl/pinctrl/pinmux-pins 或者 cat /sys/kernel/debug/pinctrl/pinctrl/pinmux-pins

    cat /sys/kernel/debug/gpio //查看GPIO当前的申请使用情况和当前的电平状态

    #define DELAY_TIME_HXD 100 //设置i2c clk, hxd019大概要求10k左右
    #define GPIO_SDA 250
    #define GPIO_SCL 251
    
    

    2、初始化gpio模拟的i2c通讯SDA和SCL, 拉高SDA和SCL,初始化的效果是SDA和SCL总线上全部呈现高电平

    static int gpio_i2c_init(void) 
    {
        int ret;
    
    	if(hxd019d_dbg_en == 1)
    		printk("hxd019d: %s, line(%d)\n", __func__, __LINE__);
    
    	if (!gpio_is_valid(GPIO_SDA)) {
    		printk("GPIO_SDA: %d is invalid\n", GPIO_SDA);
    		return -ENODEV;
    	}
        ret = gpio_request(GPIO_SDA,"GPIO_SDA");
        if(ret < 0)
        {
            printk("request GPIO_SDA error\n");
            return ret;
        }
    	if (!gpio_is_valid(GPIO_SCL)) {
    		printk("GPIO_SCL: %d is invalid\n", GPIO_SCL);
    		return -ENODEV;
    	}
        ret = gpio_request(GPIO_SCL,"GPIO_SCL");
        if(ret < 0)
        {    
            printk("request GPIO_SCL error\n");
            return ret;
        }
    
    
    	if (!gpio_is_valid(GPIO_BUSY)) {
    		printk("GPIO_BUSY: %d is invalid\n", GPIO_BUSY);
    		return -ENODEV;
    	}
        ret = gpio_request(GPIO_BUSY,"GPIO_BUSY");
        if(ret < 0)
        {    
            printk("request GPIO_BUSY error\n");
            return ret;
        }
    	
    	ret = gpio_direction_input(GPIO_BUSY); // set GPIO_BUSY as input IO
        if(ret < 0)
        {
            printk("set GPIO_BUSY direction fail");
            return ret;
        }
    
    	gpio_direction_output(GPIO_SDA, 1);
    	gpio_direction_output(GPIO_SCL, 1);
    
        return 0;
    
    }
    

    3、起始信号,用GPIO模拟起始信号,SCL保持高电平、SDA由高变低。

    static int iic_i2cstart_hxd019(void) 
    {
    	if(hxd019d_dbg_en == 1)
    		printk("hxd019d: %s, line(%d)\n", __func__, __LINE__);
    
    	gpio_direction_output(GPIO_SDA, 1);
    	gpio_direction_output(GPIO_SCL, 1);
    	udelay(DELAY_TIME_HXD);
    	udelay(DELAY_TIME_HXD);
    
    	gpio_direction_output(GPIO_SDA, 0);
    	udelay(DELAY_TIME_HXD);
    
    	udelay(DELAY_TIME_HXD);
    	udelay(DELAY_TIME_HXD);
    
    	udelay(DELAY_TIME_HXD);
    	udelay(DELAY_TIME_HXD);
    	udelay(DELAY_TIME_HXD);
    
    	udelay(DELAY_TIME_HXD);
    	udelay(DELAY_TIME_HXD);
    
    	udelay(DELAY_TIME_HXD);
    	udelay(DELAY_TIME_HXD);
    
    	gpio_direction_output(GPIO_SCL, 0);
    	udelay(DELAY_TIME_HXD);
    	udelay(DELAY_TIME_HXD);
    
    	return 0;
    
    }
    
    

    4、终止信号:用GPIO模拟起始信号,SCL保持高电平、SDA由低变高。

    static int iic_i2cstop_hxd019(void) 
    {
    	if(hxd019d_dbg_en == 1)
    		printk("hxd019d: %s, line(%d)\n", __func__, __LINE__);
    
    	gpio_direction_output(GPIO_SDA, 0);
    	gpio_direction_output(GPIO_SCL, 0);
    	udelay(DELAY_TIME_HXD);
    
    	gpio_direction_output(GPIO_SCL, 1);
    	udelay(DELAY_TIME_HXD);
    
    	gpio_direction_output(GPIO_SDA, 1);
    	udelay(DELAY_TIME_HXD);
    
    	return 0;
    
    }
    

    5、主控读取ack应答信号,即主控平台读取ACK对应的IO口处的电平。

    uint8_t GetACKSign_hxd019(void)  //主控器读取ACK对应的IO口处的电平
    {
    	uint8_t ACKSign;
    
    	if(hxd019d_dbg_en == 1)
    		printk("hxd019d: %s, line(%d)\n", __func__, __LINE__);
    
    	gpio_direction_input(GPIO_SDA);
    	udelay(DELAY_TIME_HXD);
    	udelay(DELAY_TIME_HXD);
    	udelay(DELAY_TIME_HXD);
    	udelay(DELAY_TIME_HXD);
    
    	gpio_direction_output(GPIO_SCL, 1);
    	udelay(DELAY_TIME_HXD);
    	udelay(DELAY_TIME_HXD);
    	udelay(DELAY_TIME_HXD);
    	udelay(DELAY_TIME_HXD);
    
    	ACKSign = gpio_get_value(GPIO_SDA);
    	udelay(DELAY_TIME_HXD);
    	udelay(DELAY_TIME_HXD);
    	udelay(DELAY_TIME_HXD);
    	udelay(DELAY_TIME_HXD);
    
    	gpio_direction_output(GPIO_SCL, 0);
    	udelay(DELAY_TIME_HXD);
    	udelay(DELAY_TIME_HXD);
    	udelay(DELAY_TIME_HXD);
    	udelay(DELAY_TIME_HXD);
    
    	return ACKSign;
    }
    
    

    6、主控发送ack信号,即主控平台向ACK对应的IO口发送低电平。

    void SendACKSign_hxd019(void) //主控器发送ACK
    {
    	if(hxd019d_dbg_en == 1)
    		printk("hxd019d: %s, line(%d)\n", __func__, __LINE__);
    
    	udelay(DELAY_TIME_HXD);
    	udelay(DELAY_TIME_HXD);
    	gpio_direction_output(GPIO_SDA, 0);
    	udelay(DELAY_TIME_HXD);
    
    	gpio_direction_output(GPIO_SCL, 1);
    	udelay(DELAY_TIME_HXD);
    	udelay(DELAY_TIME_HXD);
    
    	gpio_direction_output(GPIO_SCL, 0);	
    	udelay(DELAY_TIME_HXD);
    	udelay(DELAY_TIME_HXD);
    	udelay(DELAY_TIME_HXD);
    	udelay(DELAY_TIME_HXD);
    	return ;
    }
    

    7、主控发送not ACK信号,即主控平台向ACK对应的IO口发送高电平。

    void SendNoACKSign_hxd019(void) //主控器发送not ack
    {
    	if(hxd019d_dbg_en == 1)
    		printk("hxd019d: %s, line(%d)\n", __func__, __LINE__);
    
    	udelay(DELAY_TIME_HXD);
    	udelay(DELAY_TIME_HXD);
    
    	gpio_direction_output(GPIO_SCL, 1);
    	udelay(DELAY_TIME_HXD);
    	udelay(DELAY_TIME_HXD);
    
    	gpio_direction_output(GPIO_SCL, 0);
    
    	return ;
    }
    

    8、单字节读操作,它的逻辑是初始化—主控器发送起始信号—主控器逐bit读取SDA线上信号。

    static int iic_I2CReadData_hxd019(uint8_t* pbData,int num) //单字节读操作
    {
    	uint8_t readdata = 0;
    	int i=8;
    
    	gpio_direction_input(GPIO_SDA);
    	while (i--)
    	{
    		readdata <<= 1;
    
    		gpio_direction_output(GPIO_SCL, 1);
    		udelay(DELAY_TIME_HXD);
    
    		readdata |= gpio_get_value(GPIO_SDA);
    
    		gpio_direction_output(GPIO_SCL, 0);
    		udelay(DELAY_TIME_HXD);
    		udelay(DELAY_TIME_HXD);
    	}
    
    		gpio_direction_output(GPIO_SCL, 0);
    		udelay(DELAY_TIME_HXD);
    
    	*pbData = readdata;
    	if(num >= (ReadBytesTotal -1))
    		SendNoACKSign_hxd019();
    	else
    		SendACKSign_hxd019();
    
    		udelay(DELAY_TIME_HXD);
    		udelay(DELAY_TIME_HXD);
    
    	return 0;
    }
    
    

    9、单字节写操作,它的逻辑是初始化—主控器发送起始信号—主控器逐bit往SDA线上写数据。

    static uint8_t iic_I2CWriteData_hxd019(uint8_t bData) //单字节写操作
    {
    	uint8_t Data_Bit,ACKSign;
    	int i = 0;
    
    	if(hxd019d_dbg_en == 1)
    		printk("hxd019d: %s, line(%d)\n", __func__, __LINE__);
    
    	gpio_direction_output(GPIO_SCL, 0);
    	udelay(DELAY_TIME_HXD);
    						    
    	for(i = 7;i >= 0; i--)
    	{
    		udelay(DELAY_TIME_HXD);
    
    		Data_Bit= (bData >> i) & 0x01;
    
    		if(Data_Bit)
    			gpio_direction_output(GPIO_SDA, 1);
    		else
    			gpio_direction_output(GPIO_SDA, 0);
    
    		udelay(DELAY_TIME_HXD);
    		gpio_direction_output(GPIO_SCL, 1);
    		udelay(DELAY_TIME_HXD);
    		gpio_direction_output(GPIO_SCL, 0);
    	}
    	ACKSign=GetACKSign_hxd019();
    	return ACKSign;		
    	
    	
    }
    

    10、主控检查是否接收到ACK,主控器在发完第1个地址字节后,按规定被控期需要向主控器回复一个ACK信号,
    主控器如果能在总线上检测到这个ACK,就继续向被控器传送数据,否则视为本次数据传送失败。

    uint8_t i2c_ack_check(uint8_t ctrl_byte)
    {
    	iic_i2cstart_hxd019();
    	iic_I2CWriteData_hxd019(ctrl_byte);
    	if(GetACKSign_hxd019() == 0)
    	{
    
    		// time delay here is not necessary, just to make waveforms more readable
    		udelay(DELAY_TIME_HXD);
    
    		gpio_direction_input(GPIO_SDA);		// set SDA as input
    		gpio_direction_input(GPIO_SCL);		// set SCL as input
    		return 0;
    	}
    	else
    	{
    		// time delay here is to save computing resource
    		udelay(DELAY_TIME_HXD);
    		return 1;
    	}
    }
    

    11、i2c读写寄存器操作

    int gpio_analog_i2c_read(unsigned char I2cRegAddr)//读寄存器操作
    {
    	int i = 100;
    	//spin_lock(&a_lock);
    	unsigned char bValue = 0;
        unsigned char devAddr = 0;
    
    	if(hxd019d_dbg_en == 1)
    		printk("hxd019d: ------%s(%d)-------\n", __func__, __LINE__);
    
        devAddr = (chipSlaveAddr << 1);
        iic_i2copen_hxd019();
        udelay(DELAY_TIME_HXD);
        iic_i2cstart_hxd019();
        udelay(DELAY_TIME_HXD);
        iic_I2CWriteData_hxd019(devAddr);
        udelay(DELAY_TIME_HXD);
        iic_I2CWriteData_hxd019(I2cRegAddr);
        udelay(DELAY_TIME_HXD);
        iic_i2cstart_hxd019();
        udelay(DELAY_TIME_HXD);
        iic_I2CWriteData_hxd019((devAddr | 0x1));
        udelay(DELAY_TIME_HXD);
        iic_I2CReadData_hxd019(&bValue,i);
        udelay(DELAY_TIME_HXD);
        iic_i2cstop_hxd019();
        udelay(DELAY_TIME_HXD);
        iic_i2cclose_hxd019();
        udelay(DELAY_TIME_HXD);
    	//spin_unlock(&a_lock);
    	
    	return bValue;	
    	
    }
    
    int gpio_analog_i2c_write(unsigned char I2cRegAddr,unsigned char data) //写寄存器操作
    {
    
    	//spin_lock(&a_lock);
        unsigned char devAddr = 0;
    
    	if(hxd019d_dbg_en == 1)
    		printk("hxd019d: ------%s(%d)-------\n", __func__, __LINE__);
    
        devAddr = chipSlaveAddr << 1;
        iic_i2copen_hxd019();
        udelay(DELAY_TIME_HXD);
        iic_i2cstart_hxd019();
        udelay(DELAY_TIME_HXD);
        iic_I2CWriteData_hxd019(devAddr);
        udelay(DELAY_TIME_HXD);
        iic_I2CWriteData_hxd019(I2cRegAddr);
        udelay(DELAY_TIME_HXD);
        //iic_i2cstart();
        //udelay(DELAY_TIME);
        //iic_I2CWriteData((devAddr | 0x1));
        //udelay(DELAY_TIME);
        //iic_I2CReadData(&bValue);
        iic_I2CWriteData_hxd019(data);
        udelay(DELAY_TIME_HXD);
        iic_i2cstop_hxd019();
        udelay(DELAY_TIME_HXD);
        iic_i2cclose_hxd019();
        udelay(DELAY_TIME_HXD);
    	//spin_unlock(&a_lock);
    	
    	return 0;	
    	
    }
    
    展开全文
  • GPIO模拟串口

    2021-03-19 10:29:32
    波特为38400波形图如下,可以看出,一个字节的脉宽为26us.

    波特率为38400波形图如下,可以看出,一个字节的脉宽为26us.

    在72MHZ灵动微MCU上的代码为:

    #define TXD_SET		GPIO_SetBits(GPIOB,GPIO_Pin_3)
    #define TXD_RESET	GPIO_ResetBits(GPIOB,GPIO_Pin_3)
    #define Delay_Simulator_Uart(n) do {volatile unsigned int vi=0,vj=0; for (vi=0; vi<n; vi++)__asm("nop");} while (0)
    //往串口写一个字节
    unsigned char UART_Simulator_SendByte(unsigned char ch)
    {
    	TXD_RESET; //发送启始位
    	Delay_Simulator_Uart(85);//Delay2cp(39);
    	//发送8位数据位
    	for (u8 i=8; i; i--)
    	{
    		if (ch & 0x01)TXD_SET; else TXD_RESET; //先传低位
    		Delay_Simulator_Uart(85);//Delay2cp(36);
    		ch >>= 1;
    	}
    	//发送校验位(无)
    	TXD_SET; //发送结束位
    	Delay_Simulator_Uart(85);//Delay2cp(46);
            Delay_Simulator_Uart(42); // 实际使用时,刚好一个停止位时,会不稳定,有时行,有时不行。
    	return ch;
    }

    代码参考自:《51单片机模拟串口的三种方法》https://blog.csdn.net/abin_gha/article/details/5834254?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-5.control&dist_request_id=&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-5.control

    115200时,为

    256000时,为3.5us和4.0us之间跳变。

    256000时的代码为:

    #define TXD_SET		GPIO_SetBits(GPIOB,GPIO_Pin_3)
    #define TXD_RESET	GPIO_ResetBits(GPIOB,GPIO_Pin_3)
    #define Delay_Simulator_Uart(n) do {volatile unsigned int vi=0,vj=0; for (vi=0; vi<n; vi++)__asm("nop");} while (0)
    unsigned char UART_Simulator_SendByte(unsigned char ch)
    {
    	TXD_RESET; //发送启始位
    	Delay_Simulator_Uart(10);//Delay2cp(39);
    	//发送8位数据位
    	for (u8 i=8; i; i--)
    	{
    		if (ch & 0x01)TXD_SET; else TXD_RESET; //先传低位
    		Delay_Simulator_Uart(10);//Delay2cp(36);
    		ch >>= 1;
    	}
    	//发送校验位(无)
    	TXD_SET; //发送结束位
    	Delay_Simulator_Uart(10);//Delay2cp(46);
    	Delay_Simulator_Uart(5); // 实际使用时,刚好一个停止位时,会不稳定,有时行,有时不行。
    	return ch;
    }

     

    如果有重定向,刚这样写:

    int fputc(int ch, FILE *f)
    {
    	return UART_Simulator_SendByte(ch);
    }

     

     

    展开全文
  • GPIO模拟I2C程序实现

    2010-05-25 20:58:24
    GPIO模拟I2C的程序实现 #include #include #include #include #include #include #include #include #include #include #include #include #include "gpio_i2c.h

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 17,251
精华内容 6,900
关键字:

gpio模拟