标题:
ADS7142的STM32模拟IIC源程序
[打印本页]
作者:
Simon5118
时间:
2018-7-18 15:13
标题:
ADS7142的STM32模拟IIC源程序
ADS7142的IIC软件与普通的存在小小的差别,多了一个opcodd配置。详细的请看附件~
0.png
(43.5 KB, 下载次数: 66)
下载附件
2018-7-18 23:48 上传
单片机源程序如下:
#include "i2c.h"
#include "stdio.h"
#include "string.h"
#include "data.h"
#include "env.h"
#include "atc.h"
#include "ads7142.h"
#define SCL_H GPIO_SetBits(GPIOB, GPIO_Pin_6)
#define SCL_L GPIO_ResetBits(GPIOB, GPIO_Pin_6)
#define SDA_H GPIO_SetBits(GPIOB, GPIO_Pin_7)
#define SDA_L GPIO_ResetBits(GPIOB, GPIO_Pin_7)
#define SDA_read GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_7)
#define BUSY_read GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_14)
static void DelayNus(uint32_t N)
{
uint8_t i;
do{
for(i=6;i>0;i--) //8MHZ:=7; 12MHZ:=11
;
}while(--N);
}
/**
* @brief IIC Init
* @param None
* @retval None
*/
static void ads7142_gpio_init(void)
{
//I2C_InitTypeDef I2C_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
/* Configure IIC2 pins: PB10->SCL and PB11->SDA */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14; // PA1 -- ADC Channel 1 -- Work
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
/**
* @brief Set SDA Pin as Output Mode
* @param None
* @retval None
*/
static void SDA_OUT(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
/**
* @brief Set SDA Pin as Input Mode
* @param None
* @retval None
*/
static void SDA_IN()
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;// !!!
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
/**
* @brief create start signal
* @param None
* @retval 1 or 0
*/
static uint8_t IIC_Start(void)
{
SDA_OUT(); //sda output
SDA_H;
SCL_H;
DelayNus(6);
if (!SDA_read)
{
return 0;
}
SDA_L;
DelayNus(6);
if (SDA_read)
{
return 0;
}
SDA_L;
DelayNus(6);
return 1;
}
/**
* @brief Simulate IIC conmunication : Create Stop signal
* @param None
* @retval None
*/
static void IIC_Stop(void)
{
SCL_L;
SDA_OUT(); //sda output mode
DelayNus(6);
SDA_L;
DelayNus(6);
SCL_H;
DelayNus(6);
SDA_H;
DelayNus(6);
}
/**
* @brief Simulate IIC conmunication : wait for target device's ACK
* @param None
* @retval ACK (1) : receive success
* NACK(0) : receive unsuccess
*/
static uint8_t IIC_WaitAck(void)
{
uint8_t err_time = 0;
SCL_L;
SDA_IN(); //set as input mode
DelayNus(6);
SDA_H;
DelayNus(6);
SCL_H;
DelayNus(6);
while(SDA_read)
{
err_time++;
if (err_time > 250)
{
printf("ERROR:IIC_WaitAck()->SDA_read\n\r");
return 0;
}
}
SCL_L;
return 1;
}
/**
* @brief Simulate IIC conmunication : make an ACK
* @param None
* @retval None
*/
static void IIC_Ack(void)
{
SCL_L;
SDA_OUT();
DelayNus(6);
SDA_L;
DelayNus(6);
SCL_H;
DelayNus(6);
SCL_L;
DelayNus(6);
}
/**
* @brief Simulate IIC conmunication : don't make an ACK
* @retval None
*/
static void IIC_NoAck(void)
{
SCL_L;
SDA_OUT();
DelayNus(6);
SDA_H;
DelayNus(6);
SCL_H;
DelayNus(6);
SCL_L;
DelayNus(6);
}
/**
* @brief Simulate IIC conmunication : Transmit one byte Data
* @param SendByte: data to be transmit
* @retval None
*/
static void IIC_SendByte(uint8_t SendByte)
{
uint8_t i=8;
SDA_OUT();
while(i--)
{
SCL_L;
DelayNus(6);
if(SendByte&0x80)
SDA_H;
else
SDA_L;
SendByte <<= 1;
DelayNus(6);
SCL_H;
DelayNus(6);
}
SCL_L;
}
/**
* @brief Simulate IIC conmunication : Receive one byte Data
* @param ack ->Whether transmit ACK
* @retval the data have been receive
*/
static uint8_t IIC_ReceiveByte(void)
{
uint8_t i=8;
uint8_t ReceiveByte=0;
SDA_H;
while(i--)
{
ReceiveByte<<=1;
SCL_L;
DelayNus(4);
SCL_H;
DelayNus(4);
if(SDA_read)
{
ReceiveByte |= 0x01;
}
}
SCL_L;
return ReceiveByte;
}
/**
* @brief IIC write byte to device
* @param SendByte ->the write data
* WriteAddress ->device reg address
* DeviceAddresss ->device iic address
* @retval 1 or 0
*/
static uint8_t IIC_WriteByte(uint8_t SendByte, uint16_t WriteAddress, uint8_t DeviceAddress)
{
if(!IIC_Start())
{
printf("ERROR:IIC_WriteByte()->IIC_Start()\n\r");
return 0;
}
IIC_SendByte( DeviceAddress & 0xFE); // iic write address
if(!IIC_WaitAck())
{
IIC_Stop();
printf("ERROR:IIC_WriteByte()->IIC_SendByte()\n\r");
return 0;
}
IIC_SendByte(SINGLE_REG_WRITE);
if(!IIC_WaitAck())
{
IIC_Stop();
printf("write ERROR:SINGLE_REG_READ\n\r");
return 0;
}
IIC_SendByte((uint8_t)((WriteAddress) & 0xFF)); // reg address
IIC_WaitAck();
IIC_SendByte(SendByte); // write data
IIC_WaitAck();
IIC_Stop();
//DelayNus(5000); // test
return 1;
}
/**
* @brief IIC read byte from device reg
* @param pBuffer ->store address for read data
* length ->could read 1byte or continuously
* WriteAddress ->device reg address
* DeviceAddresss ->device iic address
* @retval 1 or 0
*/
static uint8_t IIC_ReadByte(uint8_t* pBuffer,uint8_t length,uint8_t ReadAddress, uint8_t DeviceAddress)
{
if(!IIC_Start())
{
printf("ERROR:IIC_ReadByte()->IIC_Start()\n\r");
return 0;
}
IIC_SendByte((DeviceAddress & 0xFE)); // iic write address
if(!IIC_WaitAck())
{
IIC_Stop();
printf("read ERROR:IIC_ReadByte()->IIC_SendByte()\n\r");
return 0;
}
IIC_SendByte(SINGLE_REG_READ); // single register read
if(!IIC_WaitAck())
{
IIC_Stop();
printf("read ERROR:SINGLE_REG_READ\n\r");
return 0;
}
IIC_SendByte((uint8_t)(ReadAddress & 0xFF)); // reg address
IIC_WaitAck();
IIC_Start();
IIC_SendByte((DeviceAddress & 0xFE) | 0x01); // iic read address
IIC_WaitAck();
while (length)
{
*pBuffer = IIC_ReceiveByte();
if(length == 1)
IIC_NoAck();
else
IIC_Ack();
pBuffer++;
length--;
}
IIC_Stop();
return 1;
}
/**
* @brief ads7142 register read
* @param reg_addr ->the register address
* buf ->data store address
* length ->read length
* @retval 1 or 0
*/
int ads7142_register_single_read(uint8_t reg_addr, uint8_t *buf)
{
int res = 0;
res = IIC_ReadByte(buf, 1, reg_addr, ADS7142_I2C_ADDRESS);
return res;
}
/**
* @brief ads7142 register write
* @param reg_addr ->the register address
* data ->write data
* @retval 1 or 0
*/
int ads7142_register_single_write(uint8_t reg_addr, uint8_t data)
{
int res = 0;
res = IIC_WriteByte(data, reg_addr, ADS7142_I2C_ADDRESS);
if(res == 0)
{
printf ("ads7142 write error\r\n");
}
return res;
}
int ADS7142Calibrate(void)
{
//This function aborts the present conversion sequence and triggers offset calibration
//Abort the present sequence
ads7142_register_single_write(ADS7142_REG_ABORT_SEQUENCE, ADS7142_VAL_ABORT_SEQUENCE);
//Perform Offset Calibration
ads7142_register_single_write(ADS7142_REG_OFFSET_CAL, ADS7142_VAL_TRIG_OFFCAL);
//Return no errors
return 0;
}
int ads7142_init(void)
{
uint8_t tmp = 0;
//DelayNus(100000);
ads7142_gpio_init();
//Calibrate the offset out of ADS7142
ADS7142Calibrate();
//Let's put the ADS7142 into High Precision Mode with both channels enabled in Single-Ended Configuration
//Select the channel input configuration
ads7142_register_single_write(ADS7142_REG_CHANNEL_INPUT_CFG, ADS7142_VAL_CHANNEL_INPUT_CFG_2_CHANNEL_SINGLE_ENDED);
//Select the operation mode of the device
ads7142_register_single_read(ADS7142_REG_CHANNEL_INPUT_CFG, &tmp);
printf ("set 0x24 = %02x\r\n", tmp);
//Select the operation mode of the device
ads7142_register_single_write(ADS7142_REG_OPMODE_SEL, ADS7142_VAL_OPMODE_SEL_HIGH_PRECISION_MODE);
//Confirm the operation mode selection
ads7142_register_single_read(ADS7142_REG_OPMODE_SEL, &tmp);
printf ("set 0x1C = %02x\r\n", tmp);
//ads7142_register_read(ADS7142_REG_OPMODE_I2CMODE_STATUS, &tmp, 1);
//Auto Sequence both channels 0 and 1
ads7142_register_single_write(ADS7142_REG_AUTO_SEQ_CHEN, ADS7142_VAL_AUTO_SEQ_CHENAUTO_SEQ_CH0_CH1);//ADS7142_VAL_AUTO_SEQ_CHENAUTO_SEQ_CH1);//
//Confirm Auto Sequencing is enabled
ads7142_register_single_read(ADS7142_REG_AUTO_SEQ_CHEN, &tmp);
printf ("set 0x20 = %02x\r\n", tmp);
//Select the Low Power Oscillator or high speed oscillator
ads7142_register_single_write(ADS7142_REG_OSC_SEL, ADS7142_VAL_OSC_SEL_HSZ_HSO);
……………………
…………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
所有资料51hei提供下载:
ads7142.rar
(5.97 KB, 下载次数: 42)
2018-7-18 15:13 上传
点击文件名下载附件
下载积分: 黑币 -5
作者:
樱木花道2018
时间:
2018-8-28 21:55
有参考价值
作者:
Lnwechag
时间:
2018-9-6 10:46
刚好在做这个芯片,多谢分享
作者:
Lnwechag
时间:
2018-9-6 10:52
刚好在做7142,多谢分享
作者:
qx7873087
时间:
2019-6-13 09:25
下来看看!!!
作者:
ocean9914
时间:
2019-6-13 17:45
努力学习中。感谢分享
作者:
zyj15698357721
时间:
2024-3-22 16:24
感谢,非常有参考价值
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1