MSP432驱动舵机串口输出角度

发布者:sigma28最新更新时间:2020-04-07 来源: eefocus关键字:MSP432  驱动舵机  串口  输出角度 手机看文章 扫描二维码
随时随地手机看文章

MSP432驱动舵机串口输出角度

备注:我用的TI官方launchpad的MSP432P401R开发板

1、舵机需要50Hz基准的PWM,占空比是0.025~0.125.如何产生PWM,当然是定时器了。查看MSP432P401R数据手册,有4个定时器。

在这里插入图片描述

2、要算出详细的具体PWM频率,就需要知道系统的时钟,定时器的时钟。MSP432时钟来源比较复杂。具体可以看手册。(上TI官网下载)

手在这里插入图片描述

5个时钟源,这里我选择HFXTCLK外部高速时钟(48MHz)

3、定时器的时钟来源可以有4种选择

在这里插入图片描述

这里我选择SMCLK时钟,定时器和串口都是SMCLK时钟源。

4、定时器具体配置代码

<1>、定义PWM结构并初始化


Timer_A_PWMConfig TIM0_PwmConfig =

{

TIMER_A_CLOCKSOURCE_SMCLK,

TIMER_A_CLOCKSOURCE_DIVIDER_4,//12MHZ / 4 = 3MHz

60000,//3000 000 / 50 = 60000

TIMER_A_CAPTURECOMPARE_REGISTER_1,

TIMER_A_OUTPUTMODE_RESET_SET,

1500//舵机初始化角度

};


<2>、定时器初始化


void TimerA0_Init(void)

{

    /* Configuring GPIO2.4 as peripheral output for PWM  */

    MAP_GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P2, 

GPIO_PIN4,

    GPIO_PRIMARY_MODULE_FUNCTION);

    /* Configuring Timer_A to have a period of approximately 500ms and

     * an initial duty cycle of 10% of that (3200 ticks)  */

    MAP_Timer_A_generatePWM(TIMER_A0_BASE, &TIM0_PwmConfig);

}


<3>、舵机角度控制


/**

 *************************************************************************

 * @brief: Servo_TurnAngle

 * @param: uch_angle -- 舵机旋转角度

 * @return: void

 * @function: 舵机旋转角度

 * @author: 

 * @version: V1.0

 * @note: 舵机需要50hz 3000000 / 60000= 50hz 60000

0度 0.5/20=0.025  60000*0.025= 1500

180度 2.5/20=0.125  60000*0.125= 7500

 *************************************************************************

**/

void Servo_TurnAngle(INT8U uch_angle)

{

FP32 f_cycle;

f_cycle = (7500.0f - 1500.0f) / 180.0f * uch_angle + 1500.0f;//定时器计数与角度

TIM0_PwmConfig.dutyCycle = (INT16U)f_cycle;//新的占空比

TIM2_PwmConfig.dutyCycle = (INT16U)f_cycle;//新的占空比

MAP_Timer_A_generatePWM(TIMER_A0_BASE, &TIM0_PwmConfig);

}


5、串口配置代码实现

<1>、串口初始化


/**

 *************************************************************************

 * @brief: Uart0_Init

 * @param: void

 * @return: void

 * @function: 串口0初始化 波特率9600

 * @author: 

 * @version: V1.0

 * @note:http://software-dl.ti.com/msp430/msp430_public_sw/mcu/msp430/MSP430BaudRateConverter/index.html

 *************************************************************************

**/

void Uart0_Init(void)

{

eUSCI_UART_Config uartConfig =

{

EUSCI_A_UART_CLOCKSOURCE_SMCLK,          // SMCLK Clock Source

78,                                     // BRDIV = 78

2,                                       // UCxBRF = 2

0,                                       // UCxBRS = 0

EUSCI_A_UART_NO_PARITY,                  // No Parity

EUSCI_A_UART_LSB_FIRST,                  // LSB First

EUSCI_A_UART_ONE_STOP_BIT,               // One stop bit

EUSCI_A_UART_MODE,                       // UART mode

EUSCI_A_UART_OVERSAMPLING_BAUDRATE_GENERATION  // Oversampling

};

    /* Selecting P1.2 and P1.3 in UART mode */

    MAP_GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P1,

   GPIO_PIN2 | GPIO_PIN3, 

   GPIO_PRIMARY_MODULE_FUNCTION);


    /* Configuring UART Module */

    MAP_UART_initModule(EUSCI_A0_BASE, &uartConfig);


    /* Enable UART module */

    MAP_UART_enableModule(EUSCI_A0_BASE);


    /* Enabling interrupts */

    MAP_UART_enableInterrupt(EUSCI_A0_BASE, EUSCI_A_UART_RECEIVE_INTERRUPT);

    MAP_Interrupt_enableInterrupt(INT_EUSCIA0);

MAP_Interrupt_enableSleepOnIsrExit();

    MAP_Interrupt_enableMaster(); 

}


这里,串口时钟来源也是有4种,这里我还是选SMCLK.串口配置结构体内的参数,根据note网址计算。也可根据手册自己计算,过程比较复杂,还是用官方出的工具吧。


<2>、发送数据

/**

 *************************************************************************

 * @brief: Uart0_SendByte

 * @param: uch_byte -- 字节

 * @return: void

 * @function:

 * @author: 

 * @version: V1.0

 * @note:

 *************************************************************************

**/

void Uart0_SendByte(INT8U uch_byte)

{

MAP_UART_transmitData(EUSCI_A0_BASE, uch_byte);

}

/**

 *************************************************************************

 * @brief: Uart0_SendDtring

 * @param: puch_buf -- 缓存指针 uin_len --数据长度

 * @return: void

 * @function: 串口发送字符串

 * @author: 

 * @version: V1.0

 * @note:

 *************************************************************************

**/

void Uart0_SendDtring(INT8U *puch_buf, INT16U uin_len)

{

INT16U i;

for(i = 0; i < uin_len; i++)

{

Uart0_SendByte(*(puch_buf + i));

}

}


<3>、串口接收中断服务函数


/**

 *************************************************************************

 * @brief: EUSCIA0_IRQHandler

 * @param: void

 * @return: void

 * @function: 串口中断服务函数

 * @author: 

 * @version: V1.0

 * @note:

 *************************************************************************

**/

void EUSCIA0_IRQHandler(void)

{

    uint32_t status = MAP_UART_getEnabledInterruptStatus(EUSCI_A0_BASE);


    MAP_UART_clearInterruptFlag(EUSCI_A0_BASE, status);


    if(status & EUSCI_A_UART_RECEIVE_INTERRUPT_FLAG)

    {

        MAP_UART_transmitData(EUSCI_A0_BASE, MAP_UART_receiveData(EUSCI_A0_BASE));

    }

}


接收到什么,重新发回。这里需要接收数据,增加接收缓存即可。


5、主函数代码

<1>、初始化定时器、串口


    MAP_WDT_A_holdTimer();//挂起看门狗

SystemClockInit(HFXT);//初始化时钟到48MHz

/* Enabling the FPU for floating point operation */

    MAP_FPU_enableModule();

    MAP_FPU_enableLazyStacking();//打开FPU,硬件运算浮点数

    

CS_initClockSignal(CS_SMCLK, CS_HFXTCLK_SELECT, CS_CLOCK_DIVIDER_4);//48MHz / 4 = 12MHz

TimerA0_Init();//定时器A0初始化

KEY_Init();//按键初始化

Uart0_Init();//串口0初始化 9600

GlobalValue_Init();//全局变量初始化

Interrupt_enableMaster();//使能全局中断


<2>、循环执行


    while (1)

    {

Key_Scanf();//按键扫描

if(t++ / 100)

{

t = 0;

LED_Control(GREEN_LED);//绿灯

}

delay_us(1);//短暂延时

sprintf((char*)buff, "舵机角度:%drn", guch_ServoAngle);

Uart0_SendDtring(buff, strlen((char*)buff));//发送数据

    }


<3>系统时钟代码


/**********************************

时钟:          默认时钟源        默认频率          描述

MCLK             DCO              3MHZ          主时钟,向CPU和外设提供时钟

    HSMCLK        DCO              3MHZ          子系统主时钟,向外设提供时钟源

SMCLK            DCO              3MHZ          低速系统主时钟,向外设提供时钟源

ACLK     LFXT(或REFO没有晶振时)   32.768kHz     辅助时钟,向外设提供时钟

BCLK     LFXT(或REFO没有晶振时)   32.768kHz     低速后配域时钟,提供LPM外设

********************************/

void SystemClockInit(u8 ClockSource)

{

 /* Halting the Watchdog */

  MAP_WDT_A_holdTimer();


if(ClockSource==LFXT ){

///////////////////////////////////////////////////////////

        /* 配置外部低速时钟引脚*/

    MAP_GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_PJ,

            GPIO_PIN0 | GPIO_PIN1, GPIO_PRIMARY_MODULE_FUNCTION);

    /* Setting the external clock frequency. This API is optional, but will

     * come in handy if the user ever wants to use the getMCLK/getACLK/etc

     * functions

     */

    CS_setExternalClockSourceFrequency(32768,48000000);


    /* Starting LFXT in non-bypass mode without a timeout. */

    CS_startLFXT(false);


    /* Initializing MCLK to LFXT (effectively 32khz) */ //主时钟

    MAP_CS_initClockSignal(CS_ACLK, CS_LFXTCLK_SELECT, CS_CLOCK_DIVIDER_1);


    /* Since we are operating at 32khz, we can operating in LF mode */

   // MAP_PCM_setPowerMode(PCM_LF_MODE);

}

else if (ClockSource==HFXT){

////////////////////////////////////////////////////////////////

    /* 配置外部高速时钟引脚 */

    GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_PJ,

            GPIO_PIN3 | GPIO_PIN2, GPIO_PRIMARY_MODULE_FUNCTION);


    /* Just in case the user wants to use the getACLK, getMCLK, etc. functions,

     * let's set the clock frequency in the code. 

     */

    CS_setExternalClockSourceFrequency(32000,48000000);


    /* Starting HFXT in non-bypass mode without a timeout. Before we start

     * we have to change VCORE to 1 to support the 48MHz frequency */

    PCM_setCoreVoltageLevel(PCM_VCORE1);

    FlashCtl_setWaitState(FLASH_BANK0, 2);

    FlashCtl_setWaitState(FLASH_BANK1, 2);

    CS_startHFXT(false);//false


    /* Initializing MCLK to HFXT (effectively 48MHz) */

    MAP_CS_initClockSignal(CS_MCLK, CS_HFXTCLK_SELECT, CS_CLOCK_DIVIDER_1);

}

else  if (ClockSource==DCO){

////////////////////////////////////////////////////////////////////////////

           /*DCO时钟源配置,内部数控振荡器*/

    /* Enabling FPU for DCO Frequency calculation */

    FPU_enableModule();

    /* Setting the DCO Frequency to a non-standard 12MHz */

    CS_setDCOFrequency(CS_12MHZ);

CS_setDCOCenteredFrequency(CS_DCO_FREQUENCY_12);//8~16MHZ

[1] [2]
关键字:MSP432  驱动舵机  串口  输出角度 引用地址:MSP432驱动舵机串口输出角度

上一篇:MSP432E401Y单片机智能小车PID调速代码
下一篇:MSP430F149程序移植——0.96OLED(ssd1306驱动)

推荐阅读最新更新时间:2024-11-11 20:44

STM32串口输出乱码的原因
最近学习 STM32 开发,申请了一块免费的开发版,按照书上的内容学习,学到USART,发现串口输出始终乱码,妈蛋的,搞不懂为啥,代码啥的都是按照书上来的啊,最后搜索很久,发现是外部 时钟 频率配置错误导致的,库使用默认8MHz晶震,可以通过宏使用25MHz晶震。具体定义在stm32f10x.h文件中 这里提供了实用8MHz或者25MHz晶震,但是我2个都尝试了,还是乱码,最后一想,是不是我的开发版晶震不是这个值哦,最后拿着开发版一看,妈蛋的,果然不是,而是使用的12MHz晶震,立马自己定义一个宏修改成12000000,编译,烧写,一下就对了。坑啊! 怎么看自己的开发版晶震是多少,看图 然后修改上面的代码,加一个宏定义就
[单片机]
STM32<font color='red'>串口</font><font color='red'>输出</font>乱码的原因
串口不定长接收数据--空闲中断方式测试
1.问题描述: 使用串口的空闲中断和接收中断进行串口数据的不定长接收 2.测试平台: (1)芯片STM32F756VGT6 (2)IAR软件环境 (3)使用芯片的串口6,和外接的RS485收发模块一起用做RS485通讯 3.实际操作: (1)串口初始化: void MX_UART6_Init(void) { huart6.Instance = USART6; huart6.Init.BaudRate = 115200; huart6.Init.WordLength = UART_WORDLENGTH_8B; huart6.Init.StopBits = UART_STOPBITS_1
[单片机]
单片机与上位机的串口通信
照片名称:串口发送数据十六进制55 照片名称:串口通信输入十六进制55 照片名称:串口通信输入十六进制55 照片名称:串口发送数据十六进制aa 照片名称:串口通信输入十六进制aa 照片名称:串口通信输入十六进制aa #include reg52.h #define uchar unsigned char #define uint unsigned int          //宏定义 sbit duan=P2^6;              //位声明 sbit wei=P2^7; uchar code sz ={             // 数码管 显
[单片机]
单片机与上位机的<font color='red'>串口</font>通信
STM32L151调试串口cubeMX
1、使用cubeMX自动生成底层代码,配置串口参数及相关IO口。 2、出现问题,可以发送,但是不能接收数据。 3、问题原因:没有开启中断。需要在初始化过程添加以下代码: __HAL_UART_ENABLE_IT(&huart1, UART_IT_RXNE);//开启串口接收中断 4、另外还要在串口接收中断函数末尾加上清除接收中断函数标识位函数: __HAL_UART_CLEAR_FLAG(&huart1,UART_FLAG_RXNE);
[单片机]
STM32学习记录14 ucosii中的串口中断
先看邵老师的书中怎么写 里面写到: C/OS中,中断服务子程序要用汇编语言来写。然而,如果用户使用的C语言编译器支持在线汇编语言的话,用户可以直接将中断服务子程序代码放在C语言的程序文件中。 再看《M3权威指南》2.11.2节与9.11节中讲到Cortex-M3在进入异常时自动压栈。。。。返回时自动出栈,再也不需要汇编语言编写了。也就是说我们可以使用C语言来编写中断服务程序。并且省去了上面程序清单的(1)(5)(6). 其实ucos中的终端和裸奔的中断写法基本一致,只是加了几条语句,如下为串口中断的写法: void USART1_IRQHandler(void) { uint8_t RxData; O
[单片机]
STM32学习记录14 ucosii中的<font color='red'>串口</font>中断
基于CCS工程MSP430串口升级(三)
一、前文 第一次接触MSP430的芯片,第一次使用CCS开发环境,花了将近一个星期的时间,才把MSP430串口升级做出来。 同样分成BOOT(引导程序)、APP(主程序)、上位机(PC端工具),三个部分来讲解。 二、正文 折腾这个功能的时候,遇到了很多问题,现在来一一描述 C和汇编语言混合编程 C语言嵌入汇编语言是asm(“xxx”);,这样一开始编译一直不过。 然后几经百度谷歌后,发现在xxx前面加上制表符t,asm( xxx );,编译就过了。 IAR没有这个问题,CCS就这样。看来CCS编译器还有待改进。 汇编语言,#和&傻傻分不清 mov #0xEFFE,PC和mov &0xEFFE,PC 一开始搞不清楚,啥区
[单片机]
基于CCS工程MSP430<font color='red'>串口</font>升级(三)
ARM7入门10,串口通信
主程序: /******************************************************************************* *File: main.C *功能: 串口发送数据 *说明: 使用外部晶振,不使用PLL,Fpclk=Fcclk/4 *******************************************************************************/ #include config.h /*********************************************************************
[单片机]
ARM7入门10,<font color='red'>串口</font>通信
STM32 HAL库 printf 串口重定向
在对printf重定向之前,一定不要有printf,否则程序马上跑飞。 在main函数之前加上如下代码对串口进行重定向,当然,串口一定要初始化之后再用printf,否则程序虽然不会飞,但是printf也不会有结果 #ifdef __GNUC__ #define PUTCHAR_PROTOTYPE int __io_putchar(int ch) #else #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f) #endif PUTCHAR_PROTOTYPE { //具体哪个串口可以更改huart1为其它串口 HAL_UART_Transmit(&huart1 , (
[单片机]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved