四極管:3 D画像のAVR 12864実現


転載は出典を明記してください。四極管です。広西師範大学電子工学院大学生科学技術革新基地メール: [email protected]
原文の住所:http://blog.csdn.net/yangxingbo0311/article/details/7201097
このコードは基地の当時の牛人を参考にして作ったのです。?後ろにはC++builderの実現があります。
 
------------------------------------------------------------------------------------------------
    :   12864            ,       12864   。    
            、      ,        ,         ,   12864         
		    
------------------------------------------------------------------------------------------------
1.          ,     :
    dispstr_12864_move(uchar x,uchar y1,uchar y2,uchar *pstr1,uint word_number,uint speed)
    :x              ;y1  (1~4)         ;y2  (1~4)      
   ;*pstr1       ;*pstr2        ;word_number          ;speed     
    。                      ,              。
--------------------------------------------------------------------------------------------------
2.12864          ,     :
    plot_12864(uchar x,uchar y,uchar *buf),      (x,y),                 
  ,x     :1~128   y      :1~64    !!!  !!!           ,    
         ,          。
--------------------------------------------------------------------------------------------------
3.12864            ,     :
    mirror_point_12864(uchar center,uchar x,uchar h,uchar *buf)center       ,      
 y  x          ,h        ,buf           。           
     。
----------------------------------------------------------------------------------------------------
4.           ,    :
    draw_Line(uchar x0,uchar y0,uchar x1,uchar y1),       (Bresenham)    ,      
  (x0,y0),(x1,y1)             。               :
①        |a-b|   abs(uchar a,uchar b)
②       subsection_point_12864(uchar x,uchar center,uchar h,uchar *buf)
③      line_piont(uchar x0,uchar y0,uchar x1,uchar *buf)
----------------------------------------------------------------------------------------------------
5.    ,    :
   draw_circle(uchar x0,uchar y0,uchar r),       (Bresenham)    ,  1/8  ,     
         。(x0,y0)      ,x0:1~128  y0:1~64  r     :1~31。 
-----------------------------------------------------------------------------------------------------
**************************************************************************************************
*************************************************************************************************/



//*******     ********//
#include "avr/io.h"
#include <util/delay.h>  
#include "math.h"  

#define data_port    PORTB	
#define RS_1()     {DDRC |= (1<<7);nop();PORTC |= (1<<7);}
#define RW_1()     {DDRC |= (1<<6);nop();PORTC |= (1<<6);}
#define EN_1()     {DDRC |= (1<<5);nop();PORTC |= (1<<5);}

#define RS_0()   {DDRC |= (1<<7);nop();PORTC &= ~(1<<7);}
#define RW_0()   {DDRC |= (1<<6);nop();PORTC &= ~(1<<6);}
#define EN_0()   {DDRC |= (1<<5);nop();PORTC &= ~(1<<5);}

#define set_output()  DDRB = 0XFF
#define set_input()   DDRB = 0X00
#define port_lcd   PINB
#define nop() asm("nop")
#define uchar unsigned char
#define uint  unsigned int





uchar   music[1024]={}; 
uchar   magic[16]={};

//**********************************************************************
void delay_100ms(uint i)
{
    uint k;
	for (k=0;k<i;k++)
	{
	    _delay_ms(10);
		_delay_ms(10);
		_delay_ms(10);
		_delay_ms(10);
		_delay_ms(10);
		_delay_ms(10);
		_delay_ms(10);
		_delay_ms(10);
		_delay_ms(10);
		_delay_ms(10);
	}
	
}
   
//**********************************************************************  


//*************    ***************/
/*   :busywait_12864()            */
/*   :  RT12864M             */
/*     :                       */
/*     :                       */
/*    :                         */
//************************************/
void busywait_12864(void)
{
    uchar bf=0;
	
loop:RS_0();
	RW_1();
	EN_1();
	set_input();
	_delay_us(6);
    bf = port_lcd;
	EN_0();
    if(bf&0x80)goto loop;
	set_output();
}
//*************    ***************/
/*   :writecomm_12864()           */
/*   :    RT12864M            */
/*     :command                 */
/*     :                       */
/*    :                         */
//************************************/ 
void writecomm_12864(uchar command)
{
    busywait_12864();
	set_output();
	RS_0();
	RW_0();
	data_port = command;
	EN_1();
	EN_0();
 
}
//*************    ***************/
/*   :writedata_12864()           */
/*   :     RT12864M          */
/*     :wrdata                  */
/*     :                       */
/*    :                         */
//************************************/ 
void writedata_12864(uchar wrdata)
{
    busywait_12864();
	set_output();
    RS_1();
	RW_0();
	data_port = wrdata;
	EN_1();
	EN_0();
}
//*************    ***************/
/*   :Init_12864()                */
/*   :   RT12864M              */
/*     :                       */
/*     :                       */
/*    :                         */
//************************************/
void Init_12864(void)
{
    
	
    writecomm_12864(0x30);//     8   ,    
    _delay_ms(1);
	writecomm_12864(0x0c);//     ON,  OFF,  OFF
    _delay_ms(1);
    writecomm_12864(0x01);//    
    _delay_ms(1);
    writecomm_12864(0x02);//    
}
//*************    ***************/
/*   :locatexy_12864()            */
/*   :                      */
/*     :x,y                     */
/*     :                       */
/*    :                         */
//************************************/
void locatexy_12864(uchar x,uchar y)
{
    uchar addr=0;
    switch(y)
        {
	       case 0:addr=0x80+x;break;
		   case 1:addr=0x90+x;break;
		   case 2:addr=0x88+x;break;
		   case 3:addr=0x98+x;break;
		   default:break;
	    }	
	writecomm_12864(addr);
}
//*************    ***************/
/*   :distwochar_12864()          */
/*   :                 */
/*     :x,y,char1,char2        */
/*     :                       */
/*    :                         */
//************************************/
void distwochar_12864(uchar x,uchar y,uchar char1,uchar char2)
{
    locatexy_12864(x,y); 
    writedata_12864(char1);
	writedata_12864(char2);
}
//*************    ***************/
/*   :dispstr_12864()             */
/*   :                      */
/*     :x,y,*pstr              */
/*     :                       */
/*    :                         */
//************************************/
void dispstr_12864(uchar x,uchar y,uchar *pstr)
{
    uint i,t=0;
    while(pstr[t]!='\0')t++;
    for(i=0;i<t;i++)
        {
		  distwochar_12864(x,y,pstr[i],pstr[i+1]);
		  i+=1;
		  x+=1;
		  if(x==8)
		    {
			  x=0;
			  y++;
			  if(y==4)y=0;
			}  
		} 
}

/*=========================================*/
/*   :drawpic(uchar *pdraw);            */
/*     :                           */
/*     :pdraw,              */
/*=========================================*/
void drawpic_12864(uchar *pdraw)
{   
	uint x,y;
	long uint k=0;
    uchar yaddr=0x80;
    //writecomm_12864(0x30);//    ---8BIT    ,    OFF
    writecomm_12864(0x34);//    ---8BIT    ,     
    for(y=0;y<32;y++)
	    {
	        writecomm_12864(yaddr++);//      Y    
	        writecomm_12864(0x80);  //      X    
	        for(x=0;x<8;x++)
		        {
		          writedata_12864(pdraw[k++]);
		          writedata_12864(pdraw[k++]);
		        }
	    }
    yaddr=0x80;
    for(y=0;y<32;y++)
	    {	
	        writecomm_12864(yaddr++);//      Y    
	        writecomm_12864(0x88);   //      X    
	        for(x=0;x<8;x++)
		        {
		            writedata_12864(pdraw[k++]);
		            writedata_12864(pdraw[k++]);
		        }
	    }
   // writecomm_12864(0x32);//    ---8BIT    ,    ON
    writecomm_12864(0x36);//    ---8BIT    ,    OFF
	//      
	
	writecomm_12864(0x30);//     8   ,    
	writecomm_12864(0x0c);//     ON,  OFF,  OFF
	writecomm_12864(0x02);//    
}



//*************    ***************************************************
//   :dispstr_12864()             
//   :                        
//     :x,y12,*pstr1,*pstr2,word_number,speed 
//     :x          ?
//           y1  (1~4)         
//           y2  (1~4)         
//           *pstr1       
//           *pstr2        
//           word_number          
//           speed               
//     :                       
//    :                         
//***********************************************************************
void dispstr_12864_move(uchar x,uchar y1,uchar y2,
                         uchar *pstr1,
						 uint word_number,uint speed)
{
    uchar i,t;
	uint move;
	
    
	for (move=0;move<word_number;move++)
	{
	    for (t=0;t<16;t++)
	    {   
	     
            for(i=0;i<t;i++)
            {
		        distwochar_12864(x,y1,pstr1[i+move*2],pstr1[i+move*2+1]);
				//distwochar_12864(x,y2,pstr2[i+move*2],pstr2[i+move*2+1]);
		        i+=1;
		        x+=1;
		        if(x==8)
		        {
			        x=0;
			    }  
			}
		} 
		delay_100ms(speed);
		
	}

}


//******************************************************
//*************    ********************************/
/*   :abs(x1-x0)                                  */
/*   :                                  */
/*     :                                     */
/*                                                    */ 
/*     :                                        */
/*    :                                          */
/*                                                  */
//*****************************************************/
int abs(int a,int b)
{
    uint fabs = 0;
    if ((a-b)>0)   fabs = a-b;
	else           fabs = b-a;
    return (fabs);
}
//****************************************************
//*************    ****************************/
/*   :plot1_12864()                            */
/*   :                                 */
/*     :      x:[-64,64]  y:[-32,31]   */
/*     :                                    */
/*    :                                      */
//*************************************************/
void plot1_12864(int x,int y,uchar *buf)
{
    uchar a=0;
	if ((x>0)|(x==0))
	{
		if (!((x+64)%8))   
		{
			a|=(1<<0);  
			buf[(31-y)*16+((x+64)/8)-1]|=a;
		}
		else          
		{
			a|=(1<<(8-(x+63)%8));
			buf[(31-y)*16+((x+64)/8)]|=a;
		}
    }
	else 
	{
		
		if (!((64+x)%8))   
		{                                               
			a|=(1<<0);  
			buf[(31-y)*16+((64+x)/8)-1]|=a;
		}
		else          
		{
			a|=(1<<(8-(x+64)%8));
			buf[(31-y)*16+(64+x)/8]|=a;
		}
	}

} 


//*************    ****************************/
/*   :plot1_12864()                            */
/*   :                                 */
/*     :      x:[-64,64]  y:[-32,31]   */
/*     :                                    */
/*    :                                      */
//*************************************************/
void plot_12864(int x,int y,uchar *buf)
{
    uchar a=0;
	
	if (!(x%8))   
	{
	    a|=(1<<0);  
	    buf[(64-y)*16+(x/8)-1]|=a;
	}
	else          
	{
	    a|=(1<<(8-x%8));
        buf[(64-y)*16+(x/8)]|=a;
    }

}

//******************************************************
//*************    ********************************/
/*   :mirror_point_12864()                         */
/*   :                                   */
/*     :     :y:[1,128]                      */
/*              :h:[1,63]     :center:[1,64]  */ 
/*     :                                        */
/*    :                                          */
/*   !!:           64(12864  64 )*/
//*****************************************************/
void mirror_point_12864(uchar center,uchar x,uchar h,uchar *buf)
{
    uchar a=0,i,high=0;
	if (h>31)  high = 31;
	else       high = h;
	
	if (!(x%8))   
	{
	    a|=(1<<0);
        for (i=0;i<high;i++)  
	    {
		    buf[(64-center+i)*16+(x/8)-1]|=a;
		    buf[(64-center-i)*16+(x/8)-1]|=a;
		}
	}
	
	else          
	{
	    a|=(1<<(8-x%8));
		for (i=0;i<high;i++)  
	    {
            buf[(64-center+i)*16+(x/8)]|=a;
		    buf[(64-center-i)*16+(x/8)]|=a;
		}
    }


}



//******************************************************
//*************    ********************************/
/*   :clear_print_12864()                          */
/*   :                                    */
/*     :     :y:[1,128]                      */
/*                                                    */ 
/*     :                                        */
/*    :                                          */
/*                                                  */
//*****************************************************/
void clear_print_12864(uchar *buffer)
{
    int i;
	for (i=0;i<1024;i++)
	{
	    buffer[i] = 0x00;
	}
	drawpic_12864(buffer);
}



//******************************************************
//*************    ********************************/
/*   :subsection_point_12864()                     */
/*   :                                       */
/*     :                                         */
/*                                                    */ 
/*     :                                        */
/*    :                                          */
/*   !!:           64(12864  64 )*/
//*****************************************************/
void  subsection_point_12864(uchar x,uchar center,uchar h,uchar *buf)
{
        uchar a=0,i,high=0;
	if (h>63)  high = 63;
	else       high = h;
	
	if (!(x%8))   
	{
	    a|=(1<<0);
        for (i=0;i<high;i++)  
	    {
		    buf[(64-center-i)*16+(x/8)-1]|=a;
		}
	}
	
	else          
	{
	    a|=(1<<(8-x%8));
		for (i=0;i<high;i++)  
	    {
            buf[(64-center-i)*16+(x/8)]|=a;
		}
		
    }
	

}


//*************    ********************************/
/*   :line_piont()                                 */
/*   :                                        */
/*     :                                         */
/*                                                    */ 
/*     :                                        */
/*    :                                          */
/*   !!:           128(12864  128 */
//*****************************************************/
void line_piont(int x0,int y0,int x1,uchar *buf)
{
    uchar i;
	for (i=x0;i<x1;i++)
	{
		plot_12864(i,y0,buf);
	}
	
}

//*************    ********************************/
/*   :load_magic_12864()                          */
/*   :                                     */
/*     :     :y:[1,128]                      */
/*                                                    */ 
/*     :                                        */
/*    :                                          */
/*                                                  */
//*****************************************************/
void load_magic_12864(uchar *buffer)  
{
	uchar i,h;
	
	for (i=0;i<16;i++)
	{
		h= buffer[i];
		line_piont(i*8+1,h+1,i*8+8,music);
		line_piont(i*8+1,h+2,i*8+8,music);
	}
}


/******************************************************** 
*   :draw_Line() 
           (Bresenham)     
*   :        。      ,    。 
*     :x0                
*       y0                
*       x1                
‘       y1                
*     :     
*   :                  。 
*********************************************************/ 
void draw_line(int x0,int y0,int x1,int y1) 
{ 
    int temp; 
    int dx,dy;               //         、       
    int s1,s2,status,i; 
    int Dx,Dy,sub; 

    dx=x1-x0; 
	
    if(dx>=0)                 //X        
    s1=1; 
    else                   //X        
    s1=-1;    
    dy=y1-y0;                 //  Y            
    if(dy>=0)   s2=1;
     
    else        s2=-1;
     
    Dx=abs(x1,x0);           //   、           
    Dy=abs(y1,y0); 
   if(Dy>Dx)               //                
   {                     // 45      ,  Y  status=1,  X  status=0  
        temp=Dx; 
        Dx=Dy; 
        Dy=temp; 
        status=1; 
    }  
   else  status=0; 
  

//********         ******************************************* 
    //if(dx==0)                 //       ,       
    //line_piont(x0,y0,x1,music); 
    //if(dy==0)                 //       ,       
   // subsection_point_12864(x0,y0,y1,music); 


//*********Bresenham           *****************************  
    sub=2*Dy-Dx;               // 1          
    for(i=0;i<Dx+1;i++) 
    {  
        plot_12864(x0,y0,music);           //    
        if(sub>=0)                              
        {  
            if(status==1)             //   Y  ,x  1 
            x0+=s1;  
            else                   //   X  ,y  1              
            y0+=s2;  
            sub-=2*Dx;               //           
        }  
        if(status==1) 
        y0+=s2;  
        else      
        x0+=s1;  
        sub+=2*Dy;  
    } 

 
} 




/*************************************************************** 
  :Draw_circle (       ) 
  :  Bresenham  1/8  ,          7/8    
   
           8  
        0 
      7   1 
    6       2 
      5   3 
        4  
*****************************************************************/ 
void draw_circle(uchar x0,uchar y0,uchar r) 
{ 
    int a,b; 
    int di; 
    a=0; 
    b=r; 
    di=3-2*r;             //           
    while(a<=b) 
   {    //plot_12864(uchar x,uchar y,uchar *buf)
        plot_12864(x0-b,y0-a,music);           //3            
        plot_12864(x0+b,y0-a,music);           //0            
        plot_12864(x0-a,y0+b,music);           //1      
        plot_12864(x0-b,y0-a,music);           //7            
        plot_12864(x0-a,y0-b,music);           //2            
        plot_12864(x0+b,y0+a,music);           //4                
        plot_12864(x0+a,y0-b,music);           //5 
        plot_12864(x0+a,y0+b,music);           //6  
        plot_12864(x0-b,y0+a,music);            
        a++; 
        /***  Bresenham    **/    
        if(di<0) 
        di +=4*a+6; 
        else 
        { 
            di +=10+4*(a-b);    
            b--; 
        }  
        plot_12864(x0+a,y0+b,music); 
     
	} 
} 


//*************    ********************************/
/*   :cube_3D()                                    */
/*   :3D                                */
/*     :                                         */
/*                                                    */ 
/*     :                                        */
/*    :                                          */
/*   !!:           64(12864  64 )*/
//*****************************************************/
/*        */
//#define OFFSETX 30 
uchar OFFSETX = 64;        
#define OFFSETY 38         
#define OFFSETZ 60

/////////////////////////////////      /////////////////////////////////////////////////////////
/*const signed int aa[23]={8,-8,-8,8,8,-8,-8,8,8,8,8,8,8,0,4,-4,-8,-8,-8,-8,-8,-8,-8}; // x 
const signed int bb[23]={8,8,-8,-8,8,8,-8,-8,0,-4,4,-2,2,8,8,8,4,4,4,-4,-4,-4,0};   // y 
const signed int cc[23]={-8,-8,-8,-8,8,8,8,8,6,-6,-6,0,0,-6,6,6,-6,0,6,6,0,-6,0};   // z

const int ff[22]={1,2,3,4,5,6,7,8,1,2,3,4,9,9,12,14,14,17,19,20,21,22};         // start
const int gg[22]={2,3,4,1,6,7,8,5,5,6,7,8,10,11,13,15,16,19,20,21,18,23};       // end*/
/////////////////////////////////////////////////////////////////////////////////////////////////////

const signed int aa[14]={-16,-14,-18,-12,-20,8,-8,0,20,12,20,12,20,12}; // x 
const signed int bb[14]={16,10,10,0,0,16,16,0,16,16,10,10,0,0};   // y 
const signed int cc[14]={0,0,0,0,0,0,0,0,0,0,0,0,0,0};   // z

const int ff[13]={1,3,1,2,3,6,7,10,12,10,9,12,12};         // start
const int gg[13]={3,5,2,4,2,8,8,12,14,9,11,11,13};       // end

/////////////////////////////////////////////////////////////////////////////////////////////////////////

/*const signed int aa[16]={-11,-3,-7,11,-3,-13,-1,-7,-13,-1,0,8,4,8,0,0}; // x 
const signed int bb[16]={20,20,12,16,16,12,12,12,0,0,20,20,16,12,12,0};   // y 
const signed int cc[16]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};   // z

const int ff[12]={1,2,4,3,6,8,8,11,11,12,13,14};         // start
const int gg[12]={3,3,5,8,7,9,10,16,12,13,14,15};       // end*/

/////////////////////////////////////////////////////////////////////////////////////////////////////////
/*const signed int aa[16]={-26,-26,-16,-12,-12,-3,-3,2,10,18,22,30,22,30,22,30}; // x 
const signed int bb[16]={16,0,0,16,0,16,0,16,0,16,16,16,8,8,0,0};   // y 
const signed int cc[16]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};   // z

const int ff[13]={1,2,4,4,6,5,8,9,11,13,11,13,15};         // start
const int gg[13]={2,3,5,6,7,7,9,10,13,15,12,14,16};       // end*/

/////////////////////////////////////////////////////////////////////////////////////////////////////////


int sx,sy,ex,ey;                   // define global vars for calling graphics subroutines
float rotx=0.00;                     // starting amount of x rotation
float roty=0.00;                     // starting amount of y rotation
float rotz=0.00;                     // starting amount of z rotation


/**************************************************************************
*                 3D     
***************************************************************************/
void Disply3D(float xpos,float ypos,float zpos)   
{
    int newx[23];                     // translated screen x co-ordinates for vertex
    int newy[23];                     // translated screen y co-ordinates for vertex
    int i,loop;                         // temp variable for loops
    int vertex;
    float xt,yt,zt,x,y,z,sinax,cosax,sinay,cosay,sinaz,cosaz;   // lots of work variables
    for (loop=0;loop<1;loop++)
    {
        xpos=xpos+0.00;               // move the object
        ypos=ypos+0.00;               // it would wander off screen
        zpos=zpos+0.00;               // really quick, so leave it centered
		rotx=rotx+0.00;                 // rotate the cube on X axis
		roty=roty+0.15;                 // and on its y axis
		rotz=rotz+0.00;                 // dont bother with z or it gets confusing
		
		sinax=sin(rotx);               // precalculate the sin and cos values
		cosax=cos(rotx);             // for the rotation as this saves a 
		
		sinay=sin(roty);             // little time when running as we
		cosay=cos(roty);             // call sin and cos less often
		
		sinaz=sin(rotz);             // they are slow routines
		cosaz=cos(rotz);           // and we dont want slow!
		
		for (i=0; i<14; i++)         // translate 3d vertex position to 2d screen position
		{
			x=aa[i];                   // get x for vertex i
			y=bb[i];                   // get y for vertex i
			z=cc[i];                   // get z for vertex i
			
			yt = y * cosax - z * sinax;         // rotate around the x axis
			zt = y * sinax + z * cosax;       // using the Y and Z for the rotation
			y = yt;
			z = zt;
			
			yt = y * cosax - z * sinax;         // rotate around the x axis
			zt = y * sinax + z * cosax;       // using the Y and Z for the rotation
			y = yt;
			z = zt;
			
			xt = x * cosay - z * sinay;       // rotate around the Y axis
			zt = x * sinay + z * cosay;       // using X and Z
			x = xt;
			z = zt;
			
			xt = x * cosaz - y * sinaz;         // finaly rotate around the Z axis
			yt = x * sinaz + y * cosaz;       // using X and Y
			x = xt;
			y = yt;
			
			x=x+xpos;                         // add the object position offset
			y=y+ypos;                         // for both x and y
			z=z+OFFSETZ-zpos;           // as well as Z
			
			newx[i]=(x*64/z)+OFFSETX;       // translate 3d to 2d coordinates for screen
			newy[i]=(y*64/z)+OFFSETY;       // drawing so we can see the cube
		}
		
		for (i=0; i<13; i++)           // draw the lines that make up the object
		{
			vertex=ff[i]-1;               // temp = start vertex for this line
			sx=newx[vertex];           // set line start x to vertex[i] x position
			sy=newy[vertex];           // set line start y to vertex[i] y position
			vertex=gg[i]-1;             // temp = end vertex for this line
			ex=newx[vertex];           // set line end x to vertex[i+1] x position
			ey=newy[vertex];           // set line end y to vertex[i+1] y position
			if((sx>255) | (sy>255) | (ex>255) |( ey>255))
			{
				sx=255;
				sy=255;
				ex=255;
				ey=255;
			}
			draw_line(sx,sy,ex,ey);
		}
	}

}