完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
Product Number: AD7616
Software Version: 使用STM32单片机普通I/O口模拟spi通讯,ad7616使用串行突发序列器,请问怎么回读结果 #include "ad7616.h" #include "delay.h" #include "sdram.h" #include "string.h" u8 ad7616_range; const u8 CH_DATA[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77}; /* Dx引脚端口 */ const GPIO_TypeDef *PORT_LIST[18] = { AD7616_CONV_GPIO_Port0, AD7616_RST_GPIO_Port0, AD7616_RD_GPIO_Port0, AD7616_CS_GPIO_Port0, AD7616_BUSY_GPIO_Port0, AD7616_D4_GPIO_Port0, AD7616_D11_GPIO_Port0, AD7616_D12_GPIO_Port0, AD7616_D10_GPIO_Port0, // AD7616_CONV_GPIO_Port1, AD7616_RST_GPIO_Port1, AD7616_RD_GPIO_Port1, AD7616_CS_GPIO_Port1, // AD7616_BUSY_GPIO_Port1, AD7616_D4_GPIO_Port1, AD7616_D11_GPIO_Port1, AD7616_D12_GPIO_Port1, // AD7616_D10_GPIO_Port1, }; /* Dx引脚 */ const u16 PIN_LIST[18] = { AD7616_CONV_Pin0, AD7616_RST_Pin0, AD7616_RD_Pin0, AD7616_CS_Pin0, AD7616_BUSY_Pin0, AD7616_D4_Pin0, AD7616_D11_Pin0, AD7616_D12_Pin0, AD7616_D10_Pin0, // AD7616_CONV_Pin1, AD7616_RST_Pin1, AD7616_RD_Pin1, AD7616_CS_Pin1, // AD7616_BUSY_Pin1, AD7616_D4_Pin1, AD7616_D11_Pin1, AD7616_D12_Pin1, // AD7616_D10_Pin1, }; /** * @brief AD7616端口初始化 * @param mode uint8_t 模式选择 */ void AD7616_GPIO_Init(void) { u8 i; GPIO_InitTypeDef GPIO_InitStruct = {0}; /* 端口时钟使能 */ RCC->AHB4ENR |= RCC_GPIO_Port; for(i = 0; i < sizeof(PIN_LIST) / sizeof(u16); i++) { GPIO_InitStruct.Pin = PIN_LIST; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; GPIO_InitStruct.Pull = GPIO_NOPULL; if(((PIN_LIST==AD7616_D11_Pin0) (PORT_LIST==AD7616_D11_GPIO_Port0))|| ((PIN_LIST==AD7616_D12_Pin0) (PORT_LIST==AD7616_D12_GPIO_Port0))|| ((PIN_LIST==AD7616_BUSY_Pin0) (PORT_LIST==AD7616_BUSY_GPIO_Port0))|| ((PIN_LIST==AD7616_D11_Pin1) (PORT_LIST==AD7616_D11_GPIO_Port1))|| ((PIN_LIST==AD7616_D12_Pin1) (PORT_LIST==AD7616_D12_GPIO_Port1))|| ((PIN_LIST==AD7616_BUSY_Pin1) (PORT_LIST==AD7616_BUSY_GPIO_Port1))) { GPIO_InitStruct.Mode = GPIO_MODE_INPUT; //浮空输入模式 } else { GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; } HAL_GPIO_Init((GPIO_TypeDef*)PORT_LIST, GPIO_InitStruct); //初始化GPIO HAL_GPIO_WritePin((GPIO_TypeDef*)PORT_LIST, PIN_LIST, GPIO_PIN_RESET); } HAL_GPIO_WritePin(AD7616_CS_GPIO_Port0, AD7616_CS_Pin0, GPIO_PIN_SET); // HAL_GPIO_WritePin(AD7616_CS_GPIO_Port1, AD7616_CS_Pin1, GPIO_PIN_SET); HAL_GPIO_WritePin(AD7616_RD_GPIO_Port0, AD7616_RD_Pin0, GPIO_PIN_SET); // HAL_GPIO_WritePin(AD7616_RD_GPIO_Port1, AD7616_RD_Pin1, GPIO_PIN_SET); } /** * @brief 向AD7616写入16位数据 串行软件模式下有效 * @param data uint16_t 数据 */ static void AD7616_Write_Serial_Word(uint16_t data) { u16 i; u16 shift = 0x8000; for(i = 0; i < 16; i++) { bool level = shift data; if(level) { AD7616_D10_GPIO_Port0->BSRRL = AD7616_D10_Pin0; } else { AD7616_D10_GPIO_Port0->BSRRH = AD7616_D10_Pin0; } shift >>= 1; AD7616_RD_GPIO_Port0->BSRRH = AD7616_RD_Pin0; AD7616_RD_GPIO_Port0->BSRRL = AD7616_RD_Pin0; } } /** * @brief 写寄存器 * @param address uint8_t 寄存器地址 * @param data uint8_t 数据 */ static void AD7616_Write_Register(uint8_t address, uint8_t data) { u16 wrtie_data = 0; u16 shift = 0x8000; u16 i; /* 选择写命令,必须将位D15设为1 */ wrtie_data = (((uint16_t)address << 9) | 0x8000) | (u16)data; AD7616_CS_GPIO_Port0->BSRRH = AD7616_CS_Pin0 ; for(i = 0; i < 16; i++) { bool level = shift wrtie_data; if(level) { AD7616_D10_GPIO_Port0->BSRRL = AD7616_D10_Pin0; } else { AD7616_D10_GPIO_Port0->BSRRH = AD7616_D10_Pin0; } shift >>= 1; AD7616_RD_GPIO_Port0->BSRRH = AD7616_RD_Pin0; AD7616_RD_GPIO_Port0->BSRRL = AD7616_RD_Pin0; } AD7616_CS_GPIO_Port0->BSRRL = AD7616_CS_Pin0 ; } /** * @brief 配置AD7616量程 * @param range uint8_t 量程 */ static void AD7616_Set_Range(uint8_t range) { u8 range_data = 0; ad7616_range = range; range_data = (range << 6) | (range << 4) | (range << 2) | range; AD7616_Write_Register(Input_Range_Register_A1, range_data); AD7616_Write_Register(Input_Range_Register_A2, range_data); AD7616_Write_Register(Input_Range_Register_B1, range_data); AD7616_Write_Register(Input_Range_Register_B2, range_data); } static void AD7616_Write(u16 u16data) { u8 i; u16 shift = 0x8000; AD7616_CS_GPIO_Port0->BSRRH = AD7616_CS_Pin0 ; for(i = 0; i < 16; i++) { bool level = shift u16data; if(level) { AD7616_D10_GPIO_Port0->BSRRL = AD7616_D10_Pin0; } else { AD7616_D10_GPIO_Port0->BSRRH = AD7616_D10_Pin0; } shift >>= 1; AD7616_RD_GPIO_Port0->BSRRH = AD7616_RD_Pin0; AD7616_RD_GPIO_Port0->BSRRL = AD7616_RD_Pin0; } AD7616_CS_GPIO_Port0->BSRRL = AD7616_CS_Pin0 ; } //序列器 static void AD7616_Sequencer(void) { // AD7616_Write(0xC000); // AD7616_Write(0xC211); // AD7616_Write(0xC522); // AD7616_Write(0x0000); u8 i; u16 wrtie_data; u16 shift = 0x8000; for(i = 0; i < 32; i++) { AD7616_Write_Register(0x20+i,CH_DATA[i%8]); } /* 选择写命令,必须将位D15设为1 */ wrtie_data = (((uint16_t)0x20 << 9) | 0x8000) | (u16)0x00 | 0x100; AD7616_CS_GPIO_Port0->BSRRH = AD7616_CS_Pin0 ; for(i = 0; i < 16; i++) { bool level = shift wrtie_data; if(level) { AD7616_D10_GPIO_Port0->BSRRL = AD7616_D10_Pin0; } else { AD7616_D10_GPIO_Port0->BSRRH = AD7616_D10_Pin0; } shift >>= 1; AD7616_RD_GPIO_Port0->BSRRH = AD7616_RD_Pin0; AD7616_RD_GPIO_Port0->BSRRL = AD7616_RD_Pin0; } AD7616_CS_GPIO_Port0->BSRRL = AD7616_CS_Pin0 ; } /** * @brief 设置AD7616串行输出模式 * @param format uint8_t 格式 */ void AD7616_Set_Serial_Output_Format(uint8_t format) { if(format == Line_1_Output) { HAL_GPIO_WritePin(AD7616_D4_GPIO_Port0, AD7616_D4_Pin0, GPIO_PIN_RESET); } else if(format == Line_2_Output) { HAL_GPIO_WritePin(AD7616_D4_GPIO_Port0, AD7616_D4_Pin0, GPIO_PIN_SET); } } /** * @brief AD7616复位 */ void AD7616_Reset(void) { AD7616_RST_GPIO_Port0->BSRRH = AD7616_RST_Pin0 ; AD7616_RST_GPIO_Port1->BSRRH = AD7616_RST_Pin1 ; delay_ms(1); AD7616_RST_GPIO_Port0->BSRRL = AD7616_RST_Pin0 ; AD7616_RST_GPIO_Port1->BSRRL = AD7616_RST_Pin1 ; delay_ms(10); } /** * @brief 启动AD7616转换 */ void AD7616_Conversion(void) { u8 i = 0; AD7616_CONV_GPIO_Port0->BSRRH = AD7616_CONV_Pin0; // delay_us(1); AD7616_CONV_GPIO_Port0->BSRRL = AD7616_CONV_Pin0; } /** * @brief 获取AD7616串行通道数据 * @return uint16_t 通道数据 */ static void AD7616_Get_Serial_Data(uint16_t *data) { u8 i,j; u16 shift = 0x8000; GPIO_PinState state = GPIO_PIN_RESET; for(i = 0; i < 32*2; i += 2) { shift = 0x8000; for(j = 0; j< 16; j++) { AD7616_RD_GPIO_Port0->BSRRH = AD7616_RD_Pin0; state = HAL_GPIO_ReadPin(AD7616_D12_GPIO_Port0, AD7616_D12_Pin0); //读取DB12引脚 if(state == GPIO_PIN_SET) { data |= shift; } else if(state == GPIO_PIN_RESET) { data = (~shift); } state = HAL_GPIO_ReadPin(AD7616_D11_GPIO_Port0, AD7616_D11_Pin0); //读取DB11引脚 if(state == GPIO_PIN_SET) { data[i+1] |= shift; } else if(state == GPIO_PIN_RESET) { data[i+1] = (~shift); } shift >>= 1; AD7616_RD_GPIO_Port0->BSRRL = AD7616_RD_Pin0; } delay_us(1); } } /** * @brief 获取AD7616单次采集数据 * @param data uint16_t 数组指针 */ void AD7616_Read_Data(u16 *u16data) { u16 i = 0, j = 0; u16 shift = 0x8000; GPIO_PinState busy = GPIO_PIN_SET; GPIO_PinState state[2] = {GPIO_PIN_RESET}; do { busy = AD7616_BUSY_GPIO_Port0->IDR AD7616_BUSY_Pin0; } while(busy); AD7616_Write(0x0000); AD7616_CS_GPIO_Port0->BSRRH = AD7616_CS_Pin0; delay_us(1); for(i = 0; i < 32*2; i+=2) { shift = 0x8000; for(j = 0; j < 16; j++) { AD7616_RD_GPIO_Port0->BSRRH = AD7616_RD_Pin0; state[0] = HAL_GPIO_ReadPin(AD7616_D12_GPIO_Port0, AD7616_D12_Pin0); //读取DB12引脚 state[1] = HAL_GPIO_ReadPin(AD7616_D11_GPIO_Port0, AD7616_D11_Pin0); //读取DB11引脚 if(state[0] == GPIO_PIN_SET) { u16data |= shift; } else { u16data = (~shift); } if(state[1] == GPIO_PIN_SET) { u16data[i+1] |= shift; } else { u16data[i+1] = (~shift); } shift >>= 1; AD7616_RD_GPIO_Port0->BSRRL = AD7616_RD_Pin0; } delay_us(1); } AD7616_CS_GPIO_Port0->BSRRL = AD7616_CS_Pin0; } void AD7616_Init(uint8_t format, uint8_t range) { AD7616_GPIO_Init(); AD7616_Set_Range(range); //量程 AD7616_Sequencer(); //序列器 AD7616_Write_Register(Config_Register, 0x64); //配置寄存器 // AD7616_Write(0x8464); AD7616_Reset(); //复位 AD7616_Set_Serial_Output_Format(format); //2个串口 AD7616_Conversion(); } /** * @brief 将数字量转换为电压量 * @param data uint16_t 数字量 * @return double 电压量 单位毫伏(mv) */ double AD7616_Digital2Voltage(uint16_t data) { int16_t signed_data = data; switch (ad7616_range) { case Range_2_5_V: return signed_data * 5.0 / 65536.0 * 1000.0; case Range_5_V: return signed_data * 10.0 / 65536.0 * 1000.0; case Range_10_V: return signed_data * 20.0 / 65536.0 * 1000.0; } return 0; } |
|
相关推荐
1个回答
|
|
要使用STM32单片机的普通I/O口模拟SPI通讯,并与AD7616串行突发序列器进行通信,您需要遵循以下步骤:
1. 硬件连接: - 将STM32单片机的I/O口连接到AD7616的SPI接口。通常需要连接以下引脚:SCLK(时钟线)、CS(片选线)、DIN(数据输入线)和DOUT(数据输出线)。 2. 初始化SPI接口: - 在STM32单片机上配置I/O口为SPI模式。这通常涉及到设置GPIO模式、速度和上拉/下拉电阻。 3. 编写SPI通信函数: - 编写一个函数来发送和接收SPI数据。这个函数将负责生成SCLK时钟信号,控制CS信号,并在DIN和DOUT线上传输数据。 4. 发送命令: - 根据AD7616的数据手册,编写一个函数来发送命令。命令通常包括操作码、通道选择和转换速率等信息。 5. 读取结果: - 在发送命令后,您需要等待AD7616完成转换。这可以通过检查DOUT线上的数据就绪信号或使用其他方法实现。 - 当转换完成后,使用SPI通信函数从DOUT线上读取数据。AD7616的数据格式可能是16位或24位,具体取决于您的配置。 6. 数据处理: - 将从DOUT线上读取的数据转换为实际的模拟值。这通常涉及到对数据进行缩放和偏移校正。 以下是一个简化的示例代码,展示了如何使用STM32单片机的I/O口模拟SPI通讯: ```c #include "stm32f1xx_hal.h" #define SPI_SCLK_PIN GPIO_PIN_0 #define SPI_CS_PIN GPIO_PIN_1 #define SPI_DIN_PIN GPIO_PIN_2 #define SPI_DOUT_PIN GPIO_PIN_3 void SPI_Init(void) { // 初始化GPIO和SPI接口 } void SPI_SendByte(uint8_t data) { // 发送一个字节的数据 } uint8_t SPI_ReceiveByte(void) { // 接收一个字节的数据 } void AD7616_SendCommand(uint16_t command) { // 发送AD7616命令 HAL_Delay(1); // 等待命令完成 } uint32_t AD7616_ReadData(void) { // 读取AD7616数据 uint32_t data = SPI_ReceiveByte(); return data; } int main(void) { HAL_Init(); SPI_Init(); uint16_t command = 0x0003; // 示例命令 AD7616_SendCommand(command); uint32_t data = AD7616_ReadData(); // 处理数据 // ... while (1) { // ... } } ``` 请注意,这只是一个示例,您需要根据您的具体硬件和需求进行调整。同时,确保参考AD7616的数据手册以获取正确的命令格式和数据解析方法。 |
|
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
773 浏览 1 评论
762 浏览 0 评论
488 浏览 0 评论
1683 浏览 1 评论
MCU用3.3V通过三极管和mos控制12V通断导致不能即使开断
1295 浏览 5 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-8-16 02:34 , Processed in 0.443389 second(s), Total 42, Slave 35 queries .
Powered by 电子发烧友网
© 2015 www.ws-dc.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号