PIC单片机如何从汇编转向PICC

发布者:心满意足最新更新时间:2020-01-06 来源: elecfans关键字:PIC单片机  汇编  PICC 手机看文章 扫描二维码
随时随地手机看文章

一、如何从汇编转向PICC

首先要求你要有C语言的基础。C代码的头文件一定要有#include,它是很多头文件的集合,C编译器在pic.h 中根据你的芯片自动载入相应的其它头文件。这点比汇编好用。载入的头文件中其实是声明芯片的寄存器和一些函数。


static volaTIle unsigned char TMR0 @ 0x01;

staTIc volaTIle unsigned char PCL @ 0x02;

staTIc volatile unsigned char STATUS @ 0x03;

可以看出和汇编的头文件中定义寄存器是差不多的。如下:

TMR0 EQU 0X01;

PCL EQU 0X02;

STATUS EQU 0X03;

都是把无聊的地址定义为大家公认的名字。

PIC单片机如何从汇编转向PICC

1、如何赋值?

如对TMR0 附值,汇编中:

MOVLW 200;

MOVWF TMR0;

当然得保证当前页面在0,不然会出错。

C语言:

TMR0=200;//无论在任何页面都不会出错。

可以看出来C是很直接了当的。并且最大好处是操作一个寄存器时候,不用考虑页面的问题。一切由

C自动完成。


2、如何位操作?

汇编中的位操作是很容易的。在C中更简单。C的头文件中已经对所有可能需要位操作的寄存器的每

一位都有定义名称:

如:PORTA 的每一个I/O口定义为:RA0、RA1、RA2。。。RA7。OPTION 的每一位定义为:PS0、

PS1、PS2 、PSA 、T0SE、T0CS、INTEDG 、RBPU。可以对其直接进行运算和附值。

如:

RA0=0;

RA2=1;

在汇编中是:

BCF PORTA,0;

BSF PORTA,2;

可以看出2 者是大同小异的,只是C 中不需要考虑页面的问题。


3、内存分配问题

在汇编中定义一个内存是一件很小心的问题,要考虑太多的问题,稍微不注意就会出错。比如16 位的

运算等。用C 就不需要考虑太多。下面给个例子:

16 位的除法(C 代码):

INT X=5000;

INT Y=1000;

INT Z=X/Y;

而在汇编中则需要花太多精力。

给一个小的C 代码,用RA0 控制一个LED 闪烁:

#include

void main()

{

int x;

CMCON=0B111; //掉A 口比较器,要是有比较器功能的话。

ADCON1=0B110; //掉A/D 功能,要是有A/D 功能的话。

TRISA=0; //RA 口全为输出。

loop:RA0=!RA0;

for(x=60000;--x;){;} //延时

goto loop;

}

说说RA0=!RA0 的意思:PIC 对PORT 寄存器操作都是先读取----修改----写入。上句的含义是程序先读RA0,然后取反,最后把运算后的值重新写入RA0,这就实现了闪烁的功能。


二、浅谈PICC 的位操作

由于PIC 处理器对位操作是最高效的,所以把一些BOOL 变量放在一个内存的位中,既可以达到运算速度快,又可以达到最大限度节省空间的目的。在C 中的位操作有多种选择。

*********************************************

如:char x;x=x|0B00001000;

char x;x=x & 0B11011111;

把上面的变成公式则是:

#define bitset(var,bitno)(var |=1《#define bitclr(var,bitno)(var &=~(1《则上面的操作就是:

char x;bitset(x,4);

char x;bitclr (x,5);

*************************************************

但上述的方法有缺点,就是对每一位的含义不直观,最好是能在代码中能直观看出每一位代表的意思,这样就能提高编程效率,避免出错。如果我们想用X 的0-2 位分别表示温度、电压、电流的BOOL 值可以如下:


unsigned char x @ 0x20;

bit temperature@ (unsigned)&x*8+0;

bit voltage@ (unsigned)&x*8+1;

bit current@ (unsigned)&x*8+2;

这样定义后X的位就有一个形象化的名字,不再是枯燥的1、2、3、4 等数字了。可以对X 全局修改,也可以对每一位进行操作:

char=255;

temperature=0;

if(voltage)。。.。。.

*****************************************************************

还有一个方法是用C 的struct 结构来定义,如:

struct cypok{

temperature:1;

voltage:1;

current:1;

none:4;

}x @ 0x20;

这样就可以用

x.temperature=0;

if(x.current)。。.。

等操作了。

**********************************************************

上面的方法在一些简单的设计中很有效,但对于复杂的设计中就比较吃力。如象在多路工业控制上。


前端需要分别收集多路的多路信号,然后再设定控制多路的多路输出。如:有2 路控制,每一路的前端信号有温度、电压、电流。后端控制有电机、喇叭、继电器、LED。如果用汇编来实现的话,是很头疼的事情,用C 来实现是很轻松的事情,这里也涉及到一点C 的内存管理(其实C 的最大优点就是内存管理)。


采用如下结构:

union cypok{

struct out{

motor:1;

relay:1;

speaker:1;

led1:1;

led2:1;

}out;

struct in{

none:5;

temperature:1;

voltage:1;

current:1;

}in;

char x;

};

union cypok an1;

union cypok an2;

上面的结构有什么好处呢?

细分了信号的路an1 和an2;

细分了每一路的信号的类型(是前端信号in 还是后端信号out):

an1.in ;

an1.out;

an2.in;

an2.out;

然后又细分了每一路信号的具体含义,如:

an1.in.temperature;

an1.out.motor;

an2.in.voltage;

an2.out.led2;等

这样的结构很直观的在2 个内存中就表示了2 路信号。并且可以极其方便的扩充。

如添加更多路的信号,只需要添加:

union cypok an3;

union cypok an4;

从上面就可以看出用C 的巨大好处。


三、PICC 之延时函数和循环体优化。

很多朋友说C 中不能精确控制延时时间,不能象汇编那样直观。其实不然,对延时函数深入了解一下就能设计出一个理想的框架出来。一般的我们都用for(x=100;--x;){;}此句等同与x=100;while(--x){;};或for(x=0;x《100;x++){;}。来写一个延时函数。

在这里要特别注意:X=100,并不表示只运行100 个指令时间就跳出循环。

可以看看编译后的汇编:

x=100;while(--x){;}

汇编后:

movlw 100

bcf 3,5

bcf 3,6

movwf _delay

l2 decfsz _delay

goto l2

return


从代码可以看出总的指令是是303 个,其公式是8+3*(X-1)。注意其中循环周期是X-1 是99 个。这里总结的是x 为char 类型的循环体,当x 为int 时候,其中受X 值的影响较大。建议设计一个char 类型的循环体,然后再用一个循环体来调用它,可以实现精确的长时间的延时。下面给出一个能精确控制延时的函数,此函数的汇编代码是最简洁、最能精确控制指令时间的:


void delay(char x,char y){

char z;

do{

z=y;

do{;}while(--z);

}while(--x);

}

其指令时间为:7+(3*(Y-1)+7)*(X-1)如果再加上函数调用的call 指令、页面设定、传递参数

花掉的7 个指令。则是:14+(3*(Y-1)+7)*(X-1)。如果要求不是特别严格的延时,可以用这个函数:

void delay(){

unsigned int d=1000;

while(--d){;}

}


此函数在4M 晶体下产生10003us 的延时,也就是10mS。如果把D 改成2000,则是20003uS,以此类推。有朋友不明白,为什么不用while(x--)后减量,来控制设定X 值是多少就循环多少周期呢?现在看看编译它的汇编代码:

bcf 3,5

bcf 3,6

movlw 10

movwf _delay

l2

decf _delay

incfsz _delay,w

goto l2

return


可以看出循环体中多了一条指令,不简洁。所以在PICC 中最好用前减量来控制循环体。

再谈谈这样的语句:

for(x=100;--x;){;}和for(x=0;x《100;x++){;}

从字面上看2 者意思一样,但可以通过汇编查看代码。后者代码雍长,而前者就很好的汇编出了简洁的代码。所以在PICC 中最好用前者的形式来写循环体,好的C 编译器会自动把增量循环化为减量循环。因为这是由处理器硬件特性决定的。PICC 并不是一个很智能的C 编译器,所以还是人脑才是第一的,掌握一些经验对写出高效,简洁的代码是有好处的。


四、深入探讨PICC之位操作

1、用位操作来做一些标志位,也就是BOOL变量.可以简单如下定义:

bit a,b,c;

PICC会自动安排一个内存,并在此内存中自动安排一位来对应a,b,c.由于我们只是用它们来简单的表示一些0,1信息,所以我们不需要详细的知道它们的地址\位究竟是多少,只管拿来就用好了。


2、要是需要用一个地址固定的变量来位操作,可以参照PIC.H里面定义寄存器。

如:用25H内存来定义8个位变量.

static volatile unsigned char myvar @ 0x25;

static volatile bit b7 @ (unsigned)&myvar*8+7;

static volatile bit b6 @ (unsigned)&myvar*8+6;

static volatile bit b5 @ (unsigned)&myvar*8+5;

static volatile bit b4 @ (unsigned)&myvar*8+4;

static volatile bit b3 @ (unsigned)&myvar*8+3;

static volatile bit b2 @ (unsigned)&myvar*8+2;

static volatile bit b1 @ (unsigned)&myvar*8+1;

static volatile bit b0 @ (unsigned)&myvar*8+0;

这样即可以对myvar操作,也可以对B0--B7直接位操作.

但不好的是,此招在低档片子,如C5X系列上可能会出问题.

还有就是表达起来复杂,你不觉得输入代码累么?呵呵


3、这也是一些常用手法

#definetestbit(var, bit)((var) & (1 《《(bit)))

//测试某一位,可以做BOOL运算

#definesetbit(var, bit)((var) |= (1 《《 (bit)))//把某一位置1

#defineclrbit(var, bit)((var) &= ~(1 《《 (bit)))//把某一位清0

附上一段代码,可以用MPLAB调试观察

#i nclude “pic.h”

#definetestbit(var, bit)((var) & (1 《《(bit)))

#definesetbit(var, bit)((var) |= (1 《《 (bit)))

#defineclrbit(var, bit)((var) &= ~(1 《《 (bit)))

char a,b;

void main()

关键字:PIC单片机  汇编  PICC 引用地址:PIC单片机如何从汇编转向PICC

上一篇:51单片机与AVR和PIC单片机之间的比较
下一篇:PIC单片机RC振荡器的使用及校准方法

推荐阅读最新更新时间:2024-10-31 20:36

PIC单片机 读/写 MMC/SD 卡的简单小程序
这里介绍一个简单的PIC单片机 读/写 MMC/SD 卡的小程序 // MMC module connections sbit Mmc_Chip_Select at LATC0_bit; // for writing to output pin always use latch (PIC18 family) sbit Mmc_Chip_Select_Direction at TRISC0_bit; // eof MMC module connections const LINE_LEN = 43; char err_txt = FAT16 not found ; char file_contents = X
[单片机]
<font color='red'>PIC单片机</font> 读/写 MMC/SD 卡的简单小程序
PIC单片机精通_串口通信模块C实现
1.串口通讯头/定义文件 usart.h #ifndef _SERIAL_H_ #define _SERIAL_H_ #define BAUD 9600 #define FOSC 9216000L #define NINE 0 /* Use 9bit communication? FALSE=8bit */ #define DIVIDER ((int)(FOSC/(16UL * BAUD) -1)) #define HIGH_SPEED 1 #if NINE == 1 #define NINE_BITS 0x40 #else #define NINE_BITS 0 #endif #if HIG
[单片机]
STM8与汇编语言(13)--修改CPU的时钟
在有些单片机的应用系统中,并不需要CPU运行在多高的频率。在低频率下运行,芯片的功耗会大大下降。因此希望单片机能提供这个功能,STM8单片机确实有这个功能,并且修改也非常方便。 下面的实验程序首先将CPU的运行时钟设置在8MHZ,然后快速闪烁LED指示灯。接着,通过修改主时钟的分频系数和CPU时钟的分频系数,将CPU时钟频率设置在500KHZ,然后再慢速闪烁LED指示灯。通过观察LED指示灯的闪烁频率,可以看到,同样的循环代码,由于CPU时钟频率的改变,闪烁频率和时间长短都发生了变化。 同样还是利用ST的开发工具,生成一个汇编程序的框架,然后修改其中的main.asm,修改后的代码如下。 stm8/ #inc
[单片机]
交换指令(5条)举例——mcs51单片机汇编语言
交换 指令 (5条) 这5条指令的功能是把累加器A中的内容与源操作数所指的数据相互交换。 XCH A,Rn ;(A)←→(Rn)累加器与工作寄存器Rn中的内容互换 XCH A,@Ri ;(A)←→((Ri))累加器与工作寄存器Ri所指的存储单元中的内容互换 XCH A,data ;(A)←→(data)累加器与直接地址单元中的内容互换 XCHD A,@Ri ;(A3-0)←→((Ri)3-0)累加器与工作寄存器Ri所指的存储单元中的内容低半字节互换 SWAP A ;(A3-0)←→(A7-4)累加器中的内容高低半字节互换
[单片机]
一种高性能便携式PIC单片机湿度检测仪的研制
    摘 要: 介绍了一种高性能便携式PIC单片机湿度检测仪的研制,详细阐明了有关的工作原理和关键技术。本测试仪充分应用PIC单片机自身的软硬件资源,具有智能化,小型便携、可编程等优点,在农业、水文系统、环境监测、气象等许多领域具有广泛的应用。     关键词: PIC单片机 湿度测试仪 土壤含水量     适时准确地测量周围环境的湿度和土壤含水量在国民经济发展的许多领域中具有广泛的应用,如在农业上为了科学地对土壤进行管理,需要经常测试土壤含水量;在水利工程中,如水文站、堤坝上也需经常测试土壤含水量,此外,土壤湿度测量在环保、气象、国防施工中更是不可缺少的测量项目。如何使这种繁琐的测量以及相关数据处理实现
[工业控制]
PIC单片机模拟异步串行通讯UART源程序
简介:用TMR0实现定时查询。任何带中断的PIC上都可以实现。可用此法扩展多个串口。 ;|--------------------------------------------------------------| ;| Implement duplex USART base on normal I/O pin | ;| Using TIMER0 interrupt for bit timing | ;| Tested on PIC16F83 running at 4MHz | ;| Written by Paul Zhang, Microchip Tech Inc
[单片机]
ARM汇编 控制伪指令之一
汇编控制伪指令用于控制汇编程序的执行流程,常用的汇编控制伪指令包括以下几条: IF 、 ELSE 、 ENDIF WHILE 、 WEND MACRO 、 MEND MEXIT 1、 IF、ELSE、ENDIF 语法格式: IF 逻辑表达式 指令序列 1 ELSE 指令序列 2 ENDIF IF 、 ELSE 、 ENDIF 伪指令能根据条件的成立与否决定是否执行某个指令序列。当 IF 后面的逻辑表 达式为真,则执行指令序列 1 ,否则执行指令序列 2 。其中, ELSE 及指令序列
[单片机]
Microchip新增低成本USB PIC单片机
2008年6月3日,单片机和模拟半导体供应商——Microchip Technology Inc.(美国微芯科技公司)今天宣布新增一系列支持USB应用的8位PIC®单片机(MCU)。PIC18F13K50及PIC18F14K50(PIC18F1XK50)是目前Microchip所有USB单片机中成本最低的,可提供多种其他平价8位单片机欠缺的功能,使得更多应用能添加嵌入式USB功能。 有了这一新的产品系列,Microchip现拥有业界最全面的8位、16位及32位USB单片机产品线,且均由单一集成开发环境——免费的MPLAB® IDE支持。该集成开发环境为所有PIC单片机提供了统一的开发平台,为设计工程师研发性能更高及功
[单片机]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved