Ti MSP430F5529LP学习笔记

一边学习,一边记录,有踩坑,有试错,有经验。此前完全不会电。

配置阶段就不赘述了,真的,Ti的开发者手册就很明白。比别的开发板配置简单不止一点点(笔者同时还在学STM32)

1.点亮LED灯

成功,耗时几分钟。

LED2

#include <msp430.h> 


/**
 * main.c
 */
int main(void)
{
    WDTCTL = WDTPW | WDTHOLD;   // stop watchdog timer
    //P4.7为输出
    P4DIR=0x80;  //0x80=1000 0000,查看数据手册可知,P4.7为输出,P4其他脚为输入
    //P4.7输出高电平
    P4OUT=0x80;  //0x80=1000 0000,查看数据手册可知,P4.7为输出高电平,P4其他脚为下拉输入
    return 0;
}

把P4改为P1,80改01 

附代码图为LED1,2一起亮.

看视频,了解看门狗是什么。

队友来了,我不是一个人了。直接开搞超声波模块。

 

 在这里插入图片描述

 还是要再了解一波MSP430,不然程序也不会写呀。又去看视频教程了

 

 从液晶显示屏开始练手吧!

#include <msp430.h>


#define RS_CLR P1OUT &= ~BIT2;
#define RS_SET P1OUT |=  BIT2;
#define RW_CLR P1OUT &= ~BIT3;
#define RW_SET P1OUT |=  BIT3;
#define EN_CLR P1OUT &= ~BIT4;
#define EN_SET P1OUT |=  BIT4;
#define DataPort P3OUT

void LCD1602_Port_init()
{
    P3SEL |= 0x00;
    P3DIR |= 0xFF;
    P1DIR |= BIT2 + BIT3 + BIT4; // 控制口设置为输出模式
}

void LCD1602_write_com(unsigned char com)
{
    RS_CLR;
    RW_CLR;
    DataPort = com; // 命令写入端口
    delay_ms(5);
    EN_SET;
    delay_ms(5);
    EN_CLR;
}

void LCD_init(void)
{
    EN_CLR;
    LCD1602_write_com(0x38); // 显示模式设置, 8位数据显示,双行
    delay_ms(5);
    // LCD1602_write_com(0x08); // 显示关闭
    // delay_ms(5);
    LCD1602_write_com(0x0C); // 显示开及光标设置
    delay_ms(5);
    LCD1602_write_com(0x06); // 显示光标移动设置
    delay_ms(5);
    LCD1602_write_com(0x01); // 显示清屏
    delay_ms(5);
}

int main(void)
{
    // Stop watchdog timer to prevent time out reset
    WDTCTL = WDTPW | WDTHOLD;
    LCD1602_Port_init();
    LCD1602_init();
    LCD1602_write_com(0x01);
    LCD1602_write_com(0x80);
    LCD1602_write_data('6');
    LCD1602_write_data(0x39);
    LCD1602_write_com(0xc0);
    LCD1602_write_data('7');
    LCD1602_write_data(0x32);
    return 0;
}

企图接入1602显示屏,不行。但是不认为是接线错误,应该是显示屏被烧坏了。

#include <msp430.h>

#define CPU_F ((double)8000000)
#define delay_us(x) __delay_cycles((long)(CPU_F*(double)x/1000000.0))
#define delay_ms(x) __delay_cycles((long)(CPU_F*(double)x/1000.0))

#define DataDir     P3DIR
#define DataPort    P3OUT
//#define Busy        0x80
//#define CtrlDir     P1DIR
#define RS_CLR P1OUT&=~BIT3;    //RS = P1.3
#define RS_SET P1OUT|=BIT3;
#define RW_CLR P1OUT&=~BIT4;    //RW = P1.4
#define RW_SET P1OUT|=BIT4;
#define EN_CLR P1OUT&=~BIT5;    //EN = P1.5
#define EN_SET P1OUT|=BIT5;

/*------------------------------------------------
              判忙函数
------------------------------------------------*/
 int LCD_Check_Busy(void)
 {
    DataPort= 0xFF;
    RS_CLR;
    RW_SET;
    EN_CLR;
    delay_ms(5);
    EN_SET;
    return (DataPort & 0x80);
 }

 void Port_init()
 {
     P1DIR |= BIT3+BIT4+BIT5;
     DataDir = 0xFF;
 }
/*------------------------------------------------
              写入命令函数
------------------------------------------------*/
 void LCD_Write_Com(unsigned char com)
 {
    // while(LCD_Check_Busy()); //忙则等待
    delay_ms(5);
    RS_CLR;
    RW_CLR;
    EN_SET;
    DataPort= com;
    delay_ms(5);
    EN_CLR;
 }
/*------------------------------------------------
              写入数据函数
------------------------------------------------*/
 void LCD_Write_Data(unsigned char Data)       //ok
 {
    //while(LCD_Check_Busy()); //忙则等待
    delay_ms(5);
    RS_SET;
    RW_CLR;
    EN_SET;
    DataPort= Data;
    delay_ms(5);
    EN_CLR;
 }

/*------------------------------------------------
                清屏函数
------------------------------------------------*/
 void LCD_Clear(void)
 {
 LCD_Write_Com(0x01);
 delay_ms(5);
 }
/*------------------------------------------------
              写入字符串函数
------------------------------------------------*/
 void LCD_Write_String(unsigned char x,unsigned char y,unsigned char *s)  //ok
 {
    if (y == 0)
    {
        LCD_Write_Com(0x80 + x);     //表示第一行
    }
    else
    {
        LCD_Write_Com(0xC0 + x);      //表示第二行
    }
    while (*s)
    {
        LCD_Write_Data( *s);
        s++;
    }
 }
/*------------------------------------------------
              写入字符函数
------------------------------------------------*/
 void LCD_Write_Char(unsigned char x,unsigned char y,unsigned char Data)      //OK
{
    if (y == 0)
    {
        LCD_Write_Com(0x80 + x);
    }
    else
    {
        LCD_Write_Com(0xC0 + x);
    }
        LCD_Write_Data(Data);
}
/*------------------------------------------------
              初始化函数
------------------------------------------------*/
void LCD_Init(void)                                    //ok
{
    LCD_Write_Com(0x38);    /*显示模式设置*/
    delay_ms(5);
    LCD_Write_Com(0x38);
    delay_ms(5);
    LCD_Write_Com(0x38);
    delay_ms(5);
    LCD_Write_Com(0x38);
    LCD_Write_Com(0x08);    /*显示关闭*/
    LCD_Write_Com(0x01);    /*显示清屏*/
    LCD_Write_Com(0x06);    /*显示光标移动设置*/
    delay_ms(5);
    LCD_Write_Com(0x0C);    /*显示开及光标设置*/
}

/*------------------------------------------------
                    主函数
------------------------------------------------*/
void main(void)
{
    WDTCTL = WDTPW | WDTHOLD;        // stop watchdog timer

    Port_init();
    delay_ms(10);
    LCD_Init();
    LCD_Clear();//清屏
    while (1)
    {
        LCD_Write_Char(7,0,'o');
        LCD_Write_Char(8,0,'k');
        LCD_Write_String(0,1,"make it possible");
        while(1);
    }
}

下面是pid调速测试,是失败的?加入时间循环去判别,时钟对不上。 

#include <msp430.h>

#define ENCODER_A_PIN       BIT4
#define ENCODER_B_PIN       BIT5
#define ENCODER_A_INT       TA0CCTL1
#define ENCODER_B_INT       TA0CCTL2

#define MOTOR_A_PIN         BIT2
#define MOTOR_B_PIN         BIT3

#define TARGET_SPEED        1000
#define TARGET_SPEED1       5000
#define Kp                  0.1
#define Ki                  2.5
#define Kd                  0.5

volatile int encoderCount = 0;
volatile int motorSpeed = 0;

double error = 0;
double previousError = 0;
double integral = 0;
double derivative = 0;

void initPWM()
{
    // 初始化定时器和PWM模块
    // 设置定时器的计数模式和频率
    // 设置PWM模块的输出引脚和占空比
}

void initEncoder()
{
    // 配置引脚为输入模式
    P1DIR &= ~(ENCODER_A_PIN | ENCODER_B_PIN);
    P1REN |= ENCODER_A_PIN | ENCODER_B_PIN;
    P1OUT |= ENCODER_A_PIN | ENCODER_B_PIN;
    P1IE |= ENCODER_A_PIN | ENCODER_B_PIN;
    P1IES |= ENCODER_A_PIN | ENCODER_B_PIN;
    P1IFG &= ~(ENCODER_A_PIN | ENCODER_B_PIN);
}

void initMotor()
{
    // 配置引脚为输出模式
    P1DIR |= MOTOR_A_PIN | MOTOR_B_PIN;
    P1OUT &= ~(MOTOR_A_PIN | MOTOR_B_PIN);
}

void initPID()
{
    // 初始化PID控制器的参数
    error = 0;
    previousError = 0;
    integral = 0;
    derivative = 0;
}

void setMotorSpeed(int speed)
{
    // 设置电机的速度
    motorSpeed = speed;
    // 根据速度和PID控制器的输出值来控制电机引脚的状态
    if (motorSpeed > 0)
    {
        P1OUT |= MOTOR_A_PIN;
        P1OUT &= ~MOTOR_B_PIN;
    }
    else if (motorSpeed < 0)
    {
        P1OUT |= MOTOR_B_PIN;
        P1OUT &= ~MOTOR_A_PIN;
    }
    else
    {
        P1OUT &= ~(MOTOR_A_PIN | MOTOR_B_PIN);
    }
}

int main(void)
 {
    WDTCTL = WDTPW | WDTHOLD; // 停用看门狗定时器

    // 初始化
    initPWM();
    initEncoder();
    initMotor();
    initPID();

    __enable_interrupt(); // 允许中断

    unsigned int timer = 0; // 计时器变量,单位为毫秒

    while (1)
    {
        // 主循环中可以添加其他的控制逻辑

        if (timer < 2000) // 前5秒
        {
            // 示例:将电机速度设置为目标速度
            setMotorSpeed(TARGET_SPEED);
        }
        else if (timer < 2000) // 后5秒
        {
            // 示例:将电机速度设置为不同的目标速度
            setMotorSpeed(-TARGET_SPEED);
        }
        else
        {
            // 其他时间段的逻辑
        }

        // 示例:读取编码器计数值
        int currentCount = encoderCount;

        // 示例:使用PID控制器计算控制量
        error = TARGET_SPEED - currentCount;
        integral += error;
        derivative = error - previousError;
        double controlOutput = Kp * error + Ki * integral + Kd * derivative;

        // 示例:根据控制量调整电机速度
        setMotorSpeed((int)controlOutput);

        previousError = error;

        // 示例:延时一段时间
        __delay_cycles(1000); // 延时1ms

        timer += 1; // 增加计时器
    }

    return 0;
}

#pragma vector=PORT1_VECTOR
__interrupt void encoderInterrupt(void)
{
    if (P1IFG & ENCODER_A_PIN)
    {
        // 处理编码器A相中断事件
        if (P1IN & ENCODER_B_PIN)
        {
            encoderCount++;
        }
        else
        {
            encoderCount--;
        }
        P1IFG &= ~ENCODER_A_PIN;
    }

    if (P1IFG & ENCODER_B_PIN)
    {
        // 处理编码器B相中断事件
        if (P1IN & ENCODER_A_PIN)
        {
            encoderCount--;
        }
        else
        {
            encoderCount++;
        }
        P1IFG &= ~ENCODER_B_PIN;
    }
}

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值