#include
#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*3 1080/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 //横向上最右边,范围也就是47
void 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句,先设定为中间位置了,所以调整也从中间开始,左右旋转deltAngle
changeAngleY=1080;
while(1)
{
if(USART_RX_STA&0x80) //接收完
{
len=USART_RX_STA&0x3f;//得到此次接收到的数据长度
/******************下面这几句发送串口的 不知道为什么会影响PWM波的输出***********************/
// printf("n您发送的消息为:n");
// for(t=0;t // { // 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("nn");//插入换行 USART_RX_STA=0; delay_ms(20); }else { // times++; // /* // if(times%5000==0) // { // printf("nMiniSTM32开发板 串口实验n"); // printf("正点原子@ALIENTEKnnn"); // } // */ // 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:%fn",pidValueX); //printf("pidValueY:%fn",pidValueY); // // printf("errorX:%dn",errorX); // printf("errorY:%dn",errorY); if( (errorX>margine) || (errorX<-margine) ) { changeAngleX=changeAngleX-pidValueX; if(changeAngleX changeAngleX=minAngle; if(changeAngleX>maxAngle) changeAngleX=maxAngle; tim3PWM(changeAngleX); } else //if( ( errorX { tim3PWM(changeAngleX); } if( (errorY>margine) || (errorY<-margine) ) { changeAngleY=changeAngleY-pidValueY; if(changeAngleY changeAngleY=minAngle; if(changeAngleY>maxAngle) changeAngleY=maxAngle; tim4PWM(changeAngleY); } else if( ( errorY { 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;极性进行设置*****************************/ } }
上一篇:STM32八种输入输出模式详解
下一篇:STM32实战 2.矩阵键盘通过串口3输出
推荐阅读最新更新时间:2024-03-16 16:27
设计资源 培训 开发板 精华推荐
- 消息称 AMD 将入局手机芯片领域,采用台积电 3nm 工艺
- 英飞凌推出OptiMOS™ Linear FET 2 MOSFET, 赋能先进的热插拔技术和电池保护功能
- SGMII及其应用
- 贸泽开售用于机器人和机器视觉的 STMicroelectronics B-CAMS-IMX模块
- 三星 Exynos 2600 芯片前景堪忧:良率挑战严峻,有被取消量产风险
- 苹果搁置反垄断报告的请求遭印度监管机构拒绝,案件将继续推进
- 2024年Automechanika Shanghai海量同期活动刷新历届记录,汇聚行业智慧,共谋未来发展
- 企业文化分享 如何培养稀缺的硅IP专业人员?SmartDV开启的个人成长与团队协作之旅
- 恩智浦发布首个超宽带无线电池管理系统解决方案
- 北交大本科生探秘泰克先进半导体开放实验室,亲历前沿高科技魅力