1、青岛大学-TI 大学生创新中心 傅强2前沿1、430系列单片机系统工程设计与实践这本书是我见过的最好的关于单片机的书,非常值得逐字逐句的彻底学习一遍。2、与51不同,430单片机是处理器,通过对比两者的区别,可以建立起代码移植的思想。3、430单片机属于混合信号处理器,资源极其丰富,有利于全面学习硬件知识。青岛大学-TI 大学生创新中心 傅强31.1 初识430单片机430:低功耗之王,水果电池驱动1、为什么我们在乎功耗?凡是以电池为电源的电子设备都看重低功耗。几乎所有的单片机会标榜自己有低功耗方面的设计。2、430为什么可以成为低功耗之王?在硬件上,和不用的模块可以休眠在软件上,必须设计恰当
2、的休眠和唤醒430是实现低功耗的必要条件,非充分条件。青岛大学-TI 大学生创新中心 傅强41.1.1 430单片机的应用前景便携设备,高集成度、小型化。野外安置的终身电池设备。无需额外供电的自供电设备。高精度测量、控制领域。当普通单片机用。青岛大学-TI 大学生创新中心 傅强51.1.2 430单片机的特点多时钟系统时钟、功能模块时钟、休眠唤醒时钟软件设置时钟16位处理器,单指令周期模块化结构各模块完全独立,不需要干涉避免了与外部模块复杂的数据通信学会最贵的430,等于会用了全系列430青岛大学-TI 大学生创新中心 傅强6采用冯诺依曼结构(普林斯顿结构),程序指令存储器和数据存储器统一编址
3、。举例:实现存储器中两数据相乘,要经过3个步骤,通过总线取两个数据和取出指令(干什么)到。如果是哈佛结构,数据总线和指令总线分开。430可以在里跑程序,加上具有控制器,可实现固件更新。中的升级代码-复制到运行-擦除升级1.1.2 430单片机的特点青岛大学-TI 大学生创新中心 傅强7科普:、存储器存储器挥发性存储器非挥发性存储器可擦写只读速度最高最贵要定时刷新紫外线擦写电擦写电擦写计算机一二级缓存计算机内存条绝种贵,慢前途无量绝种了6个晶体管构成1一个晶体管+电容充放电 我们现在用的51,都是 的,但是内部没有控制器,所以需要存实时数据。430带控制器,单片机自己就能擦写,所以不用。青岛大学
4、-TI 大学生创新中心 傅强8430425A资源8处理速度512(数据)+16(程序代码)内置控制器,剩余可存数据。内置时钟管理单元,可内部倍频3路同步采样、差分输入、32倍程控增益放大器的16位温度传感器1.2V基准源和输出缓冲器128段驱动器增强串口看门狗定时器16位定时器,3路捕获和2路内置复位电路16个双向可中断口内置电能计量模块后缀带A的,比如425A带硬件乘法器青岛大学-TI 大学生创新中心 傅强91.1.3 430单片机最小系统一般单片机最小系统需要什么?电源、晶振、复位、下载/仿真接口430425自带片内数控时钟(),掉电复位电路()一般讲究一点都需要“电源监视芯片”内部时钟一
5、般不如晶振精确可以外接手表晶振32.768k,然后倍频、可下载+调试,只能下载青岛大学-TI 大学生创新中心 傅强101.2 430单片机开发软件入门一般用430软件工程管理、程序编辑、代码编译下载、仿真调试工程管理:管理外部函数、头文件。程序编辑:写代码编译:替程序员处理所有打杂的事情汇编调试:真正的考验水平的地方,不是所有单片机都支持调试,这是要硬件支持的。青岛大学-TI 大学生创新中心 傅强11全速执行、单步执行。执行到光标处设置断点(在程序中加一个空操作,然后用来设断点)查看变量寄存器查看调用函数关系青岛大学-TI 大学生创新中心 傅强121.3 430单片机C语言基础C语言、编译器和
6、机器码之间的关系语言、编译器和机器码之间的关系().C语言源文件编译器(8086)机器码430编译器430单片机机器码51编译器51单片机机器码l在写C语言的过程中,尽量消除不同的差异,或者将差异集中到一个地方做修改,那么就能方便的实现代码移植。l我们现在写C程序,就必须按此要求严格要求自己。l这样才能一通百通,才能减少重复劳动。青岛大学-TI 大学生创新中心 傅强131.3.1 变量我们为什么要定义各种变量?定义短字节变量有哪些好处和坏处?定义长字节变量有哪些好处和坏处?一些特殊的关键字 7=1,2,3,4,5,6,7 本地全局变量 b;不被优化 c;不对其初始化为什么要慎重使用全局变量?青
7、岛大学-TI 大学生创新中心 傅强141.3.2 数学运算尽可能避免浮点数运算。运算慢、非常慢。占用多。所以应尽量避免使用浮点数。防止定点数溢出。x;a;*1000和1000都是型,a65溢出应改为*(1000)或()a*1000青岛大学-TI 大学生创新中心 傅强15小数的处理例如,温度的最后计算公式为:*1.32/1.25-273为避免浮点数可改为:()*132/125-273如需保留1位小数,则:()*1320/125-2730 扩大10倍程序中加上明确注释在显示时,将小数点移位即可减小乘除法取平均时,尽量取2、4、8等2次幂,这样可以用移位代替乘除(可编译器自动)后缀带A的型号有硬件乘
8、法器(自动使用)青岛大学-TI 大学生创新中心 傅强161.3.3 位操作精简指令处理器如何写口?P2=P2|0 x01;2.0置高 按位或P2 0 x01;一般均简写成这样P2 0 x01;2.1置低 按位与P2=0 x04;2.2取反 按位异或 0(0 x01)宏定义.P2 0;2.0置高P1(123)1.1 P1.2 P1.3置低精简指令处理器如何读口?;(P15)0)P2 0;(P15)P2 0;(P1(56)P2 0;(P15)1;读P1.5值赋给0;青岛大学-TI 大学生创新中心 傅强171.3.4 寄存器操作如何理解寄存器操作?如果设计模拟电路算是天才干的事情,那么操作单片机的寄
9、存器就算是傻瓜干的事情。处理器把能干的事全干了,需要人过问的事情,通过一系列开关让人来选择,所以这是傻瓜就能干的事情越是功能强大的处理器,需要配置的寄存器越多。处理器说明书就是用来查寄存器功能的青岛大学-TI 大学生创新中心 傅强18宏定义帮助我们理解抽象的数字查说明书,找到控制串口收发的是1寄存器的最高两位,我们可以用下面的赋值。1 6开串口收中断1 7开串口发中断为便于记忆和理解,头文件中有如下宏定义:0(0 x40)在430 x42 0(0 x80)头文件中已有1 00以后我们接触高级处理器的程序中,大部分都是这么写,不会像51里面直接写0 x20这样青岛大学-TI 大学生创新中心 傅强
10、19特别注意:使用“”赋值不会影响其他位,但要搞清楚是不是要先对标志位清0。例如:控制器输出模式有3个控制位,可以表示8种模式。头文件中定义了07宏定义,000-111。1 3011.1 6110实际效果是111,也就是模式7青岛大学-TI 大学生创新中心 傅强201.3.5 中断中断的作用是快速响应事件430中几乎所有“资源”都带中断,为的是休眠后,唤醒。发送指令给模块,然后休眠。模块执行完毕后,中断唤醒。中断向量表位于最高段0000(512B)特别注意!430的中断没有中断嵌套的优先级 ().青岛大学-TI 大学生创新中心 傅强21430 x42x头文件中的中断向量表 (0*2u)/*00
11、 基础定时器)2(1*2u)/*02 P2*/1(4*2u)/*08 P1*/1(5*2u)/*0 A 1/2*/0(6*2u)/*0 A 0*/0(8*2u)/*00 串口发送*/0(9*2u)/*02 串口接收*/(10*2u)/*04 */16(12*2u)/*08 16位*/(14*2u)/*0 */(15*2u)/*0 */青岛大学-TI 大学生创新中心 傅强22中断的具体过程事先将中断服务程序入口地址装入中断向量表。中断发生后,如果中断被允许(可屏蔽中断),将当前程序地址和状态寄存器压入堆栈。跳转到中断服务程序入口,备份寄存器入堆栈。开始执行中断服务程序。退出中断前,恢复寄存器。取
12、回寄存器,跳转回中断前主程序地址。青岛大学-TI 大学生创新中心 傅强23退出中断时唤醒进中断前休眠,那么退出中断后仍然休眠。可以在中断子程序中修改堆栈中的,使得中断结束后,不休眠。().()此函数经汇编优化青岛大学-TI 大学生创新中心 傅强24中断标志位同类中断合并成一个总的中断。由软件判断中断标志位来确定具体中断。什么是标志位?不急用、待查询。1 P1()(P15).(P16).P10;青岛大学-TI 大学生创新中心 傅强251.3.6 内部函数头文件和4300();或0();();();或();();或;();或();(x);()青岛大学-TI 大学生创新中心 傅强261.3.7 库函
13、数 430提供100个库函数字符处理类数学类输入和输出类通用子程序类字符串处理类库函数是C语言通用的,内部函数与特定处理器有关。青岛大学-TI 大学生创新中心 傅强271.4 文件管理将大程序划分为若干小的C文件,最常用的划分方法是按功能模块划分(对象)。/*DataProcess.c */int Sum(int a,int b,int c)int y;y=a+b+c;return(y);float Average(int a,int b,int c)float y;y=a+b+c;return(y/3);/*DataProcess.h */Extern int Sum(int a,int b
14、,int c);Extern float Average(int a,int b.intc);/*main.c */#include“DataProcess.h”.void main().Tem=Average(tem1,tem2,tem3);Weight=Sum(W1,W2,W3);.青岛大学-TI 大学生创新中心 傅强28全局变量的处理隶属关系模糊的全局变量单独建隶属于某模块的,写在模块c文件中/*global.c */int BattVoltage;unsigned int SystemStatus;int Temperature;/*global.h */Extern int Batt
15、Voltage;Extern unsigned int SystemStatus;Extern int Temperature;/*DataProcess.c */Unsigned char OverflowFlag;int Sum(int a,int b,int c)int y;y=a+b+c;If(y65535)OverflowFlag=1;return(y);/*DataProcess.h */Extern int Sum(int a,int b,int c);Extern unsigned char OverflowFlag;青岛大学-TI 大学生创新中心 傅强291.5 代码优化编译
16、器可自动对代码进行优化速度快,但占多速度慢,占少可选优化等级,等级越高,占越小调试阶段最好关闭优化要是不优化还有变量改变,则加青岛大学-TI 大学生创新中心 傅强301.6 风格对于写程序代码,有3个层次首先,计算机要能读其次,要自己能读最后,要别人能读青岛大学-TI 大学生创新中心 傅强311.6.1 变量命名规则变量名要有含义,不要随便用变量名最好是名词词性,1-4个单词每个单词首字母大写;必须出现空格时,用下划线代替;单词较长,适当简写;多个模块都有的变量,按“模块名_变量名”;1;约定俗成的变量不要改动I、j作为循环变量,p、q作为指针,s、t表示字符串青岛大学-TI 大学生创新中心
17、傅强321.6.2 函数命名规则模块名_不及物动词模块名_及物动词+名词首字母大写专用名词全部大写长单词缩写返回值是布尔型的,对返回1还是0的表意清晰Unsigned int ADC16_Sample();CharLCD_Init();CharRTC_Get();VoidPWM_SetPeriod();VoidFlash_WriteChar();VoidUART_GetChar();CharKey_GetKey();CharTouchPad_GetKey();TransmitTxRecetiveRxCountCntTo2CharUART_CheckTxBuff();/检查缓冲区Char UAR
18、T_IsTxBuffFull();/缓冲区是否已满青岛大学-TI 大学生创新中心 傅强331.6.3 表达式好的表达式可以朗读出来消除歧义,运算优先级拿不准就加括号,表达式复杂就拆开。If(UART_IsTxBuffFull()UART_ClearTxBuff();ElseUART_PutChar(0 x55);i=5;j=+i;结果i=6,j=6等效于i=5;i=i+1;j=i;i=5;j=i+;结果i=6,j=5等效于i=5;j=i;i=i+1;青岛大学-TI 大学生创新中心 傅强341.6.4 风格一致性For(i=0;i100;i+)for(j=0;jDOT;i-)/从第6位到小数点依
19、次递减 if(DispBuffi=0)DispBuffi=;/如果该位数值是0,则替换成空格 else break;/如果不是,则跳出循环For(i=6;iDOT;i-)/对全部6位显示数据进行判断 if(DispBuffi=0)DispBuffi=;/消隐小数点前的无效0 else break;青岛大学-TI 大学生创新中心 傅强36功能函数的注释/*名 称:LCD_DisplayDigit()*功 能:在LCD上任意位置显示一个数字*入口参数:Digit:待显示数字 (09)Location:显示位置 从左至右对应76543210*出口参数:无*说 明:调用该函数不影响LCD其他位的显示。
20、*范 例:LCD_DisplayDigit(3,0);/在第一位(右侧最低位)显示3 LCD_DisplayDigit(2,1);/在第二位显示2 LCD_DisplayDigit(1,2);/在第三位显示1 -显示结果:123*/void LCD_DisplayDigit(char Digit,char Location)char DigitSeg;/存放字形笔划的变量 char*pLCD;/存放LCD显存指针的变量 DigitSeg=LCD_TabDigit;/得到待显示数字的字形笔划 pLCD=&LCDM1;/获得LCDM1的地址 pLCDLocation=DigitSeg;/在LCDM
21、1之后Location个单元显示出数字 青岛大学-TI 大学生创新中心 傅强371.6.6 宏定义宏定义给予常数可读性宏定义全部大写,以区别变量数据加括号,注释使用/*/#define TXBUFF_SIZE(128)/*发送缓冲区大小*/#define LCD_ROW(128)/*点阵液晶行数*/#define LCD_CLUMN(128)/*点阵液晶列数*/#define LCD_BUF_SIZE(LCD_CLUMN*LCD_ROW/8)/*点阵液晶缓冲区大小*/Unsigned char TxBuffTXBUFF_SIZE;/定义发送缓冲区Char IsTxBuffFull()if(Nu
22、mOfTxChars=TXBUFF_SIZE)return(1);/缓冲区是否满?else return(0);青岛大学-TI 大学生创新中心 傅强38使用宏定义时,要防止定点数溢出宏定义的用途广泛增强程序的可移植性进行软件版本的管理#define VOLT_RATE(1000)/*比例系数*/.long Voltage;Int InputValue;.Voltage=InputValue*VOLT_RATE;/*可能溢出*/#define VOLT_RATE(long(1000)/*比例系数,强行整成long*/青岛大学-TI 大学生创新中心 傅强391.7可移植性可移植性是嵌入式软件设计的
23、重要思想用到不同的硬件,比如到数码管用到不同的处理器,比如51到430,编程时应尽量消除硬件差异无法消除的差异,集中到小的局部来修改青岛大学-TI 大学生创新中心 傅强401.7.1 消除差异例如用宏定义消除口操作的差异此后的程序不用修改,直接用和来操作口#include”MSP430 x42x.h”#define LED_ONP2OUT|=BIT0#define LED_OFFP2OUT&=BIT0#include”reg51.h”Sbit LED=P20;#define LED_ONP2.0=1;#define LED_OFFP2.0=0;青岛大学-TI 大学生创新中心 傅强411.7.2
24、 消除硬件差异用宏定义消除硬件差异例如或数码管的口,顺序经常会改变/*宏定义,数码管ag、DP各段对应的比特,更换硬件只用改动以下8行*/#define a0 x01#define b0 x02#define c0 x04#define d0 x08#define e0 x10#define f0 x20#define g0 x40#define DP0 x80/*宏定义自动生成段码表,不要改动*/Const char LCD_Tab=a+b+c+d+e+f,/0b+c,/1a+b+d+e+g,/2a+b+c+d+g,/3b+c+f+g,/4a+c+d+f+g,/5a+c+d+e+f+g,/6
25、a+b+c,/7a+b+c+d+e+f+g,/8a+b+c+d+f+g,/9#undef a.青岛大学-TI 大学生创新中心 傅强42 用函数来消除硬件差异例如控制电机的启和停直流电机设置口高低电平即可步进电机要输出一定规则的脉冲序列大型交流电机需要用串口控制变频器我们把具体操作“封”在函数里Moter_ON().Moter_OFF().青岛大学-TI 大学生创新中心 傅强431.7.3 软件层次划分大量复杂的调用函数需要有清晰的层次关系菜单/人机界面Key_GetKey();Key_WaitKey();键盘缓冲区【FIFO】定时扫描并判断按键LCD_Clear();LCD_DisplayNu
26、mber();LCD_DisplayDecimal();LCD_InsertChar();LCD_DeleteChar();显示缓冲区【数组】LED定时循环扫描LED显存映射应用层功能函数层硬件隔离层硬件驱动层青岛大学-TI 大学生创新中心 傅强44应用层:最终功能,往往和人的感官有关功能层:功能函数,表达具体要干什么硬件隔离层:宏定义、缓冲区、函数封装硬件隔离层(硬件抽象层 ,)是非常重要的环节。功能函数只操作硬件隔离层的数据,与具体硬件无关。硬件驱动层:和具体硬件有关的代码,硬件驱动层从硬件隔离层获得“指示”,或是将“结果”发送至硬件隔离层。青岛大学-TI 大学生创新中心 傅强45软件划分
27、层次的好处每个层的函数只对上下层“可见”,这样设置好接口参数后,各单元软件可独立开发。改动硬件时,只需配置相应的底层驱动,修改硬件隔离层,而整个大软件功能可以不变。软件的可移植性增强。功能层的函数无需关心硬件如何实现,以及何时何处被应用层调用,专心做好自己的事情就行。将大型软件任务分块,团队合作。只要明确了模块功能,接口规范,就能分派任务。青岛大学-TI 大学生创新中心 傅强461.7.4 接口Void RTC_Tick(int DivSec)/硬件无关的走时函数,DivSec入口 char Days;/每月的天数变量 DSEC+;/定时中断加数 DISABLE_INT;/宏定义关总中断 If
28、(DSEC=DivSec)SECOND+;DSEC=0/校正中断时间 If(SECOND=60)MINUTE+;SECOND=0 If(MINUTE=60)HOUR+;MINUTE=0 If(HOUR=24)DATE+;HOUR=0 If(MONTH=2)/闰年判断 if(YEAR%4=0)Days=29;elseDays=28;elseDays=MONTH_TableMONTH-1;/月份天数查表 If(DATEDays)MONTH+;DATE=1;If(MONTH12)YEAR+;MONTH=1;If(YEAR=100)YEAR=0;/只显近百年时间 RESTORE_INT;/宏定义恢复中
29、断青岛大学-TI 大学生创新中心 傅强471.7.5 屏蔽一个好的子函数,应消灭细节特征,只暴露最基本的要程序员选择的选项。类似于处理器中,设置各种特殊功能寄存器。比如,手机拨号。手机和手机的实际拨号过程差异巨大,但是我们看起来的拨号程序都是一样操作的。UART_Init(2400,n,8,1);/2400比特,无校验,8位数据,1位停止位青岛大学-TI 大学生创新中心 傅强481.8 版本管理如果一个程序一开始设计就有N个变种(版本),用移植的办法改写,变成N种程序是不明智的。因为维护起来困难。例如,有一个版本的软件按键带声音、另一个不带声音。可以用宏定义+条件编译宏来实现版本管理。/*Co
30、nfig.h*/#define KEYTONEON/*是否打开按键音*/#define RS485ON/*是否打开RS485通信口*/#define SCREENLCD/*显示屏驱动LED=数码管 LCD=液晶*/.Char Key_GetKey()/读键盘函数char KeyKey=Key_ReadFIFO();/从键盘缓冲区读一个按键#if(KEYTONE=ON)/KEYTONE打开才编译下一句if(Key!=NOKEY)Beep(30);/有效按键则蜂鸣30ms#endifreturn(Key);/返回键值青岛大学-TI 大学生创新中心 傅强49本章小结MSP430单片机的入门知识特点(低功耗、混合信号)资源与结构(精简指令、普林斯顿结构)C语言(位操作、寄存器操作、中断、内部函数、库函数)软件工程的共性问题文件管理(拆成小的c程序,头文件调用)代码优化(编译器的作用,先不优化)风格(命名规则、表达式、注释、宏定义)可移植性(cpu差异、硬件差异、软件层次、接口、屏蔽)版本管理(宏定义与条件编译宏)