『壹』 stm32控制机械臂抓取的代码
实现stm32控制机械臂抓取的激枝运代码,首先需要实现机械臂的控制程序,包括初始化、变量定义、初始位置、转矩计算等。其次,实现传感器的数据采集,例如光电传感器、避障传感器、力感传感器等。再者,根据传感器采集的数据,得出机械臂各关节抓取需要的角度、角速度、转矩等参数,以控制机械臂实现物体抓取。最后,根据参数计算得出的角度,控制机械臂的舵机,从而实现抓取动作。搭团以上算法是实现stm32控制机械臂抓取的流程,通过编写程序明梁来实现代码。
『贰』 用单片机stm32控制二轴云台要用到哪些模块
看你用什么控制云台,如果用的是舵机的话,只需要用到定时器的pwm输出就行,改变pwm占空比,即可控制舵机转动。pwm频率一般在50Hz。 具体看舵机型号
『叁』 利用stm32的单片机完成下面的要求,程序该怎么写,用C语言
用两个定时器分别对两个LED灯闪烁,KEY1和KEY2要设置为外部中断输入,当进入中断时KEY1_DANG或KEY2_DANG指向下一个档位,并且发送串口。给你提供点思路。
void main()
{
while(1)
{
if(key1_dang==0x01)
中断定时1设置为0.2秒
if(key1_dang==0x02)
中断定时1设置为0.4秒
if(key1_dang==0x03)
中断定时1设置为0.6秒
if(key1_dang==0x04)
中断定时1设置为0.8秒
if(key1_dang==0x05)
中断定时1设置为1.0秒
if(key2_dang==0x01)
中断定时2设置为0.2秒
if(key2_dang==0x02)
中断定时2设置为0.4秒
if(key2_dang==0x03)
中断定时2设置为0.6秒
if(key2_dang==0x04)
中断定时2设置为0.8秒
if(key2_dang==0x05)
中断定时2设置为1.0秒
}
}
『肆』 如何编写STM32控制LED反转C程序
/*****************主要的用户自己编写的文件*********************/
/**
***********************************************************************
* @file : main.c
* @author : xr
* @date : 2014年5月14日08:23:25
* @version : V1.0
* @brief : 采用轮询方式检测按键 STM32F103VE T6 MCU
***********************************************************************
* @attention
* 实验平台 : 野火ISO-MINI-STM32开发板
* 实验现象 : 按下按键K2,实现LED1小灯的亮灭反转
* 按下按键K3,实现LED2小灯的亮灭反转
***********************************************************************
*/
#include "stm32f10x.h" /* 上帝之手 STM32库头文件 */
#include "led.h"
#include "key.h"
/**
* @brief : 主函数
* @param : 无
* @retval : 无
*/
int main(void)
{
ConfigLed(); /* 初始化LED控制端口 */
ConfigKey(); /* 初始化按键控制端口 */
LED1( ON ); /* 开始时点亮LED1 */
LED2( ON ); /* 开始时点亮LED2 */
while (1)
{
/* add your codes ^_^ */
/* 检测按键K2是否按下 */
if ( KeyScan( GPIOA, GPIO_Pin_0 ) == KEY_ON )
{
/* LED1反转 读取GPIOB 0端口位的值并用1减去之后再写入此位即LED1的控制位 */
GPIO_WriteBit( GPIOB, GPIO_Pin_0, (BitAction)(1 - GPIO_ReadOutputDataBit( GPIOB, GPIO_Pin_0 )));
}
/* 检测按键K3是否按下 */
if ( KeyScan( GPIOC, GPIO_Pin_13 ) == KEY_ON )
{
/* LED2反转 */
GPIO_WriteBit( GPIOC, GPIO_Pin_4, (BitAction)(1 - GPIO_ReadOutputDataBit( GPIOC, GPIO_Pin_4 )));
}
}
}
/**********************************************END OF FILE******************/
/**
***************************************************************
* @file led.h
* @author xr
* @date 2014年5月17日13:00:58
* @brief LED小灯驱动头文件
***************************************************************
* @attention
* 实验平台 : 野火ISO-MINI开发板
* LED小灯硬件连接 : -------------------
* | LED1 ---- PB0 |
* | LED2 ---- PC4 |
* | LED3 ---- PC3 |
* -------------------
***************************************************************
*/
#ifndef _LED_H_
#define _LED_H_
#include "stm32f10x.h" /* 使用stm32库 */
/* 控制小灯: 1 灭 0 亮 */
#define ON 0
#define OFF 1
/* 带参宏 */
#define LED1(a) if (a) \
GPIO_SetBits( GPIOB, GPIO_Pin_0 ); \
else \
GPIO_ResetBits( GPIOB, GPIO_Pin_0 )
#define LED2(a) if (a) \
GPIO_SetBits( GPIOC, GPIO_Pin_4 ); \
else \
GPIO_ResetBits( GPIOC, GPIO_Pin_4 )
#define LED3(a) if (a) \
GPIO_SetBits( GPIOC, GPIO_Pin_3 ); \
else \
GPIO_ResetBits( GPIOC, GPIO_Pin_3 )
void ConfigLed(void);
#endif /* _LED_H_ */
/*******************************************************END OF FILE*****/
/**
***************************************************************
* @file led.c
* @author xr
* @date 2014年5月17日13:00:58
* @brief LED小灯驱动
***************************************************************
* @attention
* 实验平台 : 野火ISO-MINI开发板
* LED小灯硬件连接 : -------------------
* | LED1 ---- PB0 |
* | LED2 ---- PC4 |
* | LED3 ---- PC3 |
* -------------------
***************************************************************
*/
#include "led.h"
/**
* @brief : 配置LED小灯的GPIO端口
* @param : 无
* @retval : 无
*/
void ConfigLed(void)
{
GPIO_InitTypeDef GPIO_InitStruct; /* 定义GPIO_InitTyPeDef结构体变量 */
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC, ENABLE ); /* 开启APB2总线上的GPIOB和GPIOC时钟 */
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP; /* 设置引脚为通用强推挽输出 */
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; /* 设置输出为50MHZ */
/* 调用库函数初始化GPIOB端口 */
GPIO_Init ( GPIOB, &GPIO_InitStruct );
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_3; /* 选择3,4引脚 */
/* 调用库函数初始化GPIOC的34引脚 */
GPIO_Init (GPIOC, &GPIO_InitStruct );
/* 关闭LED */
GPIO_SetBits ( GPIOB, GPIO_Pin_0 );
GPIO_SetBits ( GPIOC, GPIO_Pin_4 | GPIO_Pin_3 );
}
/*************************************************END OF FILE***********/
/**
『伍』 ad7793在stm32下的控制程序谁有,千分悬赏。经验证后付费也可以。
够详细了吧。。。
void AD7793_GPIO_Config(void){ GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_6 | GPIO_Pin_7; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(GPIOA, &GPIO_InitStructure); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); AD7793_CS_SET(); }void WriteToReg(unsigned char ByteData) { unsigned char temp; unsigned char i; AD7793_CS_CLR(); temp=0x80; for(i=0;i<8;i++) { if((temp & ByteData)==0) { AD7793_DIN_CLR(); } else { AD7793_DIN_SET(); } AD7793_SCLK_CLR(); Delay(200); AD7793_SCLK_SET(); Delay(200); temp=temp>>1; } AD7793_CS_SET();}void AD7793_Reset(void) //复位{ unsigned int ResetTime; ResetTime=32; AD7793_SCLK_SET(); AD7793_CS_CLR(); AD7793_DIN_SET(); while(ResetTime--) { WriteToReg(0xff); Delay(100); AD7793_SCLK_CLR(); Delay(100); AD7793_SCLK_SET(); } AD7793_CS_SET();}unsigned char AD7793_ReadStatusRegister(void) //读状态寄存器{ unsigned char j; unsigned char temp; WriteToReg(0x40); AD7793_DIN_SET(); AD7793_CS_CLR(); temp=0; AD7793_DOUT_SET() for(j=0; j<8; j++) { AD7793_SCLK_CLR(); AD7793_DOUT_SET() if(AD7793_DOUT_GET()==0) { temp=temp<<1; }else { temp=temp<<1; temp=temp+0x01; } Delay(200); AD7793_SCLK_SET(); Delay(200); } AD7793_CS_SET(); return temp;}void Ad7793_WriteModeRegister(unsigned char ModeRegisterH,unsigned char ModeRegisterL) //写模式寄存器{ WriteToReg(0x08); WriteToReg(ModeRegisterH); WriteToReg(ModeRegisterL);}void Ad7793_WriteConfigRegister(unsigned char ConfigRegisterH,unsigned char ConfigRegisterL) //写配置寄存器{ WriteToReg(0x10); WriteToReg(ConfigRegisterH); WriteToReg(ConfigRegisterL); }void Ad7793_WriteIORegister(unsigned char IORegister) //写IO寄存器{ WriteToReg(0x28); WriteToReg(IORegister); }long AD7793_ReadDataRegister(void) //读数据寄存器{ union long_4uchar AD7793Result; unsigned char i,j; unsigned char temp; temp=AD7793_ReadStatusRegister(); while((temp&0x80)==0x80) { temp=AD7793_ReadStatusRegister(); } WriteToReg(0x58); AD7793_DIN_SET(); AD7793_CS_CLR(); AD7793_DOUT_SET() for(i=0; i<3; i++) { for(j=0; j<8; j++) { AD7793_SCLK_CLR(); AD7793_DOUT_SET() if(AD7793_DOUT_GET()==0) { temp=temp<<1; }else { temp=temp<<1; temp=temp+0x01; } Delay(200); AD7793_SCLK_SET(); Delay(200); } AD7793Result._4byte._uchar[3-i]=temp; } AD7793_CS_SET(); AD7793Result._long=AD7793Result._long>>17; return AD7793Result._long;}void Init_AD7793(void){ AD7793_GPIO_Config(); AD7793_Reset(); Ad7793_WriteModeRegister(0x00,0x0a); Ad7793_WriteConfigRegister(0x1A,0x10); Ad7793_WriteIORegister(0x03);}
『陆』 请教一个stm32程序:我写了一个按键控制LED灯翻转,调试成功的程序如下:
有问题的那个程序
u8 ReadValue=GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_10);
只在上面那条指令采集了一次按键数据。
等到执行回到 while(!ReadValue);//等待按键被放开答 这条指令时
数据仍然是上次采集到的那个值代表按键按下,(!ReadValue)这个值永远成立,所以无法代表按键断开。所以程序一直卡死在这条指令上。如果要通过就必须在判据里重新读取按键状态,像正确的程序那样用这样的指令
while(!GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_10));//等待按键被放开
另外因为你只读取了一次按键状态,所以下面那么多一堆软件消除抖动的程序白写了。
综上,正确的程序在每个判断的时刻都要重新读取下按键状态。
『柒』 请问哪位大神有基于STM32的SVPWM控制程序,求小弟我参考一下~~
你说的是PWM事件生成吧
void PWM_Init(u16 arr,u16 psc)
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE); //使能GPIO外设和AFIO复用功能模块时钟使能
//用于TIM3的CH2输出的PWM通过该LED显示
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
//设置该引脚为复用输出功能,输出TIM3 CH2的PWM脉冲波形
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7; //TIM_CH2
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
//GPIO_WriteBit(GPIOA, GPIO_Pin_7,Bit_SET); // PA7上拉
TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值 80K
TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值 不分频
TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //选择定时器模式:TIM脉冲宽度调制模式2
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
TIM_OCInitStructure.TIM_Pulse = 0; //设置待装入捕获比较寄存器的脉冲值
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高
TIM_OC2Init(TIM3, &TIM_OCInitStructure); //根据TIM_OCInitStruct中指定的参数初始化外设TIMx
TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable); //使能TIMx在CCR2上的预装载寄存器
TIM_ARRPreloadConfig(TIM3, ENABLE); //使能TIMx在ARR上的预装载寄存器
TIM_Cmd(TIM3, ENABLE); //使能TIMx外设
}
TIM_SetCompare2(TIM3,led0pwmval);
『捌』 求stm32控制四自由度舵机的程序
这个应该是通过串口发送数据信息的,发送和接收在一根信号线上,手上没有现成的程序,你看看这个在其他网上的行不行,
最好根据手册自己写
#include <avr/io.h>
#include <util/delay.h>
void InitUart0(void)
{
UCSR0A = 0x02; // 设置为倍速模式
UBRR0H = 0;
UBRR0L = 1;
UCSR0B = (1<<RXEN)|(1<<TXEN);// 接收器与发送器使能
UCSR0C = (3<<UCSZ0);
DDRE &= ~_BV(PE0); // 初始化RX 端口默认方向为输入
PORTE &= ~_BV(PE0); // 初始化RX 端口默认状态为高阻
DDRE |= _BV(PE1); // 初始化TX 端口默认方向为输出
PORTE |= _BV(PE1); // 初始化TX 端口默认状态为高电平
DDRA |= _BV(PA0); // 初始化使能端口状态方向为输出
PORTA &= ~_BV(PA0); // 初始化使能端口状态为RX 状态
DDRA |= _BV(PA1); // 初始化使能端口状态方向为输出
PORTA |= _BV(PA1); // 初始化使能端口状态方为TX 状态
}
void SendUart0Byte(unsigned char data)
{
while ( !( UCSR0A & (1<<UDRE)) );// 等待发送缓冲器为空
UDR0 = data;/* 将数据放入缓冲器,发送数据*/
}
void SetServoLimit(unsigned char id, unsigned short int cw_limit, unsigned short int ccw_limit)
{
unsigned short int temp_ccw = 0; // 临时速度,用于进行方向判别
unsigned short int temp_cw = 0;
unsigned char temp_ccw_h = 0; // 待发送数据h 位
unsigned char temp_ccw_l = 0; // 待发送数据l 位
unsigned char temp_cw_h = 0;
unsigned char temp_cw_l = 0;
unsigned char temp_sum = 0; // 校验和寄存变量
if (ccw_limit > 1023)
{
temp_ccw = 1023; // 限制速度值在可用范围内
}
else
{
temp_ccw = ccw_limit;
}
if (cw_limit > 1023)
{
temp_cw = 1023;
}
else
{
temp_cw = cw_limit;
}
temp_ccw_h = (unsigned char)(temp_ccw >> 8);
temp_ccw_l = (unsigned char)temp_ccw; // 将16bit 数据拆为2个8bit 数据
temp_cw_h = (unsigned char)(temp_cw >> 8);
temp_cw_l = (unsigned char)temp_cw; // 将16bit 数据拆为2个8bit 数据
PORTA &= ~_BV(PA1);
PORTA |= _BV(PA0); // 使总线处于主机发送状态
UCSR0A |= (1<<TXC0); // 清除UART0写完成标志
SendUart0Byte(0xFF); // 发送启动符号0xFF
SendUart0Byte(0xFF); // 发送启动符号0xFF
SendUart0Byte(id); // 发送id
SendUart0Byte(7); // 发送数据长度为参数长度+2,参数长度为3
SendUart0Byte(0x03); // 命令数据为“WRITE DATA”
SendUart0Byte(0x06); // 舵机控制寄存器首地址
SendUart0Byte(temp_cw_l); // 发送顺时针位置限制低位
SendUart0Byte(temp_cw_h); // 发送顺时针位置限制高位
SendUart0Byte(temp_ccw_l); // 发送逆时针位置限制低位
SendUart0Byte(temp_ccw_h); // 发送逆时针位置限制高位
temp_sum = id + 7 + 0x03 + 0x06 + temp_cw_l + temp_cw_h + temp_ccw_l + temp_ccw_h;
temp_sum = ~temp_sum; // 计算校验和
SendUart0Byte(temp_sum); // 发送校验和
while ( !( UCSR0A & (1<<TXC0)) ) // 等待发送完成
{ // (Waiting for finishing sending)
;
}
PORTA |= _BV(PA1);
PORTA &= ~_BV(PA0); // 使总线处于主机接收状态
_delay_ms(2); //送完成后,总线会被从机占用,反馈应答数据,所以进行延时
}
void SetServoPosition(unsigned char id, unsigned short int position, unsigned short int
velocity)
{
unsigned short int temp_velocity = 0; // 临时速度,用于进行方向判别
unsigned short int temp_position = 0;
unsigned char temp_velocity_h = 0; // 待发送数据h 位
unsigned char temp_velocity_l = 0; // 待发送数据l 位
unsigned char temp_position_h = 0;
unsigned char temp_position_l = 0;
unsigned char temp_sum = 0; // 校验和寄存变量
if (velocity > 1023)
{
temp_velocity = 1023; // 限制速度值在可用范围内
}
else
{
temp_velocity = velocity;
}
if (position > 1023)
{
temp_position = 1023;
}
else
{
temp_position = position;
}
temp_velocity_h = (unsigned char)(temp_velocity >> 8);
// 将16bit 数据拆为2个8bit 数据
temp_velocity_l = (unsigned char)temp_velocity;
temp_position_h = (unsigned char)(temp_position >> 8);
// 将16bit 数据拆为2个8bit 数据
temp_position_l = (unsigned char)temp_position;
PORTA &= ~_BV(PA1);
PORTA |= _BV(PA0); // 使总线处于主机发送状态
UCSR0A |= (1<<TXC0); // 清除UART0写完成标志
SendUart0Byte(0xFF); // 发送启动符号0xFF
SendUart0Byte(0xFF);
SendUart0Byte(id); // 发送id
SendUart0Byte(7); // 发送数据长度为参数长度+2,参数长度为3
SendUart0Byte(0x03); // 命令数据为“WRITE DATA”
SendUart0Byte(0x1E); // 舵机控制寄存器首地址
SendUart0Byte(temp_position_l); // 发送速度数据低位
SendUart0Byte(temp_position_h); // 发送速度数据高位
SendUart0Byte(temp_velocity_l); //发送位置低字节
SendUart0Byte(temp_velocity_h); // 发送位置高字节
temp_sum = id + 7 + 0x03 + 0x1E + temp_position_l + temp_position_h + temp_velocity_l +
temp_velocity_h;
temp_sum = ~temp_sum; // 计算校验和
SendUart0Byte(temp_sum); // 发送校验和 (Send the checksum)
while ( !( UCSR0A & (1<<TXC0)) ) // 等待发送完成
{ // (Waiting for finishing sending)
;
}
PORTA |= _BV(PA1);
PORTA &= ~_BV(PA0); // 使总线处于主机接收状态
_delay_ms(2); // 发送完成后,总线会被从机占用,反馈应答数据,所以进行延时
}
void SetServoVelocity(unsigned char id, signed short int velocity)
{
unsigned char temp_sign = 0; // 临时符号,用于进行方向判别
unsigned short int temp_velocity = 0; // 临时速度,用于进行方向判别
unsigned char temp_value_h = 0; // 待发送数据h 位
unsigned char temp_value_l = 0; // 待发送数据l 位
unsigned char temp_sum = 0; // 校验和寄存变量
if (velocity < 0)
{
temp_velocity = -velocity; // 如果为负数,则取绝对值
temp_sign = 1; // 设置负数符号标志
}
else
{
temp_velocity = velocity;
temp_sign = 0; // 设置正数符号标志
}
if (temp_velocity > 1023)
{
temp_velocity = 1023; // 限制速度值在可用范围内
}
temp_velocity |= (temp_sign << 10);
temp_value_h = (unsigned char)(temp_velocity >> 8);
// 将16bit 数据拆为2个8bit 数据
temp_value_l = (unsigned char)temp_velocity;
PORTA &= ~_BV(PA1);
PORTA |= _BV(PA0); // 使总线处于主机发送状态
UCSR0A |= (1<<TXC0); // 清除UART0写完成标志
SendUart0Byte(0xFF); // 发送启动符号0xFF
SendUart0Byte(0xFF); // 发送启动符号0xFF
SendUart0Byte(id); // 发送id
SendUart0Byte(5); // 发送数据长度为参数长度+2,参数长度为3
SendUart0Byte(0x03); // 命令数据为“WRITE DATA”
SendUart0Byte(0x20); // 舵机控制寄存器首地址
SendUart0Byte(temp_value_l); // 发送速度数据低位
SendUart0Byte(temp_value_h); // 发送速度数据高位
temp_sum = id + 5 + 0x03 + 0x20 + temp_value_l + temp_value_h;
temp_sum = ~temp_sum; // 计算校验和
SendUart0Byte(temp_sum); // 发送校验和
while ( !( UCSR0A & (1<<TXC0)) ) // 等待发送完成
{
;
}
PORTA |= _BV(PA1);
PORTA &= ~_BV(PA0); // 使总线处于主机接收状态
_delay_ms(2); // 发送完成后,总线会被从机占用,反馈应答数据,所以进行延时
}
int main(void)
{
InitUart0();
SetServoLimit(2,0,1023);
while(1)
{
_delay_ms(1000); //延时1s
SetServoPosition(2, 1000, 500); //控制舵机以500的速度运动到1000的位置
_delay_ms(1000); //延时1s
SetServoPosition(2, 200, 100); //控制舵机以100的速度运动到200的位置
}
}