单片机c语言学习

2024-04-30

单片机c语言学习(通用6篇)

篇1:单片机c语言学习

单片机C语言之一___________________________________________________________________ _____________________ 预处理 一》宏定义:

1、不带参数:

#define 标识符 常量表达式

/*#define是宏定义命令,宏名(标识符)好习惯用大写*/ #define NIL 0x80

2、带参数:/*相当于小函数*/ #define 宏名(参数表)字符串

/*不仅要时行字任串替换还要进行参数的替换,在宏定义时,宏名与带参数的括弧之间不应该加空格,否则将空格以后的字符串都作为替代字符串的一部分,这可是很容易出错的*/ 如:#define SQ(a,b)a*b 使用:x=12;y=10;area=SQ(x,y);/*则area=12*10=120*/ 二》文件包含:

#include <文件名>或#include “文件名” /*在C中用双引用形式更保险,在C51中常用物是尖括弧形式*/ 三》条件编译:

/*一般源程序中的所有程序行都参加编译,但有时希望对其中一部分内容只在满足一定条件下才进行编译,也就是对一部分内容指定编译的条件。*/ #if、#elif、#else、#endif、#ifdef、#ifndef /*选择不同的编译范围,产生不同的代码,提供通用性。*/ /*如对8051在6MHZ与12MHZ下有*/ #ifdef cpu==8051 #define FREQ 6 /*程序段*/ #else #define FREQ 12/*程序段*/ #endif /*这样下面的原程序不用做任何修改便可以使用于两种时钟频率的单片机系统*/ 四》其他:

1、#error:捕捉不可预料的编译条件

#if(myv!=0&&myv!=1)/*假定其值必为0或1*/ #error myv must be 1 or 0/*出错时显示*/ #endif

2、#pragma:用于在程序中向编译器传送各种编译控制命令 #pragma 编译命令序列

/*例:想按如下命令编译ex.c c51 ex.c debug cod large可用:*/

#pragma DB CD LA #pragma disable /*禁止中断*/

单片机C语言之二_____________________________________________________________________________________ 一》数据类型:

char int long 1:unsinged 0~255 0~65535 0~4294967295 2:signed-128~127-32768~32767-2147483648~2147483647 指针:* 3字节 位标量: sbit 特殊功能寄存器:sfr 16位特殊功能寄存器:sfr16 占2个内存单元,0~65535 可寻址位:sbit利用他可访问51单片机的内部RAM中的可寻址位或特殊功能寄存器中的可寻址位 sfr P0=0x80;sbit P0_1=P0^1;/*将P0口的口地址定义为80H,将P0.1位定义为P1_1*/ 二》数据存贮类型

表1.C51数据存贮类型

━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━ 数据存贮类型 ┃ 与存贮空间的对应关系

━━━━━━━╋━━━━━━━━━━━━━━━━━━━━━━━━━━ data ┃ 直接寻址片内数据存贮区,访速度快 bdata ┃ 可位寻址片内数据存贮区,允许位与字节混合访问 idata ┃ 间接寻址片内数据存贮区,可访问片内全部RAM地址空间

pdata ┃ 分页寻址片外数据存贮区(256字节)由MOVX @R0访问 xdata ┃ 片外数据存贮区(64K),由MOVX @DPTR访问 code ┃ 代码存贮区(64K),由MOVC @DPTR访问

━━━━━━━┻━━━━━━━━━━━━━━━━━━━━━━━━━━ 变量的存贮类型定义: char data var /*字符变量var被定义为data存贮类型,C51编译器将把该变量定位在51单片机片内数据区存贮区中*/ bit bdata flag /*位变量flag被定义为bdata存贮类型,C51编译器将把该变量定位在51单片机片内数据区存贮区(RAM)中的位寻址区:20H--2FH*/

三》typedef:重新定义数据类型

typedef 已有数据类型 新的数据类型 typedef int word;/*将word定义为整型*/ word i,j;/*将i,j定义为整型*/ 四》位运算符:

━━━━┳━━━━━┳━━━━━┳━━━━━━┳━━━━━━┳━━━━━━ ~ ┃ & ┃ | ┃ ^ ┃ << ┃ >> ━━━━╋━━━━━╋━━━━━╋━━━━━━╋━━━━━━╋━━━━━━

按位取反┃ 按位与 ┃ 按位或 ┃ 按位异或 ┃ 左移 ┃ 右移

━━━━┻━━━━━┻━━━━━┻━━━━━━┻━━━━━━┻━━━━━━

对移位:如<< ,a<<2,即为将二进制的a左移两位,若a=0x8f,即10001111,a=a<<2,将导致a=0x3c(00111100),右边补零。五》条件运算符:

逻辑表达式? 表达式1:表达式2 六》指针与地址运算符: *取内容 &取地址

七》强制类型转换:(类型)=表达式(char *)0xb000 八》sizeof 取数据类型、变量以及表达式的字节数的运算符; 九》continue:中断语句:结束本次循环。

单片机C语言之三_____________________________________________________________________________________ 函数:

一》中断服务函数与寄存器组定义:

函数类型 函数名(形式参数表)[interrupt n][using n] n为中断号,0~31:

━━━━┳━━━━━┳━━━━━ 中断编号┃ 中断向量┃ 入口地址 ━━━━╋━━━━━╋━━━━━ 0 ┃ 外中断0 ┃ 0003H ━━━━╋━━━━━╋━━━━━ 1 ┃ 定时器0 ┃ 000BH ━━━━╋━━━━━╋━━━━━ 2 ┃ 外中断1 ┃ 0013H

━━━━╋━━━━━╋━━━━━ 3 ┃ 定时器1 ┃ 001BH ━━━━╋━━━━━╋━━━━━ 4 ┃ 串行口 ┃ 0023H ━━━━┻━━━━━┻━━━━━

后面的n指的是四个工作寄存器组的一个:0~3 对函数目标代码影响如下:

在函数入口处将当前工作寄存器组保护到堆栈中;指定的工作寄存器内容不会改变,函数返回前将被保护的工作寄存器组从堆栈中恢复!例(定时1ms):

#include sbit P1_0=P1^0;void timer0(void)interrupt 1 using 1{ P1_0=!P1_0;TH0=-(1000/256);TL0=-(1000%256);} main(){ SP=0x60;P1_0=0;TMOD=0X01;TH0=-(1000/256);TL0=-(1000%256);EA=1;ET0=1;TR0=1;do{}while(1);} /* 注意:

1、如果中断函数中用到浮点运算,必须保存浮点寄存器的状态。(在math.h中保存浮点寄存器函数为pfsave, 恢复浮点寄存器的状态函数为fprestore)

2、如果在中断函数中调用了其他函数,则被调函数所使用的工作寄存器组与中断函数的一致!*/

单片机C语言之四_____________________________________________________________________________________

一、局部变量与全局变量(外部变量):

1、全局变量若不在开头定义则加extern

2、全局变量会使代码长,占用内存多

二、存储方式:

自动变量(auto):缺省,函数调用存在,退出消失。

内部变量 静态变量(static):static int a=5;始终存在,退出不消失,但不能访问。寄存器变量(register):速度最快。通常只给编译器一个建议,由编译器根 据实际情况确定。(见下)变量 全局变量(global): 外部变量

静态变量(static): 寄存器变量例: #include int_power(m,e)int m;register int e;{ register int temp;temp=1;for(;e;e--)temp*=m;return(temp);} main(){ „„ }

三、函数的参数和局部变量的存储器模式: 三种存储器模式:small,compact,large.一个函数的存储器模式确定了函数的参数和局部变量在内存中的地址空间 small:内部ram compact, large:外部RAM 函数类型 函数名(形式参数表)[存储器模式] 例:

#pragma large /*默认存储器模式为large*/ extern int calc(char I,int b)small;/*指定small模式*/ extern int func(int I,float f)large;/*指定large模式*/ int large_te(int I,int k)/*未指定,按默认的large模式处理*/ { return(mtest(I,k)+2);}

利用存储器混合模式编程,充分利用有限的存储空间,还可加快程序的执行速度!

单片机C语言之五_____________________________________________________________________________________ 数组 1>初始化数组: unsigned char a[5]={0x11,0x22,0x33,0x44,0x55} 或

unsigned char a[ ] ={0x11,0x22,0x33,0x44,0x55,0x66} 3>数组作为函数的参数:不但可以由变量作为函数的参数外,还可以用数组名作为函数的参数。一个数组数组名表示该数组的首地址。用一个数组名作为函数的参数时,在执行函数调用的过程中参数传递方式采用的是地址传递。将实际参数数组首地址传递给被调函数中的形式参数数组,这样一来两个数组就占有同一段内存单元。见下图:

a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7] a[8] a[9] 起始地址1000 b[0] b[1] b[2] b[3] b[4] b[5] b[6] b[7] b[8] b[9] 用数组名作为函数的参数,应该在主调函数和被调函数中分别进行数组定义而不能只在一方定义数组。而且在两个函数中定义的数组类型必须一致,如果类型不一致将导致编译出错。实参数组和型参数组的长度可以一致可以不一致,编译器对形参数组的长度不做检查,直只是将实参数组的首地址传递给行参数组。如果希望行参数组能得到实参数组的全部元素,则应使两个数组的长度一致。定义型参数组时可以不指定长度,只在数组名后面跟一个方括号[]。这时为了在被调函数中处理数组元素的需要,应另外设置一个参数来传递数组元素的个数。

例:用数组作为函数的参数,计算两个不同长度的数组中所有元素的平均值 #include float average(array,n)int n;float array[ ];{ int I;float aver,sum=array[0];for(I=1;I

float pot_1[2]={99.9,88.8};float pot_2[3]={11,22,33.3};average(pot_1,2);average(pot_1,3);}

单片机C语言之六_____________________________________________________________________________________ 软件法去干扰:

工程上我们在采集数据时一般要求精度达到5%%,大于这个值将认为无效。我在实际应用中采用8535对32路数据进行采集(8535带10位AD,带看门狗),发现数据跳动有时达7%%,这是由于各种干扰造成的。主要来自于随机干扰,下面就各种干扰的方法给出简单的去除方法:

1、白噪声:最重要的统计特性为平均值为0,可采取每路数据采集几次求平均的方法;

2、随机干扰:该点明显高于或低于附近正常采样值,故采取中值滤波法,即对被测信号连续采样M次,进行大小排序,取大小居中的1/3个采样值进行算术平均;

3、电源干扰:特点是有固定周期,故可采用定时采样求平均的方法。

由于各种排序与求平均算法用C易于实现,故C常常用于采集系统中软件去干扰。至于排序算法可参考上一篇文章,有一个经典的程序。

在实际中我们采用每路猜9个值,排序,取中间3个,求平均。然后。,每路数据几乎不动!

单片机C语言之七_____________________________________________________________________________________ 指针:可对内存地址直接操作

基于存贮器的指以贮器类为参量,它在编译时才被确定。因此为指针选择存贮器的方法可以省掉,以这些指针的长度可为1个字节(idata *,data *,pdata *)或2个这节(code *,xdata *)。char xdata *address;ADC0809具有8个模拟量输入通道,采用中断方式,在中断函数中读取8个通道的A/D转换值,分别存储在外部RAM的1000H~1007H单元。ADC0809端口地址为00F0H。

程序定义了两个指针变量* ADC和* ADCdata,分别指向ADC0809端口地址(00F0H)和外部RAM单元地址(1000H~1007H)

由*ADC=I送入通道数,启动ADC0809进行A/D转换,转换结束时产生INT1中断。在中断服务函数int1()中通过temp=*ADC和*ADCdata=temp;读取A/D转换结果并存到外部RAM中。#include unsigned int xdata *ADC;/*定义ADC0809端口指针*/ unsigned int xdata *ADCdata;/*定义ADC0809数据缓冲器指针*/ unsigned char I;

void main(){ ADC=0x00f0;/*定义端口地址和数据缓冲器地址*/ ADCdata=0x1000;I=8;/* ADC0809有8个模拟输入通道*/ EA=1;EX1=1;IT1=1;/*开中断*/ *ADC=I;/*启动ADC0809*/ WHILE(I);/*等待8个通道A/D转换完*/ } void int1()interrupt 2 { unsigned char tmp;temp=*ADC;/*读取A/D转换结果*/ *ADCdata=temp;/*结果值存到数据缓冲区*/ ADCdata++;/*数据缓冲区地址加1*/ i—;*ADC=I;/*启动下一个模拟输入通道A/D转换*/ } 除了用指针变量来实现对内存地址的直接操作外,c51编译器还提供一组宏,该宏定义文件为:“absacc.h”,利用它可十分方便地实现对任何内存空间的直接操作,改写上面的程序: #include #include /*包含绝对地址操作预定义头文件*/ #define ADC 0x00f0;/*定义ADC0809端口地址*/ #define ADCdata 0X1000 /*定义数据缓冲器地址*/ unsigned char I;void main(){ I=8;/ *ADC0809有8个模拟输入通道*/ EA=1;ex1=1;it1=1;/ *开中断*/ XBYTE[ADC]=I;/*启动0809 */ While(i);/*等待8个通道转换完毕*/ } void int1()interrupt2 { unsigned char tmp;tmp=XBYTE[ADC];/*读取A/D转换结果*/ i--;XBYTE[ADCdata+I]=tmp;/**结果值存储到数据缓冲器*/ XBYTE[ADC]=I;/*启动下一个模拟输入通道A/D转换*/ } 两指针相减-----计算字符串的长度 #include main(){

char *s=”abcdef”;int strlen(char *s);printf(“n length of ‘%%s’=%%dn”,s,strlen(s));} int strlen(char *s){ char *p=s;while(*p!=’’)p++;return(p-s);} 结果为:length of ‘abcdef’=6 注:不允许指针之间进行加,乘,除,移位,或屏蔽运算,也不允许用float类型数据与指针做加,减运算!

抽象型指针:

ANSI新标准增加了一种“void * ”的指针类型,这是一种抽象型指针,即可以定义一个指针变量,但不指定该指针是指向哪种类型的数据的。在赋值时需进行强制类型转换: Char *p1;Void *p2;P1=(char*)p2;抽象型指针可以用来在每个存储区内访问任意绝对地址或者用来产生绝对调用。

篇2:单片机c语言学习

8.1 在定义的时候,*ap中的‘*’是指针类型说明符;

在进行指针预算时,x = *ap 中的‘*’是指针运算符。8.2 如果在已定义好的指针变量,并引用,即

int *ap, int a;ap = &a;则在进行指针运算的时候:

(1)*ap与a是等价的,即 *ap就是a;

(2)&*ap:由于*ap与a等价,则&*ap与&a等价(地址);

(3)*&a:由于&a = ap,则*&a与*ap等价,即*&a与a等价(变量);(4)*ap++相当于a++。

8.3 指向数组的指针变量的定义,应用,赋值:

int a[10];int *app;则有两种方法:app = &a[0];或 app = &a;(1)app+I 或a+i就是数组元素a[i]的地址;(2)*(app+i)或 *(a+i)就是元素a[i]中的内容;

(3)指针变量也可以带下表,即app[i]与*(app+i)等价。8.4 数组和指针可以互换,但在代码执行的效率上却大不相同。用数组找元素必须每次计算元素的地址,效率不高;而用指针则直接指向某个元素,不必每次计算地址,可以大大的提高运算效率。8.5 关于指针的运算:

(1)p++(或p+=1):使指针p指向下一个数组元素,地址加1;

(2)*p++:先得到p指向的变量值,再执行p加1,指向下一个数组元素;(3)*++p:先使p加1,指向下一个数组元素,再去p指向的变量值;(4)(*p)++:表示p指向的变量值加1;

(5)若p指向当前数组中的第i个元素,则:

(p--)与a[i--] 等价:先执行*p,然后p自减;(++p)与a[++i] 等价:先执行p自加,再执行*p;(--p)与a[--p] 等价:先执行p自减,再执行*p。

8.6 指向多维数组:

定义一个二维数组:a[3][4];定义一个指针变量:(*p)[4];(注意:列数相同(第二维相同))使指针变量指向数组:p = a;此时: p与a等价:指向数组a[3][4]的第0行首地址;

p+1与a+1等价:指向数组a[3][4]的第1行首地址; p+2与a+2等价:指向数组a[3][4]的第2行首地址;

而:

*(p+1)+3与& a[1][3]等价,指向a[1][3]的地址;

*(*(p+1)+3)与a[1][3]等价,表示a[1][3]的值; 一般的:对于数组a[i][j]来讲,有

*(p+i)+j相当于&a[i][j],表示第i行第j列元素的地址; *(*(p+i)+j)相当于a[i][j],表示第i行第j列元素的值。

8.7 指向结构体:

如果指针p指向结构体数组msg1[0]的首地址,则:

(1)(*p).flg与p->flg和msg1[0].flg三者完全等价,即(*p).成员名 与p->成员名 以及 结构体数组元素成员名三种形式是等价的;

(2)p+1:使指针指向结构数组msg1[0]的下一个元素msg1[1]的首地址;(3)由于指向运算符->的优先级高于自加运算符++,则:

(++p)->flg:先使p自加1指向msg1[1]的地址,再指向msg1[1]的flg成员值;(p++)->flg:先得到msg1[0].flg的值,再使p自加1指向msg1[1]的首地址;

篇3:单片机的C语言分析

1 为什么要用C语言

1.1 汇编语言的优势及不足

众所周知, 汇编语言是面向机器的语言, 它一刻也离不开具体的机器, 所以不同的机器, 汇编语言也不同。

汇编语言是与计算机的机器语言一一对应的, 因此, 用汇编语言编写的程序效率高, 占用储存空间小, 运行速度快, 这是汇编语言程序的优势所在。

然而祸为福所倚, 正因为汇编语言与计算机的硬件密不可分, 不同的机器就有不同的汇编语言, 因此汇编语言难学、难编、难读、难懂、难移植, 这五难是公认的, 几乎所有的单片机教材中都有相应的论述[2]。既是所有用汇编语言从事过单片机的开发与应用的工程技术人员的共同感受;也是所有用汇编语言从事过单片机教学的各级各类教师的共同感受。这就是汇编语言的不足。

1.2 C语言的优势与不足

C语言是一种结构化语言, 它层次清晰, 按模块化组织程序, 易于调试和维护。C语言的表现能力和处理能力极强。它不仅具有丰富的运算符和数据类型, 便于实现各类复杂的数据结构, 它还可以直接访问内存的物理地址, 进行位 (bit) 一级的操作。由于C语言实现了对硬件的编程操作, 因此C语言集高级语言和底层级语言功能于一体, 既可用于系统软件的开发, 也适合于应用软件的开发。此外, C语言还具有效率高、可移植性强等特点, 因此C语言广泛地移植到了各类各型计算机上, 从而形成了多种版本的C语言, 单片机的C语言就是这多种版本之一, 它是应用于51单片机的一种C程序开发语言.现在几乎所有的单片机、微处理器、微控制器开发平台都支持用C语言进行程序设计。使C语成为当代最优秀的程序设计语言之一, 获得了极为广泛的应用。

C语言进入51单片机后, 它的优势得到了充分的展示, 它不象汇编语言那样要熟练掌握指令系统, 也不要象汇编语言那样要对程序的起始地址、主程序的起始地址、中断服务子程序起始地址、保护现场、恢复现场、保存断点、返回断点、堆栈指针、进堆栈、出堆栈、子程序中的入口参数、出口参数、参数的传递、四组工作寄存器的内在联系等难度很大的知识点要有非常透彻的了解;它只要求对单片机的片内结构有个大致的了解;它易学、易懂、上手快;它功能强大, 移植性强;它集高级语言和底层语言于一身;它的各种各样的数据 (信息) 既可以以变量的形式出现于各个函数中, 也可以以地址的形式访问单片机的片内、片外的各种数据存储器及程序存储器的任何单元。可以说, 汇编语言能做到的事情, C语言不但能做到, 而且能轻而易举的实现之。因此它获得了越来越广泛的应用。正因为C语言有如此明显的优越性, 原来使用汇编语言的工程技术人员也纷纷抛弃汇编语言而跨入用C语言开发单片机的行列中。这就是我们为什么要用C语言对单片机进行教学的原因。

C语言相对汇编语言而言, 同样功能的程序所需内存相对较多, 执行速度相对较慢, 这就是C语言的不足。

2 单片机的C语言教学法

2.1 单片机的发展使汇编语言的优势失去光泽

C51系列单片机在各行各业获得了广泛应用这已经是不争的事实, 继最初的基本型8031/8051/8751和增强型8032/8052/8752后, 相继又推出了AT89C51/89C52/89S52/89C55和S T C 8 9 C 5 1/S T C 8 9 C 5 2/STC89S51/STC89S52/STC89C55, 目前的S T C 1 2 C 5 A 6 0 S 2系列单片机, 它的应用程序空间有8K/16K/20K/32K/40K/48K/52K/60K字节;它的工作频率范围为0-35MHZ, 由于它的机器周期是单时钟周期, 即一个时钟周期就是一个机器周期 (光这一点就使单片机的运行速度提高12倍) , 所以0-35MHZ的工作频率相当普通的8051的0-420MHZ的工作频率, 这两大优势使C51相对于汇编语言而言的代码运行效率低和代码长的缺陷得到了很好的弥补, 也使得用汇编语言编写的程序效率高、占用储存空间小、运行速度快这一汇编语言的优点失去了光泽, 使这一优点变得没有什么实际意义了。相反它的难编、难读、难懂、难移植的缺点没有丝毫改变。为C51成为单片机开发与应用的主流程序设计语言奠定了基础。

2.2 C语言教学法的实践

对单片机实施C语言教学法时, 将C语言程序中不需要的汇编语言的指令系统、伪指令、汇编语言程序设计都删去不讲, 讲述单片机的硬件知识时也以C语言编程需要为出发点, 与C51编程无关的硬件知识不再讲授。

理论课的具体做法是:第1章单片机慨述 (花两学时讲授单片机的发展历史及发展趋势, 单片机的应用, MCS-51系列, ATMEL系列, STC系列单片机简介) ;第2章STC89C51单片机的硬件结构, 重点讲授存储器的分布及结构、四个行I/O口 (P0、P1、P2、P3) 、40个片脚及功能;第3章讲授单片机的C51基础知识, 由于开设单片机课程之前, 学生已经学习完C语言程序设计, 这一章重点介绍C51与标准C的不同之处, 复习C语言程序的基本结构与相关语句 (if语句、swith/case语句、while语句、for语句) 的用法。笫4章介绍Keil C51软件的安装、项目的建立、C51程序的编辑、编译、下载及执行 (做一个实验解决) 和C51的库函数。第5-第7章介绍89C51的内部资源, 包括STC89C51的中断系统, 定时器/计数器, 串行囗及它们的C51编程技术。第8-第11章介绍STC89C51单片机与I/O接口、独立键盘、矩阵键盘、LED显示器、LCD显示器、A/D、D/A及I2C的C51编程及应用技术, 第5章及以后各章介绍硬件知识时着重讲授51单片机中21个特殊功能寄存器中的15个 (P0、P1、P2、P3、IE、IP、TCON、SCON、TMOD、TH0、TL0、TH1、TL1、PCON、SBUF) 的功能及用法, 如何实现I/O控制、外中断控制、定时中断控制、计数中断控制、LED静态显示、LED动态显示、独立键盘检测、行列式键盘检测、LCD1602显示字符、LCD12864 (或LCD12232) 显示汉字、A/D转换及显示、D/A转换及显示、I2C电路在线存储数据等各种实用的编程技术及理论基础知识。

2.3 与C语言教学法配套的实验

单片机的教学不管用哪种教学方法, 实践动手能力的培养是非常重要的一环, 与单片机C语法教学法配套的实验开发板不但功能强、性能好、而且价格便宜 (150元/套左右) , 可以开出I/O控制 (流水灯) 、外中断控制、定时中断控制、计数中断控制、LED静态显示、LED动态显示、独立键盘检测、行列式键盘检测、LCD1602显示字符、LCD12864 (或LCD12232) 显示汉字、A/D转换及显示、D/A转换及显示、I2C电路在线存储数据、单片机控制继电器、单片机控制报警器、单片机控制步进电机、单片机与单片机的串行通信、单片机与PC机的串行通信等20多个实验, 学生爱不释手, 许多家庭经济条件许可的学生干脆自己买一台, 有空闲时就动手, 这种开发实验板激发起学生浓厚的兴趣, 大大提高了学生的积极性, 为单片机的C语言教学法提供了理想的实验手段和支撑。

2.4 与C语言教学法配套的课程设计

开设单片机原理及应用课程的多数专业都有一个与该课程配套的课程设计。与单片机的C语言教学法配套的课程设计有实时时钟的设计与实现和数据集系统的设计与实现, 下面我们把实时时钟的设计与实现的功能及具体做法介绍如下。

要求实现的具体功能:

1) 时间显示在LCD1602液品上, 按秒实现更新;

2) 能够利用按键随时调节时钟的时、分、秒, 按键可设计三个有效键, 分别为功能选择键、数值大键、数值小键;

3) 每次有键按下时, 蜂鸣器都以短“滴”声报警;

4) 利用AT24C02实现断电自动保护显示数据的功能, 当下次上电时接着上次断电前的时间数据继续运行;

5) 在LCD1602的第一行显示年、月、日和星期, 第二行显示时、分、秒;

具体做法:第一步先用Proteus仿真实现之, 第二步在万能板上焊接调试成功。其结果是70%以上的同学能做出来, 达到良好或优良, 30%的同学为中等和及格。

3 单片机的C语言教学法效果

笔者于2011年上半年及下半年针对民办独立学院的计算机科学与技术专业0801班、网络工程专业0801班、电子信息工程专业0901班三个班的教学实践证明, 不管是单片机的内部结构、内部资源还是理论与实践结合在一起的单片机控制流水灯、单片机的外中断控制报警器、控制继电器、LED静态显示、LED动态显示、定时中断实现实时时钟的显示、串行通讯、独立键盘的检测与显示、行列式键盘的检测与显示、LCD1602显示字符及左移右移、LCD12864显示汉字及左移右移、DAC0832数模转换及显示、ADC0809系列的模数转换及显示、E2PROMAT24C02与单片机的通讯等的教学都非常顺利, 与汇编语言教学法相比真有半功倍之效。学生学起来轻松, 兴趣盎然, 劲头十足;教师教起来也是轻松愉快, 信心十足。本文中的有关课程设计的内容难度也不小, 先用Proteus仿真, 然后各自在万能板上焊接单片机的最小系统配以LCD1602、AT24C02及报警器, 70%的同学可以达到良好及以上。有人说你要是用单片机做出一个电子钟, 那你基本上已经掌握单片机的80%了, 这句话有道理, 电子钟对编程的综合性要求还是相当高的【3】。从这句话也可以看出单片机C语言教学法的效果。

参考文献

[1]唐存皮, 陈小琴, 金红.提高单片机教学效果的实验教法方法探讨[J].电气电子教学学报.2006 (3) :108-109.

[2]刘剑, 刘奇.51单片机开发与应用基础教程 (C语言版) [M].北京:中国电力出版社, 2012.

篇4:高职C语言与单片机融合教学初探

关键词: 高职教育 C语言 单片机 融合教学 智能车

引言

随着电子技术的飞速发展,采用C语言开发的单片机控制类产品占据了大量市场。单片机产品的设计、生产、调试和维修岗位需要大量高职人才。因此,C语言课程和单片机应用课程成为应用电子、电气自动化、计算机控制技术等工科专业的主干课程。这些课程的实践性要求较高,对高职学生有一定难度。因此,开展高职院校C语言和单片机课程的教学改革成为高职教学研究的热点。根据高职学生的特点和岗位需求开展教学工作,对学生更快地适应工作岗位有重要的现实意义。笔者结合多年C语言和单片机的教学经验,对高职的C语言和单片机的融合教学进行探讨。

1.传统教学的不足

1.1知识遗忘率高。

国内高职院校电子电气类专业的单片机教学大多选用汇编语言或者C语言开发单片机应用系统。以51单片机为主流的汇编语言,指令数量多,不方便记忆。因此,越来越多的高职院校转向C语言开发工具的单片机教学。根据传统的高职教学方案,C语言课程和单片机课程开设在不同学期,C语言是单片机的先修课程。为了构建相对完整的知识体系,学生在学习完C语言之后才开始学习单片机,时间相隔长达半年之久。这种做法导致知识遗忘率较高,迫使一些教师把复习C语言作为单片机课程的教学内容之一,以此强化教学效果。由于总学时有限,单片机本体的教学内容相对减少,导致学生对单片机学得不深、学得不透。

1.2内容枯燥,实践少。

在C语言的机房教学过程中,主要的输入输出设备是键盤和屏幕,以简单计算为主的教学内容相对枯燥,表现形式单一。学生很容易把C语言单纯理解为计算机专业课,与所学的电子电气专业无关。这种对C语言主要功能的认识误区,会降低学习兴趣,削弱单片机开发的语言基础。C教学实践表明:电类专业的高职学生很难深入理解指针和数组的应用,对C语言的嵌入式开发功能理解不透,导致先修课程基础不牢固。进入单片机学习阶段以后,薄弱的C语言基础将会妨碍单片机的教学效果。同时,单片机特有的寄存器C定义和特殊位指令还需要补充学习。

传统的单片机教学以理论教学为主,按照“硬件封装—寄存器功能—软件流程—外围接口”的顺序,强调和追求完整的单片机理论体系结构。由于缺乏合适的实践载体,因此大量专业术语的枯燥讲解使学生上课时昏昏沉沉,似懂非懂。过多的理论灌输使很多学生放弃了单片机课程的学习。这种“重理论、轻实践”的教学模式培养出的学生,很难快速适应今后的单片机工作岗位。

1.3理实脱节,创新少。

传统的单片机课程大多数采用实验箱进行实践教学[1],完成验证性的实验。这种实践模式跟单片机的实际产品有很大差异,教学效果不理想。不少“95后”的学生功利心强,为了早点完成实验,过度追求实验结果,忽略了单片机硬件电路装调、软件调试测试方面的能力提高。当全部课程结束的时候,很多同学对单片机产品开发、装调的全过程不了解,对单片机仿真器的仿真方法(尤其是硬件仿真)掌握不到位。这种教学过程理实脱节的现象,抑制了学生创新能力的发挥。

2.融合教学的设计

针对上述问题,我们探索把C语言和单片机的知识有效融合,推进教学改革,开展项目教学,采用“教、学、做”一体化的融合教学,强化教学效果,更好地体现高职高专的教学特色和教学理念。

教学改革方案的总体思路是:以具有吸引力的项目载体为主线,把C语言和单片机课程融合,开设“C语言与单片机”课程。在高职教学过程中,采用“教、学、做”一体化授课,提高学生动手实践能力。以够用为原则,适当精简C语言的教学内容,降低教学深度。适度增加单片机应用的自主创新环节,鼓励学生思考,提高应用创新能力。

2.1项目载体。

合适的项目载体有利于实现高职项目化教学[2],促进学生技能的培养。选择“贴近生活”、“通俗易懂”的项目载体,是提高学生学习兴趣的有效手段。在本教学方案设计中,我们选用的项目载体是:单片机智能车。智能车属于机电一体化的作品,体积小,重量轻,实施难度适合高职高专的教学水平。项目载体的主要功能是采用AT89S52单片机控制车轮伺服电机,实现智能车的运动控制。在光电传感器的配合下,单片机控制小车进行循迹运动。在超声传感器的支持下,单片机控制小车实现“避障”功能。

2.2具体方案。

“C语言与单片机”融合课程总计60学时,其中实践30学时,理实比为1:1。教学全过程以单片机智能车为核心,以学生为主体,教师起引导作用。学生通过智能车的制作与调试提高动手实践能力,通过思考和提问激发创新思维。整体教学方案可以分成六个模块,简述如下:

(1)课程导入和智能车综述

在这个教学模块中,教师首先讲授单片机的典型应用、历史沿革、主流分支和前沿技术,使学生了解课程的教学目标和对应工作岗位,浅显了解单片机产品。其次,教师演示装调好的智能车实物,学生能正确理解智能车的主要功能,提高学习兴趣。实践环节安排的内容是单片机智能车的结构件安装。在教师的指导下,学生根据产品套件说明书的要求,使用螺丝刀完成车架、车轮、电机、电沲盒等结构件的安装和调试。在装调完毕以后,教师补充讲解智能车应用场合和综述,学生对项目载体有了更加清晰的认识。

(2)控制板的硬件设计与装调

首先,学生完成智能车单片机控制电路板的安装、焊接和硬件调试。其次,教师讲解单片机最小系统(包含:单片机、时钟电路、复位电路)的电路结构和工作原理。学生在明确单片机IO接口使用方法之后,简单了解车轮伺服电机的驱动电路工作原理。通过“讲练结合”的教学方法,学生得到了单片机产品的硬件设计、安装、调试的全过程体验,掌握了电路组成和原理,提高了单片机硬件装调的实践能力。

(3)简单运动的开发调试

本教学模块主要完成智能小车C51的IO接口控制,实现伺服车轮的前进功能。教师在简要介绍51单片机系统的软硬件开发环境之后,把教学重点转入C语言。通过LED亮灯的样例程序,完成C语言的概述导入。在本模块教学中,主要涉及的C51知识点有:数据类型、运算符与表达式;C51特殊功能寄存器的C定义;51的位类型与位运算;顺序结构程序设计。在操作方面,学生须掌握KEILμVision软件开发平台的使用方法,包括代码编辑、编译、下载和仿真调试。

(4)复杂运动的开发调试

本教学模块的主要功能是:通过C51控制小车的伺服车轮,完成后退、转圈、加减速、转向等复杂运动功能。在这一阶段,学生可以通过项目载体的调试,结合51单片机的特点,完成C语言中选择结构程序、循环结构程序的学习。在此基础上,教师引导学生尝试进行程序优化,教会学生数组的使用、函数的调用技巧。

(5)人机接口模块的开发调试

在智能小车的单片机控制板上,增加数码显示和触须接口,可以完成小车运动计时和触碰避障功能。在教学过程中,通过“先做后讲”的方式提高學习兴趣能够取得更加理想的教学效果。学生通过实践环节观察单片机人机接口的电路结构,通过C51编程与调试直接体验“软件去抖动”、“LED字形码编程”等应用技巧。

(6)避障模块的开发调试

避障模块装调是智能小车项目载体的综合教学环节。在C语言应用部分,侧重指针、结构体编程和开发。在单片机方面,须掌握“中断”的概念及其应用方法、串行接口的调试与编程。避障模块采用了红外反射传感器,融合了传感器应用[3]、模拟信号调理等方面知识。因此,开发调试智能小车的避障模块,能加深学生对单片机产品总体框架的理解,培养他们的单片机综合应用能力和开发能力。教学实践表明:部分优秀学生在这一阶段能优化和创新避障算法程序,提升小车的智能化水平,学生的产品创新意识得到进一步强化。

以上六个模块的教学方案以智能小车装调为核心,包含了传统C语言课程和单片机课程的主要知识点。智能小车体积小,重量轻,易于携带,便于各种教学方法的灵活运用[4]。比如:我们把课堂教学与课外教学紧密结合,组织“城院巧匠杯智能小车”竞赛,激发学生学习热情,丰富课余生活,提高学生的单片机综合应用能力和创新能力。“C语言与单片机”融合课程采用模块计分的评价考核方式,前五个模块各占总分的15%,第六模块占25%。在考核方案中,重视学生的过程体验,把团队协作、职业素养作为评价的重要组成部分,提高学生综合职业素质。

结语

高职传统的C语言课程和单片机课程分开教学,知识遗忘率高,教学效率低,融合度差,理实不能有效结合,不利于创新型人才的培养。针对上述不足,本文探讨了以单片机智能车为项目载体的C语言与单片机融合教学设计,给出了六模块教学的具体方案。教学实践表明:采用“教、学、做”一体化融合两门课程的教学改革方案,方便运用各种教学方法,学以致用,有效激发高职学生的学习热情,有助于创新能力和职业素质的培养,达到良好的教学效果。

参考文献:

[1]冯惠秋,吕宁.《单片机基础及应用》课程实践模式探索[J].职业教育研究,2013(6):123-124.

[2]焦玉全,朱燕祥.单片机原理及应用课程项目化教学探索[J].读与写(教育教学刊),2013(7):29-30.

[3]李潇雯.智能小车设计中传感器的应用[J].太原大学教育学院学报,2015(2):96-99.

篇5:初步学习单片机C语言学习心得1

感觉自己在c语言方面的知识很不熟悉,知识自己初步懂得c语言而已,今后的学习自己要多看c语言,这对以后的学习很重要,没有基础谈何学习以后更加难懂的知识,就已今天的一个程序而言,一个流水灯的程序,被2个for循环搞的晕头转向,#include

Void delay(int)

void delay(int t){int a,b;for(a=0;a

for(b=0;b<1100;b++);} void main(){

P1=0xfe;

delay(100);

P1=0xfd;

delay(100);

P1=0xfb;

delay(100);

P1=0Xf7;

delay(100);

P1=0xef;

delay(100);

P1=0xdf;

delay(100);

P1=0xbf;

delay(100);

P1=0X7f;

delay(100);

} 自己始终把t*1100当成时间,其实不是,而是t*1100还要乘以一个T,T是执行一个分号所用的时间,另外以下的表格对于自己而言也很重要!!#include sbit D1=P1^0;unsigned a;void main(){ while(1){

a=60000;

D1=0;

while(a--);

a=60000;

D1=1;

while(a--);} }

灯光闪烁程序 #include #define uint unsigned int #define uchar unsigned char sbit D1=P1^0;void delay();void main(){ while(1){

D1=0;

delay();

D1=1;

delay();

} } void delay(){ uint x,y;for(x=100;x>0;x--)

for(y=600;y>0;y--);} 利用调用子程序设计闪灯。#include #include #define uint unsigned int #define uchar unsigned char uchar temp;void delay(uint);void main(){

temp=0xfe;

P1=temp;while(1){

temp=_crol_(temp,1);

delay(2000);

P1=temp;

} } void delay(uint z){ uint x;uchar y;for(x=z;x>0;x--)

for(y=20;y>0;y--);} 利用intrins函数以及延时子程序编写流水灯

编写一个流水灯,在灯亮的时候蜂鸣器响,灯灭的时候蜂鸣器不响,亮灭灯时间间隔为0.5s #include #include #define uint unsigned int #define uchar unsigned char uchar temp;sbit gu=P2^3;void delay(uint);void main(){

temp=0xfe;

P1=temp;// gu=0;while(1){

gu=0;

temp=_crol_(temp,1);

delay(1920);

P1=temp;

gu=1;

delay(1920);}

} void delay(uint z){ uint x;uchar y;for(x=z;x>0;x--)

for(y=20;y>0;y--);}

中断优先级

#include #define uint unsigned int #define uchar unsigned char sbit wede=P2^6;sbit dude=P2^7;uchar code table[]={ 0x3f,0x06,0x5b,0x4f, 0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c, 0x39,0x5e,0x79,0x71};uchar num,tt;void main(){ num=0;tt=0;TMOD=0x01;TH0=(65536-50000)/256;TL0=(65536-50000)%256;EA=1;ET0=1;TR0=1;wede=1;P0=0xe3;wede=0;dude=1;P0=0x3f;dude=0;

while(1)

{

if(tt=20)

{

tt=0;

num++;

if(num=16)

num=0;

dude=1;

P0=table[num];

dude=0;

篇6:单片机C语言知识点

【转义字符】 【语句】 【#define】 #define 新名 原名 【typedef】

typedef 原类型名 新类型名;【sbit】 sbit P1_0=P1^0;在reg52.h或reg51.h的头文件下,要使用P0.0~7….一定要事先位定义。【if】

(1)if(表达式)语句; 表达式的值为真,则执行其后的语句,否则不执行该语句,继续执行

这条语句的下一条。(2)if(表达式)语句1; else 语句2;

表达式的值为真,则执行语句 1,否则执行语句2。(3)if(表达式1)语句1; else if(表达式2)语句2; else if(表达式3)语句3; …

else if(表达式m)语句m; else 语句n;

依次判断表达式的值,只要出现某个表达式的值为真时,则执行其对应的语

句。然后跳到整个if 语句之外继续执行程序。【switch】(1)switch(表达式){ case常量表达式1: 语句1;case常量表达式2: 语句2;------------------------case常量表达式n: 语句n;default : 语句n+1;} 计算表达式的值。并逐个与其后的常量表达式值相比较,当表达式的值与

某个常量表达式的值相等时,即执行其后的语句,然后不再进行判断,继续执行后面所有 case 后的语句。(2)

switch(表达式){ case 常量表达式1:语句1;Break;case 常量表达式2:语句2;Break;case 常量表达式3:语句3;Break;------------------------case 常量表达式n:语句n;Break;default : 语句n+1;} 计算表达式的值。并逐个与其后的常量表达式值相比较,当表达式的值与

某个常量表达式的值相等时,即执行其后的语句。【goto】 goto 语句标号;

goto 语句标号; 其中语句标号是按标识符规定书写的符号,放在某一语句行的前面,标号后加冒号(:)。语句标号起标识语句的作用,与goto 语句配合使用。【while】(1)

while(表达式)语句;

只要这个表达式所表描述的事情成立或该表达式经过计算后的值是非0 值,就一直循环执行其后

面的语句;当表达式所描述的事情不成立或经过计算后表达式的值为0 时,就不再执行其后 面的语句,并跳出while 循环。(2)do 语句; while(表达式);

先执行循环中的语句,然后再判断表达式是

否为真,如果为真则继续循环;如果为假,则终止循环。【for】

for(循环变量赋初值;循环条件;循环变量增量)语句 1)先求解表达式1。

2)求解表达式2,若其值为真(非0),则执行语句,然后执行下面第3)步;若其值为

假(0),则结束循环,转到第5)步。3)求解表达式3。4)转回上面第2)步继续执行。

5)循环结束,执行for语句下面的一个语句。【数组】(一维数组)

类型说明符数 组名

[常量]; unsigned char a[10];(二维数组)

类型说明符 数组名 [常量] [常量]; unsigned char b[3][3];int display[2][3]={{1},{3}};

上一篇:月班级工作计划下一篇:六条禁令、十不准规定