山东大学飞思卡尔单片机教学第6章C语言程序设计课件.ppt

上传人(卖家):晟晟文业 文档编号:5038642 上传时间:2023-02-05 格式:PPT 页数:43 大小:270.50KB
下载 相关 举报
山东大学飞思卡尔单片机教学第6章C语言程序设计课件.ppt_第1页
第1页 / 共43页
山东大学飞思卡尔单片机教学第6章C语言程序设计课件.ppt_第2页
第2页 / 共43页
山东大学飞思卡尔单片机教学第6章C语言程序设计课件.ppt_第3页
第3页 / 共43页
山东大学飞思卡尔单片机教学第6章C语言程序设计课件.ppt_第4页
第4页 / 共43页
山东大学飞思卡尔单片机教学第6章C语言程序设计课件.ppt_第5页
第5页 / 共43页
点击查看更多>>
资源描述

1、第六章 C语言程序设计1关于实验安排 1010周和周和1111周的周二晚上在兴隆山校区计算中心周的周二晚上在兴隆山校区计算中心1 1号和号和3 3号机房号机房(1 1、2 2班班1 1号机房,号机房,3 3、4 4班班2 2号机房号机房,17,17:3030前到)前到)开放实验:开放实验:1111周、周、1212周和周和1313周在千佛山校区机械厂教学车间楼周在千佛山校区机械厂教学车间楼207207(1 1、2 2班星期六全天;班星期六全天;3 3、4 4班星期天全天:如有特殊事情者,班星期天全天:如有特殊事情者,可灵活选择;可灵活选择;上午上午9 9:0000下午下午1717:0000)实验

2、后撰写实验报告实验后撰写实验报告集成开发环境先用熟集成开发环境先用熟4.64.6版本;然后会用版本;然后会用5.05.0版本版本第六章 C语言程序设计2本周实验安排 实验实验4 4:掌握最基本:掌握最基本C C语言程序的调试及运行方法语言程序的调试及运行方法1.1.建立一个建立一个C C语言工程,并按要求编写求两个数最大值的语言工程,并按要求编写求两个数最大值的C C语言语言程序,编译并排错;程序,编译并排错;2.2.使用全速调试,并观察程序运行结果;使用全速调试,并观察程序运行结果;3.3.使用单步调试,并观察数据区、寄存器区、存储器区的数据使用单步调试,并观察数据区、寄存器区、存储器区的数

3、据变化。变化。实验实验5 5:使用仿真方法,编写并调试复杂的:使用仿真方法,编写并调试复杂的C C语言程序语言程序1.1.自定义一个包含自定义一个包含1010个无符号个无符号intint型的数组,数组元素分别是型的数组,数组元素分别是1010,9 9,8 8,7 7,6 6,5 5,4 4,3 3,2 2,1 1,0 0。使用冒泡排序法对该数组元。使用冒泡排序法对该数组元素进行从小到大排序,调试并观察存储器区数据变化,程序要素进行从小到大排序,调试并观察存储器区数据变化,程序要有注释。有注释。第六章 C语言程序设计3本周实验安排 2.2.基于上个程序,把排序好的数组进行数字滤波:去除最大的基于

4、上个程序,把排序好的数组进行数字滤波:去除最大的3 3个和最小的个和最小的3 3个,剩下的求平均,调试并观察存储器区数据变化,个,剩下的求平均,调试并观察存储器区数据变化,程序要有注释。程序要有注释。3.3.课本课本195195页例页例2 2、例、例3 3,课本,课本196196页例页例4 4调试并观察存储器区数据变化。调试并观察存储器区数据变化。第六章 C语言程序设计4第六章 C语言程序设计 6-1 C6-1 C语言程序设计基础语言程序设计基础6-2 6-2 MC9S12的的C编程与编程与ANSI C的不同的不同6-3 6-3 C C程序设计举例程序设计举例内容提要内容提要:第六章 C语言程

5、序设计5单片机编程语言单片机编程语言 汇编语言 优点:执行效率高,时序控制精确 C语言 优点:程序开发速度快,提高开发工作效率;软件调试直观;可维护性好;可移植性好(与汇编语言相比较)。单片机单片机C语言语言单片机C语言和标准C语言的用法基本相同,但是单片机C语言是针对于资源少的MCU,它的编程方法和编程手段与PC机上使用C语言还是有很大差别。6-1 C语言程序设计基础第六章 C语言程序设计6多文件多文件C语言工程的头文件语言工程的头文件当代码量非常大时,程序员一般会把代码分成几个部分,然后写入到多个文件中。这些文件一般分为C文件和H文件。作为一般规则,以下内容应该放到H文件中:预处理和宏定义

6、结构、联合和枚举声明typedef声明外部函数声明全局变量声明如果定义的变量仅仅被一个C文件所私有,那么不可放到H文件中。第六章 C语言程序设计7其它其它C语言基础知识参见补充课件:语言基础知识参见补充课件:“补充补充(自己看自己看)_C语言基础语言基础.PPT”第六章 C语言程序设计8CodeWarrior数据类型数据类型 6-2 MC9S12的C编程与ANSI C的不同第六章 C语言程序设计9自定义自定义CodeWarrior数据类型数据类型 在CodeWarrior环境下按ALT+F7打开工程的通用设置,选择“Compiler for HC12”面板然后点按钮“Type Sizes”。建

7、议不要随意更改数据类型的设置第六章 C语言程序设计10数据类型的事实数据类型的事实 代码大小和执行时间的最大节约可通过为变量选择最合适的数据类型而得到。16位微控制器内部的数据长度是16位(2字节),所以首选的数据类型是“int”。16位机处理16位数据比8位数据的效率更高。对于9S12单片机来说,16位数据类型效率最高,因此在使用中,尽量选择int类型数据。第六章 C语言程序设计11存贮类修饰符存贮类修饰符以下关键字用于声明变量,以指定特定需要或内存中变量存贮的相关条件。static(静态变量)volatile(可变变量)const(只读变量)这三个关键字,一起让我们不仅可写出好的代码,而且

8、可写出紧凑的代码。第六章 C语言程序设计12static在函数体声明的静态变量,在函数调用期间保持其值;在模块内声明静态的变量(但在函数体之外),能被模块内所有函数访问;在模块内声明静态的函数,只能被模块内其它函数调用。如:static int func(int x,int y);当一个C语言工程由多个程序员进行编写时,就不用担心自己所定义的函数与别人定义的重名了。如果在函数名和函数类型前加extern,则表示此函数是外部函数,可以被其他文件中的函数调用。如:extern int func(int x,int y)。第六章 C语言程序设计13File1.c#include /*包含文件FILE

9、2.c中的函数*/void main(void)MyFunction();/*第一次进入MyFunction之前,myVar=0*/MyFunction();/*第二次进入MyFunction之前,myVar=1*/File2.cvoid MyFunction(void)static char myVar=0;/*本地变量声明为static*/myVar=myVar+1;/*myVar是本地变量,但它保持了自己的值*/第六章 C语言程序设计14可变(可变(volatile)变量)变量 volatile的本意是“易变的”,就是该变量会以编译器无法预知的方式发生变化,请编译器不要做优化(所有的编译

10、器的优化均假设编译器知道变量的变化规律)。也就是说是其值在正常程序流程以外可能改变的变量。在嵌入式系统中,这种情况通过两种主要途径发生:一是中断服务程序,二是硬件动作。例如,通过串口接收到一个字符,然后串口状态寄存器的值会发生改变,这完全在程序流程之外发生。在嵌入式设备中,最好将所有外设寄存器声明为volatile。第六章 C语言程序设计15例子例子由于访问寄存器的速度要快过RAM,所以编译器一般都会作减少存取外部RAM的优化。比如:static int i=0;int main(void).while(1)if(i)dosomething();/*Interrupt service rout

11、ine.*/void ISR_2(void)i=1;第六章 C语言程序设计16程序的本意是希望ISR_2中断产生时,在main当中调用dosomething函数,但是,由于编译器判断在main函数里面没有修改过i,因此可能只执行一次对从i到某寄存器的读操作,然后每次if判断都只使用这个寄存器里面的“i副本”,导致dosomething永远也不会被调用。如果将将变量加上volatile修饰,则编译器保证对此变量的读写操作都不会被优化(肯定执行)。此例中i也应该如此说明。第六章 C语言程序设计17Const变量变量关键字“const”,C语言中命名最差的关键字,并不表示恒量,而是代表“只读”。在嵌

12、入式系统中,有很大的不同,这一会应会明白。const是C+中最常用的几个关键字之一,对确保程序的完整性有着重要的意义。它在调用者和被调用者之间传递这样一种信息:Baby,我不会改变你的,放心吧。Const声明可用于任何变量,它告诉编译器将其存贮在ROM代码。编译器保留了那个位置程序存贮器地址。由于位于ROM中,其值不能改变。第六章 C语言程序设计18Const的用法:的用法:const unsigned short a;unsigned short const a;const unsigned short*a;unsigned short*const a;第六章 C语言程序设计19Const

13、volatile 变量变量 现在讨论一个深奥的问题,一个变量既能是常量,又能是可变量吗?如果是这样,这意味什么,怎样使用?答案是“能”。这个修饰符应该用于能出乎意料地改变的任何存贮器位置,因此需要volatile限定语,由于const该变量是只读的。第六章 C语言程序设计20最明显的例子是硬件状态寄存器,象SCI状态寄存器SCS1。这个寄存器包含信号状态标志,如发送空、发送完成、接收满以及其它。这是一个可变寄存器由于这些标志的改变依赖于串行通信的状态,这也是只读,由于标志不能被程序直接改写,它们只对模块的状态作出响应。这个状态寄存器最佳声明方法是:#define SCS1 (*(const v

14、olatile unsigned char*)0 x0016)第六章 C语言程序设计21访问固定内存位置与PC机不同,嵌入式系统通常的特点是需要编程者访问一个指定的存贮器位置。练习:在某个项目中需要将绝对地址0 x2FFA处整型变量的值设为0 xAA55(编译器为纯粹的ANSI编译器)。完成这个任务的代码是:int*ptr;ptr=(int*)0 x2FFA;*ptr=0 xAA55;第六章 C语言程序设计22访问访问I/O寄存器寄存器 一个普通而有用的形式是使用如下的#define指示:#define PortA (*(volatile unsigned char*)0 x0000)这种情况

15、下,Port A为地址0 x0000处字符型变量。#define实际做的是每次发现PortA时放置一个构件。也就是说在代码中写:PortA=0 x3F,实际做的就是告诉编译器0 x0000是一个volatile-unsigned-char类型的指针,它的内容等于0 x3F。第六章 C语言程序设计23数组数组C语言允许程序员用几种不同方法存取数组的内容。选择最适合的方法来存取,可以提高代码的效率。数组的访问方法有:硬编码:Array0=12*UNIT_VOLTS;编译时决定地址,执行速度快。变址增加Arrayindex+=12*UNIT_VOLTS;快速,比硬编码灵活。数组指针*(ArrayPt

16、r+)=12*UNIT_VOLTS;执行速度快,可读性差,可和循环一起使用。第六章 C语言程序设计24C语言与汇编语言的混合编程语言与汇编语言的混合编程 在绝大多数场合采用C语言编程可完成预期的目的,但是对一些特殊情况进行编程时要结合汇编语言。汇编语言具有直接和硬件打交道、执行代码的效率高等特点,可以做到C语言所不能做到的一些事情:1.一个程序中的关键部分对执行速度有很高要求,实时性强。用汇编编程可以更有效的利用CPU的寄存器和指令集,用其产生的代码比用编译器产生的代码运行更快。2.对特定硬件接口的访问。例如对I/O端口的访问,或者用于禁止、启用中断系统。因此,选用C语言编程时,还需要夹杂一些

17、汇编程序,通过这种混合编程的方法将C语言和汇编语言的优点结合起来,这已经成为MCU开发最流行的编程方法。第六章 C语言程序设计25C中使用汇编中使用汇编 目前大多数MCU系统,在C语言中使用汇编语言有两种情况:一种是汇编程序部分和C程序部分为不同模块或不同的文件,通常由C程序调用汇编程序模块的变量和函数(也可称为子程序或过程);另一种是嵌入式汇编,即在C语言程序中嵌入一段汇编语言程序。C语言中嵌入汇编语句:_asm AssemblyInstuction;asm(AssemblyInstruction);asm AssemblyInstruction AssemblyInstruction 第六

18、章 C语言程序设计26C中调用汇编指令构成的子程序:当汇编程序和C程序为不同模块时,程序一般可分为若干个C程序模块和汇编程序模块,C程序模块通常是程序的主体框架,而汇编程序模块通常是若用C语言实现则效率不高的函数组成,也可以是已经成熟的、没有必要再转化成C语言的汇编子程序。在这种混合编程技术中,关键是参数的传递和函数的返回值。它们必须有完整的约定,否则数据的交换就可能出错。定义汇编子程序,定义格式如下:_子程序名代码rts第六章 C语言程序设计27注意:第一,在子程序名前加_;第二,在C代码中调用汇编子程序时可直接调用:子程序名();第三,在子程序中不能使用映象寄存器的宏定义,只能用它们的直接

19、地址;第四,汇编子程序的编写时,对于使用过的寄存器需要进行保护。在汇编中使用C语言在汇编中也可以调用C代码中的变量与子程序。使用C代码中定义的变量:在变量名前加_或%,例如unsigned char PortA;asm(LDAA%PortA)调用C代码中定义的函数:在函数名前加_,例如:function1();asm(BRA _function1);第六章 C语言程序设计28C语言的中断语言的中断 CodeWarrior编译器提供了一个非ANSI的变通的方法,在源码中直接指定中断向量号t。表达式以interrupt关键字开始,接着是中断向量号,最后是函数原型。interrupt 7 void

20、RTI_ISR(void)/*RTI_ISR Function Codes*/9S12所有的中断源共分成55个优先级。处在最高优先级的中断是复位中断,它的中断向量号为0,第二位的是时钟监视器复位中断,它的中断向量号为1,以此类推。第六章 C语言程序设计29标准标准C库库 标准库如stdio.h通常包含在编译器中。Getchar()、gets()、printf()、putchar()、puts()、scanf()、sprintf()、sscanf()等,都是这些库中的常用函数。当给PC机写这段代码,printf()缺省的控制台是显示器,但HC12没有显示器作为片外外设,如果这样调用库函数,哪个端

21、口用于显示?什么时候我们定义它?在哪儿?在嵌入式编程中,通常printf()调用putchar()执行打印,这假定控制台缺省为片上串行口(SCI)。如果需要使用这个功能,则需要修改基础库函数putchar()才能正确输出。第六章 C语言程序设计30C语言入口语言入口 在MC9S12的C程序中,程序的入口在什么地方?程序是怎样起动的呢?在工作站或PC上操作系统从磁盘上装入程序并建立环境。而在嵌入式系统中没有操作系统。对程序员来说,程序员必须处理程序起动的每个方面。嵌入式应用,特别是用C或C+写的代码,需要一个起动模块,在起动main()之前配置硬件和代码。通常不可避免地用汇编语言写成,这个模块是

22、处理器离开复位状态第一个执行的代码。第六章 C语言程序设计31C起动代码通常执行下列动作起动代码通常执行下列动作(1)关中断;(2)将初始化数据从ROM复制到RAM;(3)将未初始化数据区清零;(4)为堆栈定位空间以及初始化堆栈;(5)创建并初始化堆;(6)执行构造函数并初始化所有全局变量(仅C+);(7)开中断;第六章 C语言程序设计32最后,起动代码调用main(),启动应用的剩余部分。当然针对于MC9S12来说,启动代码可以不必这么麻烦。可以只初始化堆,初始化硬件然后直接跳转到main函数,下面是一个启动代码的例子 第六章 C语言程序设计33void _Startup()asm LDS

23、0 x1000 JSR HardInit JSR main 程序员可以自己编写启动代码,可以将应用程序中的硬件初始化程序都放在启动代码里面,这样就可以比较专注地在应用程序中做要做的事情。第六章 C语言程序设计34程序的链接与定位程序的链接与定位 对于MC9S12单片机来说,由于RAM,EEPROM,寄存器可以重新映射,而且不同型号的单片机内部FLASH大小也不一样,这样程序编译后存放在什么位置,成了我们必须告诉链接器的内容,因为链接器不知道你用的单片机RAM放在什么地方,ROM放在什么地方。为了方便管理,CodeWarrior自动生成一个.prm文件,此文件用来管理程序的定位。但是该文件并不一

24、定与用户的实际情况相符,因此在链接前,必须自己核对该文件是否与实际的硬件相符。看书的192页。第六章 C语言程序设计356-3 C程序设计举例第六章 C语言程序设计36例例1 对从RAM中0 x1000地址开始的10个无符号字节型数进行由小到大排序 程序分析:可以使用C语言把一个unsigned char类型的数组存储到从0 x1000开始的内存空间中,数组的大小为10个字节,内容由程序员自定义。由小到大的排序使用冒泡法完成。unsigned char data10 0 x1000,i,j,temp;/*定义数组*/void main(void)for(i=0;i10;i+)/*初始化数组*/

25、datai=20-i;for(i=0;i9;i+)/*使用冒泡法排序*/for(j=0;jdataj+1)temp=dataj;dataj=dataj+1;dataj+1=temp;for(;);注:若在函数内定义变量,须在函数体开始处定义第六章 C语言程序设计37例例2 求求1+2+100的和然后分成低、高字节存放在的和然后分成低、高字节存放在0 x1000和和0 x1001地地址单元中址单元中 程序分析:求1+2+100可以用100次循环来实现,因为求出来的和不可以用一个字节表示,所以必须分成高低字节存储。下面先给一个错误的程序。unsigned int sum 0 x1000=0,i=0

26、;void main(void)for(;i=100;i+)sum+=i;for(;)第六章 C语言程序设计38下面给出正确的程序:unsigned char sum_lowbyte 0 x1000=0,sum_highbyte 0 x1001=0,i=0;unsigned int sum;void main(void)for(;i8;for(;)第六章 C语言程序设计39例例3 产生一个随机数,然后返回结果产生一个随机数,然后返回结果程序分析:产生随机数可以调用一个函数rand(),使用它可以返回一个0到32767之间的随机数。然后使用switch-case进行处理。注意使用rand()函数

27、,必须包含标准库stdlib.h。此头文件在CodeWarrior安装目录“libHC12cinclude”目录中。#include int i,j;void main(void)i=rand();i=i/10000;switch(i)case 0:j=1000;break;case 1:j=2000;break;case 2:j=3000;break;case 3:j=4000;break;default:j=5000;for(;)第六章 C语言程序设计40例例4 C语言嵌入汇编语句语言嵌入汇编语句 有时在C语言中嵌入汇编语句是很有用的。比如在时序需要严格控制的场合,使用汇编语言加入几条“N

28、OP”指令,显然能够改变程序运行的时序;在需要对较大数据表操作的场合,使用汇编语言查表显然有更高的效率。假设程序中存在两个无符号整型数据表,需要做的工作是把两个表中对应元素相乘,再把结果相加并存储。即实现如下公式:其中n为数组的大小,Xi和Yi分别为数组元素。在9S12指令集中,有一条指令EMACS可以实现乘加操作,我们可以使用这条指令来完成以上的计算。第六章 C语言程序设计41程序代码和详细注释如下:#include#include#pragma LINK_INFO DERIVATIVE mc9s12dg128b#include main_asm.h unsigned int data14;

29、unsigned int data24;/*定义两个数组*/unsigned int*tbl1,*tbl2;/*指向数组的指针*/unsigned char i;/*计数变量*/unsigned long sum;/*保存结果*/第六章 C语言程序设计42void main(void)EnableInterrupts;asm_main();result=0;tbl1=data1;/*取得数组指针*/tbl2=data2;for(i=0;i4;i+)/*给数组初值*/data1i=i+1;data2i=i+1;for(i=0;i4;i+)asmLDX tbl1;X中保存第一数组地址 LDY tbl2;Y中保存第二数组地址 EMACS sum;乘加操作*/tbl1+=1;/*地址自加*/tbl2+=1;for(;)第六章 C语言程序设计43谢谢!

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 办公、行业 > 各类PPT课件(模板)
版权提示 | 免责声明

1,本文(山东大学飞思卡尔单片机教学第6章C语言程序设计课件.ppt)为本站会员(晟晟文业)主动上传,163文库仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。
2,用户下载本文档,所消耗的文币(积分)将全额增加到上传者的账号。
3, 若此文所含内容侵犯了您的版权或隐私,请立即通知163文库(发送邮件至3464097650@qq.com或直接QQ联系客服),我们立即给予删除!


侵权处理QQ:3464097650--上传资料QQ:3464097650

【声明】本站为“文档C2C交易模式”,即用户上传的文档直接卖给(下载)用户,本站只是网络空间服务平台,本站所有原创文档下载所得归上传人所有,如您发现上传作品侵犯了您的版权,请立刻联系我们并提供证据,我们将在3个工作日内予以改正。


163文库-Www.163Wenku.Com |网站地图|