IIC设备的驱动

  • IIC设备一般有一个双向通讯线,一个时钟信号线,属于同步串行总线,运行速度较快
#include "ds3231.h"  //导入头文件dht11.h  
#include "main.h"

int fputc(int ch, FILE *f)
{      
	while((USART1->SR&0X40)==0);//循环发送,直到发送完毕   
    USART1->DR = (u8) ch;      
	return ch;
}

void Usart1_Init(unsigned int baud)
{

	GPIO_InitTypeDef gpio_initstruct;
	USART_InitTypeDef usart_initstruct;
	NVIC_InitTypeDef nvic_initstruct;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);							//打开GPIOA的时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);							//打开USART1的时钟z
	
	//PA9	TXD
	gpio_initstruct.GPIO_Mode = GPIO_Mode_AF_PP;										//设置为复用模式
	gpio_initstruct.GPIO_Pin = GPIO_Pin_9;											//初始化Pin9
	gpio_initstruct.GPIO_Speed = GPIO_Speed_50MHz;									//承载的最大频率
	GPIO_Init(GPIOA, &gpio_initstruct);												//初始化GPIOA
	
	//PA10	RXD
	gpio_initstruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;								//设置为浮空输入
	gpio_initstruct.GPIO_Pin = GPIO_Pin_10;											//初始化Pin10
	gpio_initstruct.GPIO_Speed = GPIO_Speed_50MHz;									//承载的最大频率
	GPIO_Init(GPIOA, &gpio_initstruct);												//初始化GPIOA
	
	usart_initstruct.USART_BaudRate = baud;
	usart_initstruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;		//无硬件流控
	usart_initstruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;						//接收和发送
	usart_initstruct.USART_Parity = USART_Parity_No;									//无校验
	usart_initstruct.USART_StopBits = USART_StopBits_1;								//1位停止位
	usart_initstruct.USART_WordLength = USART_WordLength_8b;							//8位数据位
	USART_Init(USART1, &usart_initstruct);
	
	USART_Cmd(USART1, ENABLE);														//使能串口
	
	USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);									//使能接收中断
	
	nvic_initstruct.NVIC_IRQChannel = USART1_IRQn;									//usart1中断号
	nvic_initstruct.NVIC_IRQChannelCmd = ENABLE;										//中断通道使能
	nvic_initstruct.NVIC_IRQChannelPreemptionPriority = 0;							//抢占中断优先级(值越小优先级越高)
	nvic_initstruct.NVIC_IRQChannelSubPriority = 2;									//子中断优先级(值越小优先级越高)
	NVIC_Init(&nvic_initstruct);														//初始化NVIC
}

#include "main.h"

//IIC初始化
void IIC_Init(void)
{ 
    IIC_SDA(1);
    IIC_SCL(1);  
}

//产生IIC起始信号
void IIC_Start(void)
{
	SDA_OUT();     //sda线输出
	IIC_SDA(1);	  	  
	IIC_SCL(1);
	delay_us(4);
 	IIC_SDA(0);//START:when CLK is high,DATA change form high to low 
	delay_us(4);
	IIC_SCL(0);//钳住I2C总线,准备发送或接收数据 
}	  
//产生IIC停止信号
void IIC_Stop(void)
{
	SDA_OUT();//sda线输出
	IIC_SCL(0);
	IIC_SDA(0);//STOP:when CLK is high DATA change form low to high
 	delay_us(4);
	IIC_SCL(1); 
	delay_us(4);			
	IIC_SDA(1);//发送I2C总线结束信号				   	
}
//等待应答信号到来
//返回值:1,接收应答失败
//        0,接收应答成功
u8 IIC_Wait_Ack(void)
{
    u8 ucErrTime=0;
    SDA_IN();      //SDA设置为输入  
    IIC_SDA(1);delay_us(1);	   
    IIC_SCL(1);delay_us(1);	 
    while(READ_SDA)
    {
            ucErrTime++;
            if(ucErrTime>250)
            {
                    IIC_Stop();
                    return 1;
            }
    }
    IIC_SCL(0);//时钟输出0 	   
    return 0;  
} 
//产生ACK应答
void IIC_Ack(void)
{
  IIC_SCL(0);
  SDA_OUT();
  IIC_SDA(0);
  delay_us(2);
  IIC_SCL(1);
  delay_us(2);
  IIC_SCL(0);
}
//不产生ACK应答		    
void IIC_NAck(void)
{
	IIC_SCL(0);
	SDA_OUT();
	IIC_SDA(1);
	delay_us(2);
	IIC_SCL(1);
	delay_us(2);
	IIC_SCL(0);
}					 				     
//IIC发送一个字节
//返回从机有无应答
//1,有应答
//0,无应答			  
void IIC_Send_Byte(u8 txd)
{                        
    u8 t;   
    SDA_OUT(); 	    
    IIC_SCL(0);//拉低时钟开始数据传输
    for(t=0;t<8;t++)
    {              
        IIC_SDA((txd&0x80)>>7);
        txd<<=1; 	  
        delay_us(2);   //对TEA5767这三个延时都是必须的
        IIC_SCL(1);
        delay_us(2); 
        IIC_SCL(0);	
        delay_us(2);
    }	 
} 	    
//读1个字节,ack=1时,发送ACK,ack=0,发送nACK   
u8 IIC_Read_Byte(unsigned char ack)
{
	unsigned char i,receive=0;
	SDA_IN();//SDA设置为输入
        for(i=0;i<8;i++ )
	{
          IIC_SCL(0); 
          delay_us(2);
          IIC_SCL(1);
          receive<<=1;
          if(READ_SDA)receive++;   
          delay_us(1); 
        }					 
    if (!ack)
        IIC_NAck();//发送nACK
    else
        IIC_Ack(); //发送ACK   
    return receive;
}


//IIC读一个字节 
//reg:寄存器地址 
//返回值:读到的数据
u8 ADXL345_RD_Reg(u8 reg)
{       
    u8 res;
    IIC_Start(); 
    IIC_Send_Byte((DS3231_ADDR<<1)|0);//发送器件地址+写命令	
    IIC_Wait_Ack();		//等待应答 
    IIC_Send_Byte(reg);	//写寄存器地址
    IIC_Wait_Ack();		//等待应答
    IIC_Start();
    IIC_Send_Byte((DS3231_ADDR<<1)|1);//发送器件地址+读命令	
    IIC_Wait_Ack();		//等待应答 
    res=IIC_Read_Byte(0);//读取数据,发送nACK 
    IIC_Stop();			//产生一个停止条件 
    return res;		
}

//IIC写一个字节 
//reg:寄存器地址
//data:数据
//返回值:0,正常
//    其他,错误代码
u8 ADXL345_WR_Reg(u8 reg,u8 data) 				 
{ 
    IIC_Start(); 
    IIC_Send_Byte((DS3231_ADDR<<1)|0);//发送器件地址+写命令	
    if(IIC_Wait_Ack())	//等待应答
    {
      IIC_Stop();		 
      return 1;		
    }
    IIC_Send_Byte(reg);	//写寄存器地址
    IIC_Wait_Ack();		//等待应答 
    IIC_Send_Byte(data);//发送数据
    if(IIC_Wait_Ack())	//等待ACK
    {
      IIC_Stop();	 
      return 1;		 
    }		 
    IIC_Stop();	 
    return 0;
}
void time_set(u8 a_p,u8 hone,u8 min,u8 sec)
{
	u8 hone_hex,min_hex,sec_hex;
	hone_hex=(hone/10)*16+hone%10;
//	if(a_p)
//		hone_hex&=0xdf;
//	else
//		hone_hex|=0x20;
	min_hex=(min/10)*16+min%10;
	sec_hex=(sec/10)*16+sec%10;
	ADXL345_WR_Reg(0x02,hone_hex);
	ADXL345_WR_Reg(0x01,min_hex);
	ADXL345_WR_Reg(0x00,sec_hex);
}



2021.04.11更新加入头文件

#ifndef _ds3231_h
#define _ds3231_h
#include "stm32f10x.h"
#define DS3231_ADDR 0x68

#define IIC_SDA(x)     PBout(7)=x?1:0
#define IIC_SCL(x)     PBout(6)=x?1:0

//IO方向设置
#define SDA_OUT()  {GPIOB->CRL&=0X0FFFFFFF;GPIOB->CRL|=7<<28;}
#define SDA_IN()   {GPIOB->CRL&=0X0FFFFFFF;GPIOB->CRL|=4<<28;}
										   

#define	READ_SDA  PBin(7)  //数据端口	 

#define delay_us  SysTick_Delay_Us
void IIC_Init(void);
void Usart1_Init(unsigned int baud);
u8 ADXL345_RD_Reg(u8 reg);
u8 ADXL345_WR_Reg(u8 reg,u8 data) ;
void time_set(u8 a_p,u8 hone,u8 min,u8 sec);

#endif

使用时相应的函数名更改一下就好

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值