📄 main.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 + -