【设计分享】基于stm32f4的三维旋转显示平台
给大家分享个基于stm32f4的设计,下面有硬件图和源程序。(
不是我写的,只是分享而已)
摘要
1. 系统方案

[tr] [/tr]

2. 系统硬件设计



3. 系统软件设计

//input: endpoints of segments which formedthe outline of a 3D model
//x position with range 0-95
//y position with range 0-95
//z position with range 0-128
/******************************************/
//from later discussion, one of the Qformat
//type should replace the char type
/******************************************/
struct Coordinate_3D
{
_iqxPosition;
_iqyPosition;
_iqzPosition;
};
//after you get the intersection points in3d coordinate, you need to remap it into 2d coordinate on the very electricalplane,
//and the conversion is quite simpleCoordinate_2D.yPosition = Coordinate_3D.zPosition; Coordinate_2D.xPosition =sqrt(xPosition^2+yPosition^2)
struct Coordinate_2D
{
charxPosition;
charyPosition;
};
struct Line
{
structCoordinate_3D beginPoint;
structCoordinate_3D endPoint;
unsignedchar color;
};
//frame structure to store the visiblepoints in one electrical frame
//need to be discussed
//here’s the prototype of the Framestructure, and basically the frame struture should contain the visible points,
//and the zero points. As we have enclosedthe number of zero points after each visible points in their own datastructure,
//only the number of zero points at the beginningof the whole frame should be enclosed in the frame struture
struct Frame
{
intzerosBefore;
PointQueue_tvisiblePointQueue;
};
//we need a union structure like colorplane with bit fields to store the color imformation of every four FPGAs in onedata segment
//actually, it’s a kind of frustrateingthing that we had to rebind the data into such an odd form.
union ColorPalette
{
struct
{
unsigned char color1 : 4;
unsigned char color2 : 4;
unsigned char color3 : 4;
unsigned char color3 : 4;
}distributedColor;
unsignedshort unionColor;
};
//and now we need a complete pointstructure to sotre all the imformation above
//here we add a weight field = yPosition*96+ xPosition, which will facilitate
//our sort and calculation of the zero pointsnumber between each visible point
//it’s important to understand that, 4corresponding points on the LED panel
//will share one visiblepoint datastructure.(一块stm32负责4块16*16的LED,每块对应的点的4位颜色信息,拼成16位的数据段)
struct VisiblePoint
{
structCoordinate_2D coord;
unionColorplane ColorPalette;
intweight;
intzerosAfter;
};
//as now you can see, we need some thing tostore the visible points array
typedef struct QueueNode
{
structVisiblePoint pointData;
structQueueNode * nextNode;
}QueueNode_t, *QueueNode_ptr;typedef struct
{
QueueNode_ptrfront;
QueueNode_ptrrear;
}PointQueue_t;
//finally, we will have 16*16 words(16bits)to write into the fifo after each electrial frame sync cmd.
//it may hard for us to decide the framestructure now, let’s see how will the work flow of the algorithm be.
//firstly, the overall function will belike this
void Real3DExt(struct Line inputLines[],int lineNumber, struct Frame outputFrames[])
//then we need some real implementationfunction to calculate the intersection points
//with 0 = no intersection points, 1 = onlyhave one intersection points, 2 = the input line coincides the given electricalplane
//2 need to be treated as an exception
//the range of the degree is 0-359
//it’s important to mention that each intersectionpoint we calculate, we need to
//remap its coordinate from a 32*32 fieldto x,y = 0-15, as each stm32 only have a 32*32
//effective field(those intersection pointsout of this range belong to other stm32), which can be decided by its address
int InterCal(struct Line inputLine, structVisiblePoint * outputPoint, int degree)
//so we will need something like this inthe Real3DExt function:
for (int j = 0; j < 360; j++)
{
for(inti = 0; i < lineNumber; i++ )
InterCal(struct Line inputLine, struct VisiblePointoutputPoint, int degree);
……
}
/******************************************/
//simple float format version of InterCal
/******************************************/
//calculate formula
//Q = [-1,1,-1];
//P = [1,1,-1];
//V = Q – p = [-2,0,0];
//Theta = pi/6;
//Tmp0 = Q(1)*sin(Theta) – Q(2)*cos(Theta);
//Tmp1 = V(1)*sin(Theta) – V(2)*cos(Theta);
//Result = Q – (Tmp0/Tmp1)*V
float32_t f32_point0[3] ={-1.0f,1.0f,-1.0f};
float32_t f32_point1[3] ={1.0f,1.0f,-1.0f};
float32_t f32_directionVector[3],f32_normalVector[3], f32_theta,
f32_tmp0, f32_tmp1, f32_tmp2, f32_result[3];
arm_sub_f32(f32_point0,f32_point1,f32_directionVector,3);
f32_theta = PI/6.0f;
f32_normalVector[0] =arm_sin_f32(f32_theta);
f32_normalVector[1] = arm_cos_f32(f32_theta);
f32_normalVector[2] = 0.0f;
arm_dot_prod_f32(f32_point0,f32_normalVector, 3, &f32_tmp0);
arm_dot_prod_f32(f32_directionVector,f32_normalVector, 3, &f32_tmp1);
f32_tmp2 = f32_tmp0/f32_tmp1;
arm_scale_f32(f32_normalVector, f32_tmp2,f32_normalVector, 3);
arm_sub_f32(f32_point0, f32_normalVector,f32_result, 3);//and than we need to decide whether to adda new visible point in the point queue, or to update
//the color field of a given point in thepoint queue(as 4 visible point share one data structure). from this point, youwill find that, it may be
//sensible for you not to diretly insert anew point into the end of point queue but to insert it in order
//when you build the pointqueue. it seemsmore effective.
void EnPointQueue(PointQueue_t * inputQueue,QueueNode_t inputNode);
//finally we will get an sorted queue atthe end of the inner for loop
//than we need to calculate the number ofinvisible points between these visible points
//and to store it in each frame structure.the main purpose to do so is to offer an quick generation
//of the blank point(color field = 16’b0)between each electrical frame
//the work flow will be like this:
loop
{
dmaoutput of the blank points;
outputof the visible points;
}
/******************************************/
//some points need more detailed discussion
/******************************************/
//1.memory allocation strategy
//a quite straight forward method will beestablishing a big memnory pool in advance, but the drawback of this method
//is that it’s hard for you to decide thesize of the memory pool. Another way would be the C runtime library method,
// and you can use build-in function mallocto allocate the memory, but it will be a quite heavy load for the m3 cpu
// as you need dynamic memeory allocationthroughout the algorithm.
//2.the choice of Q format of the IQMATHlibrary
//from the discussion above, the range ofthe coordnate is about 1-100, but the range of sin&cos is only 0-1,sothere’s a large gap between them.
//may be we can choose iq24?? Simultaneously,another big problem will be the choice between IQMATH and arm dsp library astheir q format is
//incompatible with each other. as far asmy knowledge is concerned, we should choose IQMATH with m3 without fpu, andcmsis dsp library with m4 with fpu.//more detail discussion about the range ofthe algorithm
//x,y range is -64 to 64
//the formula is
//Tmp0 = Q(1)*sin(Theta) – Q(2)*cos(Theta);
//Tmp0 range is -128 to 128
//Tmp1 = V(1)*sin(Theta) – V(2)*cos(Theta);
//Tmp1 range is -128 to 128
//Result = Q – (Tmp1/Tmp2)*V
//because the minimal precision of thecoordinate is 1, so if the result of Tmp1/Tmp2 is bigger than 128, the Resultwill be
//saturated. With the same reson, if(Tmp1/Tmp2)*V >= 128 or <= -127, the result will be saturated
4. 系统创新
5. 评测与结论
附录




