通過cubeMX配置STM32RCT6的IO口與ads1256ADC模塊的連接IO口工作模式SPI,還有接受中斷接受狀態引腳,最終ADC采集數據經過卡爾曼濾波器濾波輸出,詳情請見附件
單片機源程序如下:
- #include "ads1256.h"
- int32_t adcVaule = 0x00;
- float voltage = 0x00;
- float filterVoltage = 0.0;
- float filterVoltage2 = 0.0;
- void delayXus(uint16_t us) {
- uint16_t diff = 0xffff - 5 - us;
- //設置定時器的計數值
- __HAL_TIM_SET_COUNTER(&htim6, diff);
- //啟動定時器計數
- HAL_TIM_Base_Start(&htim6);
- //判定計數結束
- while(diff < 0xffff - 5) {
- diff = __HAL_TIM_GET_COUNTER(&htim6);
- }
- //延時完成關閉定時器計數
- HAL_TIM_Base_Stop(&htim6);
- }
- /*
- * 功 能:實現SPI協議總線發送一個字節的數據信息
- * 參 數:待發送的數據信息
- * 返回值:無
- */
- void spiWriteByte(uint8_t txData) {
- uint8_t tempData = 0x00;
- HAL_SPI_TransmitReceive(&hspi1, &txData, &tempData, 1, 100);
- }
- /*
- * 功 能:實現SPI協議總監接受一個字節的數據信息
- * 參 數:無
- * 返回值:接受到的數據信息
- */
- uint8_t spiReadByte(void) {
- uint8_t tempDataT = 0xff;
- uint8_t tempData = 0x00;
- HAL_SPI_TransmitReceive(&hspi1, &tempDataT, &tempData, 1, 100);
- return tempData;
- }
- /*
- * 功 能:向ads1256寄存器中寫入一個字節的數據
- * 參 數:regAdd寄存器地址 regData待寫入的數據信息
- * 返回值:無
- */
- void spiWriteRegData(uint8_t regAdd, uint8_t regData) {
- //拉低SPI協議的CS引腳
- HAL_GPIO_WritePin(GPIOC, GPIO_PIN_5, GPIO_PIN_RESET);
- //等待RDY的引腳變低
- while(HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_4));
- //寫入寄存地地址
- spiWriteByte(WREG | (regAdd & 0x0F));
- //寫入即將寫入數據的個數
- spiWriteByte(0x00);
- //寫入數據信息
- spiWriteByte(regData);
- //拉高SPI協議的CS引腳
- HAL_GPIO_WritePin(GPIOC, GPIO_PIN_5, GPIO_PIN_SET);
- }
- /*
- * 功 能:初始化ads1256
- * 參 數:無
- * 返回值:無
- */
- void ads1256Init(void) {
- disableInterrupt();
- while(HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_4));
- //開啟芯片的自校準
- HAL_GPIO_WritePin(GPIOC, GPIO_PIN_5, GPIO_PIN_RESET);
- spiWriteByte(SELFCAL);
- while(HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_4));
- HAL_GPIO_WritePin(GPIOC, GPIO_PIN_5, GPIO_PIN_SET);
- //設置ads1256的狀態寄存器
- spiWriteRegData(STATUS, 0x06); //數據發送高位在前 自動校準 啟用buf
- spiWriteRegData(MUX, MUXP_AIN0 | MUXN_AIN1); //單端模式
- //設置ads1256的增益
- spiWriteRegData(ADCON, GAIN_1);
- //設置ads采樣速率
- spiWriteRegData(DRATE, RATE_30000);
- //設置IO狀態
- spiWriteRegData(IO, 0x00);
- //再次進行校準
- while(HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_4));
- //開啟芯片的自校準
- HAL_GPIO_WritePin(GPIOC, GPIO_PIN_5, GPIO_PIN_RESET);
- spiWriteByte(SELFCAL);
- HAL_GPIO_WritePin(GPIOC, GPIO_PIN_5, GPIO_PIN_SET);
- enableInterrupt();
- }
- /*
- * 功 能:從ads1256中讀取出相關數據信息
- * 參 數:下一次轉換通道
- * 返回值:讀取到的數據信息
- */
- int32_t ads1256ReadValue(uint8_t channel) {
- int32_t sum = 0;
- //等待準備好信號變低
- while(HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_4));
- //設置下次轉換的通道
- spiWriteRegData(MUX, channel);
- HAL_GPIO_WritePin(GPIOC, GPIO_PIN_5, GPIO_PIN_RESET);
- spiWriteByte(SYNC); //發送同步命令
- delayXus(5);
- spiWriteByte(WAKEUP); //發送喚醒命令
- delayXus(5); //延時一下
- spiWriteByte(RDATA); //發送讀數據命令
- delayXus(25);
- sum |= (spiReadByte() << 16);
- sum |= (spiReadByte() << 8);
- sum |= (spiReadByte());
- HAL_GPIO_WritePin(GPIOC, GPIO_PIN_5, GPIO_PIN_SET);
- if(sum > 0x7fffff)
- sum -= 0x1000000;
- adcVaule = sum;
- voltage = (float)(adcVaule * 5.0 / 8388607); //計算電壓
- printf("ADC采集數據:%0x,%f\n", adcVaule, voltage);
- HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_4);
- return sum;
- }
- /*
- * 功 能:實現ads的增益設置
- */
- void setGain(uint8_t gain) {
- disableInterrupt();
- while(HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_4));
- HAL_GPIO_WritePin(GPIOC, GPIO_PIN_5, GPIO_PIN_RESET);
- switch(gain) {
- case 0:
- spiWriteRegData(ADCON, GAIN_1);
- break;
- case 1:
- spiWriteRegData(ADCON, GAIN_2);
- break;
- default:
- break;
- }
- HAL_GPIO_WritePin(GPIOC, GPIO_PIN_5, GPIO_PIN_SET);
- enableInterrupt();
- }
- /*
- * 功 能:設置ads1256的采集速率
- */
- void setRate(uint8_t rate) {
- disableInterrupt();
- while(HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_4));
- HAL_GPIO_WritePin(GPIOC, GPIO_PIN_5, GPIO_PIN_RESET);
- switch(rate) {
- case 0:
- spiWriteRegData(DRATE, RATE_2_5);
- break;
- case 1:
- spiWriteRegData(DRATE, RATE_10);
- break;
- default:
- break;
- }
- HAL_GPIO_WritePin(GPIOC, GPIO_PIN_5, GPIO_PIN_SET);
- enableInterrupt();
- }
- /*
- * 功 能:實現屏蔽所有中斷函數
- */
- void disableInterrupt(void) {
- __set_PRIMASK(1);
- }
- /*
- * 功 能:開啟全局中斷
- */
- void enableInterrupt(void) {
- __set_PRIMASK(0);
- }
- /*
- * 功 能:實現外部中斷回調函數
- */
- void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) {
- int32_t sum = 0x00;
- disableInterrupt();
- if((GPIO_Pin == GPIO_PIN_4) && (HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_4) == GPIO_PIN_RESET)) {
- //設置下次轉換的通道
- spiWriteRegData(MUX, MUXP_AIN0 | MUXN_AINCOM);
- HAL_GPIO_WritePin(GPIOC, GPIO_PIN_5, GPIO_PIN_RESET);
- spiWriteByte(SYNC); //發送同步命令
- delayXus(5);
- spiWriteByte(WAKEUP); //發送喚醒命令
- delayXus(5); //延時一下
- spiWriteByte(RDATA); //發送讀數據命令
- delayXus(25);
- sum |= (spiReadByte() << 16);
- sum |= (spiReadByte() << 8);
- sum |= (spiReadByte());
- HAL_GPIO_WritePin(GPIOC, GPIO_PIN_5, GPIO_PIN_SET);
- if(sum > 0x7fffff)
- sum -= 0x1000000;
- adcVaule = sum;
- HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_4);
- }
- enableInterrupt();
- }
- float filterlowerpass(float adc) {
- //y(n) = qX(n)+(1-q)Y(n-1)
- float filterVaule = 0;
- static float adcold = 0;
- filterVaule = 0.5 * adc + 0.5 * adcold;
- adcold = adc;
- return filterVaule;
- }
- float kalman_filter(float ADC_Value) {
- float x_k1_k1, x_k_k1;
- static float ADC_OLD_Value;
- float Z_k;
- static float P_k1_k1;
- static float Q = 0.0001;
- static float R = 5;
- static float Kg = 0;
- static float P_k_k1 = 1;
- float kalman_adc;
- static float kalman_adc_old = 0;
- Z_k = ADC_Value;
- if (abs(kalman_adc_old - ADC_Value) >= 10) {
- x_k1_k1 = ADC_Value * 0.382 + kalman_adc_old * 0.618;
- } else {
- x_k1_k1 = kalman_adc_old;
- }
- x_k_k1 = x_k1_k1;
- P_k_k1 = P_k1_k1 + Q;
- Kg = P_k_k1 / (P_k_k1 + R);
- kalman_adc = x_k_k1 + Kg * (Z_k - kalman_adc_old);
- P_k1_k1 = (1 - Kg) * P_k_k1;
- P_k_k1 = P_k1_k1;
- ADC_OLD_Value = ADC_Value;
- kalman_adc_old = kalman_adc;
- return kalman_adc;
- }
復制代碼- /* Includes ------------------------------------------------------------------*/
- #include "main.h"
- #include "spi.h"
- #include "tim.h"
- #include "usart.h"
- #include "gpio.h"
- /* Private includes ----------------------------------------------------------*/
- /* USER CODE BEGIN Includes */
- #include "ads1256.h"
- /* USER CODE END Includes */
- /* Private typedef -----------------------------------------------------------*/
- /* USER CODE BEGIN PTD */
- /* USER CODE END PTD */
- /* Private define ------------------------------------------------------------*/
- /* USER CODE BEGIN PD */
- /* USER CODE END PD */
- /* Private macro -------------------------------------------------------------*/
- /* USER CODE BEGIN PM */
- /* USER CODE END PM */
- /* Private variables ---------------------------------------------------------*/
- /* USER CODE BEGIN PV */
- /* USER CODE END PV */
- /* Private function prototypes -----------------------------------------------*/
- void SystemClock_Config(void);
- /* USER CODE BEGIN PFP */
- /* USER CODE END PFP */
- /* Private user code ---------------------------------------------------------*/
- /* USER CODE BEGIN 0 */
- /* USER CODE END 0 */
- /**
- * @brief The application entry point.
- * @retval int
- */
- int main(void) {
- /* USER CODE BEGIN 1 */
- /* USER CODE END 1 */
- /* MCU Configuration--------------------------------------------------------*/
- /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
- HAL_Init();
- /* USER CODE BEGIN Init */
- /* USER CODE END Init */
- /* Configure the system clock */
- SystemClock_Config();
- /* USER CODE BEGIN SysInit */
- /* USER CODE END SysInit */
- /* Initialize all configured peripherals */
- MX_GPIO_Init();
- MX_TIM6_Init();
- MX_SPI1_Init();
- MX_USART1_UART_Init();
- /* USER CODE BEGIN 2 */
- ads1256Init();
- /* USER CODE END 2 */
- /* Infinite loop */
- /* USER CODE BEGIN WHILE */
- while (1) {
- /* USER CODE END WHILE */
- /* USER CODE BEGIN 3 */
- voltage = (float)(adcVaule * 5.0 / 8388607); //計算電壓
- //filterVoltage = filterlowerpass(voltage); //低通濾波
- filterVoltage2 = kalman_filter(voltage); //卡爾瑪濾波
- //printf("voltage:%f\n\t", voltage);
- //printf("filterVoltage:%f\n\t", filterVoltage2);
- //HAL_Delay(5);
- }
- /* USER CODE END 3 */
- }
- /**
- * @brief System Clock Configuration
- * @retval None
- */
- void SystemClock_Config(void) {
- RCC_OscInitTypeDef RCC_OscInitStruct = {0};
- RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
- /** Initializes the CPU, AHB and APB busses clocks
- */
- RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
- RCC_OscInitStruct.HSEState = RCC_HSE_ON;
- RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
- RCC_OscInitStruct.HSIState = RCC_HSI_ON;
- RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
- RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
- RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
- if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
- Error_Handler();
- }
- /** Initializes the CPU, AHB and APB busses clocks
- */
- RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK
- | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
- RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
- RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
- RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
- RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
- if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK) {
- Error_Handler();
- }
- }
- /* USER CODE BEGIN 4 */
- int fputc(int ch, FILE *f) {
- HAL_UART_Transmit(&huart1, (uint8_t*)&ch, 1, 100);
- return ch;
- }
- /* USER CODE END 4 */
- /**
- * @brief This function is executed in case of error occurrence.
- * @retval None
- */
- void Error_Handler(void) {
- /* USER CODE BEGIN Error_Handler_Debug */
- /* User can add his own implementation to report the HAL error return state */
- /* USER CODE END Error_Handler_Debug */
- ……………………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼
所有資料51hei提供下載:
ADS1256_INT.7z
(268.5 KB, 下載次數: 467)
2019-3-12 18:13 上傳
點擊文件名下載附件
中斷模式 下載積分: 黑幣 -5
|