Vector的实现__2018.06.14

本文介绍了一个自定义的Vector容器类实现,包括基本操作如push_back、pop_back、resize等,以及迭代器的设计与实现。此外,还展示了如何利用NgxMemPool进行内存管理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

代码:Vector0.h

#ifndef VECTOR0_H
#define VECTOR0_H
#include "Ngx_pool.h"
#include <iostream>
using namespace std;

template<typename T>
class myallocater
{
public:
	//construct构造  destroy析构
	//allocate开辟内存 deallocate释放内存
	myallocater() :count(0) {}
	void construct(void *ptr, const T &val)
	{
		new (ptr)T(val);
	}
	void destroy(T *ptr)
	{
		ptr->~T();
	}
	//开辟内存
	void* allocate(u_int size)
	{
		if (0 == count)
		{
			p.ngx_create_pool(4096);
			++count;
		}
		return p.ngx_palloc(size);
	}
	//释放内存
	void deallocate(void *ptr)
	{
		count = 0;
		p.ngx_destroy_pool();
	}
private:
	NgxMemPool p;
	int count;
};
template<typename T,typename Allocator=myallocater<T>>
class Vector
{
public:
	typedef T value_type;
	//template<typename T>
	//默认构造的vector,底层没分配过内存
	Vector() :mpVec(NULL), mSize(0), mCur(0) {}
	Vector(int size, const T &val = T())
		:mSize(size), mCur(0)
	{
		mpVec = (T*)_allocator.allocate(mSize*sizeof(T));
		for (int i = 0; < msize; ++i)
		{
			_allocator.construct(mpVec + i, val);
		}
	}
	//拷贝构造
	Vector(const Vector<T> &src)
	{
		if (0 == src.mSize)
		{
			mpVec = (T*)_allocator.allocate(1 * sizeof(T));
			mSize = 1;
			mCur = 0;
		}
		else
		{
			T *p = (T*)_allocator.allocate(src.mSize * sizeof(T));
			for (int i = 0; i < src.mCur; ++i)
			{
				_allocator.construct(p + i, src.mpVec[i]);
			}
			for (int i = 0; i < mCur; ++i)
			{
				_allocator.destroy(&mpVec[i]);
			}
			mSize = src.mSize;
			mCur = src.mCur;
			mpVec = p;
		}
	}
	//operator=
	Vector<T>& operator=(const Vector<T> &src)
	{
		if (this == &src)
			throw "error";
		for (int i = 0; i < mCur; ++i)
		{
			_allocator.destroy(&mpVec[i]);
		}
		mpVec = (T*)_allocator.allocate(src.mSize * sizeof(T));
		for (int i = 0; i < src.mCur; ++i)
		{
			_allocator.construct(mpVec + i, src.mpVec[i]);
		}
		mSize = src.mSize;
		mCur = src.mCur;
	}
	T& operator[](int index)
	{
		if (empty())
			throw "error";
		return mpVec[index];
	}
	~Vector()
	{
		if (!empty())
		{
			for (int i = 0; i < mCur; ++i)
			{
				_allocator.destroy(&mpVec[i]);
			}
			_allocator.deallocate(mpVec);
		}
	}

	//末尾添加元素
	void push_back(const T &val)
	{
		if (full())
			reSize();
		_allocator.construct(mpVec + mCur++, val);
	}
	//末尾删除
	void pop_back()
	{
		_allocator.destroy(&mpVec[--mCur]);
	}



	T front()const { return mpVec[0]; }
	T back()const { return mpVec[mCur - 1]; }
	int size()const { return mCur; }
	bool full()const { return mCur == mSize; }
	bool empty()const { return 0 == mSize; }

	//内存以2倍方式增长
	void reSize()
	{
		if (empty())
		{
			mpVec = (T*)_allocator.allocate(1 * sizeof(T));
			mSize = 1;
			mCur = 0;
		}
		else
		{
			T *p = (T*)_allocator.allocate(mSize * 2 * sizeof(T));
			for (int i = 0; i < mCur; ++i)
			{
				_allocator.construct(p + i, mpVec[i]);
			}
			for (int i = 0; i<mCur; ++i)
			{
				_allocator.destroy(&mpVec[i]);
			}
			mSize *= 2;
			mpVec = p;
		}
	}
	//定义当前容器的迭代器类型
	class iterator
	{
	public:
		typedef T value_type;
		iterator(T *ptr = NULL) :p(ptr) {}
		bool operator!=(const iterator &it)const { return p != it.p; }
		bool operator==(const T &val)const { return *p == val; }
		void operator=(const iterator &src) { return *p == *src.p; }
		void operator++() { ++p; }
		void operator--(int) { --p; }
		T& operator*() { return *p; }
		iterator operator+(const int size)const { return iterator(p + size); }
		iterator operator-(const int size)const { return iterator(p - size); }
		bool operator<(const iterator &src)const { return p < src.p; }
		bool operator>(const iterator &src)const { return p > src.p; }
		int operator-(const iterator &src)const { return p - src.p; }
		T& operator[](const int index) { return p[index]; }
	private:
		T *p;
	};
	iterator begin()const { return iterator(mpVec); }
	iterator end()const { return iterator(mpVec + mCur); }

	/*
	C++17次课作业:完成下面的三个接口
	在it迭代器的位置,插入val元素
	it位置合法:it在【first,last】范围
	特殊情况:容器已经满了,插入要先扩容
	it位置不合法: 插入失败,抛异常
	*/
	void insert(iterator &it, const T &val)
	{
		if (it < begin() || it > end())
			throw "error";
		if (this->full())
			this->reSize();
		*it = val;
	}
	/*
	删除的容器,按值删除,按迭代器删除
	*/
	void erase(const T &val)
	{
		iterator it = this->begin();
		for (; it != this->end(); ++it)
		{
			if (*it == val)
			{
				iterator tmp(it + 1);
				for (; tmp != end(); ++tmp)
					*(tmp - 1) = *tmp;
				_allocator.destroy(mpVec + mCur - 1);
			}
		}
		--mCur;
	}
	void erase(const iterator &it)
	{
		if (it < begin() || it > end())
			throw "error";
		iterator tmp(it + 1);
		for (; tmp != end(); ++tmp)
			*(tmp - 1) = *tmp;
		_allocator.destroy(mpVec + mCur - 1);
		--mCur;
	}
private:
	T *mpVec;
	int mSize;
	int mCur;
	Allocator _allocator;
};

main.cpp

#include "Ngx_pool.h"
#include "Vector0.h"
#include <iostream>
#include <vld.h>
#include <Windows.h>
#include <time.h>
using namespace std;
template<typename Container>
void showContainer(Container &con)
{
	Container::iterator it = con.begin();
	for (; it != con.end(); ++it)
	{
		cout << *it << " ";
	}
	cout << endl;
}
int main1()
{
	Vector<int> MyIntVector;
	for (int i = 0; i < 10; ++i)
	{
		MyIntVector.push_back(i);
	}
	showContainer(MyIntVector);
	return 0;
}
int main(int argc, char* argv[])
{
	Vector<int> vec1, vec2;

	srand(time(0));
	for (int i = 0; i < 10; ++i)
	{
		vec1.push_back(rand() % 100);
		vec2.push_back(rand() % 100);
	}
	//默认从小到大排序   vector<int>::iterator  list<int>::iteartor
	//showContainer(vec1);

	/*vec1.insert(vec1.begin(),99);

	vec1.erase(vec1.begin());
	showContainer(vec1);*/

	//由小到大
	//mysort(vec1.begin(), vec1.end(),smallpfunc<int>);
	cout << "vec1:";
	showContainer(vec1);
	cout << "vec2:";
	showContainer(vec2);

	//Vector<int>::iterator it = myfind(vec1.begin(),vec1.end(),20);

	


	/*
	需要一种通用的方式,来遍历任何的容器   operator[]做不到的
	通用: 怎么通用?是使用方式通用呢?还是所有容器共用一个迭代器呢?
	数组operator[]
	链表
	二维数组
	哈希表
	红黑树

	迭代器和容器是一一对应的,所以在设计上,把迭代器这个类,设计成容器类型的嵌套类性
	*/
	/*
	1.需要在容器里面定义嵌套类性  iterator
	2.给容器提供begin方法     iterator begin();  把容器第0号位元素的迭代器返回回去
	3.给容器提供end方法       iterator end();    把容器末尾元素后继位置的迭代器返回回去
	4.给迭代器提供operator!=
	5.给迭代器提供operator++()
	6.给迭代器提供operator*()
	*/
	/*Vector<int>::iterator it = vec1.begin();
	for (; it != vec1.end(); ++it)
	{
	cout << *it << " ";
	}
	cout << endl;*/

	return 0;
}

Ngx_pool.h

#ifndef NGX_POOL_H
#define NGX_POOL_H
typedef unsigned char u_char;
typedef unsigned int u_int;
typedef struct ngx_pool_s ngx_pool_t;
typedef struct ngx_pool_large_s ngx_pool_large_t;
const int MAX = 4096;

const int NGX_ALIGNMENT = sizeof(unsigned long);
#define ngx_align_ptr(p, a)\
	(u_char *) (((unsigned int) (p) + ((unsigned int) a - 1)) & ~((unsigned int) a - 1))


typedef struct
{
	u_char		*last;
	u_char		*end;
	ngx_pool_t	*next;
	u_int		failed;
}ngx_pool_data_t;

struct ngx_pool_s
{
	ngx_pool_data_t		d;
	ngx_pool_t			*current;//指向当前内存的指针。
	ngx_pool_large_t	*large;
};
struct ngx_pool_large_s
{
	ngx_pool_large_t	*next;
	void				*alloc;
};
class NgxMemPool
{
public:
	//创建ngx内存池
	void ngx_create_pool(u_int size);
	//销毁ngx内存池
	void ngx_destroy_pool();
	//重置内存池
	void ngx_reset_pool();
	//开辟内存,对齐
	void* ngx_palloc(u_int size);
	//开辟内存,不对齐
	void* ngx_pnalloc(u_int size);
	//把内存归还给内存池
	bool ngx_pfree(void *p);

	//开辟小块内存
	void *ngx_palloc_small(u_int size, int align);
	//开辟新的小块
	void *ngx_palloc_block(u_int size);
	//开辟大块内存
	void *ngx_palloc_large(u_int size);
private:
	ngx_pool_t *_pool;
};
#endif

Ngx_pool.cpp

#include "Ngx_pool.h"
#include "Vector0.h"
#include <iostream>
#include <vld.h>
#include <Windows.h>
#include <time.h>

using namespace std;
//创建ngx内存池
void NgxMemPool::ngx_create_pool(u_int size)
{
	_pool = (ngx_pool_t*)malloc(size);
	if (NULL == _pool)
	{
		return;
	}
	_pool->d.last = (u_char*)_pool + sizeof(ngx_pool_t);
	_pool->d.end = (u_char*)_pool + size;
	_pool->d.next = NULL;
	_pool->d.failed = 0;
	_pool->current = _pool;//当前指针位置
	_pool->large = NULL;
}
//销毁ngx内存池
void NgxMemPool::ngx_destroy_pool()
{
	//先释放large指向外部开辟的大内存
	ngx_pool_large_t	*pLarge;
	for (pLarge = _pool->large; pLarge != NULL; pLarge = pLarge->next)
	{
		if (pLarge->alloc)
		{
			free(pLarge->alloc);
			pLarge->next = NULL;
		}
	}
	ngx_pool_t			*p;
	ngx_pool_t			*n;

	for (p = _pool, n = _pool->d.next;; p = n)
	{
		free(p);
		p = NULL;
		if (NULL == n)
		{
			break;
		}
	}

}
//重置内存池
void NgxMemPool::ngx_reset_pool()
{
	ngx_pool_large_t	*pLarge;//指向内存池外开辟的大块内存
	ngx_pool_t			*p;//指向内存池的指针
	//先释放内存池外开辟的大块内存
	for (pLarge = _pool->large; pLarge != NULL; pLarge = pLarge->next)
	{
		if (pLarge->alloc)
		{
			free(pLarge->next);
			pLarge->alloc = NULL;
		}
	}
	//再重置内存池中的内存
	for (p = _pool; p; p = p->d.next)
	{
		p->d.last = (u_char*)p + sizeof(ngx_pool_t);
	}
	_pool->current = _pool;
}
//开辟内存,对齐
void* NgxMemPool::ngx_palloc(u_int size)
{
	if (size <= MAX)
	{
		return ngx_palloc_small(size,0);
	}
	return ngx_palloc_large(size);
}
//把内存归还给内存池
bool NgxMemPool::ngx_pfree(void *p)
{
	ngx_pool_large_t *pLarge;
	//只检查是否是大内存块,如果是大内存块则释放
	for (pLarge = _pool->large; pLarge; pLarge->next)
	{
		if (p == pLarge->alloc)
		{
			free(pLarge->alloc);
			pLarge->alloc = NULL;
			return true;
		}
	}
	return false;
}
//开辟小块内存
void*NgxMemPool::ngx_palloc_small(u_int size,int align)
{
	u_char		*m;
	ngx_pool_t	*p;
	p = _pool->current;
	do {
		m = p->d.last;
		if (align)
		{
			m = ngx_align_ptr(m,NGX_ALIGNMENT);
		}
		if ((u_int)(p->d.end - m) >= size)
		{
			p->d.last = m + size;
			return m;
		}
	} while (p);
	//开辟内存过大,内存池中没有合适的内存,则重新开辟指定大小的内存块
	return ngx_palloc_block(size);
}
//开辟新的小内存块
void *NgxMemPool::ngx_palloc_block(u_int size)
{
	u_int	psize;
	u_char	*m;
	ngx_pool_t	*pnew, *t;

	psize = (u_int)(_pool->d.end-(u_char*)_pool);
	m = (u_char*)malloc(psize);
	if (NULL == m)
		return NULL;

	pnew = (ngx_pool_t*)m;
	pnew->d.end = m + psize;
	pnew->d.next = NULL;
	pnew->d.failed = 0;

	/*将m指针移动数据头的大小位置*/
	m += sizeof(ngx_pool_data_t);
	/*进行内存对齐计算*/
	m = ngx_align_ptr(m, NGX_ALIGNMENT);
	/*设置新内存块的last,即申请使用size大小的内存*/
	pnew->d.last = m + size;

	/*对链表进行整理current指针要重新确认*/

	/*这里循环用来寻找最后一个节点 */
	for (t = _pool->current; t->d.next != NULL; t = t->d.next)
	{
		if (t->d.failed++ > 4)	//failed的值只在此处被修改
		{
			t->current = t->d.next;	//失败4次以上移动current指针  
		}
	}
	/*在循环中next可能会指向NULL 所以current也可能会被置NULL*/
	t->d.next = pnew;  //将这次分配的内存块pnew加入该内存池链表中

					   /*对current确认为NULL时则重新确认位置*/
	_pool->current = t->current ? t->current : pnew;

	return m;
}
//开辟大块内存
void *NgxMemPool::ngx_palloc_large(u_int size)
{
	void              *p;
	u_int         n = 0;
	ngx_pool_large_t  *large;

	// 直接在系统堆中分配一块空间  
	p = (void *)malloc(size);
	if (p == NULL)
	{
		return NULL;
	}

	// 查找到一个空的large区,如果有,则将刚才分配的空间交由它管理  
	for (large = _pool->large; large; large = large->next)
	{
		if (NULL == large->alloc)
		{
			large->alloc = p;
			return p;
		}
		if (n++ > 3)
		{
			break;
		}
	}
	//为了提高效率, 如果在三次内没有找到空的large结构体,则创建一个
	large = (ngx_pool_large_t*)ngx_palloc_small(size, 1);
	if (NULL == large)
	{
		free(p);
		return NULL;
	}
	large->alloc = p;
	large->next = _pool->large;
	_pool->large = large;
	return p;
}



/* USER CODE BEGIN Header */ /** ****************************************************************************** * @file : main.c * @brief : Main program body ****************************************************************************** * @attention * * Copyright (c) 2021 STMicroelectronics. * All rights reserved. * * This software is licensed under terms that can be found in the LICENSE file * in the root directory of this software component. * If no LICENSE file comes with this software, it is provided AS-IS. * ****************************************************************************** */ /* USER CODE END Header */ /* Includes ------------------------------------------------------------------*/ #include "main.h" /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ /* 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 ---------------------------------------------------------*/ FMAC_HandleTypeDef hfmac; DMA_HandleTypeDef handle_GPDMA1_Channel1; /* USER CODE BEGIN PV */ /* FMAC configuration structure */ FMAC_FilterConfigTypeDef sFmacConfig; /* Array of filter coefficients A (feedback coefficients) in Q1.15 format */ static int16_t aFilterCoeffA[COEFF_VECTOR_A_SIZE] = { 10432,-17296, 17696,-12512, 5536, -1296 }; /* Array of filter coefficients B (feed-forward taps) in Q1.15 format */ static int16_t aFilterCoeffB[COEFF_VECTOR_B_SIZE] = { 828, 1170, 2360, 2293, 2360, 1170, 828 }; /* Array of input values in Q1.15 format */ static int16_t aInputValues[ARRAY_SIZE] = { 0, 660, -194, 1731, 1, 2194, 725, 2018, 1775, 1501, 2703, 1085, 3072, 1084, 2701, 1499, 1772, 2014, 721, 2189, -5, 1725, -200, 653, -6, -666, 187, -1737, -7, -2199, -730, -2022, -1778, -1504, -2705, -1086, -3072, -1083, -2700, -1496, -1768, -2010, -716, -2184, 10, -1719, 206, -647, 13, 672, -181, 1742, 12, 2204, 734, 2026, 1781, 1506, 2706, 1086, 3072, 1082, 2698, 1494, 1765, 2006, 712, 2179, -16, 1713, -212, 640, -19, -679, 175, -1748, -18, -2209, -739, -2030, -1784, -1509, -2708, -1087, -3072, -1081, -2696, -1491, -1762, -2002, -707, -2173, 21, -1707, 218, -634, 26, 685, -169, 1754, 23, 2214, 743, 2033, 1787, 1511, 2710, 1088, 3072, 1080, 2695, 1489, 1758, 1998, 702, 2168, -27, 1701, -225, 628, -32, -691, 163, -1760, -29, -2219, -748, -2037, -1791, -1513, -2711, -1089, -3072, -1080, -2693, -1486, -1755, -1994, -698, -2163, 33, -1695, 231, -621, 39, 698, -156, 1766, 34, 2224, 752, 2041, 1794, 1516, 2713, 1089, 3072, 1079, 2691, 1484, 1752, 1990, 693, 2158, -38, 1689, -237, 615, -45, -704, 150, -1772, -40, -2229, -757, -2045, -1797, -1518, -2714, -1090, -3071, -1078, -2689, -1481, -1749, -1986, -688, -2153, 44, -1683, 243, -608, 52, 710, -144, 1778, 45, 2234, 761, 2049, 1800, 1520, 2716, 1091, 3071, 1077, 2687, 1478, 1745, 1982, 684, 2148, -50, 1677, -250, 602, -58, -717, 138, -1784, -51, -2239, -766, -2052, -1803, -1523, -2717, -1092, -3071, -1076, -2686, -1476, -1742, -1978, -679, -2142, 55, -1671, 256, -596, 64, 723, -132, 1790, 56, 2244, 770, 2056, 1806, 1525, 2719, 1092, 3071, 1075, 2684, 1473 }; /* Array of output data to preload in Q1.15 format */ static int16_t aOutputDataToPreload[COEFF_VECTOR_A_SIZE] = { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }; /* Array of calculated filtered data in Q1.15 format */ static int16_t aCalculatedFilteredData[ARRAY_SIZE]; /* Expected number of calculated samples */ uint16_t ExpectedCalculatedOutputSize = MEMORY_PARAMETER_D2; /* Status of the FMAC callbacks */ __IO uint32_t HalfOutputDataReadyCallback = CALLBACK_NOT_CALLED; __IO uint32_t OutputDataReadyCallback = CALLBACK_NOT_CALLED; __IO uint32_t ErrorCount = 0; /* Array of reference filtered data for IIR "7 feed-forward taps, 6 feedback coefficients, gain = 1" in Q1.15 format */ static const int16_t aRefFilteredData[ARRAY_SIZE] = { 0x01c6, 0x0403, 0x03a5, 0x03e6, 0x05b0, 0x0588, 0x051d, 0x0664, 0x06c7, 0x057a, 0x0631, 0x06c8, 0x0539, 0x0500, 0x05a5, 0x0453, 0x02f5, 0x03b2, 0x02a0, 0x00b3, 0x00fe, 0x008c, 0xfe75, 0xfe03, 0xfe6e, 0xfc64, 0xfb84, 0xfc4c, 0xfb0a, 0xf9ba, 0xfa9c, 0xfa87, 0xf8df, 0xf9d2, 0xfaa0, 0xf95d, 0xf9da, 0xfb7d, 0xfaf9, 0xfac9, 0xfd0d, 0xfd3b, 0xfcc5, 0xfecf, 0xfffd, 0xff53, 0x00ae, 0x02be, 0x01f7, 0x029c, 0x04cb, 0x0487, 0x041b, 0x0609, 0x066e, 0x0504, 0x0663, 0x0722, 0x0576, 0x0598, 0x06be, 0x0521, 0x03f7, 0x0544, 0x03f1, 0x01fe, 0x02b2, 0x0246, 0xffbf, 0xffb1, 0x0031, 0xfd99, 0xfcdc, 0xfdc8, 0xfc12, 0xfa6f, 0xfbac, 0xfb1e, 0xf8f9, 0xfa31, 0xfaba, 0xf8e4, 0xf963, 0xfb2a, 0xf9ea, 0xf9ac, 0xfc34, 0xfbdb, 0xfb28, 0xfd85, 0xfe95, 0xfd63, 0xff3a, 0x0162, 0x0027, 0x011e, 0x03b3, 0x032b, 0x02bf, 0x056e, 0x05a2, 0x0426, 0x0638, 0x071b, 0x0536, 0x05d6, 0x0788, 0x057c, 0x04b2, 0x0696, 0x04fd, 0x0307, 0x0458, 0x03e4, 0x00e7, 0x0179, 0x0201, 0xfede, 0xfe5d, 0xff91, 0xfd45, 0xfb6b, 0xfd2c, 0xfbff, 0xf96e, 0xfb01, 0xfb45, 0xf8b6, 0xf963, 0xfb49, 0xf91d, 0xf8f0, 0xfbb9, 0xfabb, 0xf9b5, 0xfc8b, 0xfd49, 0xfb76, 0xfdeb, 0x0004, 0xfe37, 0xff85, 0x028d, 0x017c, 0x0122, 0x04a4, 0x046f, 0x02e1, 0x05bb, 0x06b8, 0x046c, 0x05c4, 0x07f7, 0x0556, 0x0516, 0x07a2, 0x05ae, 0x03b5, 0x05e6, 0x0542, 0x01d6, 0x0342, 0x03c8, 0x0010, 0xfff2, 0x0195, 0xfe7f, 0xfca1, 0xff07, 0xfd19, 0xfa2a, 0xfc41, 0xfc38, 0xf8c9, 0xf9e7, 0xfbd7, 0xf89e, 0xf8a2, 0xfbb2, 0xf9e3, 0xf881, 0xfc01, 0xfc27, 0xf9a9, 0xfcd9, 0xfec2, 0xfc37, 0xfdf0, 0x0173, 0xff87, 0xff61, 0x03bb, 0x02e9, 0x0141, 0x0506, 0x05fc, 0x031a, 0x056e, 0x0801, 0x04ab, 0x051b, 0x0864, 0x05e5, 0x03f9, 0x074f, 0x0640, 0x0277, 0x04f3, 0x0570, 0x0109, 0x018d, 0x03b9, 0xff9d, 0xfe01, 0x0128, 0xfe56, 0xfb14, 0xfdf5, 0xfd7c, 0xf90e, 0xfaf7, 0xfccf, 0xf864, 0xf8c4, 0xfc36, 0xf94a, 0xf79e, 0xfc01, 0xfb37, 0xf810, 0xfc24, 0xfdb8, 0xfa2e, 0xfc8d, 0x0081, 0xfd5b, 0xfd9c, 0x02d3, 0x0120, 0xff50, 0x043e, 0x04e9, 0x0148, 0x04e8, 0x07af, 0x0377, 0x04c1, 0x08e7, 0x058c, 0x03d3, 0x088c, 0x06c6, 0x02b3, 0x0682, 0x06e5, 0x019d }; /* USER CODE END PV */ /* Private function prototypes -----------------------------------------------*/ void SystemClock_Config(void); static void SystemPower_Config(void); static void MX_GPDMA1_Init(void); static void MX_ICACHE_Init(void); static void MX_FMAC_Init(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 */ /* STM32U5xx HAL library initialization: - Configure the Flash prefetch - Configure the Systick to generate an interrupt each 1 msec - Set NVIC Group Priority to 3 - Low Level Initialization */ /* 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(); /* Configure the System Power */ SystemPower_Config(); /* USER CODE BEGIN SysInit */ /* Configure LED1 */ BSP_LED_Init(LED1); /* USER CODE END SysInit */ /* Initialize all configured peripherals */ MX_GPDMA1_Init(); MX_ICACHE_Init(); MX_FMAC_Init(); /* USER CODE BEGIN 2 */ /*## Configure the FMAC peripheral ###########################################*/ sFmacConfig.InputBaseAddress = INPUT_BUFFER_BASE; sFmacConfig.InputBufferSize = INPUT_BUFFER_SIZE; sFmacConfig.InputThreshold = INPUT_THRESHOLD; sFmacConfig.CoeffBaseAddress = COEFFICIENT_BUFFER_BASE; sFmacConfig.CoeffBufferSize = COEFFICIENT_BUFFER_SIZE; sFmacConfig.OutputBaseAddress = OUTPUT_BUFFER_BASE; sFmacConfig.OutputBufferSize = OUTPUT_BUFFER_SIZE; sFmacConfig.OutputThreshold = OUTPUT_THRESHOLD; sFmacConfig.pCoeffA = aFilterCoeffA; sFmacConfig.CoeffASize = COEFF_VECTOR_A_SIZE; sFmacConfig.pCoeffB = aFilterCoeffB; sFmacConfig.CoeffBSize = COEFF_VECTOR_B_SIZE; sFmacConfig.Filter = FMAC_FUNC_IIR_DIRECT_FORM_1; sFmacConfig.InputAccess = FMAC_BUFFER_ACCESS_POLLING; sFmacConfig.OutputAccess = FMAC_BUFFER_ACCESS_DMA; sFmacConfig.Clip = FMAC_CLIP_DISABLED; sFmacConfig.P = COEFF_VECTOR_B_SIZE; sFmacConfig.Q = COEFF_VECTOR_A_SIZE; sFmacConfig.R = GAIN; if (HAL_FMAC_FilterConfig(&hfmac, &sFmacConfig) != HAL_OK) { /* Configuration Error */ Error_Handler(); } /*## Preload the input and output buffers ####################################*/ if (HAL_FMAC_FilterPreload(&hfmac, aInputValues, INPUT_BUFFER_SIZE, aOutputDataToPreload, COEFF_VECTOR_A_SIZE) != HAL_OK) { /* Configuration Error */ Error_Handler(); } /*## Start calculation of IIR filter in polling/DMA mode #####################*/ if (HAL_FMAC_FilterStart(&hfmac, aCalculatedFilteredData, &ExpectedCalculatedOutputSize) != HAL_OK) { /* Processing Error */ Error_Handler(); } /*## Wait for the end of the handling (no new data written) #################*/ /* For simplicity reasons, this example is just waiting till the end of the calculation, but the application may perform other tasks while the operation is ongoing. */ while(HalfOutputDataReadyCallback == CALLBACK_NOT_CALLED) { } while(OutputDataReadyCallback == CALLBACK_NOT_CALLED) { } /*## Stop the calculation of IIR filter in polling/DMA mode ##################*/ if (HAL_FMAC_FilterStop(&hfmac) != HAL_OK) { /* Processing Error */ Error_Handler(); } /*## Check the final error status ############################################*/ if(ErrorCount != 0) { /* Processing Error */ Error_Handler(); } /*## Compare FMAC results to the reference values #####################*/ for (uint32_t i = 0; i < ExpectedCalculatedOutputSize; i++) { if (aCalculatedFilteredData[i] != aRefFilteredData[i]) { /* Processing Error */ Error_Handler(); } } /* There is no error in the output values: Turn LED1 on */ BSP_LED_On(LED1); /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ } /* USER CODE END 3 */ } /** * @brief System Clock Configuration * @retval None */ void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; /** Configure the main internal regulator output voltage */ if (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1) != HAL_OK) { Error_Handler(); } /** Initializes the CPU, AHB and APB buses clocks */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_MSI; RCC_OscInitStruct.MSIState = RCC_MSI_ON; RCC_OscInitStruct.MSICalibrationValue = RCC_MSICALIBRATION_DEFAULT; RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_4; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_MSI; RCC_OscInitStruct.PLL.PLLMBOOST = RCC_PLLMBOOST_DIV1; RCC_OscInitStruct.PLL.PLLM = 1; RCC_OscInitStruct.PLL.PLLN = 80; RCC_OscInitStruct.PLL.PLLP = 2; RCC_OscInitStruct.PLL.PLLQ = 2; RCC_OscInitStruct.PLL.PLLR = 2; RCC_OscInitStruct.PLL.PLLRGE = RCC_PLLVCIRANGE_0; RCC_OscInitStruct.PLL.PLLFRACN = 0; if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { Error_Handler(); } /** Initializes the CPU, AHB and APB buses clocks */ RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2 |RCC_CLOCKTYPE_PCLK3; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; RCC_ClkInitStruct.APB3CLKDivider = RCC_HCLK_DIV1; if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4) != HAL_OK) { Error_Handler(); } } /** * @brief Power Configuration * @retval None */ static void SystemPower_Config(void) { /* * Disable the internal Pull-Up in Dead Battery pins of UCPD peripheral */ HAL_PWREx_DisableUCPDDeadBattery(); /* * Switch to SMPS regulator instead of LDO */ if (HAL_PWREx_ConfigSupply(PWR_SMPS_SUPPLY) != HAL_OK) { Error_Handler(); } /* USER CODE BEGIN PWR */ /* USER CODE END PWR */ } /** * @brief FMAC Initialization Function * @param None * @retval None */ static void MX_FMAC_Init(void) { /* USER CODE BEGIN FMAC_Init 0 */ /* USER CODE END FMAC_Init 0 */ /* USER CODE BEGIN FMAC_Init 1 */ /* USER CODE END FMAC_Init 1 */ hfmac.Instance = FMAC; if (HAL_FMAC_Init(&hfmac) != HAL_OK) { Error_Handler(); } /* USER CODE BEGIN FMAC_Init 2 */ /* USER CODE END FMAC_Init 2 */ } /** * @brief GPDMA1 Initialization Function * @param None * @retval None */ static void MX_GPDMA1_Init(void) { /* USER CODE BEGIN GPDMA1_Init 0 */ /* USER CODE END GPDMA1_Init 0 */ /* Peripheral clock enable */ __HAL_RCC_GPDMA1_CLK_ENABLE(); /* GPDMA1 interrupt Init */ HAL_NVIC_SetPriority(GPDMA1_Channel1_IRQn, 0, 0); HAL_NVIC_EnableIRQ(GPDMA1_Channel1_IRQn); /* USER CODE BEGIN GPDMA1_Init 1 */ /* USER CODE END GPDMA1_Init 1 */ /* USER CODE BEGIN GPDMA1_Init 2 */ /* USER CODE END GPDMA1_Init 2 */ } /** * @brief ICACHE Initialization Function * @param None * @retval None */ static void MX_ICACHE_Init(void) { /* USER CODE BEGIN ICACHE_Init 0 */ /* USER CODE END ICACHE_Init 0 */ /* USER CODE BEGIN ICACHE_Init 1 */ /* USER CODE END ICACHE_Init 1 */ /** Enable instruction cache in 1-way (direct mapped cache) */ if (HAL_ICACHE_ConfigAssociativityMode(ICACHE_1WAY) != HAL_OK) { Error_Handler(); } if (HAL_ICACHE_Enable() != HAL_OK) { Error_Handler(); } /* USER CODE BEGIN ICACHE_Init 2 */ /* USER CODE END ICACHE_Init 2 */ } /* USER CODE BEGIN 4 */ /** * @brief FMAC half output data ready callback * @par hfmac: FMAC HAL handle * @retval None */ void HAL_FMAC_HalfOutputDataReadyCallback(FMAC_HandleTypeDef *hfmac) { HalfOutputDataReadyCallback = CALLBACK_CALLED; } /** * @brief FMAC output data ready callback * @par hfmac: FMAC HAL handle * @retval None */ void HAL_FMAC_OutputDataReadyCallback(FMAC_HandleTypeDef *hfmac) { OutputDataReadyCallback = CALLBACK_CALLED; } /** * @brief FMAC error callback * @par hfmac: FMAC HAL handle * @retval None */ void HAL_FMAC_ErrorCallback(FMAC_HandleTypeDef *hfmac) { ErrorCount++; } /* 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 */ __disable_irq(); /* LED1 is blinking */ BSP_LED_Toggle(LED1); HAL_Delay(500); while (1) { } /* USER CODE END Error_Handler_Debug */ } #ifdef USE_FULL_ASSERT /** * @brief Reports the name of the source file and the source line number * where the assert_param error has occurred. * @param file: pointer to the source file name * @param line: assert_param error line source number * @retval None */ void assert_failed(uint8_t *file, uint32_t line) { /* USER CODE BEGIN 6 */ /* User can add his own implementation to report the file name and line number, ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ /* USER CODE END 6 */ } #endif /* USE_FULL_ASSERT *根据以上的代码,使用STM32U575,ADC单通道采集,FMAC使用FIR滤波器功能,如何设计出ADC采集数据,通过GPDMA1,FMAC处理数据的代码,现已通过stm32 cubemx配置好了GPDMA1,使用标准轮询模式。需要完整的源文件和头文件
最新发布
06-12
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值