历史上的今天
今天是:2025年04月07日(星期一)
2020年04月07日 | MSP432驱动舵机串口输出角度
2020-04-07 来源:eefocus
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
史海拾趣
|
wince调试的时候的一个菜鸟问题 error an application targeting a standard sdk for windows ce.net and built for the armv4 cpu cannot be run on the emulator device In order to run this application an any cpu other than the emulator ...… 查看全部问答> |
|
请大家邦个忙,对ST的MEMS的传感器很感兴趣,型号为:LIS344alh三轴加速度计和LISY300AL陀螺仪。以前用的是Freescale的MMA7260和村田的ENC03M。数据手册的参数显示ST的传感器性能比我原来用的好,想测试一下,可国内没有可以少量订货的供货商 ...… 查看全部问答> |
|
为了不重复的发同样的资料,并且能够使得大家很快的找到需要的电子书籍查阅。我觉得论坛有必要做一个电子书籍发布的一个规则,这样便于大家浏览与下载,而且能够更好地利用好全部的网站的存储资源。 我觉得在定规则:1.在发布电子书籍的时候可以把 ...… 查看全部问答> |
|
电子类的方向那么多,现在在学校里也没有好办法真正体验到它们都是做些什么的。 现在已经要大三了。专业课也刚刚上了电路理论、数电、模电、嵌入式,但等大三课上的差不多了再考虑,又怕太晚了。 学校刚刚取消了直研,不想去考研,但是对以后的工 ...… 查看全部问答> |




