文章目录

  • 前言
  • 一、void SystemClock_Init(void)//系统初始化
    • 时钟系统结构
  • 二、void Counter_Left_Init (void) //编码器计数
    • 设置外部中断
  • 三、void TimerA1Init()//定时器初始化
    • 定时器中断函数
  • 四、void Motor_Left_Init (void)//PWM初始化
    • 解释一下如何产生pwm
    • 补充一个GPIO的规范用法
  • 五、bool UART_Init(uint16_t baseAddress, uint32_t Baudrate)//串口初始化
    • 通信规则
    • 细解一下这里的参数
    • __even_in_range的使用
    • 简单与openmv通讯
  • 六、OLED_Init()//oled初始化
    • 一个发现(和普及I2C原理)
  • 总结
  • 附件

前言

为电赛准备学习的MSP430笔记


提示:主要跟着这个大佬学的


一张经常要看的图

一、void SystemClock_Init(void)//系统初始化

时钟配置和闪烁的LED

时钟系统结构

时钟系统结构
(1)5个时钟来源
时钟系统模块具有5个时钟来源。
① XT1CLK:低频/高频振荡器,可以使用32768Hz的手表晶振、标准晶体、谐振器或4~32MHz的外部时钟源;
② VLOCLK:内部超低功耗低频振荡器,典型频率12kHz;
③ REFOCLK:内部调整低频参考振荡器,典型值为32768Hz;
④ DCOCLK:内部数字时钟振荡器,可由FLL稳定后得到;
⑤ XT2CLK:高频振荡器,可以是标准晶振、谐振器或4~32MHz的外部时钟源。
(2)3个时钟信号
时钟系统模块可以产生3个时钟信号供CPU和外设使用。
① ACLK:辅助时钟(Auxiliary Clock)。可以通过软件选择XT1CLK、REFOCLK、VLOCLK、DCOCLK、DCOCLKDIV或XT2CLK(当XT2CLK可用时)。DCOCLKDIV是FLL模块内DCOCLK经过1/2/4/8/16/32分频后获得的。ACLK主要用于低速外设。ACLK可以再进行1/2/4/8/16/32分频,ACLK/n 就是ACLK 经过1/2/4/8/16/32分频后得到的,也可以通过外部引脚进行输出。
② MCLK:主时钟(Master Clock)。MCLK的时钟来源与ACLK相同,MCLK专门供CPU使用,MCLK配置得越高,CPU的执行速度就越快,功耗就越高。一旦关闭MCLK,CPU也将停止工作,因此在超低功耗系统中可以通过间歇启用MCLK的方法降低系统功耗。MCLK也可经1/2/4/8/16/32分频后供CPU使用。
③ SMCLK:子系统时钟(Subsystem Master Clock)。SMCLK的时钟来源与ACLK相同,SMCLK主要用于高速外设,SMCLK也可以再进行1/2/4/8/16/32分频。

MSP430具有高达25Mhz的主频,让我们来配置它

//将主时钟MCLK,子系统时钟SMCLK设为25Mhz,MCLK主要用于CPU,SMCLK主要用于高速外设
//将辅助时钟ACLK设为32768Hz,主要用于低速外设
void SystemClock_Init(void)
{PMM_setVCore(PMM_CORE_LEVEL_3);     //高主频工作需要较高的核心电压//XT1振荡器的引脚复用  P5.4 XIN输入 P5.5 XOUT输出 选择单片机内部的晶振GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P5, GPIO_PIN4);GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P5, GPIO_PIN5);//起振XT1  若在LF工作下的XT1振荡器为32768hz的低频晶振,与之相匹配为12pf的电容    XCAP(0: 2pf ,1: 5.5pf, 2: 8,5pf, 3:12pf )UCS_turnOnLFXT1(UCS_XT1_DRIVE_3,UCS_XCAP_3);//XT2引脚复用   P5.2 XIN输入 P5.5 XOUT输出 板载XT2晶振为CSTCR4M00G15L99,4MHzGPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P5, GPIO_PIN2);GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P5, GPIO_PIN3);//起振XT2UCS_turnOnXT2(UCS_XT2_DRIVE_4MHZ_8MHZ);//XT2作为FLL(锁频环)的时钟源,输出为DCOCLK(内部数字时钟振荡器),8分频                      先8分频,再50倍频 4MHz / 8 * 50 = 25MHzUCS_initClockSignal(UCS_FLLREF, UCS_XT2CLK_SELECT, UCS_CLOCK_DIVIDER_8);//用于设置锁相环倍频系数,第一个系数为目标主时钟的频率 单位kHz,第二个系数为= 第一个系数/FLL的频率 (既刚刚得到的4Mhz/8)  50 = 25000khz/(0.5M)  1000k= 1M 1M =10^6khzUCS_initFLLSettle(25000, 50);//XT1作为ACLK时钟源 = 32768Hz 1分频= /1UCS_initClockSignal(UCS_ACLK, UCS_XT1CLK_SELECT, UCS_CLOCK_DIVIDER_1);//DCOCLK作为MCLK时钟源 = 25MHzUCS_initClockSignal(UCS_MCLK, UCS_DCOCLK_SELECT, UCS_CLOCK_DIVIDER_1);//DCOCLK作为SMCLK时钟源 = 25MHzUCS_initClockSignal(UCS_SMCLK, UCS_DCOCLK_SELECT, UCS_CLOCK_DIVIDER_1);//设置外部时钟源的频率,使得在调用UCS_getMCLK, UCS_getSMCLK 或 UCS_getACLK时可得到正确值 (XT1CLK_frequency,XT2CLK_frequency)UCS_setExternalClockSource(32768, 4000000);
}

二、void Counter_Left_Init (void) //编码器计数

GPIO

电机编码器的线数为11(一圈方波数)30(减速比)=330
线数太低了,我们使用4倍频来使它加倍,330
4=1320
我们需要在AB相的上升下降沿都计数(相当于原来的4倍)

现在我们用外部中断来实现编码器计数

设置外部中断

void Counter_Left_Init (void)
{//配置时,先配置功能选择寄存器PxSEL,//若为I/O端口功能,则继续配置方向寄存器PxDIR;//若为输入,则继续配置中断使能寄存器PxIE;//若允许中断,则继续配置中断触发沿选择寄存器PxIES。//只有P1 和P2 有中断功能//P1.3 P1.6 上拉输入并使能interrupt enabled    使能寄存器需和输出寄存器配合使用,才能完成上拉/下拉电阻的配置。GPIO_setAsInputPinWithPullUpResistor(GPIO_PORT_P1,GPIO_PIN3 +GPIO_PIN6);GPIO_enableInterrupt(GPIO_PORT_P1,GPIO_PIN3 +GPIO_PIN6);//设置中断类型 Hi/Lo edgeGPIO_selectInterruptEdge(GPIO_PORT_P1,GPIO_PIN3,GPIO_HIGH_TO_LOW_TRANSITION|GPIO_LOW_TO_HIGH_TRANSITION);GPIO_selectInterruptEdge(GPIO_PORT_P1,GPIO_PIN6,GPIO_HIGH_TO_LOW_TRANSITION|GPIO_LOW_TO_HIGH_TRANSITION);//清除中断标志位 IFG clearedGPIO_clearInterrupt(GPIO_PORT_P1,GPIO_PIN3 +GPIO_PIN6);//启用可屏蔽中断(具有中断功能的片上外设产生)_BIS_SR(GIE);}

中断函数

#pragma vector=PORT1_VECTOR     // P1口中断源
__interrupt
void Port_1 (void)
{//    if(GPIO_getInterruptStatus (GPIO_PORT_P1, GPIO_PIN3)||GPIO_getInterruptStatus (GPIO_PORT_P1, GPIO_PIN6))
//    {//        Counter_Left++;
//        GPIO_clearInterrupt(GPIO_PORT_P1,GPIO_PIN3 +GPIO_PIN6);
//    }_EINT();//恢复总的中断允许,避免中断处理延迟if(GPIO_getInterruptStatus(GPIO_PORT_P1, GPIO_PIN3))//当发生中断{Counter_Left++;GPIO_clearInterrupt(GPIO_PORT_P1,GPIO_PIN3);}if(GPIO_getInterruptStatus(GPIO_PORT_P1, GPIO_PIN6)){Counter_Left++;GPIO_clearInterrupt(GPIO_PORT_P1,GPIO_PIN6);}
}

三、void TimerA1Init()//定时器初始化

定时器A
我们想实现每秒sec加1

设得中断频率为25MHz / 10 / 25000 = 100Hz //即每秒刷新100下,0.01s定时
一共两个中断模式CCR0中断 TAIE中断,一个使能一个不使能
一般使用增计数模式CCR0中断

定时器A增计数模式CCR0中断

//定时0.01s
void TimerA1Init()
{Timer_A_initUpModeParam param = {0};param.clockSource = TIMER_A_CLOCKSOURCE_SMCLK; //时钟源选为SMCLK = 25MHzparam.clockSourceDivider = TIMER_A_CLOCKSOURCE_DIVIDER_10;  //10分频param.timerPeriod = 25000-1;    //计数值设为25000 - 1param.timerInterruptEnable_TAIE = TIMER_A_TAIE_INTERRUPT_DISABLE;   //不使能 TAIE中断param.captureCompareInterruptEnable_CCR0_CCIE = TIMER_A_CCIE_CCR0_INTERRUPT_ENABLE;   //使能CCR0中断param.timerClear = TIMER_A_DO_CLEAR;  //把定时器的定时计数器,分频计数器的计数值清零param.startTimer = true;     //初始化后立即启动定时器//设得中断频率为25MHz / 10 / 25000 = 100HzTimer_A_initUpMode(TIMER_A1_BASE,&param);   //配置定时器A为增计数模式
}

定时器中断函数


例如我们配置定时器1的0寄存器(在32里应该叫通道)
TIMER_A1_BASE
TIMER1_A0_VECTOR //向量名和中断函数名必须一致
TIMER1_A0_ISR //前面的1 是A1的1

#pragma vector=TIMER1_A0_VECTOR
__interrupt
void TIMER1_A0_ISR (void)
{if(n++==100){second++;n=0;}
}

四、void Motor_Left_Init (void)//PWM初始化

定时器A

解释一下如何产生pwm

Timer_A_outputPWM(uint16_t baseAddress, Timer_A_outputPWMParam ∗param)
//计时器A运行在增计数模式产生PWM

为什么说这句话是在增计数模式下呢,我们并没看到配置定时器在增计数模式,所以我们看看这个库函数怎么写的。

它在第一句把所有位进行了一个清零的操作,然后在第4句将TIMER_A_UP_MODE置1,至此我们知道它将增模式也一起配置了。
已知增计数模式下是将0加到TAxCCR0再重新计数,我们看到它将TAxCCR0置为我们可以设置的时间周期timerPeriod。dutyCycle是什么呢,下面会解释。

然后我们在这里将compareOutputMode设置 复位置位 模式

param.compareOutputMode = TIMER_A_OUTPUTMODE_RESET_SET;


增计数模式下,定时器比较输出
在这个模式下,我们发现在计数到TAxCCR1时为高电平输出,TAxCCR1~TAxCCR0时为低电平输出,而TAxCCR1就是我们上文未解释的dutyCycle(占空比),当我们将TAxCCR0设为100,TAxCCR1设为50时,那我们的占空比就为50/100 = 50%。

我们想实现电机初始化

P1.2 对应 TA0.1

void Motor_Left_Init (void)
{//P1.2 as PWM outputGPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P1, GPIO_PIN2);//P1.2复用输出//GPIO_setAsOutputPin (GPIO_PORT_P4,GPIO_PIN0 +GPIO_PIN3 );   //GPIO输出//GPIO_setOutputHighOnPin (GPIO_PORT_P4, GPIO_PIN0);  //高电位输出//GPIO_setOutputLowOnPin (GPIO_PORT_P4, GPIO_PIN3);  //低电位输出//Generate PWM - Timer runs in Up modeTimer_A_outputPWMParam param = {0};param.clockSource = TIMER_A_CLOCKSOURCE_SMCLK;      // 时钟源选为SMCLK = 25MHzparam.clockSourceDivider = TIMER_A_CLOCKSOURCE_DIVIDER_1;       //不分频//装载值设为1000 - 1param.timerPeriod =1000-1;      //时钟周期//频率为25M/1/1000 = 25000hz//P1.2 对应 TA0.1 故设为TIMER_A_CAPTURECOMPARE_REGISTER_1param.compareRegister = TIMER_A_CAPTURECOMPARE_REGISTER_1;      //选择比较寄存器param.compareOutputMode = TIMER_A_OUTPUTMODE_RESET_SET; 为//pwm最大1000param.dutyCycle = 0;//这个值compare = 300 就相当于300/1000 30%的占空比Timer_A_outputPWM(TIMER_A0_BASE, &param);
}

Timer_A_setCompareValue(uint16_t baseAddress, uint16_t compareRegister, uint16_t
compareValue)
//设置捕获比较寄存器的值

void Motor_SetSpeed_Left(int8_t Speed)
{GPIO_setAsOutputPin (GPIO_PORT_P4,GPIO_PIN0 +GPIO_PIN3 );//初始化GPIO输出if (Speed >= 0)  //正数 代表正转{GPIO_setOutputHighOnPin (GPIO_PORT_P4, GPIO_PIN0);  //高电位输出GPIO_setOutputLowOnPin (GPIO_PORT_P4, GPIO_PIN3);  //低电位输出Timer_A_setCompareValue(TIMER_A0_BASE, TIMER_A_CAPTURECOMPARE_REGISTER_1, Speed)}else{GPIO_setOutputLowOnPin (GPIO_PORT_P4, GPIO_PIN0);  //高电位输出GPIO_setOutputHighOnPin (GPIO_PORT_P4, GPIO_PIN3);  //低电位输出Timer_A_setCompareValue(TIMER_A0_BASE, TIMER_A_CAPTURECOMPARE_REGISTER_1, -Speed)//因为SetCompare要传的是无符号整型数 所以 speed加负号}
}

最终输出速度,小车开始转

void Front_Run(void)
{Motor_SetSpeed_Left(300);Motor_SetSpeed_Right(300);
}

补充一个GPIO的规范用法


首先我们对引脚配置输入或是输出

GPIO_setAsOutputPin(uint8_t selectedPort, uint16_t selectedPins);
GPIO_setAsInputPin(uint8_t selectedPort, uint16_t selectedPins);
GPIO_setAsInputPinWithPullDownResistor(uint8_t selectedPort, uint16_t selectedPins);
GPIO_setAsInputPinWithPullUpResistor(uint8_t selectedPort, uint16_t selectedPins);
GPIO_setDriveStrength(uint8_t selectedPort, uint16_t selectedPins, uint8_t
driveStrength);
GPIO_setAsPeripheralModuleFunctionOutputPin(uint8_t selectedPort, uint16_t
selectedPins);
GPIO_setAsPeripheralModuleFunctionInputPin(uint8_t selectedPort, uint16_t
selectedPins);

GPlO引脚可以被配置为在外设模块中操作,通过使用配置GPIO分配功能

GPIO_setOutputHighOnPin(uint8_t selectedPort, uint16_t selectedPins);
GPIO_setOutputLowOnPin(uint8_t selectedPort, uint16_t selectedPins);
GPIO_toggleOutputOnPin(uint8_t selectedPort, uint16_t selectedPins);
GPIO_getInputPinValue(uint8_t selectedPort, uint16_t selectedPins);

一般在程序的初始化阶段对端口进行配置。
配置时,先配置功能选择寄存器PxSEL,
若为I/O端口功能,则继续配置方向寄存器PxDIR;
若为输入,则继续配置中断使能寄存器PxIE;
若允许中断,则继续配置中断触发沿选择寄存器PxIES。

简单配置电机的两个引脚 ,第一句必不可少

   GPIO_setAsOutputPin (GPIO_PORT_P4,GPIO_PIN0 +GPIO_PIN3 );   //GPIO输出GPIO_setOutputHighOnPin (GPIO_PORT_P4, GPIO_PIN0);  //高电位输出GPIO_setOutputLowOnPin (GPIO_PORT_P4, GPIO_PIN3);  //低电位输出

五、bool UART_Init(uint16_t baseAddress, uint32_t Baudrate)//串口初始化

UART通信
P3.3(TX)和P3.4(RX)为USCI_A0串口
P4.4(TX)和P4.5(RX)为USCI_A1串口

通信规则

如图所示,异步通信字符格式由5个部分组成:一个起始位、7位或8位数据位、一个奇/偶/无校验位、一个地址位和一个或两个停止位。其中,用户可以通过软件设置数据位、停止位的位数,还可以设置奇偶校验位的有无。通过选择时钟源和波特率寄存器的数据来确定传输速率。UCMSB控制位用来设置传输的方向和选择最低位还是最高位先发送。一般情况下,对于UART通信选择先发送最低位。

USCI_A_UART_clearInterrupt(uint16_t baseAddress, uint8_t mask)
//清除UART中断源,使其不再断言。当使用中断向量生成器时,最高中断标志将自动清除
USCI_A_UART_enableInterrupt(uint16_t baseAddress, uint8_t mask)
//启用UART中断

细解一下这里的参数

huart.parity = USCI_A_UART_NO_PARITY;
//设置奇偶校验位,USCI_A_UART_ODD_PARITY奇校验    USCI_A_UART_EVEN_PARITY偶校验  USCI_A_UART_NO_PARITY 无校验位
huart.msborLsbFirst = USCI_A_UART_LSB_FIRST;
//设置最低最低位优先或最高位优先的数据发送和接收方式 通常我们接收数据中的最低位
//LSB(Least Significant Bit)是“最低有效位”。MSB(Most Significant Bit)是“最高有效位”。
huart.numberofStopBits = USCI_A_UART_ONE_STOP_BIT;
//设置停止位 USCI_A_UART_ONE_STOP_BIT 一位USCI_A_UART_TWO_STOP_BITS 两位
huart.uartMode = USCI_A_UART_MODE;
//选择模式 选取默认的异步通讯模式 当三个或多个设备通信时,
USCI支持空闲行    USCI_A_UART_IDLE_LINE_MULTI_PROCESSOR_MODE和
地址位多处理器通信格式    USCI_A_UART_ADDRESS_BIT_MULTI_PROCESSOR_MODE
还一个模式为自动波特率检测   USCI_A_UART_AUTOMATIC_BAUDRATE_DETECTION_MODE

第一个参数为选择串口基地址,第二个参数为波特率

bool UART_Init(uint16_t baseAddress, uint32_t Baudrate)
{float UART_Temp = 0;USCI_A_UART_initParam huart = {0};//将所用引脚复用为UART模式if(baseAddress == USCI_A0_BASE)         //P3.3, P3.4 = USCI_A0 TXD/RXD{GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P3, GPIO_PIN3);GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P3, GPIO_PIN4);}else if(baseAddress == USCI_A1_BASE)    //P4.4, P4.5 = USCI_A1 TXD/RXD{GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P4, GPIO_PIN4);GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P4, GPIO_PIN5);}//当目标波特率较低时,UART选用时钟源为ACLK,反之选择SMCLK//调用UCS_getACLK/UCS_getSMCLK前需正确调用UCS_setExternalClockSource函数,我已加到SystemClock_Init函数中if(Baudrate <= 9600){huart.selectClockSource = USCI_A_UART_CLOCKSOURCE_ACLK;UART_Temp = (float)UCS_getACLK()/Baudrate;}else{huart.selectClockSource = USCI_A_UART_CLOCKSOURCE_SMCLK;UART_Temp = (float)UCS_getSMCLK()/Baudrate;}if(UART_Temp < 16)  //当分频因子小于16时,采用低频波特率设置huart.overSampling = USCI_A_UART_LOW_FREQUENCY_BAUDRATE_GENERATION;else    //反之,采用过采样波特率设置{huart.overSampling = USCI_A_UART_OVERSAMPLING_BAUDRATE_GENERATION;UART_Temp /= 16;}huart.clockPrescalar = (int)UART_Temp;if(huart.overSampling == USCI_A_UART_LOW_FREQUENCY_BAUDRATE_GENERATION){   //低频波特率设置   UCBRSxhuart.secondModReg = (int)((UART_Temp - huart.clockPrescalar) * 8);}else{   //过采样波特率设置 UCBRFxhuart.firstModReg = (int)((UART_Temp - huart.clockPrescalar) * 16);}huart.parity = USCI_A_UART_NO_PARITY;huart.msborLsbFirst = USCI_A_UART_LSB_FIRST;huart.numberofStopBits = USCI_A_UART_ONE_STOP_BIT;huart.uartMode = USCI_A_UART_MODE;if (STATUS_FAIL == USCI_A_UART_init(baseAddress, &huart)) //如果成功返回一个STATUS_SUCCESS{   //初始化对应串口return STATUS_FAIL;}//Enable UART module for operation 使能对应串口USCI_A_UART_enable(baseAddress);//Enable Receive Interrupt 启用串口中断USCI_A_UART_clearInterrupt(baseAddress, USCI_A_UART_RECEIVE_INTERRUPT);USCI_A_UART_enableInterrupt(baseAddress, USCI_A_UART_RECEIVE_INTERRUPT);return STATUS_SUCCESS;
}

串口中断函数

USCI_A_UART_transmitData(uint16_t baseAddress, uint8_t transmitData)
//通过UART模块传输一个字节
USCI_A_UART_receiveData(uint16_t baseAddress)
//接收一个已发送到UART模块的字节。

下面实现将接收到的字符回传 接收一个字符就回发一个

#pragma vector=USCI_A0_VECTOR
__interrupt void USCI_A0_ISR (void)
{uint8_t receivedData = 0;switch (__even_in_range(UCA0IV,4)){//Vector 2 - RXIFGcase 2:receivedData = USCI_A_UART_receiveData(USCI_A0_BASE);USCI_A_UART_transmitData(USCI_A0_BASE,receivedData);break;default:break;}
}

__even_in_range的使用

MSP430之__even_in_range
使用__even_in_range 的好处是可以生成效率比较高的代码,在判断多中断源的中断的来源时可以使用此函数。
原型:unsigned short __even_in_range(unsigned short value, unsignedshort upper_limit);

功能:只能与switch 语句结合使用,判断value 是否为偶数且小于等于upper_limit。

简单与openmv通讯

之前已经配置好了串口,
在库函数中,没有相关的函数配置发送数据位数。只在注释里找到。


从手册里发现默认是8位数据位,

所以我们msp430串口的相关配置是:8位数据位,无奇偶校验,1位停止位

UART_Init(USCI_A1_BASE, 115200);//做一个115200的初始化

同样,我们在openmv的也进行相同操作

from pyb import UART
uart = UART(3,115200)   #定义串口3变量 #P4 P5
uart.init(115200, bits=8, parity=None, stop=1) # init with given parameters
# 8位数据位 无奇偶校验 1位停止位

最后openmv的数据传给msp430

uart.write(str(output))

我们要实现在openmv的ide里知道是否已经传到msp430,所以我们打印从msp430回传的数据

def recive_data():global uartif uart.any():tmp_data = uart.readline();print(tmp_data)recive_data();

六、OLED_Init()//oled初始化

库函数I2C驱动OLED屏幕
我们用四针脚的oled来显示,5529芯片上的资源有
P3.0 SDA //P3.1SCL
P4.1SDA //P4.2SCL
看上面的博客的需要改端口的在这可以改

也可以参考下面这个博客
OLED模块//用这个可以点亮 试过
然后在这个位置修改

一个发现(和普及I2C原理)

先搞懂一下I2C协议,这个博主讲的非常明白
I2C协议靠这16张图彻底搞懂(超详细)
然后我从发现P3.5 P3.6在芯片手册上明明没有标注有SDA功能,却可以当作SDA,SCL来用,于是深究这个问题,这个是类似的博客发的驱动oled代码

我先找到一篇博客,TI - MCU - MSP430使用指南14 -> I2C通信(eUSCI),上面说eUSCI_B有追加IIC的功能,手册上也雀实有,不过还是没有讲能用的资源有多少,
于是我开始回到GPIO的引脚上思索这个问题,SDA是双向时钟线
也就意味着双方的两个引脚必须都要有写和读的功能,而MSP430所有的引脚都有写和读的功能,所以我觉得所有的引脚都可以配置成IIC的SDA、SCL,不过这只是我的一个猜测,具体要是有不对的地方,望指正。

然后P1~P2还有中断的功能。


总结

以上就是今天要讲的内容,本文仅仅简单介绍了MSP430的使用,至此小车是可以跑起来了,为电赛强制用TI的板子做了一个简单的备战。
最后感谢一下女朋友望月12138写的代码。

附件

以下是找的一些MSP430F5529的资料
链接:https://pan.baidu.com/s/1nGVduyZzR0xHqeAV6XStqA?pwd=dwuv
提取码:dwuv

【MSP430F5529基于库函数的学习】电赛速学及小车实战相关推荐

  1. 2022电赛C题:小车跟踪(方案1+核心代码)

    目录 前言 一.题目 二.方案1 1.材料清单 2.说明 三.核心代码 四.工程获取 前言 针对2022年电赛C题小车跟踪,本团队一共是做了两种方案:       第一种主要以摄像头(openmv)为 ...

  2. 单K210模块低成本实现21电赛题送药小车

    项目实现 前言 实现成本 赛题要求 赛题分析 k210任务 stm32控制任务 实现与K210的通信 控制电机实现小车运动 其他 资料获取 前言 博主已经大三,想着暑假参加电赛,于是将21电赛的控制题 ...

  3. 【电赛优秀作品集】自动循迹小车制作方案

    简单来说自动循迹小车就是集光,机,电于一体的简易智能小车.参赛者通过论证,比较,实验之后,制作出了简易小车的循迹电路系统,整个系统基于普通玩具小车的机械结构,并利用了小车的底盘,前后轮电机及其自动复原 ...

  4. 赛宁谈靶场–面向实战的网络靶场体系

    导 语 赛宁网安聚焦网络安全攻防对抗核心技术,是国际领先的专业网络靶场提供商,产品远销全球二十多个国家."赛宁谈靶场"是赛宁网安结合市场需求,以及自身多年实践积累推出的系列文章,围 ...

  5. 都2021年了,你还在考虑电赛飞行器赛题,备赛是否有必要用基于TI处理芯片的飞控问题?

    无名创新售后群问题节选 @无名小哥 能问下今年国赛会不会指定某一款飞控呀? 答:都2021年了,你还在考虑电赛飞行器赛题备赛是否有必要用基于TI处理芯片的飞控问题? 暂不论官方是否会限定TI芯片的飞控 ...

  6. 2021电赛F题智能送药小车方案分析(openMV数字识别,红线循迹,STM32HAL库freeRTOS,串级PID快速学习,小车自动返回)

    2021全国大学生电子设计竞赛F题智能送药小车 前提:本篇文章重在分享自己的心得与感悟,我们把最重要的部分,摄像头循迹,摄像头数字识别问题都解决了,有两种方案一种是openARTmini摄像头进行数字 ...

  7. 2019电赛--OpenMV学习笔记

    此文章在我的博客链接:https://sublimerui.top/archives/f10b0e1a.html NOTES:2019电赛结束啦~辛辛苦苦4天后,现已经写成了针对题目的OpenMV总结 ...

  8. 基于stm32非接触式物体尺寸形态测量仪(电赛获得省二)

    目录(获取原文及完整代码进入主页) 一.系统方案论证与比较 1.1 系统结构 1.2 方案选择与比较 1.2.1方案一 1.2.2 方案二 1.2.3 方案选择及论证 二.理论分析与计算 2.1 图形 ...

  9. 【2022研电赛】安谋科技企业命题三等奖:基于自主跟随的无人结账一体化购物车

    本文为2022年第十七届中国研究生电子设计竞赛安谋科技企业命题三等奖作品分享,参加极术社区的[有奖活动]分享2022研电赛作品扩大影响力,更有丰富电子礼品等你来领! 基于自主跟随的无人结账一体化购物车 ...

最新文章

  1. python 为空判断场景
  2. Fedora14 yum 安装源的地址配置到官方归档地址
  3. 用mysql随机查询表a10条数据_ES简介
  4. 实现vue2.0响应式的基本思路
  5. 信用社和民营银行存款利息都高,有5万块钱存哪个更安全?
  6. linux无后缀名程序运行,linux – 如何在Ubuntu上运行无扩展(也许是ELF)文件?
  7. 修改服务器的共享内存大小,服务器共享内存大小能改么
  8. 二级高级应用计算机考试环境,1.2 上机考试环境免费阅读_全国计算机等级考试无纸化真考题库二级MS Office高级应用免费全文_百度阅读...
  9. JAVA基础——异常详解
  10. Vivado初次使用教程
  11. STM32压力传感器信号采集- C#上位机 波形显示
  12. NexusJar包私服
  13. java基础巩固-宇宙第一AiYWM:为了维持生计,Redis基础Part7(Redis常见使用(部署)方式:单机模式、主从模式、哨兵模式、集群模式)~整起
  14. Linux-ARM开发
  15. python 自动识别图形验证码
  16. 修改射手影音播放器字幕保存路径的两种方法
  17. css设置h1属性,CSS设置文本属性
  18. Python深度使用指南
  19. C/C++指向指针的指针、指向数组的指针以及存放指针的数组
  20. 【Excel从头开始】-1 Excel基础设置

热门文章

  1. 48.jango09
  2. 2020年-最新在线教育系统-开源项目排名
  3. Ribbon负载均衡策略、懒加载及饥饿加载
  4. MySQL中嵌套子查询删除出错解决方案
  5. ajax返回的图片数据格式,jquery发送ajax请求返回数据格式
  6. 【从零开始学习 SystemVerilog】11.3、SystemVerilog 断言—— Concurrent Assertions(并发断言)
  7. ASEMI代理IXYB82N120C3H1艾赛斯IGBT二极管
  8. f5负载均衡导致服务器响应,什么是F5负载均衡器,看完你就明白怎么回事了
  9. Jquery 返回上一级并刷新页面
  10. SpaceSniffer 下载与使用——查找大文件、大文件必备