⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c

📁 ARM7的ads环境下的画圆的实现
💻 C
字号:
#include"math.h"
#include"config.h" 
#define ZHI  100 
#define YUAN 360                    /*分得段数  */
#define YIBU    0.34              /*一个脉冲走的距离 */
# define  UART_BPS       115200   /*  串口通信波特率*/   
float yuanxin[2];        /*圆心*/
float zhongdian[2];     /*园的起点 */
float a_0,b_0;/*画直线时开始的绳长*/
float a_1,b_1;/*画圆时开始的绳长*/
/*******************************************UART**********************************************************/
volatile  uint8 uiGRcvNew;                                 /*  串口接收新数据的标志    */ 
uint8     uiGRcvBuf[30] = {0};                             /*  串口接收数据缓冲区                      */ 
uint32     uiGNum;                                         /*  串口接收数据的个数                      */
uint32 jihao=0;
void DelayNS (uint32 uiDly);
void __irq UART0_IRQ (void) ;
void UARTInit (void) ;
void UART0SendByte (uint8 uiDat) ;  
void UART0SendStr(uint8 const *uiStr, uint32 uiNum) ;
/*****************************************************************************************************/
int R;               /*半径*/
const uint32 ZUO=(1<<18);
const uint32 YOU=(1<<19);
const uint32 KEY=(1<<15);

void huazhixian(void);            /*画直线*/
void huayuan(void);              /*画圆*/
void Run(int ma,int mb);

int LA[ZHI],LB[ZHI];
int main()
{
  int i,j,k;
  int zuobiao[3]={0,0,0};/*接受URAT接受的圆心坐标和半径*/
   PINSEL0   = PINSEL0 & (~(0x03 << 6) ) | (0x02 << 6) ;                  /* 选择MAT0.0 输出    p0.3                */ 
   PINSEL0   = PINSEL0 & (~(0x03 << 24)) | (0x02 << 24) ;                  /* 选择MAT1.0 输出    p0.12                */
   PINSEL1=0x00000000; /*PINSEL1全设为GPIO*/
   IODIR=ZUO|YOU;/*设置p0.19  p0.20 为输出,其余为输入(包括p0.15为输入)*/
   IOCLR=ZUO|YOU;/*拉低电平*/
   
   
   
    PINSEL0    = PINSEL0 & (~0x0F)| 0x05;      /* 设置I/O 连接到UART  */ //有什么作用????????????????//
                             
    uiGRcvNew = 0; /*标志位为0*/

    UARTInit ();                                            /* 串口初始化                           */ 

    U0FCR       = 0x81;                                     /* 使能FIFO,设置8 个字节触发点  */ 

    U0IER       = 0x01;                                     /* 使能接收中断                          */ 

    IRQEnable ();
     

    VICIntSelect     = 0x00000000;                          /* 设置所有中断为向量中断                     */ 

    VICVectCntl0     = 0x20 | 0x06;                         /* 设置串口中断为最高优先级                    */ 

    VICVectAddr0     = (uint32)UART0_IRQ;                   /* 设置向量地址                          */ 

    VICIntEnable     = 1 << 0x06;                           /* 使能串口中断                          */ 

    while (1)
    { 
         if (uiGRcvNew == 1)                                 /* 判断是否有新数据                        */ 
         {   
             uiGRcvNew = 0;                                 /* 清除标志                            */ 
             UART0SendStr(uiGRcvBuf, uiGNum);              /* 向串口发送数据                         */ 
           for(i=uiGNum-1;i<=0;i--)
           {
                   j=1;
              for(k=1;k<uiGNum-i;k++)
               j*=10;
               zuobiao[jihao]+=j*(uiGRcvBuf[i]-48);
           }
           jihao++; 
           if(jihao==3)
           {
              U0IER       = 0x00000000;                                     /* 禁止接收中断                          */ 
           break;/*表明三个坐标已经接受完毕*/
           }
             
         } 
    } 
  
   
   
   
   
   
   
   
   
   
   yuanxin[0]=zuobiao[0];    /*取圆心为(400,500)*/
   yuanxin[1]=zuobiao[1];
   R=zuobiao[2];
   zhongdian[0]=yuanxin[0]-R;
   zhongdian[1]=yuanxin[1];

 huazhixian();
 huayuan();
 for(i=ZHI-1;i>0;i--)
 Run(-LA[i],-LB[i]);
 
 while(1);
    return 0;
}

void huazhixian(void)
{
int i;
int laa=0,lbb=0;/*当此的脉冲数*/
float xd,yd;               /*要画的直线的总长度*/
float x_0=140,y_0=0;  /*画直线的起点*/
float x_2,y_2;//将要达到的坐标
float Am=0,Bm=0;/*由于误差需要补的脉冲数*/
float A=0,B=0;/*绳的实际长度*/
float a,b;        /*线的长度*/
float aa,bb;     /*线将要到达的长度*/
float aaa,bbb;  /*线曾加的长度化为脉冲数,为含小数的脉冲数*/
     xd=zhongdian[0]-x_0;  /*要画的直线的x上的总长度*/
     yd=zhongdian[1]-y_0; /*要画的直线的y上的总长度*/
     A=a=aa=sqrt((0-x_0)*(0-x_0)+(1114-y_0)*(1114-y_0));  /*开始时  绳长*/
     B=b=bb=sqrt((970-x_0)*(970-x_0)+(1114-y_0)*(1114-y_0)); /*开始时  绳长  */

   for(i=1;i<=ZHI;i++)
   {
              x_2=x_0+xd*1.0*i/ZHI; //将要达到的坐标
       y_2=y_0+yd*1.0*i/ZHI;//将要达到的坐标
       aa=sqrt((0-x_2)*(0-x_2)+(1114-y_2)*(1114-y_2)); //将要达到的绳长
       bb=sqrt((1090-x_2)*(1090-x_2)+(1114-y_2)*(1114-y_2));//将要达到的绳长
       aaa=(aa-a)/(YIBU*1.0)+Am;/*走一段需要的脉冲数,加上的Am为由于误差补充的脉冲数*/
       bbb=(bb-b)/(YIBU*1.0)+Bm;/*走一段需要的脉冲数,加上的Bm为由于误差补充的脉冲数*/
       a=aa;
       b=bb;
   /*aaa*********误差*********************************************/      
           if(aaa>=0)
   {
     if((aaa-(int)(aaa))>0.5)
          laa=(int)aaa+1;
          else
          laa=(int)aaa;
          }
   if(aaa<0)
   {
      if(((int)(aaa)-(aaa))>0.5)
      laa=(int)aaa-1;
          else
          laa=(int)aaa;
          }
          A=A+1.0*laa*YIBU;
      Am=(aa-A)/YIBU;          /*需要纠正的脉冲数*/
      LA[i-1]=laa;
  /*aaa*****************误差*************************************/

   /*bbb****************误差**************************************/ 
         if(bbb>=0)
   {
     if((bbb-(int)(bbb))>0.5)
          lbb=(int)bbb+1;
          else
          lbb=(int)bbb;
          }
    if(bbb<0)
    {
      if(((int)(bbb)-(bbb))>0.5)
      lbb=(int)bbb-1;
          else
          lbb=(int)bbb;
          }
          B=B+1.0*lbb*YIBU;
      Bm=(bb-B)/YIBU;          /*需要纠正的脉冲数*/
      LB[i-1]=lbb;
   /*bbb******************误差************************************/   
   Run(laa,lbb); 
   }
   Run(Am,Bm); 
   a_1=A;/*绳的实际长度*/
   b_1=B;/*绳的实际长度*/
}
void huayuan(void)
{
 int i;
 int laa,lbb;/*当此的脉冲数*/
 float x_2,y_2;//将要达到的坐标
 float Am=0,Bm=0;/*由于误差需要补的脉冲数*/
 float A=0,B=0;/*绳的实际长度*/
 float a,b;        /*线的长度*/
 float aa,bb;     /*线将要到达的长度*/
 float aaa,bbb;  /*线曾加的长度化为脉冲数,为含小数的脉冲数*/
 A=a_1;
 B=b_1;
     a=sqrt((0-zhongdian[0])*(0-zhongdian[0])+(1114-zhongdian[1])*(1114-zhongdian[1]));  /*开始时  绳长*/
     b=sqrt((1090-zhongdian[0])*(1090-zhongdian[0])+(1114-zhongdian[1])*(1114-zhongdian[1])); /*开始时  绳长  */
 for(i=1;i<=YUAN;i++)
 { 
 x_2=(zhongdian[0]+R-cos(3.1415927*2*i/YUAN)*R);//x将要到达的位置
 y_2=(zhongdian[1]+sin(3.1415927*2*i/YUAN)*R);//y将要到达的位置 
     aa=sqrt((0-x_2)*(0-x_2)+(1114-y_2)*(1114-y_2));/*理论上将要达到的绳长*/
     bb=sqrt((1090-x_2)*(1090-x_2)+(1114-y_2)*(1114-y_2));/*理论上将要达到的绳长*/
       aaa=((aa-a)/YIBU)+Am;/*走一段需要的脉冲数,加上的Am为由于误差补充的脉冲数*/
       bbb=((bb-b)/YIBU)+Bm;/*走一段需要的脉冲数,加上的Am为由于误差补充的脉冲数*/ 
       a=aa;
       b=bb;
   /*aaa*********误差*********************************************/
   if(aaa>=0)
   {
     if((aaa-(int)(aaa))>0.5)
          laa=(int)aaa+1;
          else
          laa=(int)aaa;
          }
   if(aaa<0)
   {
      if(((int)(aaa)-(aaa))>0.5)
      laa=(int)aaa-1;
          else
          laa=(int)aaa;
          }
          A+=1.0*laa*YIBU;
      Am=(aa-A)/YIBU;          /*需要纠正的脉冲数*/
  /*aaa*****************误差*************************************/

  /*bbb****************误差**************************************/
   if(bbb>=0)
   {
     if((bbb-(int)(bbb))>0.5)
          lbb=(int)bbb+1;
          else
          lbb=(int)bbb;
          }
    if(bbb<0)
    {
      if(((int)(bbb)-(bbb))>0.5)
      lbb=(int)bbb-1;
          else
          lbb=(int)bbb;
          }
          B+=1.0*lbb*YIBU;
      Bm=(bb-B)/YIBU;          /*需要纠正的脉冲数*/
   /*bbb******************误差************************************/
 Run(laa,lbb);
    }
    Run(Am,Bm);
} 

void Run(int ma,int mb)
 { 
 int i=0,j=0;
 if(ma>=0)        
    IOCLR=ZUO;
        else   
        { IOSET=ZUO;
        ma=-ma;
        }
if(mb>=0)     
   IOCLR=YOU;
        else   
        { IOSET=YOU;/*判断需要的脉冲是正还是负*/
        mb=-mb;
        }
      T0TCR      = 0x02;                                   /* 定时器 1 复位                       */ 
     T0PR          = 0;                                   /* 不设时钟分频                         */ 
     T0MCR      = 0x03;                                   /* 设置T1MR0 匹配后复位T1TC 并产生中断              */ 
     T0EMR      = 0x03<<4;   /* 匹配翻转                           */                              
     T0MR0      = Fpclk/20/(2*ma);                              /* 设置1 秒匹配值                     */     
     T0IR      = 0x01;                                    /* 清除中断标志                         */ 

    T1TCR      = 0x02;                                   /* 定时器 1 复位                       */ 
     T1PR          = 0;                                   /* 不设时钟分频                         */ 
    T1MCR      = 0x03;                                   /* 设置T1MR0 匹配后复位T1TC   并产生中断             */ 
     T1EMR      = 0x03<<4;                              /* 匹配翻转                           */                        
     T1MR0      = Fpclk/20/(2*mb);                              /* 设置1 秒匹配值                     */ 
     T1IR      = 0x01; /* 清除中断标志                         */ 
     
                                        
      if(ma!=0)    
     T0TCR     = 0x01;
      if(mb!=0)                                    /*  启动定时器 0                       */ 
     T1TCR     = 0x01;                                    /*  启动定时器 1                       */                            
    IRQEnable();                                         /* IRQ 中断使能                   */                                     
 while(1)
     {
         if(T0IR&0x01==1)
         {
               i++;
           T0IR=0x01;/*清除中断标志*/
           if(i==2*ma)
            {    T0TCR=0x00;}
         }
         if(T1IR&0x01==1)
         {
              j++;
            T1IR=0x01;/*清除中断标志*/       
         if(j==2*mb)
            {  T1TCR=0x00;      }
         }
         if(ma==0)
          T0TCR=0x00;/*如果ma=0,则立即让定时器禁止*/
          if(mb==0)
          T1TCR=0x00;  /*如果ma=0,则立即让定时器禁止*/         
       if(((j==2*mb)|mb==0)&((i==2*ma)|ma==0))/*达到所需的脉冲数*/
       break;   
   }
 }
 
 void DelayNS (uint32 uiDly) 
{ 
     uint32 i; 
     for (; uiDly > 0; uiDly--)
     { 
         for(i = 0; i < 50000; i++); 
     } 
} 

 
void __irq UART0_IRQ (void) 
{     
 uiGNum = 0; 
     while ((U0IIR & 0x01) == 0)                               /* 判断是否有中断挂起                         */ 
        {
         switch (U0IIR & 0x0E)                               /* 判断中断标志                             */ 
            {  
              case 0x04:                                        /* 接收数据中断                             */ 

                  uiGRcvNew = 1;                                /* 置接收新数据标志                           */ 

                  for (uiGNum = 0; uiGNum < 8; uiGNum++)       /* 连续接收 8 个字节                        */ 
                   { 
                  uiGRcvBuf[uiGNum] = U0RBR; 
                  } 
                  break; 
                  
              case 0x0C:                                        /* 字符超时中断                             */ 
                  uiGRcvNew = 1; 
                  while ((U0LSR & 0x01) == 0x01)               /* 判断数据是否接收完毕                         */ 
                   {
                       uiGRcvBuf[uiGNum] = U0RBR; 
                       uiGNum++; 
                  } 
                  break; 
             default: 
                  break; 
         } 
     } 
   VICVectAddr = 0x00; 
   }
   
void UARTInit (void) 
{ 
    uint16 uiFdiv; 
    U0LCR       = 0x83;                                      /*  允许设置波特率 */ 
    uiFdiv     = (Fpclk / 16) / UART_BPS;                    /*  设置波特率*/
     
    U0DLM       = uiFdiv / 256; 
    U0DLL      = uiFdiv % 256; 
    U0LCR      = 0x03;                                       /*  锁定波特率   */ 
}  



void UART0SendByte (uint8 uiDat) 
{ 
    U0THR = uiDat;                                           /*  写入数据                           */ 
    while ((U0LSR & 0x20) == 0);                             /*  等待数据发送完毕                       */ 
}   
 
 
  void UART0SendStr(uint8 const *uiStr, uint32 uiNum) 
{ 
    uint32 i; 
    for (i = 0; i < uiNum; i++)                           /*  发送指定个字节数据                      */ 
    {  
         UART0SendByte (*uiStr++); 
    } 
} 
 
 
 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -