姓名:刘方姣 学号:22021211931 学院:电子工程学院
转自:https://www.cnblogs.com/syhstack/p/15100782.html
【嵌牛导读】包括硬件和软件部分的外部中断,定时器部分的定时中断,定时器输入捕获,PWM波输出,UART,OLED(IIC),MPU6050等设置
【嵌牛鼻子】CCS-MSP430F5529
【嵌牛提问】如何配置MSP430F5529
【嵌牛正文】
由于2021的全国电赛延期了,从今天开始打算好好整理一下使用CCS编程的经验,本篇笔记会好好整理一下我备赛期间用CCS写的程序,包括外部中断,定时器部分的定时中断,定时器输入捕获,PWM波输出,UART,OLED(IIC),MPU6050,内容涵盖了硬件和软件部分。鉴于笔者水平有限和能力不足,文中有不到之处还请看者多包涵,我的工程源代码链接会在文章末尾贴出。先贴一张peripheral图,MSP430的外部引脚及其复用功能都可在图里查到。
一·外部中断
外部中断的操作方式与GPIO一样是使用寄存器操作,所以学习相关的寄存器是不可避免的,不过MSP430的寄存器不算太多,操作外部中断主要要用到以下寄存器:
1.PxIV 中断向量表(字),P1端口的中断函数入口地址应该都放在里面,只是一个地址;
2.PxIE 中断使能寄存器,相应引脚位置1表示允许产生中断;置0表示该引脚不产生中断;
3.PxIES 中断触发方式选择寄存器,相应引脚位置1表示下降沿触发,置0表示上升沿触发;
4.PxIFG 中断标志,由于MSP430的中断使能需要使能总中断,所以仅当总中断GIE和中断使能寄存器PxIE都打开后,PxIFG高电平表示有中断请求等待待响应,等中断服务函数结束时需要软件清该标志位;
这些寄存器在TI的msp430f5xx_6xxgeneric.h头文件有如下定义
下面看一个外部中断程序,所用引脚为P2.1,对应MSP430F5529火箭板的板载按键S1,初始化为下降沿触发
二·定时器
MSP430的定时器资源还算丰富,共有两类共四个定时器,分别是3个TimerA和1TimerB,由于我对TimerA使用较多,所以本文着重来讲TimerA,三个TimerA分别为Timer0_A(5个捕获/比较寄存器),Timer1_A(3个捕获/比较寄存器),Timer2_A(3个捕获/比较寄存器),下面是TimerA的结构图
我们结合TimerA的寄存器讲解一下这张图
上半部分是整个定时器的基础,整个上半部分可通过TACTL控制寄存器来编程,从功能角度来讲从左往右分别是,自身时钟源配置TASSEL,第一次分频选择ID,定时器清零位TACLR,计数值存放寄存器TAR,工作模式控制位MC,中断标志位TAIFG以及没有在结构图出现的定时器中断使能TAIE。
上图为TACTL寄存器各个位的功能,TACTL是一个16bit寄存器,是TA类定时器的控制寄存器,在程序中对定时器进行初始化会经常用到,我会简略的说一下各个寄存器的功能和可选的模式有哪些,具体详细作用还请参考官方手册。
TASSEL 通过更改TASSEL所在位可选4个时钟任一作为当前计数器的时钟源,其中常用的是TASSEL_1 ACLK(32768Hz)以及TASSEL_2 SMCLK(1.045MHz);
IDx 分频可选1,2,4,8分频;
TACLR 定时器清零位,置位会复位寄存器;
TAIE 定时器中断使能,置1后允许中断,同样的使能中断还是需要开启总中断GIE;
TAIFG 中断标志位,该位为1表示有中断发生
定时器的基础配置通过TACTL寄存器就可以完成,但其工作模式还得依靠另一个寄存器TAxCCRx
接下来我们来看定时器的下半部分即捕获/比较控制寄存器TACCTL
TACCTL寄存器也是16bit的寄存器,是定时器实现各种捕获功能的重要寄存器,这个寄存器我们按位来理解它的用法,下面只贴出了我认为比较常用和重要的位的作用,
CMx 捕获模式设定 CM_1上升沿捕获,CM_2下降沿捕获,CM_3上升和下降沿捕获;
CCISx 捕获源选择,00为外部引脚作为捕获源,01为内部信号,配合CMx可做外部编码器输入捕获;
SCS 同步捕获源,是否与时钟同步捕获,为默认值就可;
CAP 0-比较模式,1-捕获模式;
OUTMOD 输出模式控制位,其中MOD2和MOD7可用作PWM波输出;
CCIE 中断允许,这个位是用来允许相应的通道产生中断的,并允许相应标志位CCIFG产生中断请求;
CCIFG 捕获/比较中断标志位,为1表示有中断挂起,定时器中断不需要软件清标志位
到这里定时器的初始化和功能配置已经介绍完毕,就差定时器计数溢出产生中断,而这个中断向量的入口地址存在中断向量字TAIV里,总的来说,通过配置TAxCTL和TACCTLx寄存器就可以完成MSP430的A类定时器的大部分功能,下面举PWM输出例子和定时中断例子
PWM输出
TA(A类定时器)的每个捕获/比较器都有一个输出口,这个输出口可以在定时器工作在特定输出模式时输出不同的信号,当定时器工作在OUTMOD2或者OUTMOD7时,输出口可输出PWM波,下面介绍一下MOD2和MOD7
MOD2 : 翻转/复位输出模式,当定时器计数到TACCRx值时,输出翻转,当定时器技术到TACCR0时,输出复位,显然CCR0寄存器内存放的值和当前的PWM周期有关,CCRx存放的值额占空比有关,通过更改CCR0与CCRx的值,便可实现频率和占空比可调节的方波输出。
MOD7 : 复位/置位输出模式,当定时器计数到TACCRx值时,输出复位,当定时器计数到TACCR0值时,输出置位,这个与MOD2的区别更像是STM32里PWM1模式与PWM2模式的区别一样,占空比和频率仍然是通过修改CCR0与CCRx的值来实现的。
用示波器可在TA1.1检测到下面的波形
定时中断
在比较模式下,开启捕获/比较器的中断后,CCRx每计数到设定值后,就会产生一次中断,利用这一性质可实现定时器精准定时中断。下面是一个1s的定时中断
三·UART
MSP430的串口通信由USCI(通用串行通讯接口)管理,其中USCI_A0与USCI_A1都可实现异步UART,这里直接给出初始化函数和发送函数,需要知道的是在该例程中,串口的波特率是9600,串口的波特率由选择的时钟频率和分频共同决定,此次初始化使用的是板载UART1,在火箭板上接上RXD和TXD的跳线帽后,连接上MricoUSB就可以在电脑上的串口监视器查看到单片机发送的数据
四·OLED
0.96寸的OLED屏幕相信大家都不陌生,我使用的是I2C通讯协议的OLED屏幕,虽然MSP430是板载了I2C通讯接口的,不过我使用的还是软件I2C,直接从STM32那边移植过来的,通过对GPIO引脚输出特定时序来软件模拟I2C通讯协议的写和读操作,我的屏幕SCL连接在P6.3,SDA连接在P6.4,没啥好说的,直接上源码,大家移植的时候只需要更改oled.h里SCL和SDA的置位和清位就可以了。
关于显示屏幕的显示函数,其中void OLED_ShowString(u8 x,u8 y, u8 *p,u8 Char_Size)是显示ASCII字符串函数,四个形参分别为 x坐标,y坐标,"显示的字符",字体大小有8和16可选,其他大小需要自己去字模软件去取模,显示汉字的函数没有移植过来,大家去野火论坛下载STM32的oled工程,把里面的显示汉字函数拷过来然后将取模软件的汉字取模数据存放在char Hzk[][32]就可以了。
五·MPU6050
与OLED一样,软件I2C协议MPU6050的使用我也是从STM32那边移植过来的,MPU6050的STM32源码在野火论坛上可以找到,使用的时候只需要更改宏定义SCL和SDA置位清位以及void i2c_GPIO_Config(void)就行了,还有一个需要注意的是,访问MPU6050的寄存器需要读回当前SDA的状态信息,我自己写了一个int I2C_SDA_READ(void)函数,可返回SDA的电平状态,其余与野火的源代码并无太多差别
下面简介讲解一下这个MPU6050库的使用方法,通讯协议方面这个库也是软件I2C,在野火的MPU6050使用例程里,也有硬件I2C的解决方案,不过使用硬件I2C会不兼容OLED,I2C总线会经常挂掉,所以我在MSP430中也就没有使用硬件I2C,函数void MPU6050ReadAcc(short *accData),void MPU6050ReadGyro(short *gyroData),分别可以读回寄存器原始加速度值和角加速度值,具体MPU6050的例程详解还请参照野火的MPU6050