- 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
使用时相应的函数名更改一下就好