STM32接收串口数据-输出PWM

来源:互联网 发布:linux代码学习 编辑:程序博客网 时间:2024/05/17 20:43
#include <stm32f10x_lib.h>#include "sys.h"#include "usart.h"#include "delay.h"#include "led.h" #include "key.h"#include "exti.h"#include "wdg.h"#include "timer.h"#include "string.h"  //Mini STM32开发板范例代码8//PWM输出 实验//正点原子@ALIENTEK//技术论坛:www.openedv.com  //#define led_PB12   PBout(12)   //位绑定,位定义PB12口作为LED输出。这样速度最快   这个是开始测试用的输出口//切记一定,要在这里修改一下//TIM3->CCMR1|=6<<12;  //CH2 PWM2模式与上面极性相反 平时用小灯来测试#define deltaAngle 24//8*31080/320=3.375   1080/240=4.5//下面两句为测试使用//#define deltaErrorX 3//每转动delta角度,坐标X的改变量//#define deltaErrorY 4//每转动delta角度,坐标Y的改变量#define maxAngle 1520   //1520   //对应135+22.5=157.5  360--0度 720--45度  1080--90度  1440--135度 1800--180度#define minAngle 540//540   //对应0+22.5=22.5  因为图像是640*480的 最多产生640的差距//#define maxAngle 1420   //1520   //对应135+22.5=157.5  360--0度 720--45度  1080--90度  1440--135度 1800--180度//#define minAngle 640//540   //对应0+22.5=22.5  因为图像是640*480的 最多产生640的差距#define margine 30 //横向上最右边,范围也就是47void tim3PWM(int changeAngle)//俯仰舵机{//PWM_Init(14400,100)定义了14400 对应20毫秒,720对应1毫秒,360对应0.5毫秒,电机的控制是0.5-2.5毫秒之间,1.5代表中位TIM3->CCR2 = changeAngle;//现在TIM3的2通道  TIM4的1通道 都可以用了 只需要改变这句 以及main函数中的//TIM4->CCR1 = 1080;即可//TIM4->CCR1 = changeAngle;//delay_ms(20);}void tim4PWM(int changeAngle){//TIM4->CCR1 = changeAngle;   不知道为什么总是出现1.5到2ms 再从2到1.5毫秒 跳变 貌似时钟不一样 改为tim4的2通道TIM4->CCR2 = changeAngle;//这个2通道 PB7口//delay_ms(20); //根究DS0灯的PWM显示,貌似这里是不需要等待20毫秒的}//char imgCenterX[5];  这里的4个变量,修改为在usart.h中声明,在usart.c文件中定义,在本文件中使用,切勿重复定义//char imgCenterY[5];//int imgCenterX0,imgCenterX1;//int imgCenterY0,imgCenterY1;//char testChar[]={"300 "};  测试需要 正式程序不需要int errorX=100,errorY=100;int changeAngleX;int changeAngleY;int errorX0,errorY0;int sumErrorX,sumErrorY;int diffErrorX,diffErrorY;float pidValueX,pidValueY;float Kp=0.15,Ki=0,Kd=0;int main(void){/************************接收串口数据后,再发回,显示************************************************************/u8 t;u8 len;u16 times=0; /************************************************************************************//************************************************************************************/ u16 led0pwmval=0;u16 led1pwmval=0;u8 dir=1;/************************************************************************************/ Stm32_Clock_Init(9); //系统时钟设置delay_init(72);     //延时初始化uart_init(72,9600);  //串口初始化 串口1  串口2-5的时间晶振是不一样的 小一半 LED_Init();   //初始化与LED连接的硬件接口    //PWM_Init(900,100);   //测试DS0小灯时,用这个频率PWM_Init(14400,99); //PWM频率是50hz  20ms对应的是14400 1ms对应720 TIM3_CH2->PA7 TIM4_CH2->PB7/************每次运行程序都进行中位初始化*************************/TIM3->CCR2 = 1080; //1.5毫秒 中位 90度//TIM4->CCR1 = 1080; //1.5毫秒 中位 90度TIM4->CCR2 = 1080;delay_ms(2000); changeAngleX=1080;  //因为上面3句,先设定为中间位置了,所以调整也从中间开始,左右旋转deltAnglechangeAngleY=1080;    while(1){ if(USART_RX_STA&0x80)   //接收完{   len=USART_RX_STA&0x3f;//得到此次接收到的数据长度/******************下面这几句发送串口的 不知道为什么会影响PWM波的输出***********************///printf("\n您发送的消息为:\n");//for(t=0;t<len;t++)  //imgCenterX is %-4d and imgCenterY is %-4dx轴是从第15-18个字节开始 y轴是从38-41个字节开始//{//USART1->DR=USART_RX_BUF[t]; //当向寄存器USART1->DR写数据是,会进行自动的串口发送 王博20150620//while((USART1->SR&0X40)==0);//等待发送结束//}//////test[0]=USART_RX_BUF[0];////test[1]=USART_RX_BUF[1];////test[2]=USART_RX_BUF[2];////test[3]=USART_RX_BUF[3];////////testInt = atoi(test);////printf("%d",testInt);////printf("\n\n");//插入换行USART_RX_STA=0;delay_ms(20);}else{//times++;///*//if(times%5000==0)//{//printf("\nMiniSTM32开发板 串口实验\n");//printf("正点原子@ALIENTEK\n\n\n");//}//*///if(times%200==0)printf("请输入数据,以回车键结束\n");//delay_ms(20);    }/************************************************************************************//************************************************************************************///1440对应180度的话,1440/180=8 每转1度,应该在误差上+8/*********************************主要的最终的程序 先屏蔽****************************************************//*************************************************************************************************/errorX=imgCenterX1-imgCenterX0;errorY=imgCenterY1-imgCenterY0;sumErrorX+=errorX;sumErrorY+=errorY;diffErrorX=errorX-errorX0;diffErrorY=errorY-errorY0;errorX0=errorX;errorY0=errorY;pidValueX=Kp*errorX+Ki*sumErrorX+Kd*diffErrorX;pidValueY=Kp*errorY+Ki*sumErrorY+Kd*diffErrorY;printf("pidValueX:%f\n",pidValueX);//printf("pidValueY:%f\n",pidValueY);////printf("errorX:%d\n",errorX);//printf("errorY:%d\n",errorY);    if( (errorX>margine) || (errorX<-margine) ){changeAngleX=changeAngleX-pidValueX;if(changeAngleX<minAngle)changeAngleX=minAngle;if(changeAngleX>maxAngle)changeAngleX=maxAngle;tim3PWM(changeAngleX);}else //if( ( errorX<margine ) && ( errorX>(-margine) ) ){tim3PWM(changeAngleX);}if( (errorY>margine) || (errorY<-margine) ){changeAngleY=changeAngleY-pidValueY;if(changeAngleY<minAngle)changeAngleY=minAngle;if(changeAngleY>maxAngle)changeAngleY=maxAngle;tim4PWM(changeAngleY);}else if( ( errorY<margine ) && ( errorY>(-margine) ) ){tim4PWM(changeAngleY);}//else//{// tim3PWM(1080);// tim4PWM(1080);// delay_ms(40);//}/*************************************************************************************************//*************************************************************************************************///TIM3->CCR2 = 360; //按理说,这个应该是归0的,但是舵机一般难以达到0度,所以从540开始//TIM4->CCR2 = 360;//TIM3->CCR2 = 540; //TIM4->CCR2 = 540;//TIM3->CCR2 = 720;//45度位置//TIM4->CCR2 = 720;//TIM3->CCR2 = 1080; //1.5毫秒 中位 90度//TIM4->CCR2 = 1080;//TIM3->CCR2 = 1440; //135度//TIM4->CCR2 = 1440;//TIM3->CCR2 = 1620; //TIM4->CCR2 = 1620;//TIM3->CCR2 = 1800; //按理说,这个应该是180度的,但是舵机一般难以达到180度,所以从1620截止//TIM4->CCR2 = 1800;/*************************************************************************************************//*************************************************************************************************//*******************************以上程序可PA7可以正常输出PWM波,但是必须将TIM3->CCMR1|=7<<12;极性进行设置***************************//*******************************由于上面的程序中用到了errorX变量,所以如果一起运行的话,会受到影响***************************///  if(dir)//{//errorX++;//}//   //else //{//errorX--;//}//// if(errorX>maxAngle)//dir=0;//if(errorY==0)//dir=1;////tim3PWM(errorX);////if(dir)//{//errorY++;//}//   //else //{//errorY--;//}//// if(errorY>maxAngle)//dir=0;//if(errorY==0)//dir=1;////tim4PWM(errorY);////delay_ms(5); /*******************************以上程序可PA7可以正常输出PWM波,但是必须将TIM3->CCMR1|=7<<12;极性进行设置*****************************/} }

0 0
原创粉丝点击