作者:BerenCamlost

适应于王宏波老师的《MSP430单片机》课

紧急更新!!!已完结 。求关注、收藏、点赞、评论

更新啦!还是到第七章,小更新,对部分错误做出修改,还有增加了部分重要知识点。

参考:

  1. MSP430数据手册
  2. PPT
  3. 实验教程
  4. 本文的PDF版本已经上传:https://download.csdn.net/download/weixin_43830248/14038239

第一章 绪论

1.1 单片机基础

  1. 全称:单片微型计算机(Single Chip MicroComputer)
  2. 它是把MPU、存储器、I/O口、定时器/计数器、中断系统、时钟电路、A/D-D/A等集成在一个芯片上构成的微型计算机系统。
  3. 单片机又称:单片微控制器、嵌入式微控制器

1.2 MSP430F663x片内资源

  • MSP430F663x 系列配置有一个高性能12 位ADC、比较器、两个USCI、USB2.0、硬件乘法器、DMA、四个16 位定时器、带有报警功能的RTC、LCD 驱动器和多达74 个I/O 。

1.3 进制转换

  • 【注意】小数的进制转换

1.4 原码、反码、补码的书写

  • 【注意】一般是8位补码,有时也有16位补码

1.5 位操作

P1OUT|=BIT1;                    //P1.1置1
P1OUT|=BIT0+BIT2+BIT6+BIT7;     //P1.0、 P1.2、 P1.6、 P1.7置1
P1OUT&=~BIT7;                  //P1.7清0
P1OUT&=~(BIT1+BIT3);          //P1.3、 P1.1清0
P1OUT^=BIT0;                   //P1.0取反
P1OUT^= BIT0+BIT2+BIT4+BIT6;        //P1.0、 P1.2、 P1.4、 P1.6取反
  • MSP430的C编译器不支持位寻址,所以运算中尽量减少位操作。

第2章 硬件结构

2.1 MSP430 CPU 与 MSP430X CPU

  1. MSP430 CPU是指MSP430F1xx系列采用的16 位CPU,数据总线宽度16位,地址总线宽度16位,寄存器16位。寻址空间216=64KB。
  2. MSP430X CPU(简称CPUX)是指MSP430F2xx/4xx/5xx/6xx系列采用的CPU,数据总线宽度16位,地址总线宽度20位,寄存器20位。寻址空间220=1MB。CPUX的算术逻辑单元(ALU)也可以完成20位的计算。
  3. CPUX向下兼容MSP430 CPU。

2.2 PC、SP、SR

  1. PC:
    取完指令后CPU根据该指令的字节数自动增量PC,因此20位的PC(R0)的值总是指向下一条要执行的指令。PC总是指向偶地址(bit0=0)。
  2. SP:
    1. 20位的堆栈指针,始终指向偶地址
    2. 【作用】:保护现场和恢复现场。
    3. 先进后出
    4. 堆栈分两种:
      (1)向上增长,栈底占用较低地址,栈顶占用较高地址:8051
      (2)向下增长,栈底占用较高地址,栈顶占用较低地址:MSP430、AVR
      (3)ARM支持两种增长方式的堆栈。
  3. SR:
    • 用作源或目标寄存器的16位状态寄存器(SR,也称为R2)只能用于通过字指令寻址的寄存器模式。 寻址模式的其余组合用于支持常数发生器。
    • SCG1:系统时钟发生器1该位可用于根据器件系列启用或禁用时钟系统中的功能; 例如,DCO偏置启用或禁用。
    • SCG0:系统时钟发生器0该位可用于根据器件系列启用或禁用时钟系统中的功能; 例如,FLL(频率锁定环)启用或禁用。
    • OSCOFF:关闭振荡器。 该位置1时,当LFXT1 CLK不用于MCLK或SMCLK时,它会关闭LFXT1晶体振荡器。
    • CPUOFF:CPU关闭。 该位置1时,将关闭CPU。
    • CPUOFF,OSCOFF,SCGO和SCG1位请求系统进入低功耗模式。
  • 【例如】:关闭和打开锁频环(FLL)
 __bis_SR_register(SCG0); // Disable the FLL control loopUCSCTL0 = 0x0000; // Set lowest possible DCOx, MODxUCSCTL1 = DCORSEL_3; // Set RSELx for DCO = 4.9 MHzUCSCTL2 = FLLD_1 + 74; // Set DCO Multiplier for 2.45MHz// (FLL_N + 1) * FLLRef = FdcoCLKDIV// (74 + 1) * 32768 = 2.45MHz// Set FLL Div = fDCOCLK/2__bic_SR_register(SCG0); // Enable the FLL control loop//其中__bis_SR_register()函数是将SR寄存器中的相应位置1//__bic_SR_register()函数是将SR寄存器中的相应位置0

2.3 三种系统复位

#mermaid-svg-K0HV3hZigQzhPauU .label{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);fill:#333;color:#333}#mermaid-svg-K0HV3hZigQzhPauU .label text{fill:#333}#mermaid-svg-K0HV3hZigQzhPauU .node rect,#mermaid-svg-K0HV3hZigQzhPauU .node circle,#mermaid-svg-K0HV3hZigQzhPauU .node ellipse,#mermaid-svg-K0HV3hZigQzhPauU .node polygon,#mermaid-svg-K0HV3hZigQzhPauU .node path{fill:#ECECFF;stroke:#9370db;stroke-width:1px}#mermaid-svg-K0HV3hZigQzhPauU .node .label{text-align:center;fill:#333}#mermaid-svg-K0HV3hZigQzhPauU .node.clickable{cursor:pointer}#mermaid-svg-K0HV3hZigQzhPauU .arrowheadPath{fill:#333}#mermaid-svg-K0HV3hZigQzhPauU .edgePath .path{stroke:#333;stroke-width:1.5px}#mermaid-svg-K0HV3hZigQzhPauU .flowchart-link{stroke:#333;fill:none}#mermaid-svg-K0HV3hZigQzhPauU .edgeLabel{background-color:#e8e8e8;text-align:center}#mermaid-svg-K0HV3hZigQzhPauU .edgeLabel rect{opacity:0.9}#mermaid-svg-K0HV3hZigQzhPauU .edgeLabel span{color:#333}#mermaid-svg-K0HV3hZigQzhPauU .cluster rect{fill:#ffffde;stroke:#aa3;stroke-width:1px}#mermaid-svg-K0HV3hZigQzhPauU .cluster text{fill:#333}#mermaid-svg-K0HV3hZigQzhPauU div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:12px;background:#ffffde;border:1px solid #aa3;border-radius:2px;pointer-events:none;z-index:100}#mermaid-svg-K0HV3hZigQzhPauU .actor{stroke:#ccf;fill:#ECECFF}#mermaid-svg-K0HV3hZigQzhPauU text.actor>tspan{fill:#000;stroke:none}#mermaid-svg-K0HV3hZigQzhPauU .actor-line{stroke:grey}#mermaid-svg-K0HV3hZigQzhPauU .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333}#mermaid-svg-K0HV3hZigQzhPauU .messageLine1{stroke-width:1.5;stroke-dasharray:2, 2;stroke:#333}#mermaid-svg-K0HV3hZigQzhPauU #arrowhead path{fill:#333;stroke:#333}#mermaid-svg-K0HV3hZigQzhPauU .sequenceNumber{fill:#fff}#mermaid-svg-K0HV3hZigQzhPauU #sequencenumber{fill:#333}#mermaid-svg-K0HV3hZigQzhPauU #crosshead path{fill:#333;stroke:#333}#mermaid-svg-K0HV3hZigQzhPauU .messageText{fill:#333;stroke:#333}#mermaid-svg-K0HV3hZigQzhPauU .labelBox{stroke:#ccf;fill:#ECECFF}#mermaid-svg-K0HV3hZigQzhPauU .labelText,#mermaid-svg-K0HV3hZigQzhPauU .labelText>tspan{fill:#000;stroke:none}#mermaid-svg-K0HV3hZigQzhPauU .loopText,#mermaid-svg-K0HV3hZigQzhPauU .loopText>tspan{fill:#000;stroke:none}#mermaid-svg-K0HV3hZigQzhPauU .loopLine{stroke-width:2px;stroke-dasharray:2, 2;stroke:#ccf;fill:#ccf}#mermaid-svg-K0HV3hZigQzhPauU .note{stroke:#aa3;fill:#fff5ad}#mermaid-svg-K0HV3hZigQzhPauU .noteText,#mermaid-svg-K0HV3hZigQzhPauU .noteText>tspan{fill:#000;stroke:none}#mermaid-svg-K0HV3hZigQzhPauU .activation0{fill:#f4f4f4;stroke:#666}#mermaid-svg-K0HV3hZigQzhPauU .activation1{fill:#f4f4f4;stroke:#666}#mermaid-svg-K0HV3hZigQzhPauU .activation2{fill:#f4f4f4;stroke:#666}#mermaid-svg-K0HV3hZigQzhPauU .mermaid-main-font{font-family:"trebuchet ms", verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-K0HV3hZigQzhPauU .section{stroke:none;opacity:0.2}#mermaid-svg-K0HV3hZigQzhPauU .section0{fill:rgba(102,102,255,0.49)}#mermaid-svg-K0HV3hZigQzhPauU .section2{fill:#fff400}#mermaid-svg-K0HV3hZigQzhPauU .section1,#mermaid-svg-K0HV3hZigQzhPauU .section3{fill:#fff;opacity:0.2}#mermaid-svg-K0HV3hZigQzhPauU .sectionTitle0{fill:#333}#mermaid-svg-K0HV3hZigQzhPauU .sectionTitle1{fill:#333}#mermaid-svg-K0HV3hZigQzhPauU .sectionTitle2{fill:#333}#mermaid-svg-K0HV3hZigQzhPauU .sectionTitle3{fill:#333}#mermaid-svg-K0HV3hZigQzhPauU .sectionTitle{text-anchor:start;font-size:11px;text-height:14px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-K0HV3hZigQzhPauU .grid .tick{stroke:#d3d3d3;opacity:0.8;shape-rendering:crispEdges}#mermaid-svg-K0HV3hZigQzhPauU .grid .tick text{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-K0HV3hZigQzhPauU .grid path{stroke-width:0}#mermaid-svg-K0HV3hZigQzhPauU .today{fill:none;stroke:red;stroke-width:2px}#mermaid-svg-K0HV3hZigQzhPauU .task{stroke-width:2}#mermaid-svg-K0HV3hZigQzhPauU .taskText{text-anchor:middle;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-K0HV3hZigQzhPauU .taskText:not([font-size]){font-size:11px}#mermaid-svg-K0HV3hZigQzhPauU .taskTextOutsideRight{fill:#000;text-anchor:start;font-size:11px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-K0HV3hZigQzhPauU .taskTextOutsideLeft{fill:#000;text-anchor:end;font-size:11px}#mermaid-svg-K0HV3hZigQzhPauU .task.clickable{cursor:pointer}#mermaid-svg-K0HV3hZigQzhPauU .taskText.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-K0HV3hZigQzhPauU .taskTextOutsideLeft.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-K0HV3hZigQzhPauU .taskTextOutsideRight.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-K0HV3hZigQzhPauU .taskText0,#mermaid-svg-K0HV3hZigQzhPauU .taskText1,#mermaid-svg-K0HV3hZigQzhPauU .taskText2,#mermaid-svg-K0HV3hZigQzhPauU .taskText3{fill:#fff}#mermaid-svg-K0HV3hZigQzhPauU .task0,#mermaid-svg-K0HV3hZigQzhPauU .task1,#mermaid-svg-K0HV3hZigQzhPauU .task2,#mermaid-svg-K0HV3hZigQzhPauU .task3{fill:#8a90dd;stroke:#534fbc}#mermaid-svg-K0HV3hZigQzhPauU .taskTextOutside0,#mermaid-svg-K0HV3hZigQzhPauU .taskTextOutside2{fill:#000}#mermaid-svg-K0HV3hZigQzhPauU .taskTextOutside1,#mermaid-svg-K0HV3hZigQzhPauU .taskTextOutside3{fill:#000}#mermaid-svg-K0HV3hZigQzhPauU .active0,#mermaid-svg-K0HV3hZigQzhPauU .active1,#mermaid-svg-K0HV3hZigQzhPauU .active2,#mermaid-svg-K0HV3hZigQzhPauU .active3{fill:#bfc7ff;stroke:#534fbc}#mermaid-svg-K0HV3hZigQzhPauU .activeText0,#mermaid-svg-K0HV3hZigQzhPauU .activeText1,#mermaid-svg-K0HV3hZigQzhPauU .activeText2,#mermaid-svg-K0HV3hZigQzhPauU .activeText3{fill:#000 !important}#mermaid-svg-K0HV3hZigQzhPauU .done0,#mermaid-svg-K0HV3hZigQzhPauU .done1,#mermaid-svg-K0HV3hZigQzhPauU .done2,#mermaid-svg-K0HV3hZigQzhPauU .done3{stroke:grey;fill:#d3d3d3;stroke-width:2}#mermaid-svg-K0HV3hZigQzhPauU .doneText0,#mermaid-svg-K0HV3hZigQzhPauU .doneText1,#mermaid-svg-K0HV3hZigQzhPauU .doneText2,#mermaid-svg-K0HV3hZigQzhPauU .doneText3{fill:#000 !important}#mermaid-svg-K0HV3hZigQzhPauU .crit0,#mermaid-svg-K0HV3hZigQzhPauU .crit1,#mermaid-svg-K0HV3hZigQzhPauU .crit2,#mermaid-svg-K0HV3hZigQzhPauU .crit3{stroke:#f88;fill:red;stroke-width:2}#mermaid-svg-K0HV3hZigQzhPauU .activeCrit0,#mermaid-svg-K0HV3hZigQzhPauU .activeCrit1,#mermaid-svg-K0HV3hZigQzhPauU .activeCrit2,#mermaid-svg-K0HV3hZigQzhPauU .activeCrit3{stroke:#f88;fill:#bfc7ff;stroke-width:2}#mermaid-svg-K0HV3hZigQzhPauU .doneCrit0,#mermaid-svg-K0HV3hZigQzhPauU .doneCrit1,#mermaid-svg-K0HV3hZigQzhPauU .doneCrit2,#mermaid-svg-K0HV3hZigQzhPauU .doneCrit3{stroke:#f88;fill:#d3d3d3;stroke-width:2;cursor:pointer;shape-rendering:crispEdges}#mermaid-svg-K0HV3hZigQzhPauU .milestone{transform:rotate(45deg) scale(0.8, 0.8)}#mermaid-svg-K0HV3hZigQzhPauU .milestoneText{font-style:italic}#mermaid-svg-K0HV3hZigQzhPauU .doneCritText0,#mermaid-svg-K0HV3hZigQzhPauU .doneCritText1,#mermaid-svg-K0HV3hZigQzhPauU .doneCritText2,#mermaid-svg-K0HV3hZigQzhPauU .doneCritText3{fill:#000 !important}#mermaid-svg-K0HV3hZigQzhPauU .activeCritText0,#mermaid-svg-K0HV3hZigQzhPauU .activeCritText1,#mermaid-svg-K0HV3hZigQzhPauU .activeCritText2,#mermaid-svg-K0HV3hZigQzhPauU .activeCritText3{fill:#000 !important}#mermaid-svg-K0HV3hZigQzhPauU .titleText{text-anchor:middle;font-size:18px;fill:#000;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-K0HV3hZigQzhPauU g.classGroup text{fill:#9370db;stroke:none;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:10px}#mermaid-svg-K0HV3hZigQzhPauU g.classGroup text .title{font-weight:bolder}#mermaid-svg-K0HV3hZigQzhPauU g.clickable{cursor:pointer}#mermaid-svg-K0HV3hZigQzhPauU g.classGroup rect{fill:#ECECFF;stroke:#9370db}#mermaid-svg-K0HV3hZigQzhPauU g.classGroup line{stroke:#9370db;stroke-width:1}#mermaid-svg-K0HV3hZigQzhPauU .classLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5}#mermaid-svg-K0HV3hZigQzhPauU .classLabel .label{fill:#9370db;font-size:10px}#mermaid-svg-K0HV3hZigQzhPauU .relation{stroke:#9370db;stroke-width:1;fill:none}#mermaid-svg-K0HV3hZigQzhPauU .dashed-line{stroke-dasharray:3}#mermaid-svg-K0HV3hZigQzhPauU #compositionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-K0HV3hZigQzhPauU #compositionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-K0HV3hZigQzhPauU #aggregationStart{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-svg-K0HV3hZigQzhPauU #aggregationEnd{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-svg-K0HV3hZigQzhPauU #dependencyStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-K0HV3hZigQzhPauU #dependencyEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-K0HV3hZigQzhPauU #extensionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-K0HV3hZigQzhPauU #extensionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-K0HV3hZigQzhPauU .commit-id,#mermaid-svg-K0HV3hZigQzhPauU .commit-msg,#mermaid-svg-K0HV3hZigQzhPauU .branch-label{fill:lightgrey;color:lightgrey;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-K0HV3hZigQzhPauU .pieTitleText{text-anchor:middle;font-size:25px;fill:#000;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-K0HV3hZigQzhPauU .slice{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-K0HV3hZigQzhPauU g.stateGroup text{fill:#9370db;stroke:none;font-size:10px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-K0HV3hZigQzhPauU g.stateGroup text{fill:#9370db;fill:#333;stroke:none;font-size:10px}#mermaid-svg-K0HV3hZigQzhPauU g.statediagram-cluster .cluster-label text{fill:#333}#mermaid-svg-K0HV3hZigQzhPauU g.stateGroup .state-title{font-weight:bolder;fill:#000}#mermaid-svg-K0HV3hZigQzhPauU g.stateGroup rect{fill:#ECECFF;stroke:#9370db}#mermaid-svg-K0HV3hZigQzhPauU g.stateGroup line{stroke:#9370db;stroke-width:1}#mermaid-svg-K0HV3hZigQzhPauU .transition{stroke:#9370db;stroke-width:1;fill:none}#mermaid-svg-K0HV3hZigQzhPauU .stateGroup .composit{fill:white;border-bottom:1px}#mermaid-svg-K0HV3hZigQzhPauU .stateGroup .alt-composit{fill:#e0e0e0;border-bottom:1px}#mermaid-svg-K0HV3hZigQzhPauU .state-note{stroke:#aa3;fill:#fff5ad}#mermaid-svg-K0HV3hZigQzhPauU .state-note text{fill:black;stroke:none;font-size:10px}#mermaid-svg-K0HV3hZigQzhPauU .stateLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.7}#mermaid-svg-K0HV3hZigQzhPauU .edgeLabel text{fill:#333}#mermaid-svg-K0HV3hZigQzhPauU .stateLabel text{fill:#000;font-size:10px;font-weight:bold;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-K0HV3hZigQzhPauU .node circle.state-start{fill:black;stroke:black}#mermaid-svg-K0HV3hZigQzhPauU .node circle.state-end{fill:black;stroke:white;stroke-width:1.5}#mermaid-svg-K0HV3hZigQzhPauU #statediagram-barbEnd{fill:#9370db}#mermaid-svg-K0HV3hZigQzhPauU .statediagram-cluster rect{fill:#ECECFF;stroke:#9370db;stroke-width:1px}#mermaid-svg-K0HV3hZigQzhPauU .statediagram-cluster rect.outer{rx:5px;ry:5px}#mermaid-svg-K0HV3hZigQzhPauU .statediagram-state .divider{stroke:#9370db}#mermaid-svg-K0HV3hZigQzhPauU .statediagram-state .title-state{rx:5px;ry:5px}#mermaid-svg-K0HV3hZigQzhPauU .statediagram-cluster.statediagram-cluster .inner{fill:white}#mermaid-svg-K0HV3hZigQzhPauU .statediagram-cluster.statediagram-cluster-alt .inner{fill:#e0e0e0}#mermaid-svg-K0HV3hZigQzhPauU .statediagram-cluster .inner{rx:0;ry:0}#mermaid-svg-K0HV3hZigQzhPauU .statediagram-state rect.basic{rx:5px;ry:5px}#mermaid-svg-K0HV3hZigQzhPauU .statediagram-state rect.divider{stroke-dasharray:10,10;fill:#efefef}#mermaid-svg-K0HV3hZigQzhPauU .note-edge{stroke-dasharray:5}#mermaid-svg-K0HV3hZigQzhPauU .statediagram-note rect{fill:#fff5ad;stroke:#aa3;stroke-width:1px;rx:0;ry:0}:root{--mermaid-font-family: '"trebuchet ms", verdana, arial';--mermaid-font-family: "Comic Sans MS", "Comic Sans", cursive}#mermaid-svg-K0HV3hZigQzhPauU .error-icon{fill:#522}#mermaid-svg-K0HV3hZigQzhPauU .error-text{fill:#522;stroke:#522}#mermaid-svg-K0HV3hZigQzhPauU .edge-thickness-normal{stroke-width:2px}#mermaid-svg-K0HV3hZigQzhPauU .edge-thickness-thick{stroke-width:3.5px}#mermaid-svg-K0HV3hZigQzhPauU .edge-pattern-solid{stroke-dasharray:0}#mermaid-svg-K0HV3hZigQzhPauU .edge-pattern-dashed{stroke-dasharray:3}#mermaid-svg-K0HV3hZigQzhPauU .edge-pattern-dotted{stroke-dasharray:2}#mermaid-svg-K0HV3hZigQzhPauU .marker{fill:#333}#mermaid-svg-K0HV3hZigQzhPauU .marker.cross{stroke:#333}:root { --mermaid-font-family: "trebuchet ms", verdana, arial;}#mermaid-svg-K0HV3hZigQzhPauU {color: rgba(0, 0, 0, 0.75);font: ;}

掉电复位BOR
上电复位POR
上电清除PUC

2.4 复位状态

  • 在BOR之后,初始设备条件是:
  1. RST / NMI引脚配置为复位模式。
  2. I / O引脚切换到输入模式。
  3. 状态寄存器(SR)复位。
  4. 看门狗定时器在看门狗模式下上电。

第3章 中断、时钟与低功耗

3.1 中断

3.1.1 各种中断向量

中断名称(不规范) 宏定义
port1口中断 PORT1_VECTOR
port2口中断 PORT2_VECTOR
振荡器失效中断 0xFFFA
WDT间隔定时器模式中断 WDT_VECTOR
WDT看门狗模式中断 0xFFFE
TAxCCR0中断中断 TIMER0_A0_VECTOR
TAIFG中断 TIMER0_A1_VECTOR
ADC12中断 ADC12_VECTOR
串口中断 USCI_A1_VECTOR
  • 【注意】排序顺序为实验顺序,不代表优先级大小
  • 中断向量的计算

3.1.2 中断优先级

  • 不同中断源发出的中断请求重要程度不同,每个中断源对应一个优先级,称为中断优先级。
  • 【作用】:多个中断同时发生时,决定哪个中断被响应。
  • 【注意】:
    1. 中断优先级只有在多个中断同时到来时才起作用,在中断嵌套中是不考虑的
    2. 中断优先级固定不变,取决于模块在中断向量表中的排序

3.1.3 中断嵌套

  1. CPU响应某一中断时,在开总中断的前提下若有其他中断发生,CPU将中断当前ISR,执行新的ISR。
  2. MSP430默认关闭中断嵌套,即进入中断服务函数后,默认关闭总中断。如果想要开启中断嵌套需要用户使用软件开启总中断。
  3. 开启和关闭总中断例程中最常用的方式是
__bis_SR_register(GIE); // 开启总中断
__bic_SR_register(GIE); // 关闭总中断//其中__bis_SR_register()函数是将SR寄存器中的相应位置1
//__bic_SR_register()函数是将SR寄存器中的相应位置0

3.1.4 中断服务函数

  • 如果是多元中断,可能会在终端服务函数中查看是那种中断置位,即用if或switch语句判断中断标志位是否为1.例如:
// Timer_A1 Interrupt Vector (TAIV) handler
#pragma vector=TIMER0_A1_VECTOR__interrupt void TIMER0_A1_ISR(void){switch(__even_in_range(TA0IV,14))// __even_in_range()本征函数,用于多源中断的查询。{case 0: break; // No interruptcase 2: break; // CCR1 not usedcase 4: break; // CCR2 not usedcase 6: break; // reservedcase 8: break; // reservedcase 10: break; // reservedcase 12: break; // reservedcase 14: P4OUT ^= BIT1; // TAIFGbreak;default: break;}}

3.2 UCS时钟系统

3.2.1 五种时钟源和三种时钟信号

name function
XT1 CLK 外部低频,一般接32768Hz
VLOCLK 内部,10K振荡器
REFOCLK 内部,32768Hz
DCOCLK 内部,数控振荡器,借助参考时钟
XT2 CLK 外部高频,4~32MHZ
  • 【注】DCOCLKDIV时钟为DCOCLK分频得到
name function 默认 默认频率 输出方法
ACLK 用于低速外设,可由P1.0输出 XT1CLK 32768Hz P1.0
MCLK 用于CPU和系统 DCOCLKDIV 1048576Hz 使用__delay_cycles();和LED查看
SMCLK 用于高速外设,可由P3.4输出 DCOCLKDIV 1048576Hz P3.4

3.2.2 FLL——锁频环

  • 计算公式:fDCOCLK ÷[D × (N + 1) ] = fFLLREFCLK ÷ n
  • 【注释】:
    • D:FLLD,默认为2
    • N:FLLN,默认为31
    • n:FLLREFDIV, 默认为1
    • fFLLREFCLK :FLL的参考时钟,默认为XT1CLK(32768Hz)
  • 所以fDCOCLK 默认为2097152Hz,fDCOCLKDIV默认为1048576Hz

3.2.3 UCS复位之后

  • 由于复位的时候XT1CLK未稳定,所以ACLK和FLL的参考时钟会自动变为REFOCLK(注意这里是REFOCLK,和后边WDT看门狗模式下的时钟故障保护功能,自动变成VLOCLK相区别)
  • 根据实验情况,如果在配置ACLK和FLL之前,XT1CLK未稳定,那么时钟频率会相对变低
//稳定XT1CLK和XT2CLK的程序
//1. 解锁XT1的引脚,这是f66xx设备独有的
while(BAKCTL & LOCKBAK)// Unlock XT1 pins
{BAKCTL &= ~(LOCKBAK);
}
//2. 设置XT2的引脚
P7SEL |= BIT2 + BIT3; // Port select XT2//3. 开启XT1, XT2
UCSCTL6 &= ~(XT1OFF + XT2OFF); // Set XT1, XT2 On//4. 稳定XT1CLK、XT2CLK、DCOCLK
do
{UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + DCOFFG); // Clear XT2,XT1,DCO fault flagsSFRIFG1 &= ~OFIFG; // Clear fault flags
}while (SFRIFG1&OFIFG); // Test oscillator fault flag//5. ACLK选择XT1CLK、SMCLK选择XT2CLK
UCSCTL4 |= SELA__XT1CLK + SELS__XT2CLK; // Select SMCLK, ACLK source

3.2.4 设置DCOCLK输出的频率范围

  1. 使用UCSCTL1寄存器中的DCORSEL位来设置范围
  2. 不用看UCSCTL0寄存器中的DCO和MOD位,单片机会自动设置
  3. 尽可能让输出的频率在DCORSEL控制的范围的中间位置

3.2.5 UCS模块失效安全操作

  1. 任何一种失效都会导致OFIFG(振荡器失效中断、非屏蔽)
  2. 受到OFIE使能位控制
  3. 振荡器关闭、打开但未正常工作时,对应振荡器失效位XT1 LFOFFG,XT1 HFOFFG, XT2OFFG置位;
  4. 振荡器失效位一旦置位必须用户软件清除;
  5. 若用户软件清除振荡器失效位后失效条件依然存在,振荡器失效位会自动置位。
  6. 振荡器失效事件不受GIE控制。

3.3 低功耗

模式 作用
Active 都可用FLL开
LPM0 ACLK、SMCLK可用 FLL开
LPM3 仅ACLK可用(我发现这个和LPM2差不多)
LPM4 都不可用(软件关机)
  • 最常用的开启低功耗的方式
__bis_SR_register(LPM3_bits);//开启低功耗模式3
__bic_SR_register(LPM3_bits);//关闭低功耗模式3
//也可以这样:
LPM3;//开启
LPM3_EXIT;//关闭

第四章 数字I/O模块

4.1 数字I/O模块寄存器设置

寄存器 名称 0 1 复位值
PxIN 输入寄存器 输入低 输入高 不确定
PxOUT 输出寄存器 输出低 输出高 不确定
决定上下拉输入 下拉 上拉 不确定
PxDIR 方向寄存器 输入(默认) 输出 0
PxREN 上下拉寄存器 不使能 使能 0
PxSEL 引脚功能选择 I/O功能 片内外设 0
  • 关于PxDIR,PxREN和PxOUT在正确I / O配置中的用法
PxDIR PxREN PxOUT I / O配置
0 0 x 输入,无上下拉
0 1 0 下拉输入
0 1 1 上拉输入
1 x 0/1 输出0/1
  • 对于P1,P2引脚而言,具有中断能力,利用PxIFG, PxIE,和PxIES 寄存器进行配置。
寄存器 名称 0 1 复位
PxIFG 中断标志位 无中断 有中断在等待 0
PxIE 中断使能位 不使能 使能 0
PxIES 中断边沿选择 上升沿 下降沿 不确定

4.2 按键

4.2.1 关于上下拉

  1. 对于按键必须要有上下拉,因为要有默认的输入值,不能让输入值处于浮空状态
  2. 可以选择内部的上下拉和外部的上下拉
  3. MSP430F6638具有内部上下拉,所以不一定必须使用外部上下拉

4.2.2 按键消抖

  1. 软件消抖:在首次检测到按键按下后,先执行一段延时子程序,然后再次确认按键是否按下,达到消抖目的。
  2. 硬件消抖:常用双稳态电路、单稳态电路和RC积分电路等方法。

4.3 额外的东西

对于在中断服务函数中手动清零中断标志位IFG,其实有一种更方便的方法老师没讲——PxIV,这个东西会在后边讲Timer_A中看到类似的寄存器——TAxIV

  1. 读/写这个寄存器都会使得正在等待处理的最高中断标志位清零
  2. 如果有多个中断同时到来,那么处理完最高中断后会从新开启一个中断。

第5章 看门狗WDT_A

5.1 看门狗概述

5.1.1 看门狗的作用

看门狗(Watchdog Timer-WDT)分硬件看门狗和软件看门狗,用于程序跑飞时的系统复位。

5.1.2 程序跑飞

程序跑飞不是一种硬件故障,但它会引起死机。

5.1.3 看门狗是什么

简单的说是一个定时器,从程序开始运行的时候就开始计数,当计数满的时候就会使程序复位。所以要在计满之前让看门狗定时器的数值清零,俗称喂狗。如果在计满之前看门狗没有收到喂狗信号,则认为程序已经跑飞。

5.1.4 看门狗的两种功能

  1. 分别是看门狗模式和间隔定时器模式
  2. 这两种模式使用不同的中断向量,但是都是单源中断(所以中断标志位WDTIFG可以自动清零)
    • 看门狗模式的中断是系统中断
    • 间隔定时器的中断是可屏蔽中断
    • 看门狗和间隔定时器使用相同的中断标志位:WDTIFG
    • 这两种模式不能同时使用
  3. 看门狗模式具有时钟故障保护功能,但是间隔定时器模式没有

5.2 看门狗的默认复位时间

WDTIS默认为4h,其时钟信号默认为SMCLK,而SMCLK的时钟源默认为DCOCLKDIV,DCOCLKDIV的频率默认为1048576Hz,所以时间间隔默认为
11048576Hz÷215=132s=32ms\frac{1}{1048576Hz\div 2^{15}}=\frac{1}{32}s=32ms 1048576Hz÷2151​=321​s=32ms

5.3 时钟故障保护

  1. 为保证WDT在看门狗模式下能工作,如果SMCLK或ACLK作为WDT_A时钟源发生故障,WDT将自己的时钟自动调整为VLOCLK(注意这里是VLOCLK,而不是REFOCLK )
  2. WDT_A提供故障安全时钟功能,确保在看门狗模式下不能禁止WDT_A的时钟。 这意味着LPM可能会受到WDT_A时钟选择的影响。
  3. 当WDT_A模块用于间隔定时器模式时,WDT A中没有用于时钟源的故障安全功能。

5.4 低功耗模式下的操作

用程序的要求和使用的时钟类型决定了WDT_A的配置方式。 例如,如果用户想要使用LPM3,则WDT_A不应配置为看门狗模式,其时钟源最初来自DCO,XT1为高频模式,XT2为SMCLK或ACLK。 在这种情况下,SMCLK或ACLK将保持启用状态,从而增加LPM3的当前消耗。

5.5 关闭看门狗的方法

//1. 正确的方法
WDTCTL = (WDTPW + WDTHOLD);
WDTCTL = WDTPW | WDTHOLD;//2. 错误的方法
WDTCTL |= (WDTPW + WDTHOLD);//错误

第6章 定时器Timer_A

6.1 各种寄存器(x代表数字,比如我们用的TA1,那么x=1)

6.1.1 TAxR——16位计数器

  1. 16位定时器/计数器寄存器TAxR随时钟信号的每个上升沿递增或递减(取决于工作模式)。 可以使用软件读取或写入TAxR。 另外,定时器在溢出时可以产生中断。
  2. 可以通过将TAxCTL寄存器中的TACLR位置1来清零TAxR。 将该位置1会复位TAxR,定时器时钟分频器逻辑和计数方向。 TACLR位自动复位,始终读为0。

6.1.2 TAxCTL——时钟控制

  1. TASSEL——选择时钟
  2. MC——设置计数模式
MC Mode 中文 Description
00 Stop 停止计数 定时器停止
01 Up 增计数 定时器重复从零计数到TAxCCR0的值
10 Continuous 连续计数 定时器重复从零到0FFFFh。
11 Up/down 增减计数 定时器重复从零开始计数到TAxCCR0的值并返回到零。
  1. TACLR——清空TAxR
  2. TAIE——中断使能

6.1.3 TAxCCTLn——Timer_Ax捕捉/比较控制寄存器n

捕获比较模块一共7个,n=(0~6)

  1. CAP——设置捕获模式/比较模式
  2. OUTMOD——设置输出方式(共8种)
    • 第一种是电平输出,可以指定输入的电平(OUT位)
    • 模式 2, 3, 6, and 7 对于 TAxCCR0 是没有用的因为 EQUx = EQU0.
  3. CCIE——中断使能
    【注意】:这个是捕获比较的中断使能,和上面的Timer_A的中断不同。

6.1.4 TAxCCRn——捕捉/比较寄存器n

放数的

6.1.5 TAxIV——中断寄存器

  1. 用于查询是哪个中断到来
  2. 其中包含的中断事件不包括TAxCCR0中断

6.2 中断

6.2.1TAxCCR0中断

  1. TAxCCR0 CCIFG具有最高的Timer_A中断优先级,并具有专用中断向量(TIMER0_A0_VECTOR)。 当TAxCCR0中断请求被服务时,TAxCCR0 CCIFG自动复位。
  2. 这是一个单源中断

6.2.2 TAxIV中断

  1. TAxCCRy CCIFG和TAIFG被优先化并组合以获得单个中断向量。(这表明其优先级可以被软件设置,这和所谓中断优先级是两个概念) 这话大错特错!!优先级不能设置,写错了!
  2. TAxIV用于确定请求中断的标志。
  3. 禁用Timer_A中断不会影响TAxIV值。
  4. TAxIV寄存器的任何访问,读取或写入都会自动重置最高的待处理中断标志。 如果设置了另一个中断标志,则在服务初始中断后立即产生另一个中断。(如果你们做过实验会发现后边的串口通信也有这个性质)
  5. 这是一个多源中断,但是不用手动清中断标志位

6.3 程序

6.3.1 TA0CCR0 中断

下面程序采用增计数模式,那么增加到TA0CCR0 就会产生TA0CCR0 中断,然后计数器自动清零,重新计数

  • 【注意】:这是一个单源中断

#include<msp430f6638.h>
void main(void)
{WDTCTL = WDTPW + WDTHOLD; // Stop WDTP4DIR |= BIT1; // P4.1 outputTA0CCTL0 = CCIE; // 开启TA0CCR0 的中断TA0CCR0 = 50000;TA0CTL = TASSEL__SMCLK + MC__UP + TACLR; // 时钟源选SMCLK,增计数模式,清零计数器_BIS_SR(LPM0_bits + GIE); // Enter LPM0, enable interrupts_NOP(); // For debugger
}
// Timer_A0 ISR
#pragma vector=TIMER0_A0_VECTOR
__interrupt void TIMER0_A0_ISR(void) // 注意这个中断向量
{P4OUT
}

6.3.2 TAxIV中断

下面程序,由于是连续计数模式,计数器会从0到FFFF重复计数,但是又未设置TA0CCRn的值,所以只在0FFFFh的时候才产生TAIFG这个中断,这个中断的查询在TAxIV=14的位置

  • 【注意】:这是多源中断
#include<msp430f6638.h>
void main(void)
{WDTCTL = WDTPW + WDTHOLD; // Stop WDTP4DIR |= BIT1; // P4.1 outputTA0CTL = TASSEL__ACLK + MC__CONTINUOUS + TACLR + TAIE; // 时钟源为ACLK,连续计数模式,清空计数器,是能中断__bis_SR_register(LPM3_bits + GIE); //【区分】:__bic_SR_register()这个函数是和上面的作用相反,//比如__bic_SR_register(LPM0_bits + GIE);是关闭低功耗并且关闭总中断_NOP();
}#pragma vector=TIMER0_A1_VECTOR // 这个中断向量和上面的程序不一样__interrupt void TIMER0_A1_ISR(void){switch(__even_in_range(TA0IV,14))// __even_in_range()本征函数,用于多源中断的查询。{case 0: break; // No interruptcase 2: break; // CCR1 not usedcase 4: break; // CCR2 not usedcase 6: break; // reservedcase 8: break; // reservedcase 10: break; // reservedcase 12: break; // reservedcase 14: P4OUT ^= BIT1; // TAIFGbreak;default: break;}}

第7章 模数转换器ADC12_A

7.1 概述

7.1.1 ADC12

  1. 这是一个12位的模拟量转换为数字量的内部外设
  2. 主要的过程为:
    1. 将模拟量通过某个单片机的引脚输入进去
    2. ADC读取该引脚的电压值,并根据参考电压的大小,将其转化为12位的数字量的值
    3. 将这个12位的数字值保存到一个12位寄存器中
    4. 在ADC12的中断服务函数中读取这个寄存器的值,从而进行相应的操作

7.1.2 分辨率

  1. 用数字量的二进制位数来表示。如12位ADC的分辨率就是12位
  2. 用1个LSB使输出变化的程度表示,如12位ADC的分辨率为满刻度的1/212

7.1.3 量化间隔

  1. 满量程输入电压/(2n-1)
  • 其中n为ADC的位数,这里为12
  • 满量程输入电压一般为正参考电压,即VR+

7.1.4 量化误差

是ADC的有限位数对模拟量进行量化而引起的误差,有两种计算方法:

  1. 绝对误差=量化间隔/2
  2. 相对误差=1/(2n+1)
  • 这里的n还是12

7.1.5 关于参考电压的选取(REFMSTR的设置)

在REFCTL这个寄存器中有一个神奇的位叫做REFMSTR,可以通过它来设定由谁控制ADC12的参考电压。

  1. 当REFMSTR=1时,ADC12允许通过REFCTL寄存器控制参考系统,ADC寄存器组(ADC12REFON,ADC12REF2_5,ADC12TCOFF和ADC12REFOUT)内的原先的控制位就失去了作用,但是 ADC12SR和ADC12REFBURST仍由ADC12_A控制,因为它们非常特定于ADC12_A模块。
  2. 当REFMSTR=0时,ADC12的参考电压由它自己的寄存器组设置,就是上边提到的那些寄存器

7.1.6 转换的计算公式

NADC=4095×VIN−VR−VR+−VR−N_{ADC}=4095\times \frac{V_{IN}-V_{R-}}{V_{R+}-V_{R-}} NADC​=4095×VR+​−VR−​VIN​−VR−​​

  • 其中4095的由来是212−1=40952^{12}-1=4095212−1=4095
  • 当输入电压大于正参考电压时,寄存器的值为0x0fff,当输入电压小于负参考电压时,寄存器的值为0x0000

7.2 ADC12的采样

7.2.1 SHI

  1. 一次AD转换由采样输入信号SHI的上升沿触发
  2. SHI的来源:

7.2.2 SAMPCON

  1. 采样控制信号SAMPCON控制采样周期和转换开始,当SAMPCON 为高时采样激活, SAMPCON 的下降沿触发模数转换。
  2. ADC12SHP 定义了2种采样时序(方法):
    1. 扩展采样模式

      SAMPCON的长度由SHI的时间控制。即,采样输入信号SHI直接作为采样控制信号SAMPCON,决定采样的起始时刻、采样周期转换时刻
    2. 脉冲采样模式
      脉冲采样模式下,采样输入信号SHI仅用于触发采样,采样周期由采样定时器(ADC12SHT0x和ADC12SHT1x设置)确定

7.3 各种寄存器

7.3.1 ADC12CTL0

  1. ADC12SHT1x & ADC12SHT0x

    • 用于设定采样的周期,其中
    • ADC12SHT1x配置ADC12MEM8 ~ADC12MEM15寄存器的采样周期
    • ADC12SHT0x配置ADC12MEM0 ~ADC12MEM7寄存器的采样周期
  2. ADC12REF2_5V
    内部参考电压的设置
  3. ADC12REFON
    内部参考电压开启/关闭
  4. ADC12ON
    ADC12的开启/关闭
  5. ADC12ENC
    ADC12_A的转换使能,这个位在配置寄存器之前应该置0,配置结束后置1
  6. ADC12SC
    ADC12的转换开始,这个位在转换结束后会自动复位,所以在应用程序中转换结束后应该将这一位软件置1

7.3.2 ADC12CTL1

  1. ADC12CSTARTADDx
    转换地址选择,即ADC12MEMx的选择
  2. ADC12SHSx
    SHI信号选择
  3. ADC12SHP
    采样模式选择(扩展采样和脉冲采样)
  4. ADC12SSELx
    ADC12CLK的选择
  5. ADC12CONSEQx
    模式选择,一般选择单通道单次转换,即00

7.3.3 ADC12MEMx

转换出来的值存放在这里,一般在终端服务函数中查看这个寄存器。当转换结果写入选定的ADC12MEMx, ADC12IFGx中对应标志位置位;当这个寄存器的值被读取之后,IFG自动复位。

  • 强调一下:转换结果写入ADC12MEMx时对应的ADC12IFGx置位,若对应的ADC12IEx 和GIE 置位,将会产生中断请求。

7.3.4 ADC12MCTLx

这里的x是由ADC12CTL1寄存器中的ADC12CSTARTADDx位确定的

  1. ADC12SREFx参考电压选择
  2. ADC12INCHx模拟量输入通道选择

7.3.5 ADC12IE

中断使能寄存器,使能哪一位也是由ADC12CTL1寄存器中的ADC12CSTARTADDx位确定的

7.3.6 ADC12IV

这个寄存器可以查看是哪个中断标志位置位,具体的代码是:

switch(__even_in_range(ADC12IV,34))// 注意这个内置函数,用于查看是哪个中断到来
{case 0: break; // Vector 0: No interruptcase 2: break; // Vector 2: ADC overflowcase 4: break; // Vector 4: ADC timing overflowcase 6: break;// Vector 6: ADC12IFG0case 8: break; // Vector 8: ADC12IFG1case 10: break; // Vector 10: ADC12IFG2case 12: break; // Vector 12: ADC12IFG3case 14: break; // Vector 14: ADC12IFG4case 16: break; // Vector 16: ADC12IFG5case 18: break; // Vector 18: ADC12IFG6case 20: break; // Vector 20: ADC12IFG7case 22: break; // Vector 22: ADC12IFG8case 24: break; // Vector 24: ADC12IFG9case 26: break; // Vector 26: ADC12IFG10case 28: break; // Vector 28: ADC12IFG11case 30: break; // Vector 30: ADC12IFG12case 32: break; // Vector 32: ADC12IFG13case 34: break; // Vector 34: ADC12IFG14default: break;
}

7.4 例程

注释都在例程里,仔细看哦~

#include <msp430.h>
void main(void)
{//1. 关闭看门狗WDTCTL = WDTPW | WDTHOLD; //2. 使用ADC12_A参考电压控制寄存器REFCTL0 &= ~REFMSTR; //3.1 ADC12ENC置零来设置ADC12ADC12CTL0 &=~ ADC12ENC;ADC12CTL0 = ADC12SHT12 + ADC12ON + ADC12REFON + ADC12REF2_5V; // 采样时间Tsample = 64个ADC12CLK,打开ADC12,开参考电压,参考电压VREF+=2.5V。//这里注意ADC12SHT12 和ADC12SHT02 的区别//ADC12SHT02 用于设置MEM0~MEN7的采样周期是64个ADC12CLK//ADC12SHT12 用于设置MEM8~MEN15的采样周期是64个ADC12CLKADC12CTL1 = ADC12CSTARTADD_8 + ADC12SHP + ADC12SSEL_2 + ADC12CONSEQ_0;    // ADC12MEMO8作为转换存储寄存器,脉冲采样模式, ADC时钟MCLK,单通道单次转换(缺省)ADC12MCTL8 = ADC12SREF_1 + ADC12INCH_4; // VR+ = VREF+, VR- = AVss,采样通道CH4ADC12IE = BIT8; // 使能ADC12MEM8的中断 ADC12CTL0 |= ADC12ENC; //ADC12ENC置1,开启转换P6SEL |= BIT4; // P6.4 作为ADC输入while (1){ADC12CTL0 |= ADC12SC; // 不断置位ADC12SC来实现ADC12一直转换_BIS_SR(GIE); // 开总中断__no_operation(); // For debugger}
}
#pragma vector = ADC12_VECTOR__interrupt void ADC12_ISR(void){switch(__even_in_range(ADC12IV,34)){// 这边分了很多种情况,来区分这个多源中断的不同中断源,// 可以通过设置case的顺序来实现配置中断的优先级case 0: break; // Vector 0: No interruptcase 2: break; // Vector 2: ADC overflowcase 4: break; // Vector 4: ADC timing overflowcase 6: break; // Vector 6: ADC12IFG0case 8: break; // Vector 8: ADC12IFG1case 10: break; // Vector 10: ADC12IFG2case 12: break; // Vector 12: ADC12IFG3case 14: break; // Vector 14: ADC12IFG4case 16: break; // Vector 16: ADC12IFG5case 18: break; // Vector 18: ADC12IFG6case 20: break; // Vector 20: ADC12IFG7case 22: // Vector 22: ADC12IFG8// 在这里配置要干啥break;case 24: break; // Vector 24: ADC12IFG9case 26: break; // Vector 26: ADC12IFG10case 28: break; // Vector 28: ADC12IFG11case 30: break; // Vector 30: ADC12IFG12case 32: break; // Vector 32: ADC12IFG13case 34: break; // Vector 34: ADC12IFG14default: break;}}

第八章 通用串行通信接口USCI

最后一章了!!!加油!!

8.1 串行通信概述

8.1.1 异步通信

发送设备、接收设备使用各自的时钟控制数据的发送和接收过程。为使双方的收发协调,要求发送和接收设备的时钟尽可能一致。

8.1.2 串行异步通信特点

  1. 数据按帧传输,一个数据帧包含起始位、数据位、地址
    位、校验位和停止位。
  2. 不要求收发双方时钟的严格一致
  3. 依靠起始位、停止位保持帧内数据同步。
  4. 每个字符都要附加2~3位用于起始位和停止位,各帧之
    间还有间隔,因此传输效率不高,适用于传输速度较低的
    场合。

8.2 UART——通用异步收发传输器

8.2.1 如何工作?

USCI_Ax 模块通过UCAxRXD、UCAxTXD两个引脚连接外部系统。 UCSYNC位清0时,USCI模块配置为UART模式。

8.2.2 波特率

  1. 收发采用相同的波特率

  2. 波特率指的是每秒钟传输二进制代码的位数

  3. UART字符格式由起始位,7或8个数据位,偶数/奇数/无奇偶校验位,地址位(地址位模式)和一个或两个停止位组成。

8.3 USCl操作

8.3.1 初始化和复位

  1. PUC或者置位UCSWRST后,USCI自动复位;PUC后,UCSWRST自动置位
  2. UCTXIFG传输中断标志位置位,其他的标志位和中断使能都清零。
  3. 仅可以在UCSWRST=1时配置USCI
  4. UCSWRST=0时,启动USCI
  5. 推荐的USCI配置过程如下:

8.3.2 奇偶效验位

  1. 奇效验:要求数据位中的1的个数和奇效验位的1的个数之和为奇数。
  2. 偶效验:要求数据位中的1的个数和偶效验位的1的个数之和为偶数。
  3. 比如:0xAA的二进制为10101010,其中“1”的个数为4个,那么奇效验位的“1”的个数应为1个,则奇效验位是1;如果是偶效验,那个偶效验位应该是0

8.3.3 发送和接受中断

  1. USCI收、发共用1个中断矢量。
  2. UCTXIFG置位表明UCAxTXBUF为空,可向其写入待发送字符,若UCTXIE 和GIE也置位,将产生发送中断请求。写UCAxTXBUF自动清除UCTXIFG。
  3. 每接收一个字符并将其装入UCAxRXBUF后,UCRXIFG置位,若UCRXIE和GIE也置位,将产生接收中断请求。读UCAxRXBUF自动清除UCRXIFG。
  4. 建议在这两个中断中只是用一个,不然有可能出现问题。。。
  5. 使用UCAxIV寄存器看是哪个中断到来

8.4 波特率的产生

产生波特率有两种模式,低频波特率产生模式和过采样波特率产生模式,通过设置UCOS16位进行选择。

8.4.1 关于波特率

  1. 波特率指的是每秒钟传输二进制代码的位数
  2. 波特率最大是有限制的。
  3. 在每个波特率的周期中,采样三次,采用投票法选取。

8.4.1 低频模式(UCOS16=0)

  1. 波特率最大不能超过BRCLK(USCI时钟)的1/3
  2. 波特率发生器使用一个预分频器和一个二级调制器产生位时钟BITCLK ,实现小数分频。
  3. 三次采样发生在N/2-1/2、N/2和N/2+1/2 BRCLK处,此处N为每个位时钟BITCLK周期内时钟源BRCLK周期的个数。

8.4.2 过采样模式(UCOS16=1)

  1. 在此模式下,USCI的最大波特率是UART源时钟频率BRCLK的1/16。
  2. 此模式下,波特率发生器使用一个预分频器和一个一级调制器产生位时钟BITCLKI6,该时钟比 BITCLK快16倍。
  3. 当UCBRx设置为0或1时,第一个预分频器和调制器级被旁路,BRCLK等于BITCLKI6 - 在这种情况下,不能对BITCLKI6进行调制,因此忽略UCBRFx位。

8.4.4 波特率的设置

若N <16,设置UCOS16=0选择低频波特率产生模式。
若N ≥16,设置UCOS16=1选择过采样波特率产生模式。

  1. 在低频模式下:

    • 预分频器设置: UCBRx=INT(N)
    • 二级调制器设置: UCBRSx=round[(N - INT(N)) X 8],round[ ]表示就近取整
//时钟源32768Hz,波特率2400,低频模式
UCA1CTL1 |= UCSWRST; // Put state machine in reset
UCA1CTL1 |= UCSSEL_1; // CLK = ACLK = 32768Hz
UCA1BR0 = 0x0D; // (32768/2400=13.65)
UCA1BR1 = 0x00; //
UCA1MCTL |= UCBRS_5; // (0.65*8=5.2)
UCA1CTL1 &= ~UCSWRST; // Initialize USCI state machine
  1. 过采样模式:

    • 预分频器设置: UCBRx=INT(N/16)
    • 一级调制器设置: UCBRFx=round([(N/16) - INT(N/16)] X 16)
    • 若需更高波特率精度,可同时使用二级调制器UCBRSx。
//时钟源1048576Hz,波特率9600,过采样模式
UCA1CTL1 |= UCSWRST; // **Put state machine in reset**
UCA1CTL1 |= UCSSEL_SMCK; // BRCLK = SMCLK
UCA1BR0 = 6; // 1048576/9600=109.23;109.23/16=6.83
UCA1BR1 = 0; //
UCA1MCTL = UCBRF_13 + UCOS16; //UCBRFx=0.83*16=13.28,并置位UCOS16
UCA1CTL1 &= ~UCSWRST; // **Initialize USCI state machine**

8.5 关于UCAxIV

  1. 可以通过UCAxIV确定中断由那个中断源提出
  2. 关闭中断不会影响UCAxIV的值
  3. UCAxIV寄存器的任何访问,读取或写入都会自动复位最高待处理的中断标志
  4. 如果设置了另一个中断标志,则在服务初始中断后立即产生另一个中断。

8.6 各种寄存器

8.6.1 UCAxCTL1

  1. UCSSELx,USCI时钟源,即BRCLK
  2. UCSWRST,复位USCI,必须复位后才能配置寄存器

8.6.2 UCAxBR0 & UCAxBR1

预分频寄存器。UCAxBR0 是低八位,一般只需要配置这个就可以了

8.6.3 UCAxMCTL

  1. UCBRFx,一级调制器,只能用于过采样模式
  2. UCBRSx,二级调制器,一般用于低频模式
  3. UCOS16,为1时,过采样;为0时,低频模式

8.6.4 UCAxRXBUF

接收数据的缓冲寄存器

8.6.5 UCAxTXBUF

发送数据的缓冲寄存器

8.6.6 UCAxIE

中断使能寄存器

  1. UCTXIE,发送中断使能
  2. UCRXIE,接收中断使能

8.6.7 UCAxIV

USCI中断向量寄存器
00h = 无中断待处理
02h =中断源:数据已经接收;中断标志位:UCRXIFG;中断优先级:最高
04h =中断源:传送缓冲区空; 中断标志位: UCTXIFG;中断优先级:最低

  • 【注意】:这里给大家道个歉,我在帮扶班讲的关于这个IV寄存器的部分是有点问题的。其实其中的中断优先级是不能自己定义的,单片机还是已经给你定义好了,并且在数据手册中给出。如图:

8.7 例程

8.7.1 查询方式发送/接收数据

采用查询方式,低频模式波特率,时钟源ACLK=32768Hz,波特率2400.

#include <msp430f6638.h>
void main(void)
{WDTCTL = WDTPW + WDTHOLD; // Stop WDT//以下部分为TS3A5017芯片控制代码,直接复制使用即可P3DIR = 0x30;//P3.4~P3.5设置为输出0011 0000P3OUT = 0x20;//接入S3(IN1(P3.4)=0 IN2(P3.5)=1)P4DIR = 0x30;//方向设置为输出0011 0000P4OUT = 0x10;//建立到9针串口的连接P8SEL |= BIT2+BIT3; // UCA1RXD(P8.3) UCA1TXD(P8.2) 1100UCA1CTL1 |= UCSWRST; // **Put state machine in reset**//【注意】老师给的例程中这里写错了,ACLK前面应该是两个下划线UCA1CTL1 |= UCSSEL__ACLK; // CLK = ACLKUCA1BR0 = 13; // 32768/2400=13.65 (see User's Guide)UCA1BR1 = 0x00;UCA1MCTL |= UCBRS_5; // Modulation UCBRSx = 0.65*8 = 5UCA1CTL1 &= ~UCSWRST; // Initialize USCI state machineUCA1TXBUF =0x55; //发送0x55while (!(UCA1IFG&UCTXIFG)); //等待该字节发完
}

8.7.2 中断方式

采用中断方式,过采样,时钟源SMCLK=1048576Hz,波特率9600
这里省略了很多代码。

#include <msp430f6638.h>
void main(void)
{//这里省略了关闭看门狗、配置TS3A5017芯片和稳定XT1CLK的代码P8SEL |= BIT2+BIT3; // UCA1TXD(P8.2) UCA1RXD(P8.3) 1100UCA1CTL1 |= UCSWRST; // **Put state machine in reset**UCA1CTL1 |= UCSSEL_SMCK; // BRCLK = SMCLKUCA1BR0 = 6; // 1048576/9600=109.23;109.23/16=6.83UCA1BR1 = 0; //UCA1MCTL = UCBRF_13 + UCOS16; //UCBRFx=0.83*16=13.28UCA1CTL1 &= ~UCSWRST; // **Initialize USCI state machine**UCA1IE |= UCRXIE; // Enable USCI_A0 RX interrupt__bis_SR_register(LPM0_bits + GIE); // Enter LPM0, interrupts enabled__no_operation(); // For debugger
}
#pragma vector=USCI_A1_VECTOR__interrupt void USCI_A1_ISR(void){switch(__even_in_range(UCA1IV,4)){case 0: break; // Vector 0 - no interruptcase 2: // Vector 2 - RXIFGwhile (!(UCA1IFG&UCTXIFG));
//这里,只用当UCTXIFG为1,即UCA1TXBUF空的时候,才向UCA1TXBUF中传入数据UCA1TXBUF = UCA1RXBUF; // TX -> RXed characterbreak;case 4: break; // Vector 4 - TXIFGdefault: break;}}

第九章

结束!祝大家考个好成绩

MSP430F6638单片机复习笔记相关推荐

  1. 计算机原理考研题库,2022考研853计算机专业基础综合《计算机组成原理》复习笔记及考研真题题库.pdf...

    2022考研 853计算机专业基础综合 <计算机组成原理>复习笔记及考 研真题题库 计算机系统概论 一.计算机的分类 1电子模拟计算机 模拟计算机的特点是数值由连续量来表示,运算过程也是连 ...

  2. 853计算机科学基础综合,2022考研853计算机专业基础综合《计算机组成原理》复习笔记及考研真题题库...

    2022考研853计算机专业基础综合<计算机组成原理>复习笔记及考研真题题库 计算机系统概论 一.计算机的分类 1电子模拟计算机 模拟计算机的特点是数值由连续量来表示,运算过程也是连续的. ...

  3. Spring复习笔记:4

    在复习笔记三中我们进行的案例的编写,我们可以发现,就算使用了注解的方式,xml配置文件文件还是不能够删除,现在我们来将一些新的注解可以让我们去掉xml配置文件. @Configuration 作用:指 ...

  4. matlab arr3(5 end),matlab复习笔记.doc

    matlab复习笔记.doc 如果一个语句在一行内书写太长了,可能要另起一行接着写,在这种情况下我们需要在第一行末打上半个省略号(),再开始第二行的书写.历史命令窗口(THEHISTORYCOMMAN ...

  5. 数据结构(c语言版)笔记6,2020考研计算机《数据结构(C语言版)》复习笔记(6)

    2020年计算机考研复习已经开始,新东方在线在此整理了2020考研计算机<数据结构(C语言版)>复习笔记(6),希望能帮助大家! 第六章 树知识点整理 树是n个结点的有限集合,非空时必须满 ...

  6. 2018.8.14-C#复习笔记总

    2018.8.14-C#复习笔记总 using System; using System.Collections.Generic; //using System.Linq; using System. ...

  7. 2018.8.14-C++复习笔记总

    2018.8.14-C++复习笔记总 // CPPTEST.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include<iost ...

  8. 2018.8.5 复习笔记

    2018.8.5 复习笔记 1,"a" + "b" + 3 strcat double d = 3 object obj = d int i = (int)ob ...

  9. 复习笔记2018.8.3

    复习笔记2018.8.3 1,"a" + "b" + 3 strcat double d = 3 object obj = d int i = (int)obj ...

  10. HTML+CSS+JavaScript复习笔记持更(一)——标签篇

    前言 博主现在还是在校生,目前大三,突然想起HTML的很多基础都忘记的差不多了,于是买了几本基础书,创建这篇博文用于记录复习笔记,也希望我自己在整理的时候,能帮助大家加深一些基础知识的印象,本篇博文将 ...

最新文章

  1. cURL error 60: SSL certificate problem: unable to get local issuer certifica 解决
  2. 关于a标签的 href 与 onlick
  3. [***]HZOJ 优美序列
  4. 薪资涨幅60%,直通一线互联网公司的秘密......
  5. php+html5+jquery断点续传_PHP学习路线:PHP从入门到精通教程
  6. JS 关于(function( window, undefined ) {})(window)写法的理解
  7. 让一个非窗口组件(non-windowed component)可以接受来自Windows的消息
  8. sql语句优化之not in
  9. HDU 1048 The Hardest Problem Ever
  10. Python 错误:ValueError: unsupported format character ‘Y‘ (0x59) at index 146
  11. Selenimu做爬虫 - oscarxie - 博客园
  12. Mac上使用中文Beamer添加各种格式的图片
  13. java 获取系统变量(环境变量和设置变量)
  14. 微积分手机版 pk 清华大学微积分教程
  15. 计算机安全群,大开眼界||斯坦福大学信息安全课程群
  16. exFat格式U盘 文件消失
  17. 丝裂原活化蛋白激酶TaMPK3抑制植物对ABA的反应
  18. 【visual studio】VsVim 2022
  19. unity 2d文字跟随主角移动_使用 Unity 粒子系统实现 2D 人物足迹效果
  20. java的八大基本数据类型

热门文章

  1. STM32 SHT10温湿度传感器的信号采集
  2. 修改DNS服务器的作用,请问修改DNS服务器会有什么后果
  3. IPython使用Matplotlib画图时无法显示图片
  4. linux yum vsftpd,CentOS 7 使用Yum方式安装配置vsftpd服务
  5. 关于HF-lpt130A与GoKit2.1(stm32)底版的链接通信(持更...)
  6. rest_framework--过滤器filters--搜索
  7. ArcGis 10.2运行提示“未授权”的解决方法
  8. PHP file_get_contents函数详解
  9. nfc门禁卡的复制和迁移
  10. BUUCTF:[ACTF新生赛2020]swp