历史上的今天
今天是:2025年04月09日(星期三)
2019年04月09日 | STM32接收串口数据-输出PWM
2019-04-09 来源:eefocus
#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八种输入输出模式详解
史海拾趣
|
想在英蓓特EM-STM3210E的开发板上用STM32+NAND128+SD卡做大容量存储,但用官方的例程只能对SD卡操作,对NAND不行,总是提示要格式化,但格式化不成功。NAND和SD卡用的同样的USB程序,只是根据不CBW命令中不同的逻辑块来选择memory是SD还是N ...… 查看全部问答> |
|
其他公司器件基本是遵循引脚多功能多,引脚少的频率也低功能也少,而且不是在数量少,而是根本没有。 ST的48、64脚的外设也很多,不过48和36脚缺少C以上版本,没有DAC,flash和RAM也有些少,有些遗憾。有些时候封装大小也是要考虑的,封装小 ...… 查看全部问答> |
|
*** WARNING L13: RECURSIVE CALL TO SEGMENT #include \"reg52.h\" #include //包含atof(),字符串->实数 #include //包含sprintf(),实数->字符串 #include //包含str ...… 查看全部问答> |
|
最近使用verilog对FPGA进行编程,遇到一个问题。当把一些的信号(比如输入信号,或INOUT信号)引出到测试脚上时,整个FPGA就不工作了。请问下这是怎么回事?为什么会出现这样的情况?怎么解决?望大家指点指点!… 查看全部问答> |
|
STM32在IAR中单步调试,为什么每行程序要运行两次才到下一行,跪求高手指点 STM32在IAR中单步调试,程序为下图,为什么第一行程序运行一次就到下一行,而2-5行程序必须单步两次才到下一行,第6、7行也只需一次,8-11行需要两次,12行需要一次,跪求高手指点下, 还有在下面程序中单步运行到第11 ...… 查看全部问答> |




