admin 管理员组

文章数量: 887021


2023年12月23日发(作者:python flask实例)

PICC入门笔记

PIC单片机C语言编程入门笔记

一、 C语言基础复习--------没C语言基础看起来可能有点困难。

C程序的语句

语句名称 一般形式 说明

表达式语句 表达式 ; 表达式语句由表达式加上分号“;”组成

函数调用语函数名(实际参数表); 实际参数、形式参数二个概念要理解

控制语句 附件1 控制语句用于控制程序的流程

复合语句 多个语句用括号{}括起

空语句 ; 只有分号“;”组成的语句称为空语句

赋值语句 变量=(变量=表达式); 赋值表达式再加上分号构成的表达式语句

数据输出语printf(“格式控制字符

句 串”)

附件1

(1) 条件判断语句

if语句,switch语句

(2) 循环执行语句

do while语句,while语句,for语句

(3) 转向语句

break语句,goto语句,continue语句,return语句

关系运算符

小于 小于或等于 大于 大于或等于 等于 不等于

< <= > >= == !=

关系运算符都是双目运算符,其结合性均为左结合。在六个关系运算符中,<,<=,>,>=的优先级相同,高于==和!=,==和!=的优先级相同。

关系表达式的值是“真”和“假”,用“1”和“0”表示。

逻辑运算符

与运算 或运算 非运算

&& || !

&&和或运算符||均为双目运算符。具有左结合性。 非运算符”!”为单目运算符,具有右结合性,逻辑运算的值也为“真”和“假”两种,用“1”和“0 ”来表示。

单目运算符>算术运算符>关系运算符>逻辑运算符>赋值运算符

1

第三章: 控制语句

1.if语句

C语言的if语句有三种基本形式。

1、如果表达式的值为真,则执行其后的语句, 否则不执行该语句。

if(表达式) 语句;

2、如果表达式的值为真,则执行语句1,否则执行语句2 。

If(表达式)

语句1;

else

语句2;

3、依次判断表达式的值,当出现某个值为真时, 则执行其对应的语句。然后跳到整个if语句之外继续执行程序。 如果所有的表达式均为假,则执行语句n 。

然后继续执行后续程序。

If(表达式1)

语句1;

else if(表达式2)

语句2;

else if(表达式3)

语句3;

else if(表达式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;

}

其语义是:计算表达式的值。 并逐个与其后的常量表达式值相比较,当表达式的值与某个常量表达式的值相等时, 即执行其后的语句,然后不再进行判断,

2

继续执行后面所有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语句或跳

3

出本层循环,转去执行后面的程序。由于break语句的转移方向是明确的,所以不需要语句标号与之配合。break语句的一般形式为: break; 使用break语句可以使循环语句有多个出口,在一些场合下使编程更加灵活、方便。

3.continue语句

continue语句只能用在循环体中,其一般格式是: continue;

其语义是:结束本次循环,即不再执行循环体中continue 语句之后的语句,转入下一次循环条件的判断与执行。应注意的是, 本语句只结束本层本次的循环,并不跳出循环。

第四章: 数组

1.数组定义 如:int a[10],b[3+2],c[7+FD]; FD是常量

说明:不能在方括号中用变量来表示元素的个数, 但是可以是符号常数或常量表达式。

2.数组元素的表示方法

数组元素的一般形式为: 数组名[下标] 如:a[5],a[i+j],a[i++]

说明:下标可以是变量或变量表达式

3.初始化赋值

一般形式为: static 类型说明符 数组名[常量表达式]={值,值……值};

例:static int a[10]={ 0,1,2,3,4,5,6,7,8,9 };

第五章: 函数

一.定义的一般形式

1.无参函数的一般形式 ---- 过程 如:void delay(void)

2.有参函数的一般形式

类型说明符 函数名(形式参数表)

型式参数类型说明

{

类型说明

语句

}

说明:return 返回值命令

二.函数调用的一般形式为:

可以用以下几种方式调用函数:

1、z=max(x,y)是一个赋值表达式,把max的返回值赋予变量z。

另一种为现代格式,其一般形式为:

类型说明符 被调函数名(类型 形参,类型 形参…);

函数的值只能通过return语句返回主调函数。return 语句的一般形式为:

return 表达式; 或者为:return (表达式);

在C语言中,对变量的存储类型说明有以下四种:

auto 自动变量

register 寄存器变量

extern 外部变量

static 静态变量

4

第六章:指针

1.指针变量的类型说明

其一般形式为: 类型说明符 *变量名;

staic int *p2 /*p2是指向静态整型变量的指针变量*/

说明:定义时要使用 * 号

2.指针变量的赋值方法

(1)指针变量初始化的方法 int a;

int *p=&a; /*定义并赋值*/

int a[5],*pa=a //或写成: int a[5],*pa=&a[0] 数组名也是数组的首地址

(2)赋值语句的方法 int a;

int *p; //定义

p=&a; //赋值

说明:定义后,再赋值这时不能加 * 号,它是一个指针变量

3.指针变量的运算

-------取地址运算符&,取内容运算符*

int a=5,*p=&a; //这里的*P是定义指针变量并赋值 &a是表示指数据开的地址

printf ("%d",*p); //这里的*P是表示取指针P地址中的内容

4.加减算术运算

对于指向数组的指针变量,可以加上或减去一个整数n。设pa是指向数组a的指针变量,则pa+n ,pa-n ,pa++ ,++pa ,pa-- ,--pa 运算都是合法的。

第七章:枚举,位运算

1.位运算符

& 按位与

| 按位或

^ 按位异或

~ 取反

<< 左移

>> 右移

5

二、 汇编转向PICC

1.话言代码头文件:#include ,它是很多头文件的集合。

寄存器赋值比较:

C语言 汇编语言

PORTA=200 MOVLW 200

MOVWF PORTA

说明:C操作一个寄存器时候,不用考虑页面的问题,一切由C自动完成。而汇编不行。

位操作的比较:

C语言 汇编语言

RA0=0 BCF PORTA,0

RA2=1 BSF PORTA,2

说明:C中不用考虑页面问题。

内存分配问题:

C语言 汇编语言

INT X=5000 在汇中定义一个内存是一件很小心INTY=1000 的问题,要考虑太多的问题,C语言INT Z=X/Y 不需要考虑太多。

PICC简单延时程序:

void delay(uint m)

{

uint i,j;

for(i=0;i

{

for(j=0;j<100;j++);

}

}

6

三、

1、PIC 单片机的C 语言原程序基本框架

特别注意:main 函数必须是一个没有返回的死循环。

#include //包含单片机内部资源预定义 〈〈〈 第一步 〉〉〉

#include “pc68.h” //包含自定义头文件

__CONFIG (HS & PROTECT & PWRTEN & BOREN & WDTDIS); //定义芯片工作时的配置位

void SetSFR(void); //声明本模块中所调用的函数类型

void Clock(void);

void KeyScan(void);

void Measure(void);

void LCD_Test(void);

void LCD_Disp(unsigned char);

unsigned char second, minute, hour; //定义变量

bit flag1,flag2;

void main(void) //函数和子程序

{

SetSFR();

PORTC = 0x00;

TMR1H += TMR1H_CONST;

LED1 = LED_OFF;

LCD_Test();

while(1)

{ //程序工作主循环

asm(“clrwdt”); //清看门狗

Clock(); //更新时钟

KeyScan(); //扫描键盘

Measure(); //数据测量

SetSFR(); //刷新特殊功能寄存器

}

}

2、PICC 中常用变量类型

bit 1 布尔型位变量,0 或1 两种取值

char 8 有符号或无符号字符变量,PICC 缺省认定char 型变量为

7

无符号数,但可以通过编译选项改为

有符号字节变量

unsigned char 8 无符号字符变量

3、PICC 对数据寄存器bank 的管理

如果没有特别指明,所定义的变量将被定位在bank0 如:bit

flag1,flag2

除了bank0 内的变量声明时不需特殊处理外,定义在其它bank 内的变量前面必须加上相应的bank 序号。 如:bank2 bit

flag1,flag2 ;

为避免频繁的bank 切换以提高代码效率,尽量把实现同一任务的变量定位在同一个bank 内

4、PICC 中的局部变量

PICC 把所有函数内部定义的auto 型局部变量放在bank0。为节约宝贵的存储空间,它

采用了一种被叫做“静态覆盖”的技术来实现局部变量的地址分配。但这时不能出现函数递归调用(自已调用自己)既然所有的局部变量将占用bank0 的存储空间,因此用户自己定位在bank0 内的变量字节数将受到一定的限制,在实际使用时需注意。

5、PICC 中的位变量

bit 型位变量只能是全局的或静态的。PICC 将把定位在同一bank 内的8 个位变量合并

成一个字节存放于一个固定地址

6、PICC 的其它变量修饰关键词

(1)extern — 外部变量声明例:extern bank1 unsigned char var1,

var2; 声明bank1 外部变量

(2)volatile — 易变型变量声明 例: volatile unsigned char

STATUS @ 0x03 ;

volatile bit commFlag ;

说明:在单片机中,作为输入的IO 端口其内容将是随意变化的;在中断内被修改的变量相对主程序流程来讲也是随意变化的;很多特殊功能寄存器的值也将随着指令的运行而动态改变。所有这种类型的变量必须将它们明确定义成“volatile”类型

(3)const — 常数型变量声明

例:const unsigned char name[]=”This is a demo” ; //定义一个常量字符串

(4)persistent — 非初始化变量声明

例:persistent unsigned char hour,minute,second; //定义时分秒变量

8

按照标准C 语言的做法,程序在开始运行前首先要把所有定义的但没有预置初值的变量全部清零。PICC 提供了“persistent”修饰词以声明此类变量无需在复位时自动清零。

7、 PICC 中的指针

(1)PICC 在编译C 原程序时将指向RAM 的指针操作最终用FSR 来实现

间接寻址。这样就势必产生一个问题:FSR 能够直接连续寻址的范围是256 字节(bank0/1

或bank2/3),要覆盖最大512 字节的内部数据存储空间,又该如何让定义指针?PICC 还是将这一问题留给编程员自己解决:在定义指针时必须明确指定该指针所适用的寻址区域,例

如:

unsigned char *ptr0; //①定义覆盖bank0/1 的指针

bank2 unsigned char *ptr1; //②定义覆盖bank2/3 的指针

bank3 unsigned char *ptr2; //③定义覆盖bank2/3 的指针

(2)指向ROM 常数的指针

如果一组变量是已经被定义在ROM 区的常数,那么指向它的指针可以这样定义:

const unsigned char company[]=”Microchip”; //定义ROM 中的常数

const unsigned char *romPtr; //定义指向ROM 的指针

9


本文标签: 语句 变量 表达式 循环