#include <msp430.h>
// 定义超声波传感器引脚
#define TRIGGER_PIN BIT4 // P3.4
#define ECHO_PIN BIT3 // P3.3
// 定义左轮驱动引脚
#define LEFT_FORWARD_PIN BIT2 // P1.2
#define LEFT_BACKWARD_PIN BIT3 // P1.3
// 定义右轮驱动引脚
#define RIGHT_FORWARD_PIN BIT4 // P1.4
#define RIGHT_BACKWARD_PIN BIT5 // P1.5
// 定义超声波测距阈值
#define OBSTACLE_THRESHOLD 2500
#define TURN_THRESHOLD 1000
// 初始化超声波传感器引脚和驱动引脚
void initializePins() {
// 超声波传感器引脚设置为输入/输出
P3DIR |= TRIGGER_PIN; // 设置为输出
P3DIR &= ~ECHO_PIN; // 设置为输入
// 左轮驱动引脚设置为输出
P1DIR |= LEFT_FORWARD_PIN | LEFT_BACKWARD_PIN;
// 右轮驱动引脚设置为输出
P1DIR |= RIGHT_FORWARD_PIN | RIGHT_BACKWARD_PIN;
// 初始化驱动引脚状态
P1OUT &= ~(LEFT_FORWARD_PIN | LEFT_BACKWARD_PIN |
RIGHT_FORWARD_PIN | RIGHT_BACKWARD_PIN);
}
// 控制左轮向前
void leftWheelForward() {
P1OUT |= LEFT_FORWARD_PIN;
P1OUT &= ~LEFT_BACKWARD_PIN;
}
// 控制左轮向后
void leftWheelBackward() {
P1OUT |= LEFT_BACKWARD_PIN;
P1OUT &= ~LEFT_FORWARD_PIN;
}
// 控制右轮向前
void rightWheelForward() {
P1OUT |= RIGHT_FORWARD_PIN;
P1OUT &= ~RIGHT_BACKWARD_PIN;
}
// 控制右轮向后
void rightWheelBackward() {
P1OUT |= RIGHT_BACKWARD_PIN;
P1OUT &= ~RIGHT_FORWARD_PIN;
}
// 发送超声波信号
void sendUltrasonicSignal() {
// 发送一个高电平脉冲
P3OUT |= TRIGGER_PIN;
__delay_cycles(10); // 延迟一段时间
P3OUT &= ~TRIGGER_PIN;
}
// 接收超声波返回的脉冲时间
int receiveUltrasonicSignal() {
// 等待超声波回波上升沿
while (!(P3IN & ECHO_PIN));
// 开始计时
TA0CTL = TASSEL_2 | MC_2 | TACLR; // 使用SMCLK,连续计数,清除计时器
// 等待超声波回波下降沿
while (P3IN & ECHO_PIN);
// 停止计时,返回计数值
TA0CTL = MC_0; // 停止计数
return TA0R;
}
int main(void) {
WDTCTL = WDTPW | WDTHOLD; // 停用看门狗定时器
initializePins();
while (1) {
sendUltrasonicSignal();
int pulseDuration = receiveUltrasonicSignal();
// 根据距离控制小车运动
if (pulseDuration > OBSTACLE_THRESHOLD) { // 距离大于5cm
// 前进(速度减小为原先的百分之70)
leftWheelForward();
rightWheelForward();
__delay_cycles(20000 * 0.7); // 延迟一段时间,减慢速度
} else if (pulseDuration > TURN_THRESHOLD) { // 距离小于5cm大于2cm
// 停止小车
leftWheelForward();
rightWheelForward();
__delay_cycles(100000); // 延迟一段时间
// 原地右转
leftWheelForward();
rightWheelBackward();
__delay_cycles(200000); // 延迟一段时间
} else { // 距离小于2cm
// 后退3cm
leftWheelBackward();
rightWheelBackward();
__delay_cycles(300000); // 延迟一段时间
// 停止小车
P1OUT &= ~(LEFT_FORWARD_PIN | LEFT_BACKWARD_PIN |
RIGHT_FORWARD_PIN | RIGHT_BACKWARD_PIN);
__delay_cycles(100000); // 延迟一段时间
}
}
return 0;
}
我的小车超声波代码。
p1.0就是时钟协议 p1.6就是输出引脚
- SPI SCLK(Serial Clock):它是时钟线,由主设备提供时钟信号,用于同步数据传输。
- SPI SIMO(Serial Input/Master Output):它是主设备的输出引脚,用于将数据发送到从设备。
蜂鸣器
#include <msp430.h>
#define BEEP_PIN BIT2 // 连接到P1.2引脚
void initializePins() {
P1DIR |= BEEP_PIN; // 将BEEP_PIN设置为输出
P1OUT &= ~BEEP_PIN; // 初始化BEEP_PIN为低电平
}
void beepOn() {
P1OUT |= BEEP_PIN; // 将BEEP_PIN设置为高电平
}
void beepOff() {
P1OUT &= ~BEEP_PIN; // 将BEEP_PIN设置为低电平
}
int main(void) {
WDTCTL = WDTPW | WDTHOLD; // 停用看门狗定时器
initializePins();
while (1) {
beepOn(); // 打开蜂鸣器
__delay_cycles(100000); // 蜂鸣器鸣叫持续时间
beepOff(); // 关闭蜂鸣器
__delay_cycles(100000); // 静音持续时间
}
return 0;
}
#include <msp430.h>
// OLED 屏幕引脚定义
#define OLED_PORT_SEL P1SEL
#define OLED_PORT_DIR P1DIR
#define OLED_PORT_OUT P1OUT
#define OLED_RST_PIN BIT0
#define OLED_DC_PIN BIT2
#define OLED_CS_PIN BIT3
// SPI 通信定义
#define SPI_PORT_SEL P1SEL
#define SPI_PORT_DIR P1DIR
#define SPI_PORT_OUT P1OUT
#define SPI_SIMO_PIN BIT6
#define SPI_CLK_PIN BIT5
// OLED 初始化命令和数据
#define OLED_CMD 0x00
#define OLED_DATA 0x01
#define OLED_WIDTH 128
#define OLED_HEIGHT 64
// 初始化 OLED 屏幕
void OLED_Init() {
// 配置 OLED 引脚为输出
OLED_PORT_DIR |= OLED_RST_PIN | OLED_DC_PIN | OLED_CS_PIN;
// 复位 OLED 屏幕
OLED_PORT_OUT &= ~OLED_RST_PIN;
__delay_cycles(10000); // 延迟一段时间
OLED_PORT_OUT |= OLED_RST_PIN;
// 发送初始化命令
OLED_WriteCommand(0xAE); // 关闭显示
OLED_WriteCommand(0xD5); // 设置时钟分频因子,震荡频率
OLED_WriteCommand(0x80); // 分频因子=1
OLED_WriteCommand(0xA8); // 设置驱动路数
OLED_WriteCommand(0x3F); // 默认0x3F(1/64)
OLED_WriteCommand(0xD3); // 设置显示偏移
OLED_WriteCommand(0x00); // 默认为0
OLED_WriteCommand(0x40); // 设置显示开始行 [5:0]
OLED_WriteCommand(0x8D); // 电荷泵设置
OLED_WriteCommand(0x14); // 使能电荷泵
OLED_WriteCommand(0x20); // 设置内存地址模式
OLED_WriteCommand(0x00); // 水平地址模式
OLED_WriteCommand(0xA1); // 设置段重新映射
OLED_WriteCommand(0xC8); // 设置COM扫描方向
OLED_WriteCommand(0xDA); // 设置COM引脚硬件配置
OLED_WriteCommand(0x12); // 默认0x12(0x00)
OLED_WriteCommand(0x81); // 对比度设置
OLED_WriteCommand(0xCF); // 默认0xCF(0x7F)
OLED_WriteCommand(0xD9); // 设置预充电周期
OLED_WriteCommand(0xF1); // 默认0xF1(0x22)
OLED_WriteCommand(0xDB); // 设置VCOMH
OLED_WriteCommand(0x40); // 默认0x40
OLED_WriteCommand(0xAF); // 打开显示
}
// 向 OLED 屏幕写入命令
void OLED_WriteCommand(unsigned char command) {
OLED_PORT_OUT &= ~OLED_DC_PIN; // 设置为命令模式
SPI_WriteByte(command); // 通过 SPI 发送命令
}
// 向 OLED 屏幕写入数据
void OLED_WriteData(unsigned char data) {
OLED_PORT_OUT |= OLED_DC_PIN; // 设置为数据模式
SPI_WriteByte(data); // 通过 SPI 发送数据
}
// 清空 OLED 屏幕
void OLED_ClearScreen() {
unsigned int i, j;
for (i = 0; i < 8; i++) {
OLED_WriteCommand(0xB0 + i); // 设置页地址
OLED_WriteCommand(0x00); // 设置列地址的低 4 位
OLED_WriteCommand(0x10); // 设置列地址的高 4 位
for (j = 0; j < OLED_WIDTH; j++) {
OLED_WriteData(0x00); // 将每个像素点设置为黑色
}
}
}
// 在指定位置绘制一个像素点
void OLED_DrawPixel(unsigned int x, unsigned int y) {
unsigned char page;
unsigned char column;
unsigned char value;
page = y / 8; // 计算页地址
column = x % OLED_WIDTH; // 计算列地址
value = 0x01 << (y % 8); // 计算像素值
OLED_WriteCommand(0xB0 + page); // 设置页地址
OLED_WriteCommand(0x00 + (column & 0x0F)); // 设置列地址的低 4 位
OLED_WriteCommand(0x10 + (column >> 4)); // 设置列地址的高 4 位
OLED_WriteData(value); // 绘制像素点
}
// 通过 SPI 发送一个字节的数据
void SPI_WriteByte(unsigned char data) {
while (!(UCB0IFG & UCTXIFG)); // 等待发送缓冲区空
UCB0TXBUF = data; // 将数据写入发送缓冲区
}
// SPI 初始化
void SPI_Init() {
// 配置 SPI 引脚功能
SPI_PORT_SEL |= SPI_SIMO_PIN | SPI_CLK_PIN;
// 配置 SPI 引脚方向
SPI_PORT_DIR |= SPI_SIMO_PIN;
SPI_PORT_DIR |= SPI_CLK_PIN;
// 配置 SPI 控制寄存器
UCB0CTL1 |= UCSWRST; // 禁用 SPI 模块
UCB0CTL0 |= UCMSB | UCMST | UCSYNC; // 主模式,MSB 优先,同步模式
UCB0CTL1 |= UCSSEL_2; // 时钟源选择 SMCLK
UCB0BR0 = 0x02; // 分频器设置为 2
UCB0BR1 = 0;
UCB0CTL1 &= ~UCSWRST; // 启用 SPI 模块
}
int main(void) {
WDTCTL = WDTPW | WDTHOLD; // 停用看门狗定时器
SPI_Init(); // 初始化 SPI
OLED_Init();
// 在 OLED 屏幕上显示 "520000"
OLED_ClearScreen(); // 清空屏幕
OLED_DrawPixel(10, 10); // 5
OLED_DrawPixel(20, 10);
OLED_DrawPixel(30, 10);
OLED_DrawPixel(10, 20); // 2
OLED_DrawPixel(20, 20);
OLED_DrawPixel(30, 20);
OLED_DrawPixel(10, 30); // 0
OLED_DrawPixel(20, 30);
OLED_DrawPixel(30, 30);
OLED_DrawPixel(10, 40); // 0
OLED_DrawPixel(20, 40);
OLED_DrawPixel(30, 40);
OLED_DrawPixel(10, 50); // 0
OLED_DrawPixel(20, 50);
OLED_DrawPixel(30, 50);
OLED_DrawPixel(10, 60); // 0
OLED_DrawPixel(20, 60);
OLED_DrawPixel(30, 60);
__delay_cycles(1000000); // 延迟一段时间
while (1) {
__no_operation(); // 空操作
}
}
#include <msp430.h>
#define LEFT_REAR_DRIVE BIT2
#define RIGHT_REAR_DRIVE BIT4
#define LEFT_FRONT_DRIVE BIT1
#define RIGHT_FRONT_DRIVE BIT2
#define LEFT_GRADIENT_SENSOR BIT1
#define MIDDLE_LEFT_GRADIENT_SENSOR BIT3
#define MIDDLE_GRADIENT_SENSOR BIT6
#define MIDDLE_RIGHT_GRADIENT_SENSOR BIT1
#define RIGHT_GRADIENT_SENSOR BIT0
void configureGPIO();
void configurePWM();
void driveMotors(int leftRear, int rightRear, int leftFront, int rightFront);
int main(void)
{
WDTCTL = WDTPW | WDTHOLD; // 停用看门狗定时器
configureGPIO();
configurePWM();
while (1)
{
// 读取六路灰度循迹模块的信号
int leftGradient = (P8IN & LEFT_GRADIENT_SENSOR) ? 1 : 0;
int middleLeftGradient = (P2IN & MIDDLE_LEFT_GRADIENT_SENSOR) ? 1 : 0;
int middleGradient = (P2IN & MIDDLE_GRADIENT_SENSOR) ? 1 : 0;
int middleRightGradient = (P3IN & MIDDLE_RIGHT_GRADIENT_SENSOR) ? 1 : 0;
int rightGradient = (P3IN & RIGHT_GRADIENT_SENSOR) ? 1 : 0;
// 根据光线传感器的读数控制车轮驱动
if (middleGradient)
{
// 循迹模块在中间位置,直线行驶
driveMotors(1, 1, 1, 1);
}
else if (leftGradient)
{
// 循迹模块在左边,向左转
driveMotors(0, 1, 1, 0);
}
else if (rightGradient)
{
// 循迹模块在右边,向右转
driveMotors(1, 0, 0, 1);
}
else
{
// 循迹模块没有检测到黑线,保持直行
driveMotors(1, 1, 1, 1);
}
}
return 0;
}
void configureGPIO()
{
// 配置引脚为输入或输出
P1DIR |= (LEFT_REAR_DRIVE | RIGHT_REAR_DRIVE | LEFT_FRONT_DRIVE | RIGHT_FRONT_DRIVE);
P4DIR |= (LEFT_FRONT_DRIVE | RIGHT_FRONT_DRIVE);
P8DIR |= LEFT_REAR_DRIVE;
P2DIR |= (MIDDLE_LEFT_GRADIENT_SENSOR | MIDDLE_GRADIENT_SENSOR);
P3DIR |= (MIDDLE_RIGHT_GRADIENT_SENSOR | RIGHT_GRADIENT_SENSOR);
// 配置引脚的初始状态
P1OUT &= ~(LEFT_REAR_DRIVE | RIGHT_REAR_DRIVE | LEFT_FRONT_DRIVE | RIGHT_FRONT_DRIVE);
P4OUT &= ~(LEFT_FRONT_DRIVE | RIGHT_FRONT_DRIVE);
P8OUT &= ~LEFT_REAR_DRIVE;
}
void configurePWM()
{
// 配置PWM模块
TA0CCR0 = 1000; // 设置PWM周期为1000
TA0CCTL1 = OUTMOD_7; // PWM模式7
TA0CCTL2 = OUTMOD_7;
TA0CCTL3 = OUTMOD_7;
TA0CCTL4 = OUTMOD_7;
TA0CTL = TASSEL_2 + MC_1 + TACLR; // 选择SMCLK作为时钟源,选择增计数模式,清除计数器
// 配置PWM引脚
P1DIR |= (BIT2 | BIT3 | BIT4 | BIT5); // 设置引脚为输出模式
P1SEL |= (BIT2 | BIT3 | BIT4 | BIT5); // 配置引脚复用功能为TA0.1、TA0.2、TA0.3、TA0.4
}
void driveMotors(int leftRear, int rightRear, int leftFront, int rightFront)
{
// 控制车轮驱动状态
if (leftRear)
P1OUT |= LEFT_REAR_DRIVE;
else
P1OUT &= ~LEFT_REAR_DRIVE;
if (rightRear)
P1OUT |= RIGHT_REAR_DRIVE;
else
P1OUT &= ~RIGHT_REAR_DRIVE;
if (leftFront)
P4OUT |= LEFT_FRONT_DRIVE;
else
P4OUT &= ~LEFT_FRONT_DRIVE;
if (rightFront)
P8OUT |= RIGHT_FRONT_DRIVE;
else
P8OUT &= ~RIGHT_FRONT_DRIVE;
}
车子实现四轮驱动,转向不知道是个什么逻辑?实在是跑得太快了。
#include <msp430.h>
#define LEFT_REAR_FORWARD_PIN BIT2 // P1.2
#define LEFT_REAR_BACKWARD_PIN BIT3 // P1.3
#define RIGHT_REAR_FORWARD_PIN BIT4 // P1.4
#define RIGHT_REAR_BACKWARD_PIN BIT5 // P1.5
#define LEFT_FRONT_FORWARD_PIN BIT1 // P4.1
#define LEFT_FRONT_BACKWARD_PIN BIT2 // P4.2
#define RIGHT_FRONT_FORWARD_PIN BIT2 // P8.2
#define RIGHT_FRONT_BACKWARD_PIN BIT7 // P3.7
#define LEFT_GRADIENT_SENSOR BIT1
#define MIDDLE_LEFT_GRADIENT_SENSOR BIT3
#define MIDDLE_GRADIENT_SENSOR BIT6
#define MIDDLE_RIGHT_GRADIENT_SENSOR BIT1
#define RIGHT_GRADIENT_SENSOR BIT0
void configureGPIO();
void driveMotors(int leftRear, int rightRear, int leftFront, int rightFront);
int main(void)
{
WDTCTL = WDTPW | WDTHOLD; // 停用看门狗定时器
configureGPIO();
while (1)
{
// 读取六路灰度循迹模块的信号
int leftGradient = (P8IN & LEFT_GRADIENT_SENSOR) ? 1 : 0;
int middleLeftGradient = (P2IN & MIDDLE_LEFT_GRADIENT_SENSOR) ? 1 : 0;
int middleGradient = (P2IN & MIDDLE_GRADIENT_SENSOR) ? 1 : 0;
int middleRightGradient = (P3IN & MIDDLE_RIGHT_GRADIENT_SENSOR) ? 1 : 0;
int rightGradient = (P3IN & RIGHT_GRADIENT_SENSOR) ? 1 : 0;
// 根据光线传感器的读数控制车轮驱动
if (leftGradient && !middleLeftGradient && !middleGradient)
{
// 循迹模块在左边,向左转
driveMotors(0, 1, 1, 0);
}
else if (rightGradient && !middleRightGradient && !middleGradient)
{
// 循迹模块在右边,向右转
driveMotors(1, 0, 0, 1);
}
else
{
// 循迹模块在中间位置或无法识别黑线方向,直线行驶
driveMotors(1, 1, 1, 1);
}
}
return 0;
}
void configureGPIO()
{
// 配置引脚为输出模式
P1DIR |= (LEFT_REAR_FORWARD_PIN | LEFT_REAR_BACKWARD_PIN | RIGHT_REAR_FORWARD_PIN | RIGHT_REAR_BACKWARD_PIN);
P4DIR |= (LEFT_FRONT_FORWARD_PIN | LEFT_FRONT_BACKWARD_PIN);
P8DIR |= RIGHT_FRONT_FORWARD_PIN;
P3DIR |= RIGHT_FRONT_BACKWARD_PIN;
// 配置引脚的初始状态
P1OUT &= ~(LEFT_REAR_FORWARD_PIN | LEFT_REAR_BACKWARD_PIN | RIGHT_REAR_FORWARD_PIN | RIGHT_REAR_BACKWARD_PIN);
P4OUT &= ~(LEFT_FRONT_FORWARD_PIN | LEFT_FRONT_BACKWARD_PIN);
P8OUT &= ~RIGHT_FRONT_FORWARD_PIN;
P3OUT &= ~RIGHT_FRONT_BACKWARD_PIN;
}
void driveMotors(int leftRear, int rightRear, int leftFront, int rightFront)
{
// 控制车轮驱动状态
if (leftRear)
{
P1OUT |= LEFT_REAR_FORWARD_PIN;
P1OUT &= ~LEFT_REAR_BACKWARD_PIN;
}
else
{
P1OUT &= ~LEFT_REAR_FORWARD_PIN;
P1OUT |= LEFT_REAR_BACKWARD_PIN;
}
if (rightRear)
{
P1OUT |= RIGHT_REAR_FORWARD_PIN;
P1OUT &= ~RIGHT_REAR_BACKWARD_PIN;
}
else
{
P1OUT &= ~RIGHT_REAR_FORWARD_PIN;
P1OUT |= RIGHT_REAR_BACKWARD_PIN;
}
if (leftFront)
{
P4OUT |= LEFT_FRONT_FORWARD_PIN;
P4OUT &= ~LEFT_FRONT_BACKWARD_PIN;
}
else
{
P4OUT &= ~LEFT_FRONT_FORWARD_PIN;
P4OUT |= LEFT_FRONT_BACKWARD_PIN;
}
if (rightFront)
{
P8OUT |= RIGHT_FRONT_FORWARD_PIN;
P3OUT &= ~RIGHT_FRONT_BACKWARD_PIN;
}
else
{
P8OUT &= ~RIGHT_FRONT_FORWARD_PIN;
P3OUT |= RIGHT_FRONT_BACKWARD_PIN;
}
}
#include <msp430.h>
#define PWM_PERIOD 1000 // PWM 周期,可以根据需要进行调整
#define SPEED_CHANGE_DELAY 5000 // 速度变化的延迟,单位为毫秒
void configurePWM()
{
// 配置左后轮驱动
P1DIR |= BIT2 | BIT3; // 设置 P1.2 和 P1.3 为输出
P1SEL |= BIT2 | BIT3; // 配置 P1.2 和 P1.3 为 PWM 输出
// 配置右后轮驱动
P1DIR |= BIT4 | BIT5; // 设置 P1.4 和 P1.5 为输出
P1SEL |= BIT4 | BIT5; // 配置 P1.4 和 P1.5 为 PWM 输出
// 配置左前轮驱动
P4DIR |= BIT1 | BIT2; // 设置 P4.1 和 P4.2 为输出
P4SEL |= BIT1 | BIT2; // 配置 P4.1 和 P4.2 为 PWM 输出
// 配置右前轮驱动
P8DIR |= BIT2; // 设置 P8.2 为输出
P3DIR |= BIT7; // 设置 P3.7 为输出
P8SEL |= BIT2; // 配置 P8.2 为 PWM 输出
P3SEL |= BIT7; // 配置 P3.7 为 PWM 输出
TA0CCR0 = PWM_PERIOD - 1; // 设置 PWM 的周期
// 左后轮驱动 PWM 配置
TA0CCTL1 = OUTMOD_7; // 设置输出模式为 PWM
TA0CCR1 = 500; // 设置左后轮驱动的初始占空比(0-1000之间的值,表示占空比的百分比)
// 右后轮驱动 PWM 配置
TA0CCTL2 = OUTMOD_7; // 设置输出模式为 PWM
TA0CCR2 = 500; // 设置右后轮驱动的初始占空比(0-1000之间的值,表示占空比的百分比)
// 左前轮驱动 PWM 配置
TA0CCTL3 = OUTMOD_7; // 设置输出模式为 PWM
TA0CCR3 = 500; // 设置左前轮驱动的初始占空比(0-1000之间的值,表示占空比的百分比)
// 右前轮驱动 PWM 配置
TA0CCTL4 = OUTMOD_7; // 设置输出模式为 PWM
TA0CCR4 = 500; // 设置右前轮驱动的初始占空比(0-1000之间的值,表示占空比的百分比)
TA0CTL = TASSEL_2 | MC_1; // 设置时钟源为 SMCLK,选择增计数模式
}
void delay(unsigned int ms)
{
unsigned int i;
for (i = 0; i < ms; i++)
{
__delay_cycles(1000); // 延迟 1000 个时钟周期,约等于 1 毫秒
}
}
int main(void)
{
WDTCTL = WDTPW | WDTHOLD; // 停用看门狗定时器
configurePWM(); // 配置 PWM
unsigned int delayCount = 0;
while(1)
{
if (delayCount >= SPEED_CHANGE_DELAY)
{
// 每隔五秒改变一次速度
TA0CCR1 += 100; // 改变左后轮驱动的占空比
TA0CCR2 -= 100; // 改变右后轮驱动的占空比
TA0CCR3 += 100; // 改变左前轮驱动的占空比
TA0CCR4 -= 100; // 改变右前轮驱动的占空比
// 确保占空比在 0-1000 范围内
if (TA0CCR1 > 1000)
TA0CCR1 = 0;
if (TA0CCR2 < 0)
TA0CCR2 = 1000;
if (TA0CCR3 > 1000)
TA0CCR3 = 0;
if (TA0CCR4 < 0)
TA0CCR4 = 1000;
delayCount = 0; // 重置延迟计数器
}
delay(1); // 延迟 1 毫秒
delayCount++; // 延迟计数器加一
}
return 0;
}
#include <msp430.h>
#define PWM_PERIOD 1000 // PWM 周期,可以根据需要进行调整
#define SPEED_CHANGE_DELAY 5000 // 速度变化的延迟,单位为毫秒
void configurePWM()
{
// 配置左后轮驱动
P1DIR |= BIT2 | BIT3; // 设置 P1.2 和 P1.3 为输出
P1SEL |= BIT2 | BIT3; // 配置 P1.2 和 P1.3 为 PWM 输出
// 配置右后轮驱动
P1DIR |= BIT4 | BIT5; // 设置 P1.4 和 P1.5 为输出
P1SEL |= BIT4 | BIT5; // 配置 P1.4 和 P1.5 为 PWM 输出
// 配置左前轮驱动
P4DIR |= BIT1 | BIT2; // 设置 P4.1 和 P4.2 为输出
P4SEL |= BIT1 | BIT2; // 配置 P4.1 和 P4.2 为 PWM 输出
// 配置右前轮驱动
P8DIR |= BIT2; // 设置 P8.2 为输出
P3DIR |= BIT7; // 设置 P3.7 为输出
P8SEL |= BIT2; // 配置 P8.2 为 PWM 输出
P3SEL |= BIT7; // 配置 P3.7 为 PWM 输出
TA0CCR0 = PWM_PERIOD - 1; // 设置 PWM 的周期
// 左后轮驱动 PWM 配置
TA0CCTL1 = OUTMOD_7; // 设置输出模式为 PWM
TA0CCR1 = 500; // 设置左后轮驱动的初始占空比(0-1000之间的值,表示占空比的百分比)
// 右后轮驱动 PWM 配置
TA0CCTL2 = OUTMOD_7; // 设置输出模式为 PWM
TA0CCR2 = 500; // 设置右后轮驱动的初始占空比(0-1000之间的值,表示占空比的百分比)
// 左前轮驱动 PWM 配置
TA0CCTL3 = OUTMOD_7; // 设置输出模式为 PWM
TA0CCR3 = 500; // 设置左前轮驱动的初始占空比(0-1000之间的值,表示占空比的百分比)
// 右前轮驱动 PWM 配置
TA0CCTL4 = OUTMOD_7; // 设置输出模式为 PWM
TA0CCR4 = 500; // 设置右前轮驱动的初始占空比(0-1000之间的值,表示占空比的百分比)
TA0CTL = TASSEL_2 | MC_1; // 设置时钟源为 SMCLK,选择增计数模式
}
void delay(unsigned int ms)
{
unsigned int i;
for (i = 0; i < ms; i++)
{
__delay_cycles(1000); // 延迟 1000 个时钟周期,约等于 1 毫秒
}
}
int main(void)
{
WDTCTL = WDTPW | WDTHOLD; // 停用看门狗定时器
configurePWM(); // 配置 PWM
unsigned int delayCount = 0;
while(1)
{
if (delayCount >= SPEED_CHANGE_DELAY)
{
// 每隔五秒改变一次速度
TA0CCR1 += 100; // 改变左后轮驱动的占空比
TA0CCR2 -= 100; // 改变右后轮驱动的占空比
TA0CCR3 += 100; // 改变左前轮驱动的占空比
TA0CCR4 -= 100; // 改变右前轮驱动的占空比
// 确保占空比在 0-1000 范围内
if (TA0CCR1 > 1000)
TA0CCR1 = 0;
if (TA0CCR2 < 0)
TA0CCR2 = 1000;
if (TA0CCR3 > 1000)
TA0CCR3 = 0;
if (TA0CCR4 < 0)
TA0CCR4 = 1000;
delayCount = 0; // 重置延迟计数器
}
delay(1); // 延迟 1 毫秒
delayCount++; // 延迟计数器加一
}
return 0;
}
呼吸灯代码
#include <msp430.h>
void TimeA0__PWM_Init(void)
{
P1SEL |= BIT3; //IO口复用
P1DIR |= BIT3;
TA0CTL = TASSEL__SMCLK + MC_3; //SMCLK,增减模式,计数到CCR0处
TA0CCR0 = 0x00ff; //都设置为00ffH,则初始占空比为0
TA0CCR2 = 0x00ff; //占空比(TACCR0 - TACCR2) / TACCR0,频率 = SMCLK / (TACCR0 + 1) / 2
TA0CCTL2 = OUTMOD_6; //选择比较模式,模式6:Toggle/set
}
int cnt;
int main(void)
{
WDTCTL = WDTPW | WDTHOLD; // stop watchdog timer
TimeA0__PWM_Init();
while(1)
{
for(cnt=0;cnt < 0x00ff;cnt++)
{
TA0CCR2 = cnt;
__delay_cycles(5000);
}
for(cnt=0x00ff;cnt > 0;cnt--)
{
TA0CCR2 = cnt;
__delay_cycles(5000);
}
}
}
#include <msp430.h>
// 定义LED引脚
#define RED_LED_PIN BIT2 // P1.2
#define GREEN_LED_PIN BIT3 // P1.3
#define BLUE_LED_PIN BIT4 // P1.4
// 呼吸灯的亮度范围
#define MIN_BRIGHTNESS 0 // 最小亮度
#define MAX_BRIGHTNESS 100 // 最大亮度
// 设置PWM参数
#define PWM_FREQUENCY 1000 // PWM频率(Hz)
// 初始化PWM
void initPWM()
{
// 设置时钟源为SMCLK
TA0CTL = TASSEL_2;
// 设定计数器模式为上升模式
TA0CTL |= MC_1;
// 设定PWM周期(频率)
TA0CCR0 = (1000000 / PWM_FREQUENCY) - 1;
// 设定PWM占空比为0
TA0CCR1 = 0;
TA0CCR2 = 0;
TA0CCR3 = 0;
// 设定输出模式为输出模式7(PWM模式)
TA0CCTL1 = OUTMOD_7;
TA0CCTL2 = OUTMOD_7;
TA0CCTL3 = OUTMOD_7;
// 设置引脚功能为TA0.1、TA0.2和TA0.3
P1DIR |= RED_LED_PIN | GREEN_LED_PIN | BLUE_LED_PIN;
P1SEL |= RED_LED_PIN | GREEN_LED_PIN | BLUE_LED_PIN;
}
// 设置呼吸灯亮度
void setBrightness(unsigned int brightness)
{
// 计算占空比
unsigned int dutyCycle = (brightness * (MAX_BRIGHTNESS - MIN_BRIGHTNESS)) / MAX_BRIGHTNESS;
// 更新PWM占空比
TA0CCR1 = dutyCycle;
TA0CCR2 = dutyCycle;
TA0CCR3 = dutyCycle;
}
int main(void)
{
// 停用看门狗定时器
WDTCTL = WDTPW + WDTHOLD;
// 初始化PWM
initPWM();
// 设置初始亮度为最小亮度
setBrightness(MIN_BRIGHTNESS);
// 设置亮度变化方向和步长
int direction = 1; // 1表示递增,-1表示递减
int step = 1; // 步长
// 主循环
while (1)
{
// 更新亮度
setBrightness(setBrightness + (direction * step));
// 如果亮度达到最大或最小值,改变方向
if (setBrightness >= MAX_BRIGHTNESS || setBrightness <= MIN_BRIGHTNESS)
direction = -direction;
// 延迟一段时间
__delay_cycles(10000);
}
return 0;
}