Mbed OS STM32F429 中断方式接收 ADS1256

22 篇文章 6 订阅

       经过半个月的测试,希望能够通过 TIM 捕获 DRDY 信号,启动DMA 传送ADS1256 的数据,但是始终没有成功,最后采取了折中的方式,TIM 捕获DRDY 信号,产生中断,在中断程序中读取3个字节数据。通过UDP 传送到PC 机的python 做显示。

应为调试的很辛苦,所以要分享给大家。

  1. Mbed OS 项目为 ADS1256INT2020
  2. 数据采样频率为 30KHz
  3. 数据速率=30KHz*24bit=720bps
  4. 这样的速率STM32 完全应付的来。在网络上测试也就是720 K 多一点。(因为有网络的额外开销)
/* TI Ads1256 Inerrupt Mode test
 
 ADS1256 sample rate 15Ksps
 TIM red frequncy 7.5KHz
 green frequncy 15.625Hz
*/
#include "mbed.h"
#include "EthernetInterface.h"
#include "stm32f4xx_ll_tim.h"
#define RDATA 0x01
#define RDATAC 0x03
#define SDATAC 0x0F
#define SELFCAL 0xF0
#define SELFOCAL 0xF1
#define SELFGCAL 0xF2
#define SYSOCAL 0xF3
#define SYSGCAL 0xF4
#define SYNC 0xFC
#define ATANDBY 0xFD
#define RESET  0xFE
#define WAKEUP 0xFF
static const char*          mbedIp       = "192.168.31.110";  //IP
static const char*          mbedMask     = "255.255.255.0";  // Mask
static const char*          mbedGateway  = "192.168.31.1";    //Gateway
#define SERVER_PORT   2019
#define SERVER_ADDR "192.168.31.99"
#define UDP_PORT    2018
EthernetInterface eth;
UDPSocket udpsocket;
DigitalOut green_led(PC_6);
DigitalOut red_led(PC_7);
DigitalOut _rst(PB_5);
DigitalOut _sync(PE_5);
SPI _spi(PF_9,PF_8,PF_7);
DigitalOut  _cs(PF_6); 
DigitalIn _drdy(PA_6);
 
TIM_HandleTypeDef htim3={0};
SPI_HandleTypeDef hspi5;
#define SAMPLES 240
#define HALF SAMPLES*3
#define MAX SAMPLES*3*2
uint8_t DataBuffer[MAX];
uint8_t ads1256_txbuf[8];
uint8_t ads1256_rxbuf[8];
int index;
bool  halfFlg,fullFlg;
uint32_t ReadData();
    uint32_t ReadDataContinuous(uint32_t * buffer,int samples);
    void WriteControl(uint8_t ctrl);
    void write_reg(uint8_t command,uint8_t data);
    uint8_t read_reg(uint8_t command);
    void SetPGAgain(uint8_t gain);
    void SlectChannel(uint8_t ainp,uint8_t ainn);
 void Error_Handler(void)
{
 printf("HAL error\n");
}
extern "C" void TIM3_IRQHandler(void) {
 
  red_led=!red_led;
  
 DataBuffer[index++]=_spi.write(0x00);
   DataBuffer[index++]=_spi.write(0x00);
    DataBuffer[index++]=_spi.write(0x00);
  if (index==HALF) halfFlg=true;
  if (index==MAX) {
      index=0;
      fullFlg=true;
      }
  HAL_TIM_IRQHandler(&htim3);
}
 
void TIM_Init(void){
       GPIO_InitTypeDef GPIO_InitStruct = {0};
      /* Peripheral clock enable */
    __HAL_RCC_TIM3_CLK_ENABLE();
  
   // __HAL_RCC_GPIOC_CLK_ENABLE();
      __HAL_RCC_GPIOA_CLK_ENABLE();
    /**TIM3 GPIO Configuration    
    PA6     ------> TIM3_CH1 
    */
    GPIO_InitStruct.Pin = GPIO_PIN_6;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    GPIO_InitStruct.Alternate = GPIO_AF2_TIM3;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
    
   TIM_SlaveConfigTypeDef sSlaveConfig = {0};
   TIM_MasterConfigTypeDef sMasterConfig = {0};
  TIM_IC_InitTypeDef sConfigIC = {0};
  /* USER CODE BEGIN TIM3_Init 1 */

  /* USER CODE END TIM3_Init 1 */
  htim3.Instance = TIM3;
  htim3.Init.Prescaler = 0;
  htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim3.Init.Period =0xffff;
  htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim3.Init.RepetitionCounter = 0;
   if (HAL_TIM_IC_Init(&htim3) != HAL_OK)
  {
    Error_Handler();
  }
  
   LL_TIM_EnableARRPreload(TIM3);
   LL_TIM_SetAutoReload(TIM3,0xffff);
  sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_FALLING;
  sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI;
  sConfigIC.ICPrescaler = TIM_ICPSC_DIV1;
  sConfigIC.ICFilter = 0;
  if (HAL_TIM_IC_ConfigChannel(&htim3, &sConfigIC, TIM_CHANNEL_1) != HAL_OK)
  {
    Error_Handler();
  }
   sSlaveConfig.SlaveMode = TIM_SLAVEMODE_TRIGGER;
  sSlaveConfig.InputTrigger = TIM_TS_ITR0;
  if (HAL_TIM_SlaveConfigSynchronization(&htim3, &sSlaveConfig) != HAL_OK)
  {
    Error_Handler();
  }
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE;//TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_ENABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK)
  {
    Error_Handler();
  }  
  HAL_NVIC_SetPriority(TIM3_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(TIM3_IRQn);
    };
   
    
uint32_t  ReadData()
{
    uint32_t value1,value2,value3;
      WriteControl(RDATA);
      wait_us(20);
    while(_drdy);
    value1=_spi.write(0xff);
    value2= _spi.write(0xff);
    value3= _spi.write(0xff);
    return (value1<<16) | (value2<<8) | value3; 
}
void  write_reg(uint8_t command,uint8_t data)
{
 
    while(_drdy);
    _spi.write(command | 0x50);
    _spi.write(0x00);
    _spi.write(data);
 
}
uint8_t  read_reg(uint8_t command)
{
     uint8_t v;
    while(_drdy);
    _spi.write(command | 0x10);
    _spi.write(0x00);//length
    wait_us(1);
    v=_spi.write(0xff);
    return v;
}
uint32_t  ReadDataContinuous(uint32_t * buffer,int samples)
{  int i;
   uint32_t value;
    while(_drdy);
    WriteControl(RDATAC);
    for (i=0;i<samples;i++)
      { 
        while(_drdy);
        value=_spi.write(0xff);
        value= (value<<8)+_spi.write(0xff);
        value= (value<<8)+_spi.write(0xff);
        buffer[i]=value;
      }
      return samples;
    }
void  WriteControl(uint8_t ctrl)
{
        while(_drdy);
      _spi.write(ctrl);
}

void  init()
{ _cs=1;
    _sync=1;
    _rst=0;
     wait_ms(1);
    _rst=1;
    _cs=0;
    write_reg(0x00,0x04);//status
    wait_us(1);
    write_reg(0x01,0x1);//MUX
    wait_us(1);
    write_reg(0x02,0x20);//ADCON PAG=1
    wait_us(1);
    write_reg(0x03,0xf0);// A/D Data Rate
    wait_us(1);
    write_reg(0x04,0x00);// GPIO Control Register
    wait_us(1);
    while(_drdy);
    WriteControl(SELFCAL);
    wait_us(5);
    WriteControl(SYNC);
  wait_ms(20);
    WriteControl(WAKEUP);
    wait_us(5);
 
}
void  SetPGAgain(uint8_t gain)
{
    write_reg(0x02,gain);
}
void  SlectChannel(uint8_t ainp,uint8_t ainn)
{
     write_reg(0x01,(ainp<<4) | ainn );
     write_reg(0x03,0x72);
    }
bool   SensorDetected() 
{
    //not implement
    return true;
    }
    
int main() {
    printf("ADS_1256 DAQ testing\n");
    
    eth.set_network(mbedIp,mbedMask,mbedGateway);
     eth.connect();
    printf("\nConnected  IP Address : %s\n", eth.get_ip_address());
     udpsocket.open(&eth);
     udpsocket.bind(eth.get_ip_address(),UDP_PORT);
    // SPI_Init();
      _spi.format(8,1);
    _spi.frequency(4000000);
      init();
    printf("ADS1256 ChipID=%d\n",read_reg(00));
    printf("rate=%2x\n", read_reg(0x03));
   
    
 
    index=0;
    halfFlg=false;
    fullFlg=false; 
         
     TIM_Init();
     HAL_TIM_IC_Start_IT(&htim3,TIM_CHANNEL_1);
     WriteControl(RDATAC);
    while (true) {
        if (halfFlg){
            halfFlg=false;
            udpsocket.sendto(SERVER_ADDR,SERVER_PORT, &DataBuffer[0], HALF);
            }
            if (fullFlg){
              fullFlg=false;
              udpsocket.sendto(SERVER_ADDR,SERVER_PORT, &DataBuffer[HALF], HALF);
        green_led =!green_led;
        }
       
    }
}

   Python 接收程序(ADS1256UDP.PY)

import socket
import numpy as np
from matplotlib import pyplot as plt
def bytesToInt(h1,h2,h3):
    ba = bytearray()
    ba.append(h1)
    ba.append(h2)
    ba.append(h3)

    return int.from_bytes(ba, byteorder='big')

HOST = '192.168.31.99'
PORT = 2019
BUFSIZ = 240*3
ADDR = (HOST,PORT)
udpSerSock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
udpSerSock.bind(ADDR)
t = np.linspace(0, 239, 240, True)
x =[]
y1 =[]
for i in range(240):
    x.append(i)
    y1.append(0) 
plt.ion() 
while True:
    data, addr = udpSerSock.recvfrom(BUFSIZ)
    
    for i in range(240):
         value= (bytesToInt(data[i*3+0],data[i*3+1],data[i*3+2])/8388607)*5-7.5
         y1[i]=value
    
    plt.title("ADS1256")
    plt.ylim([-2.5,2.5])       
    plt.plot(t,y1) 
    plt.pause(0.001)
    plt.clf() 

 

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
STM32单片机(STM32F429)读写(8通道带PGA的24位ADC)ADS1256软件例程源码,可以做为你的学习设计参考。 int main(void) { uint8_t i; bsp_Init(); PrintfLogo(); /* 打印例程Logo到串口1 */ bsp_DelayMS(100); /* 等待上电稳定,等基准电压电路稳定, bsp_InitADS1256() 内部会进行自校准 */ bsp_InitADS1256(); /* 初始化配置ADS1256. PGA=1, DRATE=30KSPS, BUFEN=1, 输入正负5V */ /* 打印芯片ID (通过读ID可以判断硬件接口是否正常) , 正常时状态寄存器的高4bit = 3 */ #if 0 { uint8_t id; id = ADS1256_ReadChipID(); if (id != 3) { printf("Error, ASD1256 Chip ID = 0x%X\r\n", id); } else { printf("Ok, ASD1256 Chip ID = 0x%X\r\n", id); } } #endif ADS1256_CfgADC(ADS1256_GAIN_1, ADS1256_30SPS); /* 配置ADC参数: 增益1:1, 数据输出速率 1KHz */ ADS1256_StartScan(); /* 启动中断扫描模式, 轮流采集8个通道的ADC数据. 通过 ADS1256_GetAdc() 函数来读取这些数据 */ while (1) { bsp_Idle(); /* 空闲时执行的函数,比如喂狗. 在bsp.c中 */ /* 打印采集数据 */ for (i = 0; i < 8; i++) { int32_t iTemp; iTemp = ((int64_t)g_tADS1256.AdcNow[i] * 2500000) / 4194303; /* 计算实际电压值(近似估算的),如需准确,请进行校准 */ if (iTemp < 0) { iTemp = -iTemp; printf("%d=%6d,(-%d.%03d %03d V) ", i, g_tADS1256.AdcNow[i], iTemp /1000000, (iTemp%1000000)/1000, iTemp%1000); } else { printf("%d=%6d,( %d.%03d %03d V) ", i, g_tADS1256.AdcNow[i], iTemp/1000000, (iTemp%1000000)/1000, iTemp%1000); } } printf("\r\n"); bsp_DelayMS(500); /* 每隔500ms 输出一次数据 */ } }
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值