PIC单片机C语言编程入门.docx
《PIC单片机C语言编程入门.docx》由会员分享,可在线阅读,更多相关《PIC单片机C语言编程入门.docx(10页珍藏版)》请在冰豆网上搜索。
PIC单片机C语言编程入门
PICC入门笔记
PIC单片机C语言编程入门笔记
一、C语言基础复习--------没C语言基础看起来可能有点困难。
C程序的语句
语句名称
一般形式
说明
表达式语句
表达式;
表达式语句由表达式加上分号“;”组成
函数调用语句
函数名(实际参数表);
实际参数、形式参数二个概念要理解
控制语句
附件1
控制语句用于控制程序的流程
复合语句
多个语句用括号{}括起
空语句
;
只有分号“;”组成的语句称为空语句
赋值语句
变量=(变量=表达式);
赋值表达式再加上分号构成的表达式语句
数据输出语句
printf(“格式控制字符串”)
附件1
(1)条件判断语句
if语句,switch语句
(2)循环执行语句
dowhile语句,while语句,for语句
(3)转向语句
break语句,goto语句,continue语句,return语句
关系运算符
小于
小于或等于
大于
大于或等于
等于
不等于
<
<=
>
>=
==
!
=
关系运算符都是双目运算符,其结合性均为左结合。
在六个关系运算符中,<,<=,>,>=的优先级相同,高于==和!
=,==和!
=的优先级相同。
关系表达式的值是“真”和“假”,用“1”和“0”表示。
逻辑运算符
与运算
或运算
非运算
&&
||
!
&&和或运算符||均为双目运算符。
具有左结合性。
非运算符”!
”为单目运算符,具有右结合性,逻辑运算的值也为“真”和“假”两种,用“1”和“0”来表示。
单目运算符>算术运算符>关系运算符>逻辑运算符>赋值运算符
第三章:
控制语句
1.if语句
C语言的if语句有三种基本形式。
1、如果表达式的值为真,则执行其后的语句,否则不执行该语句。
if(表达式)语句;
2、如果表达式的值为真,则执行语句1,否则执行语句2。
If(表达式)
语句1;
else
语句2;
3、依次判断表达式的值,当出现某个值为真时,则执行其对应的语句。
然后跳到整个if语句之外继续执行程序。
如果所有的表达式均为假,则执行语句n。
然后继续执行后续程序。
If(表达式1)
语句1;
elseif(表达式2)
语句2;
elseif(表达式3)
语句3;
…
elseif(表达式m)
语句m;
else
语句n;
2、条件运算符和条件表达式
由条件运算符组成条件表达式的一般形式为:
表达式1?
表达式2:
表达式3
其求值规则为:
如果表达式1的值为真,则以表达式2的值作为条件表达式的值,否则以表达式3的值作为整个条件表达式的值。
例:
max=(a>b)?
a:
b;
意义:
如果在条件语句中,只执行单个的赋值语句时,常可使用条件表达式来实现。
不但使程序简洁,也提高了运行效率。
3、switch语句
C语言还提供了另一种用于多分支选择的switch语句,其一般形式为:
switch(表达式){
case常量表达式1:
语句1;
case常量表达式2:
语句2;
…
case常量表达式n:
语句n;
default:
语句n+1;
}
其语义是:
计算表达式的值。
并逐个与其后的常量表达式值相比较,当表达式的值与某个常量表达式的值相等时,即执行其后的语句,然后不再进行判断,继续执行后面所有case后的语句。
如表达式的值与所有case后的常量表达式均不相同时,则执行default后的语句。
4、循环结构程序
while语句
while语句的一般形式为:
while(表达式)语句;
特点:
判断后执行
说明:
1.循环体如包括有一个以上的语句,则必须用{}括起来,组成复合语句。
2.应注意循环条件的选择以避免死循环。
do-while语句
do-while语句的一般形式为:
do
语句;
while(表达式);
do-while语句的语义是:
先执行循环体语句一次,再判别表达式的值,若为真(非0)则继续循环,否则终止循环。
do-while语句和while语句的区别在于do-while是先执行后判断,因此do-while至少要执行一次循环体。
而while是先判断后执行,如果条件不满足,则一次循环体语句也不执行。
for语句
for语句是C语言所提供的功能更强,使用更广泛的一种循环语句。
其一般形式为:
for(表达式1;表达式2;表达3)
语句;
表达式1---- 通常用来给循环变量赋初值,一般是赋值表达式。
也允许在for语句外给循环变量赋初值,此时可以省略该表达式。
表达式2---- 通常是循环条件,一般为关系表达式或逻辑表达式。
表达式3---- 通常可用来修改循环变量的值,一般是赋值语句。
1.首先计算表达式1的值。
2.再计算表达式2的值,若值为真(非0)则执行循环体一次,否则跳出循环。
3.然后再计算表达式3的值,转回第2步重复执行。
在整个for循环过程中,表达式1只计算一次,表达式2和表达式,3则可能计算多次。
转移语句
在C语言中提供了4种转移语句:
goto,break,continue和return。
1.goto语句--------一般不使用
goto语句也称为无条件转移语句,其一般格式如下:
goto语句标号;其中语句标号是按标识符规定书写的符号,放在某一语句行的前面,标号后加冒号(:
)。
语句标号起标识语句的作用,与goto语句配合使用。
2.break语句
break语句只能用在switch语句或循环语句中,其作用是跳出switch语句或跳出本层循环,转去执行后面的程序。
由于break语句的转移方向是明确的,所以不需要语句标号与之配合。
break语句的一般形式为:
break;使用break语句可以使循环语句有多个出口,在一些场合下使编程更加灵活、方便。
3.continue语句
continue语句只能用在循环体中,其一般格式是:
continue;
其语义是:
结束本次循环,即不再执行循环体中continue语句之后的语句,转入下一次循环条件的判断与执行。
应注意的是,本语句只结束本层本次的循环,并不跳出循环。
第四章:
数组
1.数组定义如:
inta[10],b[3+2],c[7+FD];FD是常量
说明:
不能在方括号中用变量来表示元素的个数,但是可以是符号常数或常量表达式。
2.数组元素的表示方法
数组元素的一般形式为:
数组名[下标]如:
a[5],a[i+j],a[i++]
说明:
下标可以是变量或变量表达式
3.初始化赋值
一般形式为:
static类型说明符数组名[常量表达式]={值,值……值};
例:
staticinta[10]={0,1,2,3,4,5,6,7,8,9};
第五章:
函数
一.定义的一般形式
1.无参函数的一般形式----过程如:
voiddelay(void)
2.有参函数的一般形式
类型说明符函数名(形式参数表)
型式参数类型说明
{
类型说明
语句
}
说明:
return返回值命令
二.函数调用的一般形式为:
可以用以下几种方式调用函数:
1、z=max(x,y)是一个赋值表达式,把max的返回值赋予变量z。
另一种为现代格式,其一般形式为:
类型说明符被调函数名(类型形参,类型形参…);
函数的值只能通过return语句返回主调函数。
return语句的一般形式为:
return表达式;或者为:
return(表达式);
在C语言中,对变量的存储类型说明有以下四种:
auto 自动变量
register 寄存器变量
extern 外部变量
static 静态变量
第六章:
指针
1.指针变量的类型说明
其一般形式为:
类型说明符*变量名;
staicint*p2/*p2是指向静态整型变量的指针变量*/
说明:
定义时要使用*号
2.指针变量的赋值方法
(1)指针变量初始化的方法inta;
int*p=&a;/*定义并赋值*/
inta[5],*pa=a//或写成:
inta[5],*pa=&a[0]数组名也是数组的首地址
(2)赋值语句的方法inta;
int*p;//定义
p=&a;//赋值
说明:
定义后,再赋值这时不能加*号,它是一个指针变量
3.指针变量的运算
-------取地址运算符&,取内容运算符*
inta=5,*p=&a;//这里的*P是定义指针变量并赋值&a是表示指数据开的地址
printf("%d",*p);//这里的*P是表示取指针P地址中的内容
4.加减算术运算
对于指向数组的指针变量,可以加上或减去一个整数n。
设pa是指向数组a的指针变量,则pa+n,pa-n,pa++,++pa,pa--,--pa运算都是合法的。
第七章:
枚举,位运算
1.位运算符
&按位与
|按位或
^按位异或
~取反
<<左移
>>右移
二、汇编转向PICC
1.话言代码头文件:
#include<>,它是很多头文件的集合。
寄存器赋值比较:
C语言
汇编语言
PORTA=200
MOVLW200
MOVWFPORTA
说明:
C操作一个寄存器时候,不用考虑页面的问题,一切由C自动完成。
而汇编不行。
位操作的比较:
C语言
汇编语言
RA0=0
BCFPORTA,0
RA2=1
BSFPORTA,2
说明:
C中不用考虑页面问题。
内存分配问题:
C语言
汇编语言
INTX=5000
INTY=1000
INTZ=X/Y
在汇中定义一个内存是一件很小心的问题,要考虑太多的问题,C语言不需要考虑太多。
PICC简单延时程序:
voiddelay(uintm)
{
uinti,j;
for(i=0;i{
for(j=0;j<100;j++);
}
}
三、
1、PIC单片机的C语言原程序基本框架
特别注意:
main函数必须是一个没有返回的死循环。
#include<>//包含单片机内部资源预定义〈〈〈第一步〉〉〉
#include“”//包含自定义头文件
__CONFIG(HS&PROTECT&PWRTEN&BOREN&WDTDIS);//定义芯片工作时的配置位
voidSetSFR(void);//声明本模块中所调用的函数类型
voidClock(void);
voidKeyScan(void);
voidMeasure(void);
voidLCD_Test(void);
voidLCD_Disp(unsignedchar);
unsignedcharsecond,minute,hour;//定义变量
bitflag1,flag2;
voidmain(void)//函数和子程序
{
SetSFR();
PORTC=0x00;
TMR1H+=TMR1H_CONST;
LED1=LED_OFF;
LCD_Test();
while
(1)
{//程序工作主循环
asm(“clrwdt”);//清看门狗
Clock();//更新时钟
KeyScan();//扫描键盘
Measure();//数据测量
SetSFR();//刷新特殊功能寄存器
}
}
2、PICC中常用变量类型
bit1布尔型位变量,0或1两种取值
char8有符号或无符号字符变量,PICC缺省认定char型变量为无符号数,但可以通过编译选项改为
有符号字节变量
unsignedchar8无符号字符变量
3、PICC对数据寄存器bank的管理
如果没有特别指明,所定义的变量将被定位在bank0如:
bitflag1,flag2
除了bank0内的变量声明时不需特殊处理外,定义在其它bank内的变量前面必须加上相应的bank序号。
如:
bank2bitflag1,flag2;
为避免频繁的bank切换以提高代码效率,尽量把实现同一任务的变量定位在同一个bank内
4、PICC中的局部变量
PICC把所有函数内部定义的auto型局部变量放在bank0。
为节约宝贵的存储空间,它
采用了一种被叫做“静态覆盖”的技术来实现局部变量的地址分配。
但这时不能出现函数递归调用(自已调用自己)既然所有的局部变量将占用bank0的存储空间,因此用户自己定位在bank0内的变量字节数将受到一定的限制,在实际使用时需注意。
5、PICC中的位变量
bit型位变量只能是全局的或静态的。
PICC将把定位在同一bank内的8个位变量合并
成一个字节存放于一个固定地址
6、PICC的其它变量修饰关键词
(1)extern—外部变量声明例:
externbank1unsignedcharvar1,var2;声明bank1外部变量
(2)volatile—易变型变量声明例:
volatileunsignedcharSTATUS@0x03;
volatilebitcommFlag;
说明:
在单片机中,作为输入的IO端口其内容将是随意变化的;在中断内被修改的变量相对主程序流程来讲也是随意变化的;很多特殊功能寄存器的值也将随着指令的运行而动态改变。
所有这种类型的变量必须将它们明确定义成“volatile”类型
(3)const—常数型变量声明
例:
constunsignedcharname[]=”Thisisademo”;//定义一个常量字符串
(4)persistent—非初始化变量声明
例:
persistentunsignedcharhour,minute,second;//定义时分秒变量
按照标准C语言的做法,程序在开始运行前首先要把所有定义的但没有预置初值的变量全部清零。
PICC提供了“persistent”修饰词以声明此类变量无需在复位时自动清零。
7、PICC中的指针
(1)PICC在编译C原程序时将指向RAM的指针操作最终用FSR来实现
间接寻址。
这样就势必产生一个问题:
FSR能够直接连续寻址的范围是256字节(bank0/1
或bank2/3),要覆盖最大512字节的内部数据存储空间,又该如何让定义指针?
PICC还是将这一问题留给编程员自己解决:
在定义指针时必须明确指定该指针所适用的寻址区域,例
如:
unsignedchar*ptr0;//①定义覆盖bank0/1的指针
bank2unsignedchar*ptr1;//②定义覆盖bank2/3的指针
bank3unsignedchar*ptr2;//③定义覆盖bank2/3的指针
(2)指向ROM常数的指针
如果一组变量是已经被定义在ROM区的常数,那么指向它的指针可以这样定义:
constunsignedcharcompany[]=”Microchip”;//定义ROM中的常数
constunsignedchar*romPtr;//定义指向ROM的指针